Skip to main content
  1. All Posts/
  2. Tech Logs/

Overcoming AWS Tagging Limits in Terraform & Terragrunt

·347 words·2 mins
Tech Logs Terraform Terragrunt Aws S3 Tagging Cloud
Siyad Salam
Author
Siyad Salam

Overcoming AWS Tagging Limits in Terraform & Terragrunt
#

Recently I ran into an annoying AWS limitation while working with Terraform. Turns out S3 objects can only have a maximum of 10 tags, which becomes a problem when you’re using provider-level tagging. The Problem I like to use default tags at the provider level to make sure all

provider is defined here

https://github.com/salsiy/terragrunt-examples/blob/master/root.hcl


provider "aws" {
  region = "${local.aws_region}"
  
  default_tags {
    tags = ${jsonencode(local.bucket_tags)}
  }
}

Tags for environment is defined here

https://github.com/salsiy/terragrunt-examples/blob/master/dev/env.hcl

locals {
  environment      = "dev"
  primary_region   = "us-east-1"
  
  # S3 bucket with MORE than 10 tags (to test limitation)
  bucket_tags = {
    Environment   = "dev"
    Application   = "MyApp"
    Team          = "Engineering"
    CostCenter    = "Development"
    Owner         = "[email protected]"
    DataClass     = "Internal"
    Backup        = "Daily"
    Monitoring    = "Enabled"
    Compliance    = "Standard"
    Version       = "1.0"
    Purpose       = "Testing"
    CreatedBy     = "Terraform"
  }
  
  object_tags = {
    Environment = "dev"
    Type        = "Config"
    Application = "MyApp"
    Version     = "1.0"
    Owner       = "Engineering"
    # Only 5 tags - well under the 10 tag limit for S3 objects
  }
}

This works great for most AWS resources since they support up to 50 tags. But S3 objects? They only support 10 tags maximum. So if I have 8 default tags and want to add a couple more specific tags to my S3 object, I hit the limit and get an error.

The Solution: Multiple Providers

The trick is to create a second AWS provider with fewer default tags, and use that specifically for S3 objects:

provider "aws" {
  alias  = "secondary"
  region = "${local.aws_region}"
  
  default_tags {
    tags = ${jsonencode(local.object_tags)}
  }
}

Why This Works

Most AWS resources support 50 tags, so the main provider works fine S3 objects get only the essential tags, staying under the 10-tag limit You still get consistent tagging across your infrastructure No need to remember which resources have tag limits

Complete Example You can find the complete working example in my GitHub repo:

terragrunt-examples/modules/s3-bucket-object-tag

This simple approach saved me from having to restructure my entire tagging strategy. Sometimes the best solutions are the simplest ones :)