Simple demo about how to use Atlantis on Terraform Pull request automation

Link sample you can find in the github:

https://github.com/katainaka0503/atlantis-example

Atlantis

A tool developed by Cloud Posse that executes Terraform workflows with commands on GitHub/GitLab/BitBucket Pull Requests.

By using Atlantis, for example, the following development flow can be realized

  1. Modify Terraform code and open a pull request on GitHub

  2. plan Automatically executed in the development environment and production environment directories, and the result is added as a comment on the PR

  3. Apply changes to the development environment with commands from the PR

  4. Confirm that there is no problem in applying to the development environment

  5. Apply to production environment by command from PR

  6. Automatically merge PRs after successful application to both development and production environments

It is attractive that it does not depend on the individual’s local machine, can be executed in a way that records are kept on the PR, and can handle multiple states.

Atlantis walkthrough:

https://www.youtube.com/watch?v=TmIPWda0IKg

Demo

Advance preparation

  • A domain that can use a public hosted zone on Route53 is required. This is because it must be specified as the destination of the webhook.

Terraform code to apply in Atlantis

This time, we will make it possible to apply the contents of the Terraform repository with the following directory structure from the GitHub PR.

.
├── README.md
└── example-project
    ├── environments
    │   ├── development
    │   │   └── main.tf
    │   └── production
    │       └── main.tf
    └── modules
        └── example
            └── main.tf

example-project/envoronments. The following are the directory structures corresponding to the development environment and the production environment respectively development and production

Deploy Atlantis with Terraform

Link:

https://registry.terraform.io/modules/terraform-aws-modules/atlantis/aws/latest

First, create a file like this:

atlantis/main.tf

provider "aws" {
  region  = "ap-northeast-1"
}

module "atlantis" {
  source  = "terraform-aws-modules/atlantis/aws"

  name = "atlantis"

  cidr            = "10.20.0.0/16"
  azs             = ["ap-northeast-1a", "ap-northeast-1c"]
  private_subnets = ["10.20.1.0/24", "10.20.2.0/24"]
  public_subnets  = ["10.20.101.0/24", "10.20.102.0/24"]

  route53_zone_name = "<your public R53 hosted zone name>"

  policies_arn = [
    "arn:aws:iam::aws:policy/AdministratorAccess"
  ]

  atlantis_github_user       = "<your github username>"
  atlantis_github_user_token = "<Your github user token>"
  atlantis_repo_whitelist    = ["github.com/<your github username>/*"]
}

output "webhook_url" {
  description = "Github webhook URL"
  value       = module.atlantis.atlantis_url_events
}

output "webhook_secret" {
  description = "Github webhook secret"
  value       = module.atlantis.webhook_secret
}

Next, open the prepared Terraform file with the following command apply

$ cd atlantis
$ terraform init
$ terraform apply

terraform applyWhen completed, the output will be something like:

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

webhook_secret = "XXXXXXXXXXXXXXXXXX"
webhook_url = https://<your public R53 hosted zone name>/events

webhook_secret: Make a note of the two output webhook_url values ​​as they will be used later when registering the webhook in the GitHub repository.

Apply webhook

Next, register the webhook. We will refer to:

https://www.runatlantis.io/guide/testing-locally.html#github-or-github-enterprise-access-token

From the top screen of the GitHub repository , select Settings-> Webhook-> Add Webhookin order to move to the webhook addition screen.

On that screen, make the following settings and create a Webhook.

itemset value
Payload URL< webhook_url URL output>
Content typeapplication/json
Secret< webhook_secret string output>
Which events would you like to trigger this webhook?Let me select individual events
Event typeset value
Pull request reviews
Pushes
Issue comments
Pull requests
Other eventsdo not check

Place config file in repository

Create a file with the following content in the root of atlantis.yaml the repository and push it to GitHub.

version: 3

automerge: true
projects:
  - name: development
    dir: example-project/environments/develepment
    workspace: default
    terraform_version: v0.12.1
    autoplan:
      when_modified: ["*.tf", "../../modules/**/*.tf"]
      enabled: true

  - name: production
    dir: example-project/environments/production
    workspace: default
    terraform_version: v0.12.1
    autoplan:
      when_modified: ["*.tf", "../../modules/**/*.tf"]
      enabled: true

Operation check

If you’ve made it this far, it should be working correctly.

Let’s actually make a PR and check the operation. This time I created a PR by fixing a module that affects both development and production environments.

Then, the result of planing environments/development in environments/production each directory will be added as a GitHub comment.

First, I want to apply it to the development environment, so check the dev result:

Since there is no problem, add the following comments according to the instructions of the comments:

atlantis apply -p development

And then the production:

atlantis apply -p production

Then the transfer to the production environment applyis executed! Since there is nothing else to do this time, apply PR merging was done automatically.

Summary

plan: As you can see, using Atlantis , you can run Terraform using commands on GitHub apply. This flow seems to be able to handle repositories with multiple states, which would be complicated to apply with a CI tool, without any problems.

apply: I personally think that there is a habit of doing things before merging, but I think it’s applygood that only things that can actually be done correctly are merged.

Atlantis has a lot of setting items, and depending on the setting, it seems that you can make a apply review mandatory before . In addition, it seems that there is also a lock function that prevents conflicts and problems from occurring when there are multiple PRs, so it is of course possible to support development by multiple people.

Reference:

https://qiita.com/iijimakazuyuki/items/8a98aa3a91db3b795d76