CICD for Terraform with GitHub Actions
This post is about using Terraform in CICD pipeline with GitHub actions.
Most of the time we make use of popular CICD tools like Jenkins for Infra deployment. Because its nice as we can have stages for deployment, add custom variables or jobs and we can also add prompts for user inputs to continue, which is really important. With GitHub actions, its fully automated and it can be risky sometimes, because with automated, there is a pretty good chance, that a mistake in the config and wipe off the full infrastructure.
What if we can use GitHub Actions in a safe way for CICD for Terraform? Lets get to it
If you are familiar with GitHub Actions workflw, then this config looks really simple:
namesection is the name of the workflow
ondefines when the workflow should be triggered. Here when there is a Pull Request created to the
mainbranch and when there is changes for files inside
envdefines the environment variables required for this particular workflow or for the jobs that is going to run. The variables are related to terraform config that is run. All those secrets are stored in GitHub Secrets.
jobssection contains all the jobs that needs to run for this workflow. There is:
- Install terraform
- Check terraform formatting is proper
- Initialize terraform
- Validate terraform
- Run terraform Plan
- Run commands to update the PR if its passed or failed
- Terraform is installed all the time, because I am using a public
ubuntuimage and I am not sure if proper version of terraform is installed or not. This additional help is better than building my own custom image and using it.
- The posting info job uses
actions/github-script@v6. You will need to give more attention on the format on printing information, otherwise it might look a bit ugly :P
So the jobs are similar to the ones in the terraform plan workflow. Except in here we are running plan and apply as well together. I can actually merge both these workflows into one and then check if its PR or not to run the
At this point of time when I am writing, there was an issue with the
actions/github-script@v6 action. When the Pull Request is merged, then for some reason, the
GITHUB_TOKEN cannot write on the closed PR discussion. I tried to use the same action to use with the PR
closed. Still it didn’t work. So I had to use a different action, which someone created due to the same issue.
So now create a new branch from
main and add some TF code and create a a PR against the
main branch. This is how my plan looks like
And when I merge the PR, it looks like this:
This is for setting up simple infrastructure. In this infra, the
tfvars file is inside the
infrastructure folder in the repo. For more complex environment like multiple environments, then it would be better to use terraform workspaces, provide separate
tfvars files and change the directory structure itself and based on branch, deploy to different environments.
- PR and merge from feature to development branch, goes to DEV
- PR and merge from development to main branch, goes to TEST/UAT
- And creation of tag and deploying it will go to PROD.
This is what I would see as a proper infra deployment. With this base workflows, you can also easily integrate tests with localstack or mock environments
CICD for infrastructure deployment is getting more and more as a requirement, because Infrastructure as a Code is moving as a defacto standard for provisioning Infra on any provider whether its cloud or on-premise. It would be nice to have CICD for infra with unit and integration testing. I hope this post helped you to understand how to build a CICD pipeline. With this info as a base, you can actually build complex pipelines.
Hope you enjoyed and have a nice day!