Generate dynamic text block with the same name variable

Hello there,

I’m trying to generate some Vault policies with the help of Terraform.

Here is the kind of policies I want:

team1_policy
path "services/service1-1" {
  capabilities = ["create", "read", "update", "list"]
}
path "services/service1-2" {
  capabilities = ["create", "read", "update", "list"]
}

team2_policy
path "services/service2-1" {
  capabilities = ["create", "read", "update", "list"]
}
path "services/service2-2" {
  capabilities = ["create", "read", "update", "list"]
}

On Terraform side, here is what I have:

#local.services_per_teams comes from an external data
#local.services_per_teams =
#{
#      "team1" = "service1-1, service1-2",
#      "team2" = "service2-1, service2-2"
#}
locals {
  services-list = flatten([
    for team in keys(local.services_per_teams) : [
      for service in split(",","${local.services_per_teams[team]}") : {
        team   = team
        service = service
      }
    ]
  ])
}

resource "vault_policy" "team_policy" {

  for_each = {
    for service_id in local.services-list : "${service_id.team}.${service_id.service}" => service_id
  }

  name = "${each.value.team}_policy"
  policy = <<EOT
path "services/${each.value.service}" {
  capabilities = ["create", "read", "update", "list"]
}
EOT

}

The idea is to keep the same name policy but to append the policy variable with the services.

I tried to use the following example, but it is looping and just create a huge block with the same “service name”.

policy = <<EOT
%{ for service in local.services-list ~}
path "services/${service}" {
  capabilities = ["create", "read", "update", "list"]
}
%{ endfor ~}
EOT

Can you help me on that one?

Thank you

Well, I guess I just needed a break to gather my thoughts. I was finally able to solve my issue by simplifying my code.

For posterity:

resource "vault_policy" "team_policy" {

  for_each = local.services_per_teams

  name = "${each.key}_policy"
  policy = <<EOT
%{ for service in split(",","${each.value}") ~}
path "services/${service}" {
  capabilities = ["create", "read", "update", "list"]
}
%{ endfor ~}
EOT

}

I removed completely my flatten structure and directly used the result I was getting from my external data.