Mandatory Resource Tagging
Beginner
Enforce mandatory tags on all Terraform-managed cloud resources for cost allocation, ownership tracking, environment identification, and compliance requirements.
File Patterns
**/*.tf**/*.tfvars**/terraform/****/infrastructure/**
This rule applies to files matching the patterns above.
Rule Content
rule-content.md
# Mandatory Resource Tagging
## Rule
All taggable cloud resources MUST include the required tag set. Use `default_tags` in the provider block and merge with resource-specific tags.
## Required Tags
| Tag | Example | Purpose |
|-----|---------|---------|
| `Project` | myapp | Cost allocation |
| `Environment` | production | Environment identification |
| `Team` | platform | Ownership |
| `ManagedBy` | terraform | IaC tracking |
| `CostCenter` | eng-123 | Financial tracking |
## Implementation
```hcl
# Provider-level default tags (applied to ALL resources)
provider "aws" {
region = var.region
default_tags {
tags = {
Project = var.project
Environment = var.environment
Team = var.team
ManagedBy = "terraform"
CostCenter = var.cost_center
}
}
}
# Resource-specific tags merge with defaults
resource "aws_instance" "web" {
ami = var.ami_id
instance_type = var.instance_type
tags = {
Name = "${var.project}-${var.environment}-web"
Component = "frontend"
}
}
```
## Tag Variables with Validation
```hcl
variable "environment" {
type = string
validation {
condition = contains(["dev", "staging", "production"], var.environment)
error_message = "Environment must be dev, staging, or production."
}
}
variable "team" {
type = string
validation {
condition = can(regex("^[a-z][a-z0-9-]+$", var.team))
error_message = "Team name must be lowercase alphanumeric with hyphens."
}
}
```
## Good Examples
```hcl
# All required tags present via default_tags + resource tags
resource "aws_s3_bucket" "logs" {
bucket = "${var.project}-${var.environment}-logs"
tags = {
Name = "${var.project}-${var.environment}-logs"
DataClass = "internal"
}
}
```
## Bad Examples
```hcl
# BAD: No tags at all
resource "aws_s3_bucket" "data" {
bucket = "my-bucket"
}
# BAD: Missing required tags
resource "aws_instance" "web" {
tags = {
Name = "web"
# Missing: Project, Environment, Team, ManagedBy
}
}
```
## Enforcement
- Use AWS Organizations Tag Policies to enforce at the account level
- Use tflint-ruleset-aws to check for missing tags
- OPA policies in CI to validate tag presence
- AWS Config rules to detect untagged resourcesFAQ
Discussion
Loading comments...