Terraforming the GitOps Way using Atlantis !!!
Terraform with GitOps using Atlantis (Pull request Automation)….
Do you use terraform in your Organisation? Or even for your personal Projects? If yes, by the end of this article you would change the way you manage and deploy terraform resources. Assume that you are the senior-most junior developer who has joined the Organisation and started working on your first terraform project. You’ve written the modules, scripts and have made sure that the code is working perfectly fine. Ahh, what should be the next step? To deploy the infrastructure, correct? What are the commands that you’d use?
$ terraform init $ terraform plan$ terraform apply
Awesome, you should be very happier when you see the resources being created with the terraform code. One of your bosses had now asked you to change some configurations in your code. What would be the steps?
a) Pull the latest code from any SCM.
b) Make the changes.
c) Check out the code to a different branch and raise a Pull Request. Get it reviewed.
d) Init, Plan, and Apply.
e) Merge the Request.
What if the steps could be something like this?
a) Pull the latest code.
b) Make the changes.
c) Check out the code to a different branch and raise a Pull Request. Get it reviewed. ( Terraform Plan and Merge happens Automatically ).
Wasn't that quick? Yes, it really was. How can this be achieved? Here comes Atlantis to our help. Atlantis is an application for automating Terraform via pull requests. It is deployed as a standalone application into your infrastructure. No third party has access to your credentials. Atlantis listens for GitHub, GitLab, or Bitbucket webhooks about Terraform pull requests. It then runs terraform plan
and comments with the output back on the pull request.
When you want to apply, comment atlantis apply
on the pull request and Atlantis will run terraform apply
and comment back with the output.
What is the entire story all about? (TLDR)
- Implementation of Terraform in a GitOps Way.
- Deploying Atlantis on a Kubernetes cluster and getting to see Atlantis in action.
Prerequisites
- A Kubernetes Cluster ( AKS, GKE, EKS ). We will use EKS in the article. ( I have also attached the eksctl yaml file in the same repo. You can quickly create a cluster by using eksctl create cluster -f eksctl-atlantis.yaml )
Story Resources
- GitHub Link: https://github.com/pavan-kumar-99/medium-manifests
- GitHub Branch: atlantis
Installing Atlantis using Helm Chart
We will use the official helm chart to install Atlantis on an AWS EKS cluster. But before installing there are a set of Pre-Requisites to be performed with the SCM ( GitHub in this case ) to authorize the incoming webhook ( Optional, not mandatory ) and a personal Github access token with the repo scope. Alright, let's get started.
a) Creating an Access Token: Navigate to the user setting in the GitHub console, and then create a personal access token. You can also follow the link here for a detailed description.
b) Webhook Secrets: Atlantis uses Webhook secrets to validate that the webhooks it receives from your Git host are legitimate. One way to confirm this would be to allow list requests to only come from the IPs of your Git host but an easier way is to use a Webhook Secret. Webhook secrets are actually optional. However, they’re highly recommended for security. You can use any random string generator to create your Webhook secret. It should be > 24 characters.
For example:
- Generate via Ruby with
ruby -rsecurerandom -e 'puts SecureRandom.hex(32)'
- Generate online with https://www.browserling.com/tools/random-string
c) Terraform Pre-Requisites: Atlantis supports all the backends except the local backend. In the scope of this article, we would be using s3 as the terraform backend.
d) Install with Helm: I have configured the helm values in the repo here
Let us understand the primary components of this Yaml.
- RepoConfig: An
atlantis.yaml
file specified at the root of a Terraform repo allows you to instruct Atlantis on the structure of your repo and set custom workflows. All the fields defined in the repo config section can be found here https://www.runatlantis.io/docs/repo-level-atlantis-yaml.html#reference - AWS Credentials: For AWS ( Terraform Provider ) I have used AWS Access Key and Secret Key. However, there are other parameters for other cloud providers. You can refer to the helm installation options to configure the other cloud providers.
$ helm repo add runatlantis https://runatlantis.github.io/helm-charts$ git clone https://github.com/pavan-kumar-99/medium-manifests.git \
-b atlantis$ cd medium-manifests$ helm upgrade -i atlantis runatlantis/atlantis -f
atlantis-values.yaml
As a part of the helm installation, the Atlantis server is exposed as a load balancer
$ kubectl get svc --namespace default atlantis -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
e) Configuring webhook: Steps on how to configure the webhook are documented in detail here.
f) Ahh, Finally we are now ready to get Atlantis into action. I have already created a terraform file in the ec2 folder, that would create an EC2 instance. And I have also pushed an atlantis.yaml file in the root of my repo with my custom configuration. The configuration for all these fields can be found here.
I have now raised a pull request to the atlantis branch with the following change.
As soon as I raise the Pull Request, I should see a comment on the PR with Terraform Plan Output.
Now, I will send this for approval from one of my teammates. Once the PR is reviewed and approved I can apply the configuration changes just by commenting atlantis apply
on the Pull Request.
As soon as you comment, you should be able to see the terraform apply to happen and the plan output also being commented on the same PR.
The terraform apply output is also visible in the same PR’s comment. Once the configuration is applied the branch is automatically merged and the branch is also auto-deleted.
The EC2 Instance would now be created in my AWS account. Let's verify it now.
Woahh !! The Instance is now created. I am also attaching the Pull request for reference here.
Cleanup
$ helm delete atlantis ## Delete the EKS cluster and EC2 Instance created earlier
Ahhh, these are all the steps that are needed to Implement GitOps with Terraform. I hope you have liked this article. Feel free to share your thoughts and your experiences working with Terraform automation. In case you face any issues during the deployment, please raise an issue here or feel free to reach me on my E-mail ( pavan1999.kumar@gmail.com ).
Here are some of my other articles that may interest you
Until next time…..