Terraform - GitHub Actions Integration
Recently, there was a great new resource added to the GitHub Marketplace which allows us to easily integrate the HashiCorp Terraform CLI into the CI/CD process that’s been made available with GitHub Actions. The HashiCorp Setup Terraform action is also available as a starter workflow, accessible directly within the Actions tab of your GitHub repository.
GitHub Actions
GitHub Actions make use of a YAML-formatted workflow file. This file establishes the configuration for things such as what events should include action processes, the type of runner to use, and the configuration of the jobs with the required steps to reach completion. In order for the GitHub Actions process to pick up the YAML file, there’s a specific location for it to live. Each repository using actions requires a directory structure of /.github/workflows
To give an example of how GitHub Actions and Terraform can be used together, we will be making use of a sample workflow file. To access this sample workflow in your own GitHub repository, head to the Actions tab, and click the “Set up this workflow” button from the “Terraform” option.
name: 'Terraform Plan'
on: [push, pull_request]
defaults:
run:
shell: bash
jobs:
terraform:
name: 'Terraform'
runs-on: ubuntu-latest
steps:
- name: 'Checkout'
uses: actions/checkout@v2
- name: 'Terraform Setup'
uses: hashicorp/setup-terraform@v1
with:
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
- name: 'Terraform Init'
run: terraform init
- name: 'Terraform Format'
run: terraform fmt -check
- name: 'Terraform Plan'
run: terraform plan
There are a couple of fields to focus on while creating our workflow file. First, the on field defines which repository based event/s the action should trigger as a response. These events can be high-level, such as a pull or push, or fairly granular, by only picking out events for particular branches. Next, configuring the jobs field. The first sub-level is to specify the job ID. The sample file is using terraform as a job ID. As a sub-level to the job ID is the runs-on field. This field specifies the type of runner to use. GitHub allows for hosted runners of Windows, Ubuntu, and macOS. The last sub-level we have is to configure the steps the job should process.
Steps are where all the work happens. The first step should always be a checkout action. Checkout allows the overall workflow to use a copy of the repository’s code, such as our Terraform configuration files. The second step is to set up Terraform CLI on the runner. As part of this step, we can integrate the job into Terraform Cloud or Enterprise. Adding a with field gives the ability to add Terraform based inputs such as hostname, token, Terraform version, and wrapper. The next steps allow for direct interaction with the Terraform CLI via the run field.
In Action: setup-terraform
At this point, we already have a GitHub repository with our Terraform configuration and we have our Actions workflow file. Our directory structure should resemble something like the following:
|-- tf-ghactions-demo (repository)
| |__ main.tf
| |__ .github
| └── workflows
| └── terraform.yml
We’re now ready to make either a pull request or a commit to our repository to see our newly created GitHub Action come to life!
After completing a pull request, we will see an action in progress as part of the checks process.
Opening the details link will show us information about the Terraform job which is processing as part of our configured Action.
We can also see the status of our Terraform plan action directly in Terraform Cloud by following the link shown on line 13 of the above example.
The above example is just scratching the surface of what’s possible when we combine Terraform with GitHub Actions. We can also feed information back to the pull request as comments. There’s even the option to apply the configuration after a successful pull request. For some additional examples, head over to the Starter Workflows repository and, more specifically, the terraform.yml file.