Terraform

Terraform Cloud VCS Integration Practical Guide: GitHub / GitLab Connections and Pro Exam Tips

2026-04-19
NicheeLab Editorial Team

Terraform Cloud / Enterprise is designed around VCS integration: automatic plan/apply triggers, PR comments, and commit status updates ship as first-class features.

This article focuses on practical GitHub and GitLab integration topics that are commonly tested on the Pro exam: choosing the connection method, linking workspaces, trigger conditions, and security boundaries.

VCS Integration: Big Picture and Options

The standard pattern is to create a VCS connection at the Organization level, then have each workspace pick a target repository (identifier = org/repo) and branch. From that point on, plans and applies are driven automatically by VCS events (the VCS-driven workflow).

GitHub App is the recommended integration for GitHub: it gives you finer-grained permissions, per-repository install control, and reliable PR comments and commit status updates. For GitLab, OAuth app integration is the standard choice, and you can scope triggers to a specific branch or directory.

  • VCS-driven and CLI-driven workflows are not mutually exclusive, but mixing them in a single workspace complicates operations and is usually avoided.
  • Split workspaces along branch boundaries as a baseline (e.g., main = production, develop = staging).
  • For Monorepos, use working_directory together with file_triggers / trigger_prefixes to limit the blast radius.
  • Creating or updating a PR fires a Speculative Plan; merging into the default branch starts the real plan / apply (auto_apply controls whether the apply happens automatically or waits for approval).
Integration typePrimary targetPermissions / granularity / characteristics
GitHub AppGitHub.com / GitHub Enterprise CloudInstallable per repository, follows least-privilege. PR comments and statuses are reliable. Recommended.
GitHub OAuthGitHub.com (legacy)Permission scopes tend to be broad. Remains as a migration path for legacy setups.
GitLab OAuthGitLab.com / GitLab CE/EECreate an OAuth app on the GitLab side. Branch and directory filtering supported. PR/MR comments and commit statuses supported.

VCS-driven workflow (conceptual)

push / PRwebhook / eventsmerge to defaultDeveloperGitHub / GitLabTerraform CloudWorkspaceSpeculative Planon PR / read-onlyPlan (prod) → Applyfollows permissions / approvalPR/MR commentcommit statusVCS-driven: push/PR → Webhook → TFC Workspace → Speculative Plan / real plan/Apply → PR comment

GitHub Integration (GitHub App is the First Choice)

GitHub App is the recommended integration on GitHub. An org admin adds the GitHub App connection on the Terraform Cloud side, then installs the app on the target repositories in GitHub. After that, simply assigning the chosen repository and branch to each workspace is enough to make PR comments, commit statuses, and triggers work.

On the exam, you should be able to explain the flow: fine-grained repo selection, least privilege, Speculative Plan on PR, and real plan/apply on merge to the default branch. Even when a legacy OAuth connection exists, the expectation that new setups should prefer GitHub App is a frequently tested point.

  • You can scope the installation, which aligns with the principle of least privilege.
  • Events from fork PRs may be restricted by permission and security settings, so align operations with your organization's policy.
  • PR comments include a resource change summary and key plan highlights; details live in the Run log on Terraform Cloud.

GitLab Integration (OAuth App)

On GitLab, create an OAuth app and register the redirect / callback settings shown on Terraform Cloud's VCS provider creation screen into GitLab. Once the connection is established, search for and link the target repository when creating a workspace.

GitLab integration also supports PR/MR comments, commit statuses, and Speculative Plan. For Monorepos, configure working_directory and trigger_prefixes so that unrelated changes don't kick off a Run.

  • Grant only the minimum scopes required per GitLab's documentation (typically API / repository access).
  • When used alongside CI/CD or other systems, watch out for duplicate events; consolidating Terraform apply on the Terraform Cloud side is the safer pattern.
  • Self-hosted GitLab (CE/EE) can be connected with the same flow, and the same principles apply to Terraform Enterprise.

Workspace, Branch, and Directory Design

The unit of VCS integration is the workspace. Typically you split workspaces by environment or boundary (e.g., app-prod, app-stg). Align the branch with that environment's source of truth (e.g., main → prod, develop → stg).

For Monorepos, set working_directory and limit change detection with file_triggers_enabled and trigger_prefixes. This keeps unnecessary Runs from flooding the system even in massive repos.

  • working_directory: required whenever the code lives somewhere other than the repository root.
  • trigger_prefixes: only changes under the specified paths trigger a Run. Multiple values supported.
  • ingress_submodules: when true, Git submodules are also cloned (useful when modules or policies are managed as submodules).
  • auto_apply: usually false in production (approval required); true is an option for staging environments.

Event Integration and Security Essentials

Creating or updating a PR/MR fires a Speculative Plan whose results surface in PR comments and commit statuses. When a merge to the default branch happens, the target workspace's real plan/apply starts. If a branch filter is set, pushes to other branches will not start a Run.

Security-wise, VCS connection credentials are stored securely at the Terraform Cloud organization scope and are not exposed directly to the Run environment. Manage cloud provider credentials and other secrets via workspace environment variables / sensitive variables, and never commit them to VCS.

  • PR comments and commit statuses make 'who is applying what, where' visible.
  • Events from fork PRs may be restricted depending on the connection type and the organization's security settings.
  • Terraform Cloud is public SaaS and can normally receive events from VCS. In enterprise environments, verify outbound/inbound reachability up front.

Managing VCS Integration as IaC (tfe Provider)

VCS integration itself can be managed as code. With HashiCorp's official tfe provider, you can declare the VCS repository, branch, working directory, and trigger settings at the same time you create the workspace. Org-side connections (OAuth / GitHub App) are created up front via the UI or API; their identifier (e.g., oauth_token_id) is referenced from your code.

On the exam, expect questions on: vcs_repo.identifier in tfe_workspace uses org/repo format, working_directory points to a subdirectory, and file_triggers_enabled with trigger_prefixes is how you avoid unnecessary triggers in a Monorepo.

  • Codify the workspace naming convention and the branch mapping.
  • Make the default for auto_apply explicit on a per-environment basis.
  • Mint the org connection ID (e.g., oauth_token_id) via the UI or API and pass it in as a sensitive variable.

Example: creating a workspace and VCS integration with the tfe provider

# Manage Terraform Cloud / Enterprise with the tfe provider
terraform {
  required_providers {
    tfe = {
      source = "hashicorp/tfe"
    }
  }
}

provider "tfe" {
  # For Terraform Cloud (SaaS) the hostname can be omitted. Specify it for Terraform Enterprise.
  token = var.tfe_token
}

variable "tfe_token" { type = string }
variable "organization" { type = string }
variable "oauth_token_id" { type = string } # ID of the org-level VCS connection (OAuth, etc.)

resource "tfe_workspace" "app_prod" {
  name         = "app-prod"
  organization = var.organization

  # Target only a slice of the Monorepo
  working_directory     = "infra/terraform"
  file_triggers_enabled = true
  trigger_prefixes      = ["infra/terraform/"]

  # Production usually requires manual approval
  auto_apply = false

  # Link to the VCS repository
  vcs_repo {
    identifier         = "my-org/app-infra"   # org/repo format
    branch             = "main"               # target branch
    oauth_token_id     = var.oauth_token_id   # org-level VCS connection ID
    ingress_submodules = true                 # fetch submodules
  }
}

Check Your Understanding

Pro

問題 1

You want to connect to only a specific repository on GitHub.com with least privilege, and return Speculative Plan results as PR comments and commit statuses when a PR is opened. Which integration method is recommended in Terraform Cloud?

  1. Use the GitHub App integration
  2. Use GitHub OAuth integration with broad org-wide permissions
  3. Skip VCS integration and trigger manually with the CLI
  4. Configure GitLab OAuth integration against GitHub.com

正解: A

GitHub App offers per-repository installation, least privilege, and reliable PR comment / status integration, matching both the requirements and the recommended best practices.

Frequently Asked Questions

How do I avoid unnecessary Runs in a Monorepo?

Set working_directory to the target subdirectory and combine file_triggers_enabled with trigger_prefixes. Runs are then triggered only by changes under the specified paths, and changes in other areas will not fire a Run.

What should I check when a PR doesn't trigger a Speculative Plan or no PR comment appears?

Check that the workspace is tied to the right branch, the repository is included in the VCS connection, the app (GitHub App / OAuth) has the correct permissions and install scope, fork PRs are not restricted, and that Terraform Cloud is not suppressing the Run (queue full, waiting on policy checks, etc.).

Do I need a VCS integration to publish modules to the private module registry?

Yes. Register the target repository through the VCS connection, follow the standard naming convention (terraform-<PROVIDER>-<NAME>), and apply semantic version tags. Terraform Cloud detects the tags and registers the module.

Check what you learned with practice questions

Practice with certification-focused question sets

無料で問題を解いてみる
Author

NicheeLab Editorial Team

NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.


Related articles
Terraform

HCL Syntax: Terraform's Configuration Language (2026)

HCL2 fundamentals for Terraform — blocks, attributes, expres...

Terraform

Terraform Authoring & Operations Pro: Complete Guide (2026)

Tactics for the Terraform Pro exam — module authoring, works...

Terraform

Terraform Providers: Plugin Management Fundamentals (2026)

Provider mechanics — required_providers, versions, mirrors, ...

Terraform

Terraform Resource Blocks: Declarative Infra Units (2026)

Resource block fundamentals — addresses, references, common ...

Terraform

Terraform Data Sources: Read-Only External Data (2026)

Data source basics — declaration, refresh behavior, dependen...

Browse all Terraform articles (102)
© 2026 NicheeLab All rights reserved.