Home > Back-end >  Terraform - Get a value from map output
Terraform - Get a value from map output

Time:08-10

I have created AWS IAM groups using aws_iam_group and for_each loop

resource "aws_iam_group" "all" {
  for_each = toset(local.groups)
  name     = each.key
  path     = "/"
}

Then I am outputting all groups

output "groups" {
  value = aws_iam_group.all
}

This is the result after running terraform output groups

{
  "developer" = {
    "arn" = "arn:aws:iam::*********:group/developer"
    "id" = "developer"
    "name" = "developer"
    "path" = "/"
    "unique_id" = "**************"
  }
  "devops" = {
    "arn" = "arn:aws:iam::*********:group/devops"
    "id" = "devops"
    "name" = "devops"
    "path" = "/"
    "unique_id" = "**************"
  }
}

My question:

How to get single group from the output using terraform output command?

CodePudding user response:

If you want to get only one value for the group name, I don't think that is possible to achieve with output the way you have specified it. However, what you could do is define another output and do the following:

output "developer_group" {
  value = aws_iam_group.all["developer"].arn
}

On the other hand, if you don't want another output, what you could do is use the values built-in function [1] to get only the values for the key-value pairs that are created with the for_each loop. To do so, you would need to change the output to:

output "groups" {
  value = values(aws_iam_group.all)[*].arn
}

This will output all the ARNs for all the groups and that will be a list:

groups = [
  "arn:aws:iam::*********:group/developer",
  "arn:aws:iam::*********:group/devops",
]

One last option could be to use the values built-in function but instead of using the wildcard ([*]), you would specify only the index for which you want to output the value:

output "groups" {
  value = values(aws_iam_group.all)[0].arn
}

Bear in mind that if the order in the output changes in the last example, you will probably get the ARN of a wrong group. The last example is effectively the same as the first one.

EDIT: In the light of the comments, there would need to be a couple of adjustments. I will use groups as an example for the shell script but it should be applicable to users as well since they are created the same way. The first thing to do is use the jsonencode built-in function [2], and convert the output to JSON data. Then, it can be used with jq to fetch whatever you need. So, the groups outputs would then be:

output "groups" {
  value = jsonencode(aws_iam_group.all)
}

Then, in the shell script, you could do something like:

#!/bin/bash

GROUP=$1
GROUP_ARN=$(terraform output groups | jq -r . | jq ".${GROUP}.arn")

echo ${GROUP_ARN}

[1] https://www.terraform.io/language/functions/values

[2] https://www.terraform.io/language/functions/jsonencode

CodePudding user response:

@sam ben, This should work
aws_iam_group.all["developer"].arn

since "all" is a list, we are using a specific item from the list (developer in this case) and then referring to a specific item from the "developer" (arn in the given case).

  • Related