Overview
This tutorial uses examples from the following GitHub project Terraform module repository - Dynamic Subnets.
If you enjoy creating public terraform modules for the community like I do, and host them on the public terraform registry. You will enjoy todays tutorial. We will be covering how you can automate and maintain your terraform module versioning using GitHub dependabot and also automate your module releases and pushing versioned releases to the public Terraform registry using GitHub Actions.
Getting started
Anyone can publish and share modules on the Terraform Registry for free. In this tutorial I wont be going into detail on how to create your account, linking it with your GitHub repository and doing the initial push to the registry.
This initial process is fairly well documented on HashiCorps tutorial on: How to publish modules to the registry. It is a fairly easy and frictionless process.
In this tutorial we are going to focus more on maintaining an existing module and how to automate releasing new versions using GitHub Actions. We will also look at how we can automatically update the provider versions (dependencies) used inside of the terraform module using a great feature of GitHub called Dependabot.
Enable Dependabot
Dependabot is a service built into GitHub that helps you update your dependencies automatically, so you can spend less time updating dependencies and more time building. Dependabot even includes checks for version updates for terraform providers inside of your configuration files which we will look at today.
Check out this list of package-ecosystems that's supported.
One key benefit is that dependency updates might contain security vulnerability fixes, bug fixes etc and manually keeping track of updates or updating them when a newer version is available is a lot of hassle. This is where Dependabot can help by automatically raising a Pull Request whenever there is a newer version of a dependency.
In my Terraform module repository - Dynamic Subnets, I have a terraform file called versions.tf:
terraform {
required_version = "~> 1.1.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 2.62.0"
}
}
}
We will set up dependabot by creating a special folder at the root of the repository called .github
and inside that folder create a YAML
file called dependabot.yml:
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: 'terraform' # See documentation for possible values
directory: '/' # Location of package manifests
schedule:
interval: 'daily'
NOTE: The package-ecosystem is terraform
and the versions.tf
file is at the root of the project repository, which is represented by the directory: "/"
Once the dependabot YAML
file has been created and committed to the repository, you will notice that it automatically opened a Pull-Request for me, showing me that my provider version is out of date:
Now we can decide whether we want to accept this version bump or not by either accepting and merging the pull request or cancelling and closing the pull request. As you can also see the schedule interval is set to daily
which means dependabot will check everyday to see if there are any new terraform provider versions released and automatically open a pull request if there is. Pretty neat!
Automate Releases - Terraform Registry
Say for example we take this version change (or any changes and improvements on our module), and after testing the changes on our module we want to create a new public release version of our module on the public Terraform Registry.
NOTE: I have written a public GitHub marketplace Action called: Terraform Tests for AZURE to do automated tests. Check it out.
After testing to perform a release we will create a workflow.
Under the .github
directory we will create a new folder called workflows
and in this folder we will create another YAML
file called: push-tf-registry.yml.
### This workflow can be used to manually create new release versions from a tag push using e.g. VSCODE ###
on:
push:
tags:
- '*'
name: Release to terraform public registry
jobs:
Release:
name: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.6.0
- uses: ncipollo/release-action@v1
with:
generateReleaseNotes: true
name: 'v${{ github.ref_name }}'
token: ${{ secrets.GITHUB_TOKEN }}
This workflow will trigger on a tag push and create a GitHub Release. As per the documented process for creating a new release on the public terraform registry we have to use a valid semantic version, optionally prefixed with a v.
Example of valid tags are: v1.0.1 and 0.9.4. To publish a new module, you must already have at least one tag created.
To release a new version, create and push a new tag with the proper format. The webhook will notify the registry of the new version and it will appear on the registry usually in less than a minute.
The current version of my public module is version = 1.0.3
:
This corresponds with the current release on the GitHub repository hosting the module:
With the GitHub workflow set up, Let's create a new tag and push that to our repository on GitHub. The workflow will trigger and create a new release for us automatically, so let's try it out.
After creating the tag 1.0.4
and pushing the tag to the remote repository. Notice that the workflow has triggered and ran, creating a new release automatically using the tag version number:
NOTE: The GitHub Action that creates the release has an input setting: generateReleaseNotes: true
, so the release notes have also been created for us dynamically.
As you can see the new version is also now published on the Terraform Registry
That's it, now we can automatically let Dependabot take care of our terraform provider versioning and create pull requests automatically when new provider versions are released.
Additionally we also have a really straight forward easy way to create new releases of our own module by simply creating a valid semantic version number as a tag and then push that tag to our remote repository where the GitHub Workflow will create a release for us based on the semantic version tag.
As an added bonus, I also added another section onto the Dependabot config file to also regularly check the GitHub Actions used in the workflow called: ncipollo/release-action@v1
and actions/checkout@v3.6.0
so when a new versions of these actions come out, Dependabot will also let me know that I can update my workflow actions (Ive also changed my Dependency scans to run on a specific week day and time as shown below).
version: 2
updates:
- package-ecosystem: 'terraform'
directory: '/' # Location of package manifests
schedule:
interval: 'weekly'
day: 'sunday'
time: '09:00'
timezone: 'Europe/London'
- package-ecosystem: 'github-actions'
# Workflow files stored in the
# default location of `.github/workflows`
directory: '/' # Location of package manifests
schedule:
interval: 'weekly'
day: 'friday'
time: '09:00'
timezone: 'Europe/London'
Fully Automated Testing and Release on changes to IaC
Check out the next blog post on this series: Using Terraform on GitHub that shows how to perform fully automated integration test when Dependabot opens a PR. Followed by automatically merging that pull request if all tests have finished successfully and then also as a last step automatically deploy a new release/version and pushing that to the Terraform registry: Automated Terraform Tests for Azure using GitHub Actions
I hope you have enjoyed this post and have learned something new. You can find the code samples used in this blog post on my GitHub project Terraform module repository - Dynamic Subnets. ❤️
If you are interested in checking out my public terraform modules for azure, including some cool modules like OpenAI-Service, OpenAI-Private-ChatGpt, Custom Role Definitions and Sonarqube ACI, you can find them on the public terraform registry:
Author
Like, share, follow me on: 🐙 GitHub | 🐧 X/Twitter | 👾 LinkedIn
Top comments (0)