[Github Actions] Pipelines for Terraform
Table of contents
As I’ve stated in other posts I’ve done here, I am a big fan of Github Actions. I really like the simplicity of it and how easily you can build pipelines for your Terraform code.
Here, I want to show you what pipelines I am building for my terraform code and how they are working.
In my modules, I always have three pipelines:
- AutoTag
- Pre-commit check
- Terraform deploy
Autotag
This is a rather simple pipeline that you can reuse for everything you want. I like to tag everything I am developing with this format: vMajor.Minor.Patch.
The autotag pipeline always runs when you merge your code and by default, will bump the Patch version.
In order to increase the major or the minor version of the tag, you simply need to add in your commit message #major or #minor and whenever a push is done to the main branch those will be bumped.
If you are using this pipeline in an organisation, make sure that you add a secret in the Github repository for a Personal Access Token, otherwise you won’t have enough permissions to push the tag back to the repository.
This is how it looks like:
name: Bump version
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: "0"
- name: Bump version and push tag
uses: anothrNick/github-tag-action@1.36.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WITH_V: true
DEFAULT_BUMP: patch
PreCommit
In this pipeline, I am usually checking if I ran pre-commit locally on all of my files and folders. This is checking whatever hooks I’ve added inside .pre-commit-config.yaml.
In my case the hooks are: tflint, tfdocs, fmt, validate, eof and trailing whitespaces. You can configure that file to your liking.
I’ve configured this to run on all pushes, because I want to make sure that I am not merging my feature branches without this check is passing.
Below there is an example of what I am using:
on:
push:
jobs:
pre-commit:
name: "pre-commit"
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Setup python
uses: actions/setup-python@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
- name: Install pre-commit
run: pip install pre-commit
- name: Install other dependencies
run: |
curl -sSLo ./terraform-docs.tar.gz https://terraform-docs.io/dl/v0.16.0/terraform-docs-v0.16.0-$(uname)-amd64.tar.gz
tar -xzf terraform-docs.tar.gz
chmod +x terraform-docs
mv terraform-docs /usr/local/bin/terraform-docs
curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash
- name: run pre-commit
run: pre-commit run --all-files -v
Terraform Deploy
I also have a manual pipeline that runs examples inside of my module.
Whenever you want to deploy resources inside of an example, you can refer to this pipeline and you will have to select one of three options: plan / apply / destroy. By default that option is plan.
This pipeline can be easily copied from the module to the repository in which you are going to run the code you’ve built based on your Terraform modules.
Example pipeline:
on:
workflow_dispatch:
inputs:
terraform_operation:
description: "Terraform operation: plan, apply, destroy"
required: true
default: "plan"
type: choice
options:
- plan
- apply
- destroy
jobs:
terraform:
name: "terraform"
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
- name: Go to the example directory
run: cd example
- name: Terraform init
run: terraform init
- name: Terraform plan
run: terraform plan
if: "${{ github.event.inputs.terraform_operation == 'plan' }}"
- name: Terraform apply
run: terraform apply --auto-approve
if: "${{ github.event.inputs.terraform_operation == 'apply' }}"
- name: Terraform destroy
run: terraform destroy --auto-approve
if: "${{ github.event.inputs.terraform_operation == 'destroy' }}"
The sky is the limit when it comes to what you can embed in these pipelines. These can be easily replicated to other CI/CD tools like Jenkins, Gitlab CI, Bitbucket Pipelines, Circle CI and others, so don’t feel restricted to using Github Actions.
Subscribe to my newsletter
Read articles from Flavius Dinu directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Flavius Dinu
Flavius Dinu
DevOps / Cloud Engineer ☁️ Terraform Evangelist 🚀 Docker & Kubernetes Enthusiast 🐳 Python Main 🐍