Continuous Integration for Terraform Modules with GitHub Actions
Collaborating on infrastructure projects using code can introduce challenges such as testing, configuring continuous integration, and deployment pipelines. These things help to ensure that the software is stable, and enables faster releases. These challenges extend to things like Terraform modules that help you share Terraform configuration in your organization. In this post, we’ll take a look at how you can configure a continuous integration pipeline to help test and collaborate on Terraform modules using Github Actions.
» GitHub Actions
GitHub Actions gives users the ability to configure actions based on events such as pull requests and merges to their repositories. This feature can be used for Terraform modules managed in GitHub, without having to rely on external tooling.
GitHub Actions relies on a YAML workflow file to specify the steps to execute. A typical workflow for a Terraform module includes terraform init
and terraform validate
commands. The init
command initializes the module and downloads any needed providers. The validate
command helps validate the configuration files in the module and is useful for general verification.
Now, let’s take a look at how to construct this workflow with a GitHub Actions workflow file. Create a new workflow file at /.github/workflows/workflow.yaml
in the root of the GitHub repository. The content of the workflow file should be as follows:
name: Terraform CI
on:
pull_request:
branches:
- master
jobs:
validate:
name: Validate
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v1
- name: Run a Terraform init
uses: docker://hashicorp/terraform:0.12.11
with:
entrypoint: terraform
args: init
- name: Run a Terraform validate
uses: docker://hashicorp/terraform:0.12.11
with:
entrypoint: terraform
args: validate
First, we name the workflow “Terraform CI”. Next, we specify that this workflow should be triggered on a pull request event opened against the master branch.
Then, we define each step to be run during this workflow. In the example, we use the predefined checkout
action to retrieve the code contained in the repository. After retrieving the contents of the repository, we specify steps to execute terraform init
and terraform validate
commands using the Terraform container from Docker Hub.
By using these steps, we can initialize and validate the syntax of Terraform modules in Github without setting up additional tooling. Teams can collaborate on modules and push to the repository with a continuous integration workflow.
» Continuous Testing
In addition to validating Terraform code, we can extend this workflow to incorporate automated testing of modules. This is especially important when multiple developers are collaborating on a module, and helps continuously verify that it executes as expected.
We now update our example with the addition of a step to execute unit tests implemented with Terratest, a Golang library for running tests against Terraform.
name: Terraform CI
on:
pull_request:
branches:
- master
jobs:
validate:
name: Validate
runs-on: ubuntu-latest
steps:
# Steps omitted for clarity
- name: Set up Go 1.13
uses: actions/setup-go@v1
with:
go-version: 1.13
id: go
- name: Get dependencies
run: |
if [ -f Gopkg.toml ]; then
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
dep ensure
else
go get -v -t -d ./...
fi
- name: Test
working-directory: /home/runner/work/terratest-demo/terratest-demo/test
run: go test
Similar to the previous section, we use the setup-go
action to bootstrap a Golang environment to stage the unit tests. Next, we pull down the dependencies for the test code in order to execute go test
. Before running the tests, we change to the directory containing the test files, located in /home/runner/work/{repository-name}/{repository-name}
» GitHub Status Checks
To ensure a potentially disruptive configuration does not affect a stable Terraform module, we protect the master branch from merging a pull request with failing checks. We go to the “Settings” tab on the GitHub repository and select the “Branches” section.
We select “Require status checks to pass before merging” and choose the status checks created by the GitHub actions workflow. Finally, we click “Create” to save the branch protection rule. This will ensure that pull requests can’t be completed until the checks have passed.
» Conclusion
In this post, we covered how GitHub Actions enables a flexible, native continuous integration pipeline for Terraform modules without the need to depend on external tooling. Github Actions enables us to validate syntax, test resources, and maintain the quality of our Terraform modules as we integrate changes to their configurations. To learn more about GitHub Actions, refer to the official documentation.
Sign up for the latest HashiCorp news
More blog posts like this one
Fix the developers vs. security conflict by shifting further left
Resolve the friction between dev and security teams with platform-led workflows that make cloud security seamless and scalable.
HashiCorp at AWS re:Invent: Your blueprint to cloud success
If you’re attending AWS re:Invent in Las Vegas, Dec. 2 - Dec. 6th, visit us for breakout sessions, expert talks, and product demos to learn how to take a unified approach to Infrastructure and Security Lifecycle Management.
Speed up app delivery with automated cancellation of plan-only Terraform runs
Automatic cancellation of plan-only runs allows customers to easily cancel any unfinished runs for outdated commits to speed up application delivery.