Tags are one of the most underused tools in a Terraform practitioner's toolkit. Done well, they give a consistent way to track costs, enforce compliance, manage access control, and automate operations across cloud infrastructure. Skip them entirely and you are left with ungoverned resources, surprise bills, and no easy way to answer who owns this. In the AWS environment, tagging plays an important role in cloud resource management. Tags are key-value pairs that help organize, manage, and track resources in AWS. By assigning tags to resources, resources can be categorized by purposes, owner, environment, product, line of business, and many more. Tagging facilitates tracking the cost of the resource, automation and in security.
AWS recommends that you define a robust and consistent tagging strategy to enable better auditing, cost, and access control for your AWS resources. The AWS Terraform provider v3.38.0+ allows you to add default tags to all resources that the provider creates, making it easier to implement a consistent tagging strategy for all of the AWS resources you manage with Terraform. The HashiCorp Terraform AWS Provider contains over 700 resources to standardize your AWS infrastructure for configuration in accordance with best practices. One of the most common requests we've heard is for the ability to define default tags at the provider level of your Terraform configuration.
Tags in Terraform are key-value pairs associated with cloud resources. They allow you to categorize and organize these resources for better management, cost allocation, environment identification, e.g., production, staging, development, and automation. A Tag is a key-value pair assigned to a resource in AWS. Example: Environment = dev. A Provider is a plugin that Terraform uses to interact with the APIs of the service provider - here it is AWS. A Resource is a component that the terraform manages in the AWS.
What Tags Are In Terraform And Why They Matter
Tags in Terraform are key-value pairs associated with cloud resources. They allow you to categorize and organize these resources for better management, cost allocation, environment identification, e.g., production, staging, development, and automation.
The real world consequence of consistent tagging is financial visibility and operational safety. When tags are applied uniformly, cost allocation reports can be generated by Cost Explorer without manual mapping. Access control policies can reference tag keys to restrict who can create or modify resources. Compliance audits can be automated by scanning for required tags such as Owner or Environment.
Tags are one of the most underused tools in a Terraform practitioner's toolkit. Done well, they give a consistent way to track costs, enforce compliance, manage access control, and automate operations across your cloud infrastructure. Skip them entirely and you are left with ungoverned resources, surprise bills, and no easy way to answer who owns this.
Resources in AWS can be tagged in many ways. The following tools will be used.
- Terraform, which is an Infrastructure as a code tool.
- AWS console, which is then a direct way to create tags for the resources.
- AWS CloudFormation which is an inbuilt resource in AWS.
- AWS CDK cloud development kit - which is another inbuilt resource in AWS.
- AWS CLI command line interface - which is like a command prompt in AWS.
These are some of the ways in which resources in AWS can be tagged.
AWS Tagging Strategy Recommendations
AWS recommends that you define a robust and consistent tagging strategy to enable better auditing, cost, and access control for your AWS resources.
A robust tagging strategy creates an audit trail that maps every resource to a business owner and environment. Auditing benefits emerge when security teams can filter resources by tags such as ComplianceTier or DataClassification. Cost benefits emerge when finance can allocate spend by Project, Owner, or CostCenter. Access control benefits emerge when IAM policies can condition access on tag presence or values.
The tutorial you will configure a set of default tags for your AWS resources. Then, you will override those tags for a specific resource. You will also learn how to use the default tags configuration to manage Auto Scaling group tags.
You can complete this tutorial using the same workflow with either Terraform Community Edition or HCP Terraform. HCP Terraform is a platform that you can use to manage and execute your Terraform projects. It includes features like remote state and execution, structured plan output, workspace resource summaries, and more.
This tutorial assumes that you are familiar with the Terraform and HCP Terraform workflows. If you are new to Terraform, complete Get Started tutorials first.
Default Tags In Terraform AWS Provider
As of v3.38.0 of the Terraform AWS provider, you are able to define default tags for all resources except Auto Scaling Groups.
The HashiCorp Terraform AWS Provider contains over 700 resources to standardize your AWS infrastructure for configuration in accordance with best practices. One of the most common requests we've heard is for the ability to define default tags at the provider level of your Terraform configuration. We’re pleased to announce that as of v3.38.0 of the Terraform AWS provider, you are able to define default tags for all resources except Auto Scaling Groups.
The impact of this capability is a reduction in repetitive code and a reduction in human error. Without default tags, practitioners repeat the same key-value pairs across hundreds of resources. With default tags, a single provider block establishes the baseline, and individual resources only need to declare exceptions or additions.
Using Default Tags.
You can set default tags in the provider block of your Terraform configuration. Any tags set here will also be inherited by dependent Terraform modules. Setting default tags at the provider level will not supersede tags set on individual resources as resource tags take precedence.
In order to configure default tags you will need:
Terraform 0.12 or later
Terraform AWS Provider v3.38.0 or later
The requirement table can be expressed as:
| Requirement | Value |
|---|---|
| Terraform version | 0.12 or later |
| Terraform AWS Provider version | v3.38.0 or later |
| Default tags scope | All resources except Auto Scaling Groups |
Provider Block Configuration Requirements
The provider block is the entry point for default tags.
hcl
provider "aws" {
default_tags {
tags = {
Environment = "Test"
Owner = "TFProviders"
Project = "Test"
}
}
}
Any tags set here will also be inherited by dependent Terraform modules. Setting default tags at the provider level will not supersede tags set on individual resources as resource tags take precedence.
The inheritance behavior means modules that do not declare their own tags automatically receive the provider defaults. This creates a consistent baseline across a large codebase without editing each module. The precedence behavior means a resource that explicitly defines a tag overrides the provider default for that key. This allows safe overrides for specific resources while preserving the baseline for all others.
Example resource declarations that receive defaults:
hcl
resource "aws_vpc" "example" {
cidr_block = "10.1.0.0/16"
tags = {
Name = "my-vpc-resource"
}
}
hcl
resource "aws_subnet" "example" {
cidr_block = "10.1.1.0/24"
vpc_id = aws_vpc.test.id
tags = {
Name = "my-subnet-resource"
}
}
In this pattern, the VPC and subnet receive the provider default tags Environment, Owner, Project in addition to their explicit Name tag. The Name tag is not replaced by defaults because it is set at the resource level.
How Default Tags Propagate And Precedence
Setting default tags at the provider level will not supersede tags set on individual resources as resource tags take precedence.
Precedence creates a predictable merge order. Provider defaults form the base layer. Resource specific tags form the override layer. If a key exists in both layers, the resource value wins. If a key exists only in the provider layer, it is added to the resource.
The real world consequence is safe evolution of tagging standards. An organization can introduce a new required tag at the provider level and existing resources automatically gain it on next apply unless they explicitly opt out. Resources that already define a conflicting key retain their value, preventing unexpected changes.
How to merge Terraform tags.
One useful application of the merge function in Terraform is adding additional tags to resources to combine with your default set of tags. The merge() function combines multiple maps, and tags are typically defined as a map.
In this example, a tag is set as the default in the variable, and the merge function is used to add a name tag using the tags attribute in the resource.
hcl
variable "common_tags" {
type = map(string)
default = {
Environment = "Development"
}
}
hcl
resource "aws_instance" "my_instance" {
# ... other configuration options
tags = merge(var.common_tags, {
Name = "My Web Server"
})
}
Merging tags enables composition. Common tags defined in variables can be combined with resource specific tags. The merge order determines precedence, with later maps overriding earlier ones.
How to ignore changes to Terraform to tags.
Other configuration options can include ignore_tags to prevent Terraform from reacting to external changes.
```hcl
other configuration options
ignore_tags = [
"CostCenter", # Ignore changes to tags with this key
]
```
Ignoring tag changes is useful when tags are managed by another system or by users via the console. Terraform will stop producing diffs for those keys, reducing plan noise and preventing accidental reverts.
Auto Scaling Group Tagging Limitations
Due to the dynamic nature of Auto Scaling Groups, they behave differently than other AWS resources.
An Auto Scaling group is a collection of EC2 instances that use the same configuration. You can define the range of instances in an Auto Scaling group and the desired count, and the service will ensure that that number of instances is running at any given time. If an instance is terminated, the Auto Scaling group will launch another in its place using the launch configuration at the time.
AWS Auto Scaling Groups dynamically create and destroy EC2 instances as defined in the ASG's configuration. Because these EC2 instances are created and destroyed by AWS, Terraform does not manage them, and is not directly aware of them. As a result, the AWS provider cannot apply your default tags to the EC2 instances managed by your ASG.
As expected, Terraform did not apply the default tags to this resource.
bash
$ aws autoscaling describe-tags --region us-east-2 --filters "Name=auto-scaling-group,Values=$(terraform output asg_id)"
{
"Tags": []
}
The tags include the default ASG tags but not the default tags from your provider configuration.
Use the -replace option for terraform apply to reprovision the Auto Scaling group and launch a new instance with the appropriate tags.
bash
$ terraform apply -replace aws_autoscaling_group.example
bash
...
Terraform used the selected providers to generate the following execution plan
The impact for practitioners is that ASG managed instances require explicit tagging via launch templates or via the awsautoscalinggroup tag block. Default provider tags will not flow to instances created by the ASG. Teams must design a separate tagging strategy for ASG workloads, often by tagging the launch template and enabling propagateatlaunch.
The operational consequence is a tagging gap. Resources that are long lived such as VPCs receive defaults automatically. Resources that are ephemeral such as ASG instances do not. This creates a blind spot in cost allocation unless launch templates are tagged explicitly.
Provider Differences In Terraform Tags
Tag implementation varies significantly across cloud providers. Understanding how each provider handles defaults, inheritance, and naming constraints prevents subtle misconfigurations that are easy to miss in a plan.
AWS has the most complete tagging support of the three major providers.
Provider differences matter when organizations use multi cloud modules. An AWS module that relies on provider default_tags will not behave identically on Azure or Google Cloud. Practitioners must account for differences in tag naming, case sensitivity, and propagation timing.
What we will cover:
- What are tags in Terraform?
- Use cases for tags in Terraform
- How to manage resource tags using Terraform?
- How to add multiple tags to Terraform resources?
- What are Terraform default tags?
- How to ignore changes to Terraform to tags?
- How to merge Terraform tags?
- Provider differences in Terraform tags
- Tagging shared resources on AWS
- How to enforce required tags in Terraform
- Best practices for Terraform tags
Enforcing Required Tags And Lifecycle Rules
How to enforce required tags in Terraform.
Enforcement can be achieved through lifecycle rules and policy checks. While Terraform itself does not enforce tag presence, practitioners can use validation rules in modules, Sentinel policies in HCP Terraform, or AWS Service Control Policies to require specific tags.
Best practices for Terraform tags include defining a central tag map variable, applying it via provider default_tags, allowing per resource overrides where needed, and documenting tag key conventions. Tagging shared resources on AWS often requires careful handling of propagation and cost allocation.
The article we cover everything you need to know about using tags in Terraform, from the basics of adding key-value pairs to resources, to managing default tags at the provider level, enforcing required tags with lifecycle rules, and handling provider-specific differences across AWS, Azure, and Google Cloud.
Practical Implementation Patterns
The primary key terminologies that are involved in AWS tagging with terraform are:
- Tag: A key-value pair assigned to a resource in AWS. Example: Environment = dev.
- Provider: A plugin that Terraform uses to interact with the APIs of the service provider - here it is AWS.
- Resource: Resource is a component that the terraform manages in the AWS.
A consistent implementation pattern starts with a provider block defining defaults, then resource blocks adding specific tags, then optional merge logic for variable driven tags.
The impact of this pattern is governance at scale. Teams can update Environment or Owner values in one place and propagate across hundreds of resources. Cost reports remain accurate. Access policies remain enforceable. Compliance audits become automated.
Conclusion
Terraform AWS tagging is a control plane for cost, compliance, and ownership. Default tags at the provider level provide a baseline that reduces repetition and enforces consistency across more than 700 AWS resources supported by the provider. Precedence rules ensure resource specific tags override defaults, allowing safe exceptions. Merge functions enable composition of common and specific tags. Auto Scaling Groups remain an exception due to dynamic instance creation, requiring explicit launch template tagging or ASG tag blocks.
The combination of provider defaulttags, resource level tags, merge patterns, and ignoretags configuration creates a layered tagging strategy. This strategy enables auditing, cost allocation, and access control without manual repetition. Understanding provider differences and ASG limitations prevents subtle misconfigurations that undermine governance.
Sources
1. Terraform AWS Default Tags Tutorial
2. Terraform Tags Spacelift
3. HashiCorp Blog Default Tags
4. GeeksforGeeks Tagging AWS Resources Using Terraform