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
Modify Terraform code and open a pull request on GitHub
plan
Automatically executed in the development environment and production environment directories, and the result is added as a comment on the PRApply changes to the development environment with commands from the PR
Confirm that there is no problem in applying to the development environment
Apply to production environment by command from PR
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 apply
When 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 Webhook
in order to move to the webhook addition screen.
On that screen, make the following settings and create a Webhook.
item | set value |
Payload URL | < webhook_url URL output> |
Content type | application/json |
Secret | < webhook_secret string output> |
Which events would you like to trigger this webhook? | Let me select individual events |
Event type | set value |
Pull request reviews | |
Pushes | |
Issue comments | |
Pull requests | |
Other events | do 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 apply
is 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 apply
good 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: