Easiest way to use atlantis with multiple tfvars files
Hi, I'm just wondering what is the best way to configure Atlantis for our current environment. We use multiple tfvars files as follows...
We have about 20 apps, here's one:
terraform/apps/app1
├── main.tf
├── outputs.tf
└── variables.tf
And then config for about 1-5 environments and 5 regions that are passed to the app as tfvars files:
terraform/tfvars/apps/app1
├── re01-prd01.tfvars
└── re01-stg01.tfvars
terraform/tfvars/envs
├── prd01.tfvars
└── stg01.tfvars
terraform/tfvars/regions/
├── re01.tfvars
├── re02.tfvars
...
So we would run terraform something like this:
TF_DATA_DIR="terraform/apps/app1/.terraform/re01/stg01"
terraform init -backend-config="profile=aws-account-1" -backend-config="bucket=tf-states" -backend-config="key=terraform.re01.stg01.applications.app1" -backend-config="region=eu-west-1" -backend-config="encrypt=true" -backend-config="kms_key_id=xxxx" terraform/apps/app1
terraform plan -var-file=terraform/tfvars/regions/re01.tfvars -var-file=terraform/tfvars/envs/stg01.tfvars -var-file=terraform/tfvars/apps/app1/re01-stg01.tfvars terraform/apps/app1
We use a shell alias/script to make this clean and nice to run for users. I figured we could do something like this in atlantis.yaml:
version: 3
projects:
- dir: terraform/apps/app1
workflow: app1
workflows:
order_forwarding:
plan:
steps:
- run: terraform-atlantis-runner.sh plan re01 stg01 app1 -out $PLANFILE
apply:
steps:
- run: terraform-atlantis-runner.sh apply re01 stg01 app1 -no-color $PLANFILE
But this is quite painful with 20 apps, multiple environments and regions as we would need to repeat the above about 100 times. It's also complicated because we want to trigger atlantis for terraform/apps/app1 but also terraform/tfvars/apps/app1/re01-stg01.tfvars if it exists.
I'm still experimenting but can the autoplanner help here? Am I missing any tricks to make this easier?
Any help or ideas appreciated 😄
OK I don't know if this is the right approach, perhaps there's an easier way of doing this with autoplanning?
Anyway, I wrote some short python that writes the atlantis.yaml file out as follows:
version: 3
projects:
- autoplan:
when_modified:
- '*.tf'
- ../../tfvars/apps/app1/re01-stg01.tfvars
dir: terraform/apps/app1
name: re01_stg01_app1
workflow: re01_stg01_app1
workflows:
re01_stg01_app1:
apply:
steps:
- run: ../../../files/atlantis-terraform-runner.sh apply re01 stg01 app1
plan:
steps:
- run: ../../../files/atlantis-terraform-runner.sh init re01 stg01 app1
- run: ../../../files/atlantis-terraform-runner.sh plan re01 stg01 app1
Because there is around 100 work flows (20 apps * 5 regions * 1 envs), it's not possible to do by hand.
And atlantis-terraform-runner.sh is setting all the terraform and -tfvar options according to those parameters:
TF_DATA_DIR=.terraform/re01/stg01 /atlantis-data/bin/terraform0.12.12 init -no-color
-backend-config="profile=account1"
-backend-config="bucket=tf-states-account1"
-backend-config="key=terraform.re01.stg01.applications.app1.tfstate"
-backend-config="region=eu-west-1"
-backend-config="encrypt=true"
-backend-config="kms_key_id=arn:aws:kms:xxxxx"
or
TF_DATA_DIR=.terraform/re01/stg01 /atlantis-data/bin/terraform0.12.12 plan -no-color
-var-file=../../tfvars/accounts/account1.tfvars
-var-file=../../tfvars/regions/re01.tfvars
-var-file=../../tfvars/envs/stg01.tfvars
-out $PLANFILE
You could use a custom default workflow via server-side config that intelligently figures out the arguments depending on which directory is being modified however there's no way other than your method for configuring the autoplanning.
Thanks for the reply @lkysow
You could use a custom default workflow via server-side config that intelligently figures out the arguments depending on which directory is being modified
How would I do that? Just have one single custom workflow that runs my script? How do I know what files are modified in the PR?
Your script would get run with a number of environment variables set (https://www.runatlantis.io/docs/custom-workflows.html#custom-run-command) including PROJECT_NAME. Maybe you could do some fancy splitting on that name?
Sorry, I mean how can my script know what files are modified in the PR? Like when_modified. Is this provided from Atlantis? It's not in that list of env vars. Or we I have to call the github API? Or some git diff with master?
It doesn't provide that info right now. But if you're setting up your projects the way you showed me then you'd know which files were modified based on the name of the project. You could also call the github api or do a diff.
https://github.com/3bbbeau/tfvars-atlantis-config
We use mainly .tfvars for simple Terraform components, and wanted to use Atlantis to dynamically generate configurations for monorepos, so I started writing this utility.
Still work to be done on this but I thought I'd drop it here in case someone has the same challenge and wants to fork it or otherwise contribute upstream.