CI-CD with Terraform and GitHub Actions to deploy to AWS

GitHub Actions is a CI/CD tool that can automate the provisioning of AWS resources using Terraform. Previously, I wrote a detailed post explaining the concepts associated with using Terraform to create an application load balancer that you can read here –add an application load balancer to Amazon EC2 using Terraform. In this note, I further automate the provisioning of all the AWS resources using Terraform and GitHub Actions.

Provisioning a Terraform resource consists of the following four steps:
1. Initialize the repository (terraform init) with appropriate provider versions,
2. (Optionally) format (terraform fmt) and validate (terraform validate) the code,
3. Plan (terraform plan), and finally,
4. Apply (terraform apply) the changes stated in the Terraform configuration files.
In the past, I’ve used Azure Pipelines to automate the same, and if you are interested, you can read that at –azure-pipelines-yaml-and-terraform-to-provision-aws-s3.

In GitHub actions, the process mostly stays the same compared to the manual process. The few differences are in how you authenticate GitHub Actions to communicate with your AWS account to provision resources and an automation step, namely, updating the pull request. To create a secure process, I stored the ARN of the IAM role (OpenID Connect) as a secret in this GitHub repository and then accessed via the secrets.IAM_ROLE construct.

I based my note on the learnings I found on this tutorial from HashiCorp, which is helpful and well-described. Since I was not using the Terraform cloud account, the only little change I made was -how I authenticated to GitHub actions.

I covered the authentication concept in a separate detailed note, securely-integrate-aws-credentials-with-github-actions-using-openid-connect which you must understand before using the Terraform configuration stack that I have in my repository.

A couple of essential items in the GitHub Actions YAML file to note are as follows:
Item#1: Enable GitHub Actions to acquire the below three permissions.
These permissions enable GitHub actions to read the Terraform configuration files, write the authentication token( as part of using the Open ID connect approach), and write to the pull request (the output of the terraform plan step).

Item#2: Terraform plan runs only under two conditions.
As you can see from the image below, there are only two conditions for the terraform plan command to run.
When the (i) branch is not equal to main, and (ii) when the event is a pull_request.
As a developer, I write the Terraform configuration to provision resources. And as best practice, I commit the code, not on the main branch. As I create the Terraform configurations, I need feedback to check if the code is correct. I get that when I push my code to GitHub, which triggers this pipeline. And since I am not working off the main branch, the Terraform Plan step is executed. And in case of a pull request, this step is necessary since the PR reviewer needs to see the plan file to evaluate whether to approve or reject the pull request.
Note: An option to get quick feedback if my Terraform configuration is correct is to run terraform plan from my local before pushing the code to GitHub, but that would require me to store credentials on my local (laptop), which I could not do in this case.

And finally, here is a link to my GitHub repository: add-aws-elb-ec2-terraform, where I have the GitHub Actions file.
You can also check the GitHub Actions workflow to review the build logs for this Terraform project at GitHub-actions.

I hope this note was helpful, and let me know if you have any questions or suggestions. And although I worked with an application load balancer in AWS in this use case, you can provision any AWS resource using the above approach with GitHub Actions.

One thought on “CI-CD with Terraform and GitHub Actions to deploy to AWS

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s