Dynamically generate resources blocks and content based on map (for_each/for)

Hi Guys,

I need to dynamically generate an entire resource block based on a map. So, in one file, I need something like the following, repeated for each.value:

variable "my_map" {
  type = "map"
  default = {
    key1 = "key1val",
    key2 = "key2val"
  }
}
# do the following for each entry in my_map
resource "vault_policy" "${each.key}-admin" {
  name="${each.value}-admin"
  path "ab/cd/ef/${each.value}" {
    capabilities = ["list"]
  }
  path "gh/ij/kl/${each.value}" {
    capabilities = ["list", read"]
 }
} 

How can I achieve this for_each? So far what I’ve tried is not working. Note that I’ve successfully generated one single resource block with a bunch of path definitions based on a map, but I don’t exactly know what the syntax should look like for generating repeated resource blocks.

Thanks for feedback/help.

Hi @nena-007! I have a feeling I already answered this question somewhere else yesterday :smile: but I’ll post an answer here too for posterity!

variable "my_map" {
  type = "map"
  default = {
    key1 = "key1val",
    key2 = "key2val"
  }
}

# do the following for each entry in my_map
resource "vault_policy" "admin" {
  name = "${each.value}-admin"
  policy = <<-EOT
    path "ab/cd/ef/${each.value}" {
      capabilities = ["list"]
    }
    path "gh/ij/kl/${each.value}" {
      capabilities = ["list", "read"]
    }
  EOT
} 

This will create instances with addresses vault_policy.admin["key1"] and vault_policy.admin["key2"].

Note that this isn’t really “multiple resource blocks”… instead, in Terraform’s terminology, what we have here is a single resource vault_policy.admin which has two instances vault_policy.admin["key1"] and vault_policy.admin["key2"]. One interesting consequence of that distinction is that you can refer to vault_policy.admin elsewhere in your configuration and get a map of objects representing all of the instances. That probably isn’t particularly useful in this case because policies tend to be a “leaf” node not referred to by other resources, but can be useful for chaining for_each usage across multiple resources where one resource has its for_each set to another resource’s map:

  for_each = vault_policy.admin