Recently I started working with Terraform more and more, as CloudFormation is lagging behind in terms of support for newer AWS services. Terraform has quite a steep learning curve, but once it clicks you never want to go back to the old days.
I created a public repository up on GitHub so I can play around with Terraform and other related tools. This week GitHub Satellite is on, which brought us a much needed feature: a proper GitHub Action for working with Terraform in a CI/CD pipeline. The action is called setup-terraform and is available right now.
Here’s how it works.
If you take a look at my repository you can see I’ve built a simple VPC module which I’m calling from vpc.tf
in the root of the repository. Before you dive in, you first have to configure Secrets. Secrets is where you will store your AWS credentials so Terraform can reach your environment and roll out changes if needed.
Setting up Secrets
Head to your GitHub repository settings where your Terraform templates are stored. In the left sidebar you’ll find Secrets. We’ll need three Secrets for the workflow to work:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_REGION
(example: eu-west-1)
Have a look at the documentation if you want to know how to obtain AWS credentials.
Breaking down the workflow
Now that we’ve got our Secrets set up, we can create a GitHub Action. In your GitHub repository, select Actions from the top menu and click set up a workflow yourself.
Let’s break down each step.
This GitHub Action will run on Ubuntu and will invoke a bash shell so we can set environment variables.
terraform:
name: 'Terraform'
runs-on: ubuntu-latest
defaults:
run:
shell: bash
The following step will install Terraform.
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
This is how the Action will use the Secrets you configured earlier to set environement variables. Terraform will use these credentials to talk to AWS’ API.
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
Once we have Terraform set up and the credentials loaded as environment variables we can run all commands you’re familiar with from running Terraform locally.
- name: Terraform init
run: terraform init
- name: Terraform validate
run: terraform validate
- name: Terraform format
run: terraform fmt -check
- name: Terraform plan
run: terraform plan
If you work with proper a proper Git branching strategy and make sure code only gets into master using pull requests, you can also terraform apply
right from your workflow.
- name: Terraform Apply
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
run: terraform apply -auto-approve
Using this workflow in GitHub Actions you have a fully automated CI/CD pipeline that will validate your code, and even deploy changes to the correct environment when everything checks out. Of course you can go crazy with multiple environments and repositories but these are the basics. Try it out, I’d love to see what you do with it.