DEV Community

quixoticmonk
quixoticmonk

Posted on

Terratags: Enforce Tags on your AWS Terraform configuration

Proper resource tagging is not just a best practice—it's essential for cost allocation, resource ownership, security compliance, and operational efficiency. Yet, ensuring consistent tagging across all resources remains a challenge for many teams.

The Problem: Inconsistent Resource Tagging

If you've worked with AWS resources at scale, you've likely encountered these challenges:

  • Resources deployed without proper tags, making cost allocation difficult
  • Inconsistent tagging across teams and projects
  • Manual reviews that are time-consuming and error-prone
  • Difficulty tracking tag compliance across your infrastructure

While AWS provides tagging policies and the AWS provider for Terraform offers default_tags, there was still a gap for a simple, focused tool that could validate tags before deployment and integrate seamlessly into CI/CD pipelines.The buzz around what you can build with the help of AI agents drove us to consider Amazon Q to build a solution which might solve this.

What is Terratags?

Terratags came out of a conversation with a colleague/friend of mine over what we can do ( more as a passion project or flex our muscles in building a tool in Go) to enforce tags in Terraform configuration using AWS provider. We focussed on AWS primarily because of our exposure to the provider compared to others. Maybe we could look to extend this to other providers. Terratags is a lightweight tool I conjured up over a weekend to validate and enforce tagging standards on AWS resources defined in Terraform configurations. It analyzes your Terraform files or plan outputs to identify resources that are missing required tags, generates compliance reports, and even suggests remediation steps.

Key Features of Terratags

Terratags offers several features to help enforce your tagging standards:

  1. Tag Validation: Validates that all the taggable AWS resources have the required tags defined in your configuration. The workflows built would pull down both AWS and AWSCC resources, but the utility doesn't support AWSCC resources yet.
  2. Default Tags Support: Recognizes and accounts for tags defined in the AWS provider's default_tags block
  3. Module-Level Tags: Understands tag inheritance from module-level tags to individual resources
  4. Exemption Support: Allows specific resources or resource types to be exempted from certain tag requirements
  5. HTML Reports: Generates visual reports showing tag compliance across your infrastructure
  6. Remediation: Suggests code changes to fix non-compliant resources. This is one place I could make modifications to suggest default_tags in case of AWS provider than having to add tags in each resource.
  7. Plan Integration: Works with both Terraform files and plan outputs
  8. CI/CD Integration: Easily integrates into your CI/CD pipeline to enforce tag compliance.

How It Works

  • Scans your Terraform files or plan outputs for AWS resources
  • Checks if each resource has all the required tags defined in your config which you define with a config yaml or json.
  • Considers both resource-level tags and provider default_tags
  • Respects exemptions for specific resources or tags
  • Generates compliance reports showing which resources are missing tags
  • Optionally provides remediation code to fix non-compliant resources

Core Components:

  • main.go - Entry point that processes command-line arguments, loads configurations, and orchestrates the validation workflow
  • validator.go - Validates resources against tag requirements, handles exemptions, generates reports, and suggests remediation code
  • parser.go - Extracts resources and their tags from Terraform files using HCL parsing
  • aws_taggable_resources.go - Contains a comprehensive map of all AWS resources that support tagging
  • provider.go - Identifies and extracts AWS provider configurations with default tags
  • config.go - Loads and manages configuration including required tags and exemption rules

Using Terratags is straightforward:

You can install terratags using brew if you are on Mac or with the latest binary from the releases page:

brew install terratags/tap/terratags
Enter fullscreen mode Exit fullscreen mode

Available options

Though I started off with just the --config and --file, I quickly realized I preferred it to scan a list of files in a directory than a single file. Maybe I should I still consider adding that back. The current options are as listed below:

terratags --help
Usage: terratags [OPTIONS]

Options:
  --config, -c <file>       Path to the config file (JSON/YAML) containing required tag keys
  --dir, -d <directory>     Path to the Terraform directory to analyze (default: ".")
  --verbose, -v             Enable verbose output
  --plan, -p <file>         Path to Terraform plan JSON file to analyze
  --report, -r <file>       Path to output HTML report file
  --remediate, -re          Show auto-remediation suggestions for non-compliant resources
  --exemptions, -e <file>   Path to exemptions file (JSON/YAML)
  --help, -h                Show this help message
  --version, -V             Show version information

Enter fullscreen mode Exit fullscreen mode

Run the utility against your infra configuration usingthe following command:

terratags -config config.yaml -dir ./infra
Enter fullscreen mode Exit fullscreen mode

The configuration file specifies which tags are required:

required_tags:
  - Name
  - Environment
  - Owner
  - Project
Enter fullscreen mode Exit fullscreen mode

When run, Terratags analyzes your Terraform files and outputs a report of non-compliant resources:

Tag validation issues found:
Resource aws_s3_bucket 'data_bucket' is missing required tags: Environment, Owner, Project

Summary: 2/4 resources compliant (50.0%)
Tag validation failed. Please fix the issues above.
Enter fullscreen mode Exit fullscreen mode

You can also generate HTML reports for better visualization:

terratags -config config.yaml -dir ./infra -report report.html
Enter fullscreen mode Exit fullscreen mode

Lets take a look at an example report generated with exemptions set for a specific resource.

Tag report

I have only included only some of the configuration options here. Read the the list of options and examples here.

My Journey: Learning Through Building

Learning Go

My experience with Go was initially limited to understanding the AWSCC provider's structure and implementation. Despite completing various tutorials, I struggled to advance my skills further. This project wasn't developed independently—I sought assistance throughout the development process, particularly with Go's file parsing, structure, and validation techniques with Amazon Q. Although I began development in Python, I deliberately switched to Go to see if I can learn my own limitations and improve on my understanding and develop practical experience with the language.

Working with MkDocs for Documentation

Documentation is crucial for any tool, so I decided to use MkDocs to create a clean, navigable documentation site. This was my first experience with MkDocs, and I was impressed by how easy it was to set up and customize.

The workflow was simple:

  1. Write documentation in Markdown
  2. Configure the site structure in mkdocs.yml
  3. Run mkdocs build to generate the static site
  4. Deploy to GitHub Pages

MkDocs' Material theme provided a professional look with minimal configuration, and the navigation structure made it easy for users to find what they needed.

Setting up GitHub Pages Hosting

Hosting the documentation was the next challenge. GitHub Pages offered a perfect solution—free hosting directly from the repository.

The result is a professional-looking documentation site at https://terratags.github.io/terratags/ that stays in sync with the codebase.

Building with AI Assistance

One interesting aspect of this project was using Amazon Q as an AI pair programmer. I had a clear vision of what I wanted to build, but translating that vision into code was challenging at times.

AI assistance helped in several ways:

  1. Code Generation: Generating boilerplate code and suggesting implementations for specific functions
  2. Problem Solving: Helping debug issues and suggesting alternative approaches
  3. Documentation: Assisting with writing clear documentation and examples
  4. Testing: Suggesting test cases and validation scenarios

However, I found that AI assistance works best when you have a clear understanding of what you want to build. The AI could help with implementation details, but the overall architecture and design decisions still required human judgment.One challenge was that what I had in mind wasn't always perfectly translated into words, leading to some back-and-forth iterations. This reinforced the importance of clear communication, even when working with AI.

I can't stress enough that you will need some sort of validation steps as you build anything with an AI agent. In this build out, the examples were my way of having the code generated or written be held to the expectations. Test driven development so to speak.

Future Plans and Improvements

While Terratags is already useful in its current form, I have some ideas for future improvements:

  1. Support for More Cloud Providers: Extending beyond AWS to support Azure, GCP, and other providers. Though this is limited primarily because of my understanding how some of these providers work.
  2. Custom Validation Rules: Allowing users to define custom rules for tag values, not just presence of the tags.
  3. Integration with More CI/CD Systems: Creating plugins for popular CI/CD platforms.

Conclusion

Building Terratags was a rewarding project that solved a real problem I faced in my work with AWS and Terraform. The project reinforced my belief that the best way to learn is by building something that solves a real problem. Even a weekend project can turn into a valuable tool when it addresses a common pain point.

If you're working with AWS resources in Terraform and struggling with tag compliance, give Terratags a try. It's open source, easy to use, and might just save you from the headache of inconsistent tagging.

Check out the project on GitHub and the documentation site to learn more:

I'd love to hear your feedback and suggestions for improving Terratags!

Top comments (3)

Collapse
 
pranitraje profile image
Pranit Raje

Great one!

Collapse
 
clayton_olley_9244b3263b1 profile image
Clayton Olley

One area I struggle with is resources that get created by AWS for you, like Lambda's creating CloudWatch log groups etc, and those don't get tagged. 🤨

Collapse
 
quixoticmonk profile image
quixoticmonk • Edited

yeah, I have almost always created the log groups myself to manage that. There are similar cases with Glue as well where the underlying log groups which get created when execution happens which do not get tags as the service role creates them. You could technically import them into your configuration after the fact and manage them going forward when you notice those elements which you didn't explicitly create.

OSZAR »