env0 / env0/terratag

Support defining a .terratagrc or other config file that would allow a declarative approach to how to tag resources

Open
#224 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
1.1k
Forks
50
Avg merge
55m
Merged PRs (30d)
2

Description

**Is your feature request related to a problem? Please describe.**
The problem is things are often more work than they need to be. :) The idea is that defining a bunch of tags directly in a cli argument is not super fun. It would be great to support a config file I could check into my repo that would define exactly what tags would apply to various resources. This could have various levels of functionality, from basic to advanced. Will describe some options below.

**Describe the solution you'd like**
I'll describe several possible levels of functionality.

### Basic
A yaml file containing some tags. I'd put it under a top level key to make it simple to add onto later. e.g.,

```yaml
global_tags:
tag1: val1
tag2: val2
...
```

Easy to implement, provides a lot of functionality. Calling `terratag` within this repo would tag the resources (would still require specifying the dir in this case).

### Less basic
Add the ability to use env vars or even define variables in the file (env vars is sufficient imo).
```yaml
variables: # not necessary but maybe useful
repo: "acme-infra-repo"
global_tags:
tag1: "val1-${repo}"
tag2: "val2-${MY_ENV_VAR}"
...
```

### A bit more powerful
Could have the ability to discover modules
```yaml
autodiscover:
patterns:
- "terraform/aws/**/*.tf"
- "terraform/azure/**/*.tf"
global_tags:
tag1: val1
tag2: val2
...
```

### A bit more powerful
Filters?
```yaml
autodiscover:
patterns:
- "terraform/aws/**/*.tf"
- "terraform/azure/**/*.tf"
exclude_resources:
- "aws_eks_*" # exclude some arbitrary group of resources
global_tags:
tag1: val1
tag2: val2
...
```

### Over the top
Completely flexible configs?
```yaml
tag_patterns:
- patterns:
- "terraform/aws/**/*.tf"
tags:
cloud: aws
some_key: some_val
git-repo: "${VALUE_SET_IN_ENV_VAR}"
# pulls the value from the README. maybe a dumb idea. terratag could set TERRATAG_CURRENT_DIR
docs_url: "$(pull-url-from-readme.sh "${TERRATAG_CURRENT_DIR}/README.md")"
exclude_resource_patterns:
- "*_eks_*"
keep_defaults: true
update_files_in_place: true
validations:
"/[a-z]+/" # some regex that allows only specific tag keys/values. Azure is very inconsistent with what it allows
...
```

### Beyond reasonable
Same as previous, but allow configs to be defined at any level of the hierarchy and roll them all up together.

#### terraform/aws/app_cluster/.terratagrc
```yaml
exclude_resource_patterns:
- "*_eks_*"
update_files_in_place: false
...
```

#### terraform/azure/.terratagrc
```yaml
include_patterns:
- "**/*.tf"
tags:
cloud: azure
some_key: some_val
keep_defaults: false
validations:
"/[a-z]+/" # some regex that allows only specific tag keys/values. Azure is very inconsistent with what it allows
...
```

#### root level .terratagrc
```yaml
tags:
company: acme
project: proj1
git-repo: "${VALUE_SET_IN_ENV_VAR}"
keep_defaults: true
update_files_in_place: true
...
```

All of these would be combined in such a way that the config for a dir applies to every terraform file the same dir or any subdirectory.

### Sweet spot

Probably these ideas would find a good balance and cover pretty much everything.

- Simple configs that allow defining tags w/ env var replacement
- Alternatively, vars could be passed in explicitly to avoid any unintended problems like worrying about secure env vars or something
- A wrapper script could handle setting the vars from env vars or any other values
- Allow defining at multiple levels of hierarchy and do a standard dict merge to roll them up
- Feels like this would cover any "autodiscovery" use case, maybe also have a key to exclude resources based on a pattern and/or filename
- Any directory with a .terratagrc file would indicate "hey I want to set tags here"
- Any file gets applied to any tf files in any subdirectory as long as that subdirectory also contains a terratagrc file (or that could be a configurable option)
- Have Terratest set a couple dynamic variables, e.g., the current directory name, so I can set a tag with the terraform module name
- This could be implemented in a directory specific terratagrc file but that's very error prone, if you rename a directory you need to remember to update the tag. not ideal.

I feel like there's a lot of value here. I want to be clear I'm not asking for all of this. But I'd like to be able to do something like add these tags to all resources in a module or repo:

```yaml
managed-by: terraform
git-repo: $DYNAMIC_REPO_URL_FROM_VAR
tf-module: my_module_name_which_is_the_dir_name
```

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
- Writing logic myself and calling `terratag` a bunch of times. Not as easy to sell to my team or org, can't take the code to another company, really difficult to keep consistent, unable to share the value with others.
- Another tool? Haven't looked
- Other idea? Not sure

**Additional context**
I just came across the tool and haven't even used it yet. With AWS I just generated all of this with a python script. I think the real value is in Azure where there isn't any way to set default tags at all. It would be awesome to set this up declaratively and run it in a pre-commit hook so they're always update to date.

I know this is not very concrete but it's really the basic idea I think is valuable. Everything else can be scripted around. Happy to answer any questions, thanks.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the terratag CLI entry point and trace how tag arguments and Terraform paths are currently supplied; the issue names no files or tests. First narrow the requested config format, hierarchy behavior, and environment-variable handling, then define tests that verify the agreed examples apply the declared tags.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, terraform
Domain
cli, devops, infrastructure
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.