How to validate Terraform on every pull request with a read-only GitHub Actions workflow
Format and validation checks catch broken Terraform before anyone runs a plan. They need no cloud credentials, so they can run safely on every pull request.
The workflow
This is the free sample from the DevOps Template Store. You can download it here.
name: Terraform static validation
on:
pull_request:
paths: ['**/*.tf', '.github/workflows/terraform-validate.yml']
permissions:
contents: read
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
with:
terraform_version: '1.9.8' # Example only; update and approve version
- name: Format check
run: terraform fmt -check -recursive
- name: Initialize without backend
run: terraform init -backend=false -input=false
- name: Validate
run: terraform validate -no-color
What each part does
pathsruns the job only when Terraform files, or the workflow itself, change.permissions: contents: readgives the job a read-only token. GitHub recommends givingGITHUB_TOKENthe minimum permissions it needs, with read-only access to contents as the default.- Actions pinned to a full commit SHA. GitHub's security guidance says pinning to a full-length SHA helps mitigate a backdoored action repository. GitHub now also documents workflow dependency lockfiles, which supersede SHA pinning for repositories that adopt them. Check that each SHA comes from the action's own repository, and update it on purpose.
terraform fmt -checkexits with a non-zero status if any file is not formatted, and lists those files.-recursiveincludes subdirectories.terraform init -backend=falseinstalls providers and modules without touching remote state. This is the way HashiCorp documents to initialise for validation only.terraform validatechecks that the configuration is syntactically valid and internally consistent, whatever the variables or state. It does not contact remote services or provider APIs.
What it does not do
Validation does not check your configuration against the real environment. For that, HashiCorp points to terraform plan, which includes an implied validation check.
A plan needs credentials. Run it in a separate job with short-lived credentials (for example, OIDC to your cloud) and stricter protections. Do not add credentials to this workflow.
Before production
- Set
terraform_versionto the version your team has approved. - Re-verify both action SHAs against their release tags.
- Make the check required in your branch protection rules.
The sample is a starting point, provided as-is: review it for your environment.
Try it free: Free DevOps templates: 3 samples to download
Download three starter files from the DevOps Template Store pack for free, and preview the rest of the pack.
Open the free tool →About the product: DevOps Template Store
The tool runs in your browser: your data stays on your device. No signup.
Sources
Venture Lab 10 is independent. Other product and service names are used only to describe compatibility or for comparison, and are trademarks of their owners.