Search code examples
amazon-web-servicesamazon-ec2tagsterraform

Can I create a map of {instanceid: valueOfNameTag} using terraform data?


I want to get a map using terraform data which has the following structure:

{
  instance-id(e.g. i-xxxx): ValueOfNameTag(e.g. MongoDB)
}

I can get the instance details individually like below

data "aws_instance" "test" {
  instance_id = "i-0ecb3c2fb4436b6fe"
}

But don't know hot to do it for all and create a map out of it.


Solution

  • This is essentially a three step process. The first step (already exists according to comments) is to retrieve the desired list of instance IDs:

    data "aws_instances" "this" {
      # arguments to select specific subset of instances
    }
    

    The list(string) of instances IDs will be stored in the exported resource attribute ids.

    The second step is to retrieve the tags of each individual instance:

    data "aws_instance" "this" {
      # iterate over subset of desired instances by ID
      for_each = toset(data.aws_instances.this.ids)
    
      instance_id = each.value
    }
    

    The tags for each instance will be stored in the exported resource attribute tags, and therefore can be accessed via the namespace data.aws_instance.this["<instance id>"].tags as per normal in Terraform HCL2 DSL.

    The third step is to perform a data transformation to construct a map where the key is the instance ID, and the value of a tag is the value. The example given in the question was for the value of the Name tag, so that is what we will use here in the example:

    locals {
      instance_name = { for id, attributes in data.aws_instance.this : id => attributes.tags["Name"] }
    }
    

    and the desired map of instance IDs to their respective Name tag will be stored in local.instance_name as expected. You could alternatively iterate over the data.aws_instances.this.ids list(string) in a for lambda expression and map to the exported attributes from the data.aws_instance.this[each.value].tags["Name"], but the above algorithm is slightly cleaner and slightly more efficient.