Study guide

13.4 HCP Terraform Integrations

HashiCorp Certified: Terraform Associate 004

Track your progress as you read

Finished sections get a check mark.

1 Introduction & Exam Overview

1.1 Current Exam Facts 1.2 Format, Delivery, Retakes, and Recertification 1.3 004 Changes, Terraform 1.12, and Study Plan

2 Infrastructure as Code with Terraform

2.1 What Infrastructure as Code Is 2.2 Advantages of IaC Patterns 2.3 Multi-Cloud, Hybrid, and Service-Agnostic Workflows

3 Terraform Fundamentals: Providers & State

3.1 Install and Version Terraform Providers 3.2 How Terraform Uses Providers 3.3 Configuration with Multiple Providers 3.4 How Terraform Uses and Manages State

4 Core Terraform Workflow: Init & Validate

4.1 The Terraform Write–Plan–Apply Workflow 4.2 Initialize a Working Directory 4.3 Validate a Configuration

5 Plan, Apply, Destroy, and Formatting

5.1 Generate and Review an Execution Plan 5.2 Apply Changes to Infrastructure 5.3 Destroy Terraform-Managed Infrastructure 5.4 Formatting and Style Adjustments

6 Resources, Data Sources, and References

6.1 Resource Blocks vs Data Blocks 6.2 Resource Attributes and Cross-Resource References 6.3 Resource Addressing and Interpolation Patterns

7 Variables, Outputs, and Complex Types

7.1 Input Variables, tfvars, and Precedence 7.2 Output Values 7.3 Complex Types: list, map, object, tuple, set

8 Dynamic Configuration and Dependencies

8.1 Expressions, count, for_each, and dynamic Blocks 8.2 Built-in Functions 8.3 Dependencies, depends_on, and Lifecycle Rules

9 Conditions, Secrets, and Sensitive Data

9.1 Custom Conditions: validation, precondition, postcondition, check 9.2 Sensitive Data Handling 9.3 Vault, Ephemeral Values, and Write-Only Arguments

10 Terraform Modules

10.1 How Terraform Sources Modules 10.2 Variable Scope within Modules 10.3 Using Modules in Configuration 10.4 Managing Module Versions

11 Terraform State Management

11.1 The Local Backend 11.2 State Locking 11.3 Remote State and the backend Block 11.4 Resource Drift and State Operations

12 Maintain Infrastructure with Terraform

12.1 Import Existing Infrastructure 12.2 Inspect State with the CLI 12.3 Verbose Logging and Diagnostics

13 HCP Terraform

13.1 Create Infrastructure with HCP Terraform 13.2 Collaboration and Governance Features 13.3 Workspaces and Projects 13.4 HCP Terraform Integrations

13.4 HCP Terraform Integrations

Key Takeaways Explain This Topic AI

Organization VCS connections (GitHub, GitLab, Bitbucket, Azure DevOps) let workspaces clone configuration, register webhooks, and run speculative plans on pull requests

Run triggers queue a downstream workspace after a source workspace apply succeeds (up to 20 sources); auto-apply for those runs is a separate setting

Notifications deliver Slack, Microsoft Teams, email, or signed generic webhooks; they do not fire for speculative plans or Local execution

Dynamic Provider Credentials is the current name for OIDC workload-identity auth; Vault-backed dynamic credentials mint cloud creds through Vault

Prefer the cloud block over backend "remote"; user and team tokens can start runs, but an organization token cannot create configuration versions or start runs

Last updated: August 2026

13.4 HCP Terraform Integrations

Quick Answer: Connect a VCS provider at the organization, wire run triggers and notifications on the workspace, publish modules to the private registry , authenticate providers with Dynamic Provider Credentials (OIDC; optionally Vault-backed), and call the API with the right token type . Configure the CLI with a cloud block, not the older backend "remote" .

Objective 8d on Terraform Associate (004) is configuration of those integrations. Official references: VCS providers , Run triggers , Notifications , Private registry , Dynamic provider credentials , API tokens , and backend "remote" .

VCS connections

A VCS connection is an organization object (OAuth app, GitHub App, or PAT). Workspaces then pick a repository, branch, and optional subdirectory. HashiCorp uses that connection to list repos, register webhooks , and download a commit for a run.

Supported families you should recognize: GitHub.com (GitHub App on HCP Terraform; OAuth on HCP and Enterprise), GitHub Enterprise , GitLab.com and GitLab EE/CE, Bitbucket Cloud and Bitbucket Data Center, Azure DevOps Services and Azure DevOps Server. Unsupported systems use the API-driven workflow instead.

What the webhook does:

Commit on the tracked branch → queue a real run (apply still follows auto-apply / permissions).

Pull or merge request → speculative plan , linked on the PR.

Duplicate commit SHAs are skipped.

Most providers talk HTTPS + OAuth. Azure DevOps Server and Bitbucket Data Center also need an SSH key to fetch contents. Other providers need SSH only for private submodules . You can scope a VCS connection to selected projects so not every team can see every repo. Connecting GitHub App repositories requires a user token that has completed GitHub OAuth; team and organization tokens cannot finish that personal OAuth flow.

Private / on-prem VCS can be reached with HCP Terraform agents . Terraform Enterprise that talks to a public SaaS VCS must allow inbound webhooks from the internet.

Run triggers and notifications

Run triggers connect a downstream workspace to up to 20 source workspaces . When a source apply succeeds , HCP Terraform queues a run downstream. That is how app-prod reacts after net-prod publishes new subnet IDs. Configuring a trigger requires admin on the downstream workspace and permission to read runs on the source.

Pair triggers with data sharing: allow the source workspace's state (or outputs) to be read, then use terraform_remote_state or HashiCorp's preferred tfe_outputs . Triggers do not auto-apply unless Auto-apply run triggers is enabled — a different switch from ordinary auto-apply.

Notifications were covered as a governance channel in 13.2; as an integration, remember destinations ( Slack , Microsoft Teams , email , generic webhook ), the 20-destination cap, HMAC verification on generic webhooks, and the two hard exclusions: speculative plans and Local execution send nothing.

Private registry

The HCP private registry mirrors the public Terraform Registry UX inside your organization: searchable modules and providers, version constraints, docs. You can synchronize selected public modules/providers inward so the org has an approved catalog. Private modules are usually published by pointing HCP at a VCS repo and pushing a Git tag . Sentinel can require that non-root modules come from that registry. Community CLI can source a public registry address; it does not give you this org-private catalog or its VCS publish flow.

Dynamic Provider Credentials and Vault

The official current name is Dynamic Provider Credentials . Do not write "OIDC auth" as if it were a different HCP product — OIDC is the protocol underneath.

Per plan and per apply, HCP Terraform:

Builds a workload identity token (OIDC) that names the organization, workspace or Stack, and run stage.

Presents that token to AWS, Azure, GCP, Vault, Kubernetes, or HCP.

Receives short-lived credentials, injects them into the runner, and discards them when the disposable environment is torn down.

You set up a trust relationship once on the cloud, then configure workspace environment variables such as TFC_AWS_PLAN_ROLE_ARN / apply-role equivalents, TFC_VAULT_PLAN_ROLE , and the matching Azure/GCP/HCP/Kubernetes variables. Variable sets can share that config. Self-hosted agents need agent v1.7.0+ .

Vault-backed dynamic credentials are the two-hop pattern: HCP Terraform authenticates to Vault with OIDC, then Vault's secrets engine mints AWS/GCP/Azure creds. You still configure Vault dynamic credentials first ( TFC_VAULT_* ), then the cloud-specific Vault-backed variables. Do not also pass token / address into the Vault provider block once the integration owns authentication.

This replaces long-lived AWS_SECRET_ACCESS_KEY environment variables. Community Terraform has no HCP-issued workload identity; you would have to build an equivalent OIDC federation yourself.

Tokens: CLI and API

terraform login writes a user credential for the CLI. Automation should pick a token type on purpose:

Token Bound to Can start runs / upload config versions? Notes

User One human If that user can Most flexible; orgs may disable user tokens. Shown once at creation.

Team A team If the team can apply/plan Not tied to a person who might leave. Multiple named tokens per team.

Organization The org No Owners create one org token. For creating workspaces/teams, not day-to-day runs.

Audit trails / metrics The org No Specialized read APIs.

Agent An agent pool No (not a general API token) Agents call home; you do not use this as a personal API key.

Tokens expire. HashiCorp shows the secret once . Organization tokens cannot perform remote operations, create configuration versions, or override policies. If a pipeline must terraform apply through the API, it needs a user or team token with apply rights — not the org token.

cloud block versus backend "remote"

backend "remote" (Terraform ≥ 0.11.13) was the original "enhanced" backend: it stored state in HCP/TFE and could execute CLI-driven runs. As of Terraform 1.1 (and therefore 1.12), HashiCorp recommends the cloud integration instead. cloud supports structured run output and the current workspace-tag model.

Root-module setting Terraform versions Workspace selector Notes for 004

backend "remote" Added in 0.11.13; still parses workspaces.name or workspaces.prefix Older enhanced backend. HashiCorp recommends migrating.

cloud Required 1.1+; use this on 1.12 workspaces.name or workspaces.tags (optional project ) Current CLI integration. Structured run output. No prefix . // Deprecated shape — still parses; do not write new 1.12 configs this way

  • terraform {
  • backend "remote" {
  • organization = "my-org"
  • workspaces { prefix = "my-app-" }
  • }
  • }
  • // Current shape
  • terraform {
  • cloud {
  • organization = "my-org"
  • workspaces {
  • tags = { app = "mine" }
  • }
  • }
  • }

Migration is a search-and-replace plus terraform init . name stays name . prefix becomes tags (you then select the full HCP workspace name). hostname still defaults to app.terraform.io . You still must not place a token in the file. You still cannot combine cloud with any backend block.

terraform_remote_state that reads another HCP workspace still uses backend = "remote" in the data source config — that is a reader, not the workspace's own backend declaration. For new sharing inside HCP, prefer tfe_outputs .

Scenario: the pipeline token that does nothing

A platform team creates an organization token , exports it as TFE_TOKEN in GitHub Actions, and calls the Runs API. Create-workspace succeeds; create-run returns an error. The 8d answer is the token type: switch to a team token on a team that has apply on that workspace, or use a dedicated automation user. While they are there, they replace backend "remote" { workspaces { prefix = "pay-" } } with a cloud block and tags, connect GitHub so merges (not the org token) apply pay-prod , and move AWS keys to Dynamic Provider Credentials so the workflow file holds no long-lived cloud secret.

004 traps for objective 8d

VCS is an org-level connection; the workspace only selects repo/branch.

Run triggers fire on successful apply , cap 20, separate auto-apply switch.

Official name: Dynamic Provider Credentials (OIDC). Vault-backed is the Vault hop, not a different exam product.

Org token ≠ run token.

cloud replaces backend "remote" for the root module; prefix is not a cloud argument.

Notifications skip speculative plans and Local mode.