Automate versioning of Terraform with GitHub actions

CJ Hewett
4 min readOct 19, 2023

Automate versioning of Terraform in a GitHub repo with the use of GitHub Actions and Semantic Release. GitHub Actions will automate the process of running Semantic Release on commits to a chosen branch, and Semantic release will create a Git Tag, and a GitHub Release with release notes about changes in the added commits.

This action will checkout your repo, setup node, install semantic release (this could be cached using NPM cache, to speed up future runs), run sematic-release with a GitHub token, so that the action has permissions to create a release and tag for the repo.

Code included in this post can be found here:

.github/workflows/release.yaml

This file defines the GitHub Action:

  • Runs on push to prod branch, change this to fit.
  • Sets permissions to be able to create releases
  • Checkout repo, setup node, install Semantic Release and related plugins, run Semantic Release with GitHub token.
  • GITHUB_TOKEN — you don’t need to set up the secret, that’s automagical, and handles by GitHub Actions. The token is needed so that Semantic Release is able to create and push a Git Tag, as well as create the GitHub Release.
name: GitHub Release

on:
push:
branches:
- prod

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
release:
# The type of runner that the job will run on
runs-on: ubuntu-latest

permissions:
contents: write
issues: read

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3

- name: Setup Node.js environment
uses: actions/setup-node@v3.7.0
with:
# Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0.
node-version: 18.x # optional

- name: Install Semantic Release and plugins
run: |
npm install semantic-release @semantic-release/exec @semantic-release/changelog @semantic-release/github

- name: Create Release
run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Next it our config for semantic release, so that it can work out how to bump the version, based on the commits being merged into the branch.

.releaserc.yaml

Important parts are:

  • branches — Here is is set to prod , but change this to suit your needs.
  • analyzeCommits — decides how to bump semantic version based on commit messages in the merging branch. E.g. commits beginning with feat: are considered a minor release, and fix: is considered a patch.
  • The exec command — outputs the new version to a file
---
branches:
- prod
defaultBranch: "prod"
preset: "angular"
tagFormat: "${version}"
plugins:
- "@semantic-release/commit-analyzer"
- "@semantic-release/release-notes-generator"
- "@semantic-release/changelog"
- "@semantic-release/github"
- "@semantic-release/exec"

verifyConditions:
- "@semantic-release/github"

analyzeCommits:
- path: "@semantic-release/commit-analyzer"
releaseRules:
- type: "feat"
release: "minor"
- type: "fix"
release: "patch"
- type: "breaking"
release: "major"
- type: "refactor"
release: "patch"
- type: "chore"
release: "patch"

generateNotes:
- path: "@semantic-release/release-notes-generator"
writerOpts:
groupBy: "type"
commitGroupsSort:
- "breaking"
- "feat"
- "fix"
- "chore"
commitsSort: "header"
types:
- type: "feat"
- section: "Features"
- type: "fix"
- section: "Bug Fixes"
- type: "breaking"
- section: "Breaking Changes"
- type: "refactor"
- hidden: true
- type: "chore"
- section: "Chore"
- type: "docs"
- hidden: true
- type: "doc"
- hidden: true
- type: "style"
- hidden: true
- type: "perf"
- hidden: true
- type: "test"
- hidden: true
presetConfig: true
- path: "@semantic-release/exec"
cmd: "echo ${nextRelease.version} > nextRelease"
prepare:
- path: "@semantic-release/changelog"
changelogFile: "docs/CHANGELOG.md"
publish:
- path: "@semantic-release/github"

success:
- "@semantic-release/github"

fail:
- "@semantic-release/github"

Once these files have been committed and pushed to the branch specified in the above files ( prod in this case), either directly to the branch, or merge, GitHub Actions will trigger a run and create a release.

Successful run of GitHub Action
GitHub Action logs for a successful release

Releases for a GitHub repo can be viewed at /releases path on the URL for the repository.

GitHub Release and Tag

I hope you found this useful!
Cheers 🤙,

CJ Hewett
CJ Hewett

Written by CJ Hewett

🛹 Skateboarder. 🏂 Snowboarder. 🏄 Websurfer. I write monthly* about Cloud/DevOps/IoT. AWS Certified DevOps Engineer and Terraform Associate

No responses yet

Write a response