Run Terraform with GitHub Actions#
In previous post Run Terraform within GitHub Codespaces the Terraform environment was setup within GitHub Codespaces. The next step is to run Terraform with GitHub Actions via Terraform Cloud as part of a workflow and scan the Terraform code with KICS is the first step to reduce technical debt as described in the post KICS.
Let’s start with the workflow file .github/workflows/terraform.yml
to run a KICS scan to verify the Terraform code. The workflow is triggered on push and pull request on the master branch. The Terraform code is checked out and the KICS scan is executed. The KICS scan is configured to run on the Terraform code in the directory terraform
and the results are stored in the directory build
. The KICS scan is configured to run on the Terraform platform and the output formats are JSON and SARIF so the results can be processed later. The KICS scan is configured to fail on high and medium severity issues. The KICS scan is configured to not add comments to the pull request and to exclude the query with the ID 1e434b25-8763-4b00-a5ca-ca03b7abbb66
during the scan.
---
name: Terraform
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
kics:
name: KICS scan
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Create directory build
run: mkdir -p build
- name: Run KICS Scan with SARIF result
uses: checkmarx/[email protected]
with:
path: 'terraform'
output_path: 'build'
platform_type: terraform
output_formats: 'json,sarif'
fail_on: high,medium
enable_comments: false
exclude_queries: 1e434b25-8763-4b00-a5ca-ca03b7abbb66
In the second step the file .github/workflows/terraform.yml
is extended to run Terraform with GitHub Actions. The Terraform version is configured with the environment variable TERRAFORM_VERSION
. The Terraform code is checked out and then Terraform code is checked if it is formatted correctly. After this the Terraform code is initialized, validated, and then a dry-run is executed. If the dry-run is successful and the GitHub Action runs as part of a push
event on the master
branch.
env:
TERRAFORM_VERSION: '1.4.6'
jobs:
...
terraform:
name: Terraform
runs-on: ubuntu-latest
needs: kics
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Set up Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: ${{ env.TERRAFORM_VERSION }}
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
- name: Terraform Format
id: fmt
run: terraform -chdir=terraform fmt -check
continue-on-error: true
- name: Terraform Init
run: terraform -chdir=terraform init
- name: Terraform Validate
id: validate
run: terraform -chdir=terraform validate -no-color
- name: Terraform Plan
id: plan
if: github.event_name == 'pull_request'
run: terraform -chdir=terraform plan -no-color -input=false
continue-on-error: true
- name: Terraform Plan Status
if: steps.plan.outcome == 'failure'
run: exit 1
- name: Terraform Apply
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
run: terraform -chdir=terraform apply -auto-approve -input=false
For the workflow to work correctly the secret variable TF_API_TOKEN
needs to be configured in the repository settings. The Terraform Cloud API token is used to authenticate with Terraform Cloud and can be created in the Terraform Cloud user settings. The Terraform Cloud API token is stored as secret variable in the repository settings within GitHub to prevent the token from being exposed in the workflow file.
From this point every pull request on the master branch will be checked with KICS and Terraform Cloud if it could be deployed successfully. If the pull request is merged into the master branch the Terraform code will be deployed automatically without any manual interaction.