9

To attach multiple tags to a resource, I currently use multiple tag blocks:

resource "aws_autoscaling_group" "instance" {
  ...

  tag {
    key                 = "Name"
    value               = "${var.cluster_prefix}"
    propagate_at_launch = true
  }

  tag {
    key                 = "Owner"
    value               = "${var.tag_Owner}"
    propagate_at_launch = true
  }

  tag {
    key                 = "Project"
    value               = "${var.tag_Project}"
    propagate_at_launch = true
  }
}

It works, but I wonder if there is a more concise syntax. It is also a bit error prone as you have to specify propagate_at_launch for each tag.

Update: The question was written before Terrafrom v0.12 came out. Since then the support has improved with Dynamic Nested Blocks (see my answer below).

7

For an auto-scaling-group this is the most concise syntax available.

For most other resources you use the tags syntax which looks like:

tags {
  Key1 = "value1"
  Key2 = "value2"
}
2

Terraform v0.12 added support for Dynamic Nested Blocks. The following example is derived from their blog post about the new features (see section Dynamic Nested Blocks):

locals {
  standard_tags = {
    Name    = var.cluster_prefix
    Owner   = var.tag_Owner
    Project = var.tag_Project
  }
}

resource "aws_autoscaling_group" "example" {
  # ...

  dynamic "tag" {
    for_each = local.standard_tags

    content {
      key                 = tag.key
      value               = tag.value
      propagate_at_launch = true
    }
  }
}
1

Another option is to use the terraform-null-label module. It supports passing a variable called tags as a standard Terraform map. The module then emits an output called tags_as_list_of_maps which contains the tags in the format you want. But an even better reason to use this module is to generate a consistent set of resource names that follow a fixed convention.

For example, you can do this:

module "example" {
  source     = "git::https://github.com/cloudposse/terraform-null-label.git?ref=master"
  namespace  = "eg"
  stage      = "prod"
  name       = "bastion"
  tags       = { 
                 "BusinessUnit" = "XYZ" 
                 "Snapshot" = "true"
               }
}

So from your example, we can then write something like this:

resource "aws_autoscaling_group" "instance" {
  ...
  name = "${module.example.id}"
  ...
  tags = "${module.example.tags_as_list_of_maps}"
  ...
}

NOTE: I added the name field to show how to generate co

  • What would be the best way to make "name" uniq to each ressource? if you use the null-label module every "name" on the ressources is the same. What if you want to name your subnets with a suffix like -private-subnet? Is there a way the null-label can handle that? – Izac Jun 27 at 15:27
0

The aws_autoscaling_group does support a list of tags now (https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html#tags). But this looks a bit different to the syntax of other terraform resources:

tags = [
  {
    key                 = "explicit1"
    value               = "value1"
    propagate_at_launch = true
  },
  {
    key                 = "explicit2"
    value               = "value2"
    propagate_at_launch = true
  },
]

This also allows to dynamically build tags via interpolation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.