In Terraform you can use variables to make your code more dynamic and reusable. You can use variables to pass in values from the command line, from a file, or from environment variables. In this blog post I will show you how to use GitHub Actions variables as Terraform variables.
GitHub Actions Variables
GitHub Actions variables are environment variables that are set by GitHub Actions. You can use these variables in your workflow files. For example, you can use the GITHUB_SHA
variable to get the commit SHA that triggered the workflow. You can find a list of all the available variables [here].
GitHub Actions Setup
Within the GitHub repository to where you are going to be running the terraform from, select settings -> secrets
Add 4 secrets:
AZURE_CLIENT_ID
– Will be the service principal ID from aboveAZURE_CLIENT_SECRET
– The secret that was created as part of the Azure Service PrincipalAZURE_TENANT_ID
– The Azure AD tenant ID to where the service principal was createdAZURE_SUBSCRIPTION_ID
– Subscription ID of where you want to deploy the Terraform
Terraform Setup
To assist with deploying terraform I will be using action hashicorp/setup-terraform@v2
Lets look at the example terraform plan flow
- name: Terraform Plan
run: |
export ARM_CLIENT_ID=$ARM_CLIENT_ID
export ARM_CLIENT_SECRET=$ARM_CLIENT_SECRET
export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID
export ARM_TENANT_ID=$ARM_TENANT_ID
terraform plan -input=false -var rg_name=$RG_NAME
env:
ARM_CLIENT_ID: ${{secrets.ARM_CLIENT_ID}}
ARM_CLIENT_SECRET: ${{secrets.ARM_CLIENT_SECRET}}
ARM_SUBSCRIPTION_ID: ${{secrets.ARM_SUBSCRIPTION_ID}}
ARM_TENANT_ID: ${{secrets.ARM_TENANT_ID}}
RG_NAME: "tamopsrggithub"
Notice the use of variables? In particular RG_NAME
, this the variable that has been created in the GitHub Action but used by terraform using -var
Reviewing the Terraform Plan, we can see this created variable is used:
+ resource "azurerm_resource_group" "tamops" {
+ id = (known after apply)
+ location = "uksouth"
+ name = "tamopsrggithub"
}

Complete GitHub Action workflow below
name: 'Terraform'
on:
push:
branches:
- main
pull_request:
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
- name: Terraform Init
run: |
export ARM_CLIENT_ID=$ARM_CLIENT_ID
export ARM_CLIENT_SECRET=$ARM_CLIENT_SECRET
export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID
export ARM_TENANT_ID=$ARM_TENANT_ID
terraform init
env:
ARM_CLIENT_ID: ${{secrets.ARM_CLIENT_ID}}
ARM_CLIENT_SECRET: ${{secrets.ARM_CLIENT_SECRET}}
ARM_SUBSCRIPTION_ID: ${{secrets.ARM_SUBSCRIPTION_ID}}
ARM_TENANT_ID: ${{secrets.ARM_TENANT_ID}}
- name: Terraform Plan
run: |
export ARM_CLIENT_ID=$ARM_CLIENT_ID
export ARM_CLIENT_SECRET=$ARM_CLIENT_SECRET
export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID
export ARM_TENANT_ID=$ARM_TENANT_ID
terraform plan -input=false -var rg_name=$RG_NAME
env:
ARM_CLIENT_ID: ${{secrets.ARM_CLIENT_ID}}
ARM_CLIENT_SECRET: ${{secrets.ARM_CLIENT_SECRET}}
ARM_SUBSCRIPTION_ID: ${{secrets.ARM_SUBSCRIPTION_ID}}
ARM_TENANT_ID: ${{secrets.ARM_TENANT_ID}}
RG_NAME: "tamopsrggithub"
- name: Terraform Apply
run: |
export ARM_CLIENT_ID=$ARM_CLIENT_ID
export ARM_CLIENT_SECRET=$ARM_CLIENT_SECRET
export ARM_SUBSCRIPTION_ID=$ARM_SUBSCRIPTION_ID
export ARM_TENANT_ID=$ARM_TENANT_ID
terraform apply -auto-approve -input=false -var rg_name=$RG_NAME
env:
ARM_CLIENT_ID: ${{secrets.ARM_CLIENT_ID}}
ARM_CLIENT_SECRET: ${{secrets.ARM_CLIENT_SECRET}}
ARM_SUBSCRIPTION_ID: ${{secrets.ARM_SUBSCRIPTION_ID}}
ARM_TENANT_ID: ${{secrets.ARM_TENANT_ID}}
RG_NAME: "tamopsrggithub"
With a successful run of Terraform apply, the storage account tamopsrggithub
is created using the GitHub Action variable

Full code/example in this blog post is found [here]
GitHub Repository examplere [here]