Continuous Deployment for Terraform using GitHub Actions
The goal is to automate the testing of terraform deployment so that no one has to manually apply Terraform locally.
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.
- Open https://api.slack.com/apps and click create a new app with From scratch option. Give a name of your choice and create.
- 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 Approvaltrstringer/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.
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