Introduction
In version 3.38.0 and later of the Terraform AWS Provider, a default_tags
argument is available in the provider
configuration block. This argument allows for tagging of all resources that currently support the tags
argument. It is intended as an alternative to the repetitive nature of applying the same tags repeatedly across all resources.
Fix to Known Issues
Version 5.0.0 of the provider introduced several fixes to the issues identified below. Please follow the upgrade guide and check if upgrading the provider to version 5+ avoids these issues.
Known Issues
There are several issues to avoid when using both default_tags
at the provider level and tags
at the resource level.
1. Exactly identical default_tags
and tags
arguments produce the error:
Error: "tags" are identical to those in the "default_tags" configuration block of the provider: please de-duplicate and try again
Example configuration that produces the above error:
provider "aws" { default_tags { tags = { Name = "Example" } } } resource "aws_vpc" "example" { tags = { Name = "Example" } }
This issue is reported in GitHub Issue #19204. This provider will not allow fully matching tags in both of these argument blocks.
2. Partially identical default_tags
and tags
arguments cause a planned update change when there is no change to either argument
Example configuration that produces this issue:
provider "aws" { default_tags { tags = { Match1 = "A"
Match2 = "B"
NoMatch = "X" } } } resource "aws_vpc" "example" { tags = { Match1 = "A"
Match2 = "B"
NoMatch = "Y" } }
After initial terraform apply
, all subsequent plans will result in a "perpetual diff". Running terraform plan
again on the example configuration shows a update to the matching tags Match1
and Match2
even though there hasn't been any change to these tags:
# aws_vpc.example will be updated in-place
~ resource "aws_vpc" "example" {
...
~ tags = {
+ "Match1" = "A"
+ "Match2" = "B"
# (1 unchanged element hidden)
}
# (28 unchanged attributes hidden)
This is a known issue also discussed in the comments of issue #19204. The provider does not gracefully handle identical tags in default_tags
and tags
.
3. There is no way to exclude resources from default_tags
This is noted in the documentation for default_tags
. Tags from default_tags
can only be overridden, not excluded, in individual resources.
Cause
The concept of "global" tagging was a design implemented by the default_tags
feature of the Terraform AWS Provider. There is no corresponding concept in AWS, and there is no property in AWS API responses that exposes whether tags were created at a global or a resource level for a given resource. This results in a difficulty deciding how to categorize tag data that has not been fully resolved. Further discussion can be found on GitHub here.
Workarounds
The primary recommendation is to not use identical tags in both default_tags
at the provider level and tags
at the resource level. Resource-level tags should only be used to override global tags or to apply tags specific to that resource.
If your configuration already contains a combination of identical and unique tags across resources and in the default_tags
block, there are multiple options for avoiding the perpetual diff scenario:
- Remove particular
tags
from individual resources if they are not overriding thedefault_tags
. - Remove particular
default_tags
for thosetags
which all resources already define. -
Stop using
default_tags
entirely and configuretags
directly in resources. - Stop using
default_tags
entirely and implement this behavior using variables and the merge function in each resource, e.g.:
locals {
common_tags = {
tag1 = "A"
tag2 = "B"
tag3 = "C" }
...
}
resource "aws_instance" "vm" {
...
tags = merge(local.common_tags, var.override_tags)
}