A Akrm
A Akrm

Reputation: 99

Dynamic block with optional data

let say we have this locals:

locals = {
  schemas = [
    {
      name                = "is_cool"
      attribute_data_type = "Boolean"
      mutable             = true
      required            = false
    },
    {
      name                = "firstname"
      attribute_data_type = "String"
      mutable             = true
      required            = false
      min_length          = 1
      max_length          = 256
    }
  ]
}

What I would like to achieve is to use dynamic to build schemas and when the schema is a string I would like to add the string_attribute_constraints block.

This is what I did so far but it adds an empty string_attribute_constraints block when the schema is Boolean

dynamic "schema" {
  for_each = var.schemas
  content {
    name                = schema.value.name
    attribute_data_type = schema.value.attribute_data_type
    mutable             = schema.value.mutable
    required            = schema.value.required

    string_attribute_constraints {
      min_length = lookup(schema.value, "min_length", null)
      max_length = lookup(schema.value, "max_length", null)
    }
  }
}

terraform plan:

      + schema {
          + attribute_data_type = "Boolean"
          + mutable             = true
          + name                = "is_cool"
          + required            = false

          + string_attribute_constraints {}
        }

Upvotes: 0

Views: 357

Answers (2)

Hanoj B
Hanoj B

Reputation: 371

dynamic "schema" {
    for_each = local.my_schema
    content {
      name                = schema.value.name
      attribute_data_type = schema.value.attribute_data_type
      mutable             = schema.value.mutable
      required            = schema.value.required

      dynamic "string_attribute_constraints" {
        for_each = schema.value.attribute_data_type == "String" ? [1] : []
        content {
          min_length = lookup(schema.value, "min_length", 0)
          max_length = lookup(schema.value, "max_length", 2048)
        }
      }

      dynamic "number_attribute_constraints" {
        for_each = schema.value.attribute_data_type == "Number" ? [1] : []
        content {
          min_value = lookup(schema.value, "min_value", 0)
          max_value = lookup(schema.value, "max_value", 2048)
        }
      }
    }
  }

Upvotes: 0

Martin Atkins
Martin Atkins

Reputation: 74249

You can use a second nested dynamic block to tell Terraform how many string_attribute_constraints blocks to generate based on your rule:

dynamic "schema" {
  for_each = var.schemas
  content {
    name                = schema.value.name
    attribute_data_type = schema.value.attribute_data_type
    mutable             = schema.value.mutable
    required            = schema.value.required

    dynamic "string_attribute_constraints" {
      for_each = schema.attribute_data_type == "String" ? [1] : []
      content {
        min_length = lookup(schema.value, "min_length", null)
        max_length = lookup(schema.value, "max_length", null)
      }
    }
  }
}

This works by making the for_each for the nested dynamic be an empty list in the case where we don't want to generate any blocks, and making it a single-element list in the case where we do. Since we need no references to string_attribute_constraints.key or string_attribute_constraints.value inside the block, we can set the value of the single element to anything, and so I just set it to 1 as an arbitrary placeholder.

Upvotes: 3

Related Questions