Terraform Compliance
In my post about resource tagging I wrote about the importance of tags. Of course tags are not the only important (meta-) information that each resource must contain. Also names of resources should have a consistent schema.
I am a lazy person and if I can avoid things I try to. Also, I am forgetful. So there is only one way to guarantee that tagging and naming happens in consistent way: enforcement or governance.
The tool of (my) choice is terraform-compliance.
To enforce that every resource that supports tags has all mandatory tags you can specify a BDD feature like this:
Feature: Tags identify each resource and allow to collate them to specific projects.
Scenario Outline: Ensure that specific tags are defined
Given I have resource that supports tags defined
Then it must contain <tags>
And its value must match the "<value>" regex
Examples:
| tags | value |
| namespace | .+ |
| environment | ^(test\|prod)$ |
| stage | .+ |
| name | .+ |
This feature forces the tags namespace, environment, stage and name to be set. For the tag environment only the values test and prod are allowed.
It is easy to set up (docker or pip) and can also be integrated in a CI/CD environment, for example in .gitlab-ci.yml
.
Here is an excerpt from a pipeline I use:
before_script:
- alias convert_report="jq -r '([.resource_changes[]?.change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'"
- cd terraform
- terraform --version
- terraform init
stages:
- validate
- build
- test
- deploy
validate:
stage: validate
script:
- pwd
- terraform validate
plan:
stage: build
script:
- terraform plan -out=$PLAN
- "terraform show --json $PLAN | convert_report > $JSON_PLAN_FILE"
- terraform-compliance -f features -p $PLAN
In the build stage a terraform plan is generated. The json output is now verified by terraform-compliance
. If any of the features is not met the build will stop at this point and no changes at the infrastructure will be applied.
The terraform-compliance
page has a lot more examples where and how to enforce consistent names or even security aspects (for example deny access from /0 for ssh).
Happy enforcing!