Skip to content

Access Private Terraform Modules in GitHub Actions

This guide explains how to securely pull a Terraform module from a private GitHub repository using HTTPS and a GitHub Personal Access Token (PAT). This is ideal for CI/CD workflows where module sources must remain private but accessible.


Scenario

You have two repositories:

Repo Purpose
acme-sandbox Main Terraform repo running CI
acme-terraform-modules-azure Private repo with reusable modules

Your Terraform configuration references the module repository:

module "azure_resource_group" {
  source = "git::https://github.com/acme-terraform-modules-azure/terraform-azurerm-resource_group.git?ref=main"
}

Step 1: Generate a GitHub Personal Access Token (PAT)

  • Set the owner to the organization or account hosting the modules.
  • Grant access to specific repositories or all repos in the namespace.
  • Set expiration (e.g., 90 days).
  • Required scopes: contents:read, metadata:read.

Step 2: Add the PAT to Your CI Repo

  • Go to Settings → Secrets and variables → Actions in your CI repo.
  • Create a new repository secret (e.g., GH_PAT).
  • Paste the token value.

Step 3: Configure Git to Use the PAT in CI

Add this step before terraform init in your workflow:

- name: Configure Git to use PAT for module access
  run: |
    git config --global url."https://${{ secrets.GH_PAT }}@github.com/".insteadOf "https://github.com/"

This configures Git to use the PAT for any https://github.com/ URL.

Step 4: Use HTTPS Source in Terraform

Reference the module using HTTPS:

module "azure_resource_group" {
  source = "git::https://github.com/acme-terraform-modules-azure/terraform-azurerm-resource_group.git?ref=main"
}

No need to embed credentials in the URL—GitHub Actions handles authentication via the config.

Example Workflow

jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Configure Git for private module access
        run: |
          git config --global url."https://${{ secrets.GH_PAT }}@github.com/".insteadOf "https://github.com/"

      - name: Terraform Init
        run: terraform init

      - name: Terraform Plan