Expressions in outputs

This may be by design and I’m not sure if it’s an issue with terraform or the provider. I use an expression in an output to generate a list of maps. But the output differs between the terraform outputs command & the actual output that terraform returns as a result of an apply.

My expression.

output "org_children" {
  value = {for r in data.aws_organizations_organizational_units.ou.children : r.name => r...}
}

However terraform output returns the output from the original resource and not the version of the expression. I use terragrunt which wraps terraform and uses the outputs from the terraform outputs command. So I can’t get access to the data that I want to pass using dependencies within terragrunt.

I suppose the question is should terraform not store the output value with the expression?

the module outputs the following.

org_children = {
  "Development" = [
    {
      "arn" = "arn:aws:organizations::123456789123:ou/o-2aa2aaa2a2/ou-aaaa-333rrrr3"
      "id" = "ou-cccc-444cccc4"
      "name" = "Development"
    },
  ]
  "Non-Prod" = [
    {
      "arn" = "arn:aws:organizations::123456789123:ou/o-2aa2aaa2a2/ou-aaaa-333rrrr3"
      "id" = "ou-cccc-444cccc4"
      "name" = "Non-Prod"
    },
  ]
  "Production" = [
    {
      "arn" = "arn:aws:organizations::123456789123:ou/o-2aa2aaa2a2/ou-aaaa-333rrrr3"
      "id" = "ou-cccc-444cccc4"
      "name" = "Production"
    },
  ]
  "Testing" = [
    {
      "arn" = "arn:aws:organizations::123456789123:ou/o-2aa2aaa2a2/ou-aaaa-333rrrr3"
      "id" = "ou-cccc-444cccc4"
      "name" = "Testing"
    },
  ]
}

However terraform outputs shows the following.

"org_children": {
  "value": [
    {
      "arn" = "arn:aws:organizations::123456789123:ou/o-2aa2aaa2a2/ou-aaaa-333rrrr3"
      "id" = "ou-cccc-444cccc4"
      "name": "Testing"
    },
    {
      "arn" = "arn:aws:organizations::123456789123:ou/o-2aa2aaa2a2/ou-aaaa-333rrrr3"
      "id" = "ou-cccc-444cccc4"
      "name": "Development"
    },
    {
      "arn" = "arn:aws:organizations::123456789123:ou/o-2aa2aaa2a2/ou-aaaa-333rrrr3"
      "id" = "ou-cccc-444cccc4"
      "name": "Non-Prod"
    },
    {
      "arn" = "arn:aws:organizations::123456789123:ou/o-2aa2aaa2a2/ou-aaaa-333rrrr3"
      "id" = "ou-cccc-444cccc4"
      "name": "Production"
    }
  ],
  "type": [
    "list",
    [
      "object",
      {
        "arn": "string",
        "id": "string",
        "name": "string"
      }
    ]
  ]
},
1 Like

Hi @robh007! I can’t quite follow what could be happening based on your original message. Could you create a small reproduction configuration to help me understand?

Here’s what I did to try to reproduce this issue. Create a main.tf file which converts a list of maps to an output map of maps, using the same expression:

locals {
  animals = [
    {
      "name": "dog",
      "says": "bark",
    },
    {
      "name": "cat",
      "says": "miaow",
    },
  ]
}

output "animal_sounds" {
  value = { for a in local.animals : a.name => a... }
}

Run terraform apply -auto-approve:

$ terraform apply -auto-approve

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

animal_sounds = {
  "cat" = [
    {
      "name" = "cat"
      "says" = "miaow"
    },
  ]
  "dog" = [
    {
      "name" = "dog"
      "says" = "bark"
    },
  ]
}

Run terraform output:

$ terraform output
animal_sounds = {
  "cat" = [
    {
      "name" = "cat"
      "says" = "miaow"
    },
  ]
  "dog" = [
    {
      "name" = "dog"
      "says" = "bark"
    },
  ]
}

To your question:

should terraform not store the output value with the expression?

Terraform does store the evaluated output value in the state file. I’m not sure what you mean by “with the expression”.

I think I know what’s happening now. I’ve got an old state in my module directory. Terragrunt copies the content of that module directory. I’ve just created a new directory to provide you with an example and that’s triggered the light bulb moment… thanks for looking into this for me though.

1 Like