Continuous Deployment for Terraform using GitHub Actions

Darshit Suratwala
4 min readFeb 11, 2023

--

The goal is to automate the testing of terraform deployment so that no one has to manually apply Terraform locally.

Terraform Apply Flow
Terraform Apply Flow

Scenario

TLDR; build an approval mechanism before applying terraform.
Terraform should be applied automatically after the PR is reviewed and merged into the master. Reviewers should be notified when the terraform plan is ready and only after the approval plan should be applied.

Note: This document assumes you have
- Slack workspace access to create Slack App. If not create a new workspace.
- Followed Continuous Integration setup (previous blog).

Solution

The previous blog was for triggering GitHub workflow on a pull request, whereas here terraform apply workflow will be triggered when the PR is merged into master branch.

Workflow for Terraform Apply

The workflow condition for this will be the following

on:
push:
branches:
- master
workflow_dispatch:

We are adding workflow_dispatch here just for letting users trigger this workflow manually and check.
Copy the code from https://github.com/DSdatsme/gh-terraform/blob/master/.github/workflows/terraform_apply.yml

Setup Slack Bot

To post notifications on Slack, we would need to create a slack bot in the slack workspace.

  1. Open https://api.slack.com/apps and click create a new app with From scratch option. Give a name of your choice and create.
  2. Once you are on the app configuration page, under features click OAuth & Permissions section. Under Scopes, add permission chat:write as shown in the screenshot.

3. Copy the Bot User OAuth Token and create a new repository secret in GitHub Actions with the name SLACK_BOT_TOKEN. So now you should have two repo secrets.

Using Community Actions

For this workflow, we are using two community actions

For Slack
voxmedia/github-action-slack-notify-build@v1
One thing to note here is, for each slack message for a run the messages are updated rather than sent one after another. This means when the job starts it sends starting message and when it finishes the same message is modified as success. This saves a lot of human effort to track the status of each run. This happens using message_id field. For the first message you don't need an id, but for all other slack action calls, we specify the id indicating that only update the message with that id, or else it’d create a new message every time.
Feel free to use any other community slack actions for your purpose. Ignore the resources folder which was created for a different kind of slack action which eventually I didn't use cus I wanted to keep it easy for beginners.

For Approval
trstringer/manual-approval@v1
The approval process in this action works by tracking GitHub issues.
This action creates a GitHub issue and the loop keeps on checking if the required person commented on it with approval or rejection keywords.

Approval Flow Example
Approval Loop Output

Apply!

That’s it, once the Apply workflow is merged to the master, you can trigger it manually or by making changes in PR and then merging it.

Ideas💡

  • If there are no changes in the plan, the workflow should just finish and not go to apply step.
  • Try out the GitHub environment’s approval mechanism. As in the current action, you will be billed GitHub minutes for the time it’s waiting for approval which is inefficient.
  • Explore other notification mechanisms or other slack actions.
  • Explore Slack workflows(its enterprise feature)
  • Send terraform plan output or summary along with slack message so users don't have to search in GitHub actions.

Happy Terraforming.
Cheers!

Ref:
GitHub Repo: https://github.com/DSdatsme/gh-terraform
Approval Action: https://github.com/marketplace/actions/manual-workflow-approval
Slack Action: https://github.com/marketplace/actions/slack-notify-build

--

--