Terraform count[index] with looping list of variables

40 Views Asked by At

I want to create a resource block where my first resource is created based on each value in json. My second resource is dependent on the first resource id, so I am referring with count[index].id but the second resource block need to be looped as per the number of email values. Multiple Second resources will be created for one first resource value.

file.json

[
    {
        "name": "one",
        "env": "dev",
        "org": "IT",
        "email": "[email protected], [email protected]"
    },
    {
        "name": "two",
        "env": "stg",
        "org": "HR",
        "email": "[email protected], [email protected], [email protected]"
    }
]

main.tf

locals {
        data = jsondecode(file("${path.module}/file.json"))
    }

First resource will be created for each value in json

resource "aws_sagemaker_domain" "domain" {
    count = length(local.data)
    domain_name = local.data[count.index].name
}

Second resource has a reference to first resource and need to be looped for each email value. One aws_sagemaker_domain.dmain.id will have one or many aws_sagemaker_user_profile associated based on email value.

I know we cannot use for each and count together in a resource block, I have just shown to explain what I wanted to achieve. Any help is appreciated on how this can be written.

resource "aws_sagemaker_user_profile" "user_profile"
    count = length(local.data)
    domain_id = aws_sagemaker_domain.domain[count.index].id
    for_each = split(",", local.data[count.index].email)
    user_profile_name = each.value
}

error: the count and for_each meta-arguments are mutually-exclusive, only one should be used to ve explicit about the number of resources to be created.

1

There are 1 best solutions below

1
Marcin On BEST ANSWER

You have to flatten you data:

locals {
  data_flat = merge([
    for idx, domain in local.data: {
      for email in split(",", domain.email): 
          "${domain.name}-${email}" => {
                "index": idx 
                "name": domain.name
                "env": domain.env
                "org": domain.org
                "email": email
          }        
    }
  ]...) # do NOT remove the dots
}

Then

resource "aws_sagemaker_user_profile" "user_profile"
    for_each = local.data_flat
    domain_id = aws_sagemaker_domain.domain[each.value.index].id
    user_profile_name = each.value.email
}