Spechal
Spechal

Reputation: 2706

How do I output an attribute of multiple instances of a resource created with for_each?

Let's say I have a map of environments to supply to for_each

environments = {
    "0" = "dev"
    "1" = "test"
    "2" = "stage"
}

Then for whatever reason I want to create an Azure Resource Group for each environment.

resource "azurerm_resource_group" "resource_group" {
  for_each = var.environments
  name     = "${var.resource-group-name}-${each.value}-rg"
  location = var.location
}

How do I get the outputs? I've tried the new splat to no avail.

output "name" {
  value = "${azurerm_resource_group.resource_group[*].name}"
}

output "id" {
  value = "${azurerm_resource_group.resource_group[*].id}"
}

output "location" {
  value = "${azurerm_resource_group.resource_group[*].location}"
}

Error: Unsupported attribute

in output "id":
   6:   value = "${azurerm_resource_group.resource_group[*].id}"

This object does not have an attribute named "id".

How do I output an attribute of multiple instances of a resource created with for_each?

Upvotes: 5

Views: 3640

Answers (2)

Martin Atkins
Martin Atkins

Reputation: 74109

The [*] is a shorthand for extracting attributes from a list of objects. for_each makes a resource appear as a map of objects instead, so the [*] operator is not appropriate.

However, for expressions are a more general mechanism that can turn either a list or a map into another list or map by evaluating an arbitrary expression for each element of the source collection.

Therefore we can simplify a map of azurerm_resource_group objects into a map of names of those objects like this:

output "name" {
  value = { for k, group in azurerm_resource_group.resource_group: k => group.name }
}

Your input map uses numeric indexes as keys, which is unusual but allowed. Because of that, the resulting value for the output would be something like this:

{
  "0" = "something-dev-rg"
  "1" = "something-test-rg"
  "2" = "something-stage-rg"
}

It's more common for a map in for_each to include a meaningful name as the key, so that the resulting instances are identified by that meaningful name rather than by incrementing integers. If you changed your configuration to use the environment name as the key instead, the map of names would look like this instead:

{
  "dev"   = "something-dev-rg"
  "test"  = "something-test-rg"
  "stage" = "something-stage-rg"
}

Upvotes: 6

karthikeayan
karthikeayan

Reputation: 5000

EDIT: for_each doesn't work with output

output "name"{
  value = { for k, v in var.environments : v => azurerm_resource_group.resource_group[k].name }
}

output "id"{
  value = { for k, v in var.environments : v => azurerm_resource_group.resource_group[k].id }
}

output "location"{
  value = { for k, v in var.environments : v => azurerm_resource_group.resource_group[k].location }
}

Example output,

id = {
  "dev" = "xxx"
  "stage" = "yyy"
  "test" = "zzz"
}

Upvotes: 1

Related Questions