Since terraform version 0.12 you are able to use terraform for_each under dynamic blocks, but with the latest version, you are now also able to reference for_each under resource as well.

Given last update of terraform to version 0.12.6 you are now able to use for_each using resources.

So how exactly may you use for_each to both dynamically create multiple resources of the same kind.

Terraform for_each multiple resource creation

So first, let’s explore the creation of multiple resources, and how to actually reference them in outputs so we may reuse them.

For this example we will use the ecr_repository resource, something that is quite useful is to create multiple resources.

Example of how we may actually use it:

variable "images" {
    type = list(string)
    default = ["nginx", "jenkins", "keycloak"]
}

locals{
    images = { for v in var.images : v => v }
}

resource "aws_ecr_repository" "default" {
  for_each = local.images
  name  = "${each.key}"

So, what is happening above with the local variables and their usage below with each.key?

When you define for_each in a resource, it expects either a set, or a map, so you may not pass a list directly as we are using in our own variable, so first we must convert it to a map to use it.

Why aren’t we using the toset(var.images) method here? Well, for the time being, toset will make it unusable, as it won’t convert correctly dynamic values, as it expects a well defined list ahead, so when using variables, it will complain.

Ok, so we managed to have multiple repositories created, but how may we now reference them in a output?

Example of how we may reference created resources with for_each under an output object.

output "registries_url" {
  value = {
    for instance in aws_ecr_repository.default:
    instance.name => instance.repository_url
  }
  description = "Registry URL"
}

So now, we are also creating a map from all the resources created, as an output from the created resources. In this example we want the registry urls created.

So imagine this would be a module.

You could reference a specific image the following way:

...we have our module defined above 

resource "null_resource" "example" {

  provisioner "local-exec" {
      command = "echo ${module.ecr_custom.registries_url.nginx}"
  } 
}

And that’s it for how to use for_each resource with terraform.

On our next post, we will check on how to use this feature, to conditionally create resources without the use of error-prone count

André Ilhicas dos Santos

Devops Padawan, curious about systems automation, learning new languages, paradigms tools each day.

ilhicas ilhicas


Published