atlantis icon indicating copy to clipboard operation
atlantis copied to clipboard

Easiest way to use atlantis with multiple tfvars files

Open max-rocket-internet opened this issue 6 years ago • 7 comments

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 😄

max-rocket-internet avatar Dec 06 '19 10:12 max-rocket-internet

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

max-rocket-internet avatar Dec 10 '19 15:12 max-rocket-internet

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.

lkysow avatar Dec 11 '19 23:12 lkysow

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?

max-rocket-internet avatar Dec 12 '19 10:12 max-rocket-internet

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?

lkysow avatar Dec 12 '19 18:12 lkysow

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?

max-rocket-internet avatar Dec 13 '19 09:12 max-rocket-internet

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.

lkysow avatar Dec 13 '19 16:12 lkysow

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.

3bbbeau avatar Feb 26 '24 20:02 3bbbeau