Streamline your infrastructure as code (IaC) workflows by integrating your GitHub repository with HashiCorp Terraform Cloud (HCP). This powerful combination enables automatic execution of Terraform plans and applies based on changes made to your infrastructure code, ensuring that every update to your repository triggers the necessary Terraform actions.
In this step-by-step guide, I'll explore how to integrate your GitHub repository with Terraform Cloud, keeping everything in the cloud. You'll learn how to write and develop Terraform configuration code on your laptop, push it to GitHub, and have HCP Cloud automatically trigger and deploy the resources on Azure.
Benefits of Integration
- Cloud-based infrastructure management with Terraform Cloud
- Automated Terraform workflows
- Version control and collaboration through GitHub
- Streamlined IaC processes
Prerequisites for this article
- Terraform Cloud account
- GitHub repository
- Azure subscription
I've set up a free account on HashiCorp's Terraform Cloud portal and created a new Terraform project. Read my earlier article for setting up new HCP account - HashiCorp HCP Terraform Cloud backend configuration.
In this first step I will configure API token for Project on HCP cloud for authentication purpose. Create new Project and go to its settings.
HCP Terraform offers four distinct API token types, each with varying levels of access: organization, team, user, and audit. For security, API tokens are only displayed once at creation and are then obscured. If a token is misplaced, it must be regenerated.
To generate an organization API token, navigate to Settings >> Security >> API Tokens and click 'Generate an organization token'. Select the desired expiration period and click 'Generate token'.
Note that the organization API token grants access to manage teams, team membership, and workspaces, but does not permit plans and applies within workspaces. Treat this token with utmost care, as it allows access to your account without requiring a username, password, or two-factor authentication.
Be sure to copy and securely store the token, as it will not be visible once you leave the page.
Next, navigate to (link unavailable) and access your settings by clicking on your profile picture or avatar in the top right corner. From the dropdown menu, select 'Settings'.
In the settings menu, click on 'Developer settings' from the navigation menu on the left-hand side. This will take you to the GitHub Developer Settings page, where you can manage your API keys, OAuth applications, and other developer-related settings.
In the Developer Settings, scroll down to the 'Personal access tokens' section and click on 'Generate new token' (Classic). Select the desired permissions and scopes for your token, then click 'Generate token'.
Important: Copy the generated token and store it in a secure location, such as a password manager or a secure notes app. Once you navigate away from the page, the token will not be visible again. Treat this token like a password, as it grants access to your GitHub account.
Personal access tokens (classic) function like ordinary OAuth access tokens. They can be used instead of password for Git over HTTPs, or can be used to authenticate to API over basic Authentication.
For the details permissions and role assignment check my article: Create GitHub repository and branches using Terraform
In this step, I'll set up environment variables for Terraform HashiCorp Cloud and GitHub using PowerShell. Open your PowerShell console and run the following commands to add the necessary environment variables:
$env:GITHUB_TOKEN = 'Generated GITHUB PERSONAL ACCESS TOKEN' $env:TFE_TOKEN = 'Generated HashiCorp Terraform Cloud (HCP) Token'
Replace "Generated Hashicorp Terraform Cloud (HCP) token" and "Generated GitHub_PERSONAL ACCESS_token" with your actual Terraform HashiCorp Cloud token and GitHub Personal Access Token (classic), respectively. These environment variables will be used in your Terraform configuration script to authenticate with Terraform HashiCorp Cloud and GitHub.
I am applying terraform configuration to create new GitHub repository, main branch and terraform oAuth client to authenticate to github.com using PAT token.
Download this Terraform_cloud_GitHub.com_integration_configuration code here or it is also available on github.com.
Once configuration is successful check new VCS Provider for github.com is created under organization settings >> providers.
To connect workspaces, modules and policy sets to git repositories containing terraform configurations, HCP Terraform needs to access to your version control system (VCS) provider. Use this to configure OAuth authentication with your VCS provider.
Click add new VCS Provider again. In the Connect to VCS tab, select GitHub.com (Custom).
In the Set up provider tab, Note down Authorization call back URL and copy it. Note: don't close the Add VCS Provider page.
Go to another browser page to GitHub.com >> Settings >> Developers Settings >> OAuth Apps and Register a new application.
Provide Application a name, Homepage URL as http://app.terraform.io. In the Authorization callback URL copy URL from above generated Terraform Cloud and paste it here on GitHub page. Click Register Application.
In the newly created OAuth App Click button to Generate a new client secret. Don't forget to update the application. Copy Client ID and Client Secrets, I will use them in next steps.
Go to the Terraform Cloud portal and resume adding VCS provider. Provide details such as Name, Client ID, Client Secret created from GihHub OAuth App page as above. Click Connect and continue button to proceed.
New box will open to authorize terraform cloud to GitHub with OAuth token. Click Authorize button.
Here in the Advanced settings tab, make sure Workspaces scope is selected to All Projects. Click button Skip and Finnish.
Check this complete DevOps series.
Part 0: HashiCorp HCP Terraform Cloud backend configuration
Part 1: Create GitHub repository and branches using Terraform
Part 2 Terraform modules using a github.com repository as a source
Part 3 Automating and Planning Azure Resources with Terraform and GitHub Actions
Part 4 GitHub Actions deploy azure resources with Terraform backend
Part 4.1 GitHub Actions deploy azure resources with PowerShell
Part 4.2 GitHub Actions manage Microsoft Azure Cloud with az CLI
Azure OIDC OpenID Connect password less with GitHub Actions
Above step adds new VCS provider as you can see below to HCP portal.
GitHub and Terraform integration is completed. Next go to Organization Project settings >> Variable sets. Click create a new variable set. Provide a name, in the Variable set scope and select checkbox to Apply globally [All current and future workspaces in the organization will have access to this variable set]. Create environment variable sets to authenticate to Azure Cloud to deploy services.
ARM_CLIENT_ID
ARM_CLIENT_SECRET
ARM_SUBSCRIPTION_ID
ARM_TENANT_ID
Check for more details on creating Azure Environment Variable here HashiCorp HCP Terraform Cloud backend configuration
Integration Setup Completed, I've now completed the setup and configuration of our integration between Terraform Cloud (HCP), GitHub, and Azure Cloud. To test this integration, I've written a simple Terraform configuration code that creates subnets inside an existing virtual network (vNet) in Azure. In the next Step: I am pushing code to GitHub
I'll push this Terraform configuration code to the main repository on GitHub.com. This will trigger a workflow in Terraform Cloud, which will automatically deploy the changes to Azure.
Download this Terraform_cloud_GitHub.com_integration_configuration code here or it is also available on github.com.
Next setting is to adding a new workspace by clicking Create a workspace on terraform project on HCP cloud portal. A workspace is a logical environment where Terraform configurations are managed and applied, often corresponding to a given deployment or set of infrastructure resources.
HCP Terraform organizes your infrastructure resource by workspaces. A workspace contains infrastructure resources, variables, state data, and run history. On the next page choose Version Control Workflow. This trigger runs based on changes to configuration in GitHub repositories. This system is good for users who need traceability and transparency.
Now that we have our VCS connection set up with GitHub, let's link our repository to HCP Cloud. Follow these steps:
- Select the VCS connection we created earlier, using the Client ID and Secret.
- Choose the GitHub repository you want to integrate with HCP Cloud from the list.
I am now in the final step of the wizard. Enter a descriptive Workspace Name for easy identification. Next, configure the Auto-apply settings. This determines whether the workspace will automatically apply changes after successful runs. If enabled, changes are applied without requiring manual approval. If disabled, changes require operator approval via API, CLI, VCS runs, or run triggers. For this demonstration, I'll keep the default settings. Click the Create button to finalize the configuration and establish the connection between your GitHub repository and HCP Cloud.
Now that the workspace is created, provide the required input variable. In the workspace, navigate to the Variables section. Enter the value for the subscription_id Terraform variable, which corresponds to your Azure Subscription GUID number. This variable is referenced in the Terraform configuration file pushed to GitHub. Click the Save variables button to store the input. Next, click the Start a new plan button to trigger a Terraform plan execution. This will analyze your infrastructure configuration and propose the necessary changes. The plan will utilize the Azure Subscription ID variable you just defined, ensuring your Terraform configuration is properly linked to your Azure account.
The Terraform plan has been generated based on the configuration in your GitHub repository. To apply the proposed changes, click the Confirm and Apply button. In the confirmation dialog, provide a brief description of the changes being applied. This description will be recorded in the Terraform Cloud workspace history, providing context for future reference. By confirming and applying, you're instructing Terraform to execute the planned changes and provision the defined infrastructure resources in your Azure subscription.
My Terraform configuration has been applied to Azure via the UI, using GitHub repository. Integration verified, IaC cycle complete. All good! This apply configuration is auto triggered via UI.
This is last step for testing. I've modified your Terraform Azure configuration to deploy multiple subnets inside a vNet. And pushed the updated code to GitHub using Git commands.
git add .; git commit -m "Testing via github push"; git push origin --force
Code push to GitHub triggers automatic run in Terraform Cloud. Plan execution successful: multiple subnets deployed inside vNet. Infrastructure as Code (IaC) fully automated and managed on the cloud. With this End-to-End CI/CD Pipeline verified of Terraform Cloud, GitHub, Azure Cloud.
Integration is complete!
Useful Articles
Create storage account and Service Principal using PowerShell for Terraform Azure Backend
Unlocking TF State File on Azure backend with PowerShell and Terraform Force-Unlock Command
Terraform variable precedence and priority
Terraform filter map and list object with if condition in for_each loop examples
Terraform Azure function app with private endpoint and storage account
Terraform module Azure function app with private endpoint and storage account
Terraform passing different credentials to different subscriptions with provider alias
Terraform Azure provider alias passing credentials and configuration in module resources
Terraform Azure provider passing multiple alias environment and credentials in child module
Terraform variable multiple validation advanced blocks example
Terraform variable type list with for_each for loop examples
Terraform convert single string to list or set
Terraform workspaces with example
Terraform map of object for loop with if condition example
Terraform for_each for loop list of object without count example
Terraform using for loop in attribute value without for_each