Search code examples
amazon-web-servicesterraforminfrastructure-as-code

Terraform iterate over map and create nested resources


I'm trying to iterate over a map and create some additional settings in the aws_codebuild_project. This is my first time working with loops in Terraform. My main source of confusion is that I do not know if a resource has to "support" loops, or if it is possible to iterate almost everywhere inside a resource?

variable "custom_environment_variables" {
  type    = map(any)
  default = {}
}

resource "aws_codebuild_project" "my_project" {
  # other props...

  environment {
    type = "LINUX_CONTAINER"
    # more props

    # some hardcoded environment_variable
    environment_variable {
      name  = "APP_STAGE"
      value = var.app_stage
    }
    # some dynamic environment_variable
    dynamic "custom_environment_variable" {
      for_each = var.custom_environment_variables
      environment_variable {
        name  = custom_environment_variable.key
        value = custom_environment_variable.value
      }
    }
  }
}

this code causes this error:

│ Error: Unsupported block type
│ 
│   on ../modules/static_web_pipeline/main.tf line 155, in resource "aws_codebuild_project" "my_project":
│  155:     dynamic "custom_environment_variable" {
│ 
│ Blocks of type "custom_environment_variable" are not expected here.

Solution

  • The name of the dynamic block has to match the name of the block to be created and within the block the name has to be content:

    dynamic "environment_variable" {
      for_each = var.custom_environment_variables
      content {
        name  = environment_variable.key
        value = environment_variable.value
      }
    }
    

    To answer "My main source of confusion is that I do not know if a resource has to "support" loops, or if it is possible to iterate almost everywhere inside a resource?":

    No, a resource does not need to "support" loops, but you can still not iterate everything and everywhere. You can only iterate blocks and since the resource supports the block environment_variable you can can use a dynamic block to create multiple environment_variable blocks. Think of the iteration as a core terraform feature, the resource itself does not ever see the iteration or know about it, the resource only sees multiple environment_variable blocks as if you would have typed them manually.