Default Tags for Terraform AWS Provider is finally here

Default tags for Terraform AWS provider had been in the works since I started using Terraform a couple of years ago. Now that it is finally here, does it live up to its expectation?

What is Default Tags?

Default Tags allows its user to tag all AWS resources that support tags with the exception of the aws_autoscaling_group resource. Default Tags are defined in the AWS provider configuration, and AWS resources configured with that provider will inherit default_tags. A sample usage could be:

provider "aws" {
  region = "ap-southeast-1"
  default_tags {
    tags = {
      Environment = "dev"
      Project     = "example project"
      Terraform   = true
  }

You can read more about it here and here.

Default Tags in different scenarios

From the official blog post, it states that individual resource tags will take precedence over default_tags. Let’s see it in action with a few scenarios and observe its terraform plan output.

Scenario 1: Only resource tags, no default_tags

provider "aws" {
  region = "ap-southeast-1"
}
resource "aws_vpc" "tagging_test_vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name        = "tagging-test"
    Environment = "dev"
    Terraform   = true
  }
}

terraform plan output:
image

Here, we can see the existence of a tags_all attribute that has the same value as the original tags attribute. That being said, I’ve noticed this tags_all attribute for some time now in the newer versions of AWS provider. Let’s move on to the next scenario.

Scenario 2: Only default_tags, no resource tags

provider "aws" {
  region = "ap-southeast-1"
  default_tags {
    tags = {
      Environment = "stg"
      Name        = "tagging-test-3"
  }
}
resource "aws_vpc" "tagging_test_vpc" {
  cidr_block = "10.0.0.0/16"
}

terraform plan output:
image

Without resource tags, the tags attribute disappears, leaving only the tags_all attribute with the value inherited from default_tags from the AWS provider configuration.

Scenario 3: Conflicting tags

provider "aws" {
  region = "ap-southeast-1"
  default_tags {
    tags = {
      Environment = "stg"
      Name        = "tagging-test-3"
  }
}
resource "aws_vpc" "tagging_test_vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name        = "tagging-test"
    Environment = "dev"
    Terraform   = true
  }
}

terraform plan output:
image

Similar to what the official blog post mentioned, we can observe that resource tags take precedence over default tags when there is a conflict of tag name/key.

Scenario 4: Non-conflicting tags

provider "aws" {
  region = "ap-southeast-1"
  default_tags {
    tags = {
      environment   = "stg"
      name          = "tagging-test-3"
      provisionedby = "Terraform"
  }
}
resource "aws_vpc" "tagging_test_vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name        = "tagging-test"
    Environment = "dev"
    Terraform   = true
  }
}

terraform plan truncated output:
image

Since tag names/keys are case-sensitive, all the default_tag tags in this example will be effected for aws_vpc. The tags_all attribute shows a combined list from default and resource tags, while the tags attribute only shows the resource tags.

How this could affect your Terraform State design

In a medium-to-large-sized project, Terraform state separation is one of the early design considerations a team needs to settle on. If you don’t know what state is, check out this documentation first.

image

From HashiCorp

Each Terraform state culminates in a state file, and each state file has its own Terraform and provider configurations. Since default tags are a configured on the AWS provider level, being able to enforce different default tags in different states can make any mandatory organizational tagging requirements a breeze.

For example, if your organization has different tag values for each application, it might make sense to separate all applications into it’s own state and enforce their unique application tags at the provider level.

Terraform state design is a topic I’ve always seen a lot of discussion about. I will write about it in a future post.

Closing Thoughts

image

It’s good to know that Terraform and the AWS Provider is still well supported and constantly improved on. All in all, Terraform as an IaC tool is reaching a level of maturity that I’ve been looking forward to. With the current Terraform 0.15 touted as the “beginning of the pre-release period leading up to Terraform 1.0”, I think Terraform users can expect a lot of exciting and useful releases in the coming weeks and months.

Leave a comment

Your email address will not be published. Required fields are marked *