Terraform

Terraform Dynamic Credentials: Practical OIDC Cloud Auth Guide

2026-04-19
NicheeLab Editorial Team

Dynamic Credentials is a mechanism that issues short-lived credentials from the cloud that are valid only for the duration of a Terraform run. With OIDC federation in Terraform Cloud/Enterprise (TFC/TFE), you can safely grant permissions on a per-workspace, per-run basis.

This article walks through the practical points of federating TFC/TFE (as an OIDC issuer) with AWS, Azure, and GCP, plus the design topics you should know for the Pro-level exam. The core principles are: eliminate static long-lived keys, enforce least privilege, keep sessions short, and isolate scopes.

Why Dynamic Credentials (OIDC): Key Points and Comparison

Long-lived keys (e.g., AWS Access Keys, Service Principal secrets, JSON key files) have a large blast radius on leak and are expensive to rotate. By contrast, OIDC-based dynamic credentials are issued by the cloud's STS/token endpoint on each Terraform run request and expire when the run ends. The basic architecture has TFC/TFE acting as the OIDC issuer with trust established on the cloud side.

The design principles boil down to three points: 1) scope per workspace/run, 2) least privilege on the cloud-side role/identity, and 3) short session lifetimes with automated rotation. These match the stable best practices recommended by the official documentation.

  • TFC/TFE is the OIDC issuer; define trust (Issuer/Audience/Subject, etc.) on the cloud side
  • Short-lived credentials are obtained only at run time via STS/Token Exchange
  • Never embed static keys in provider config (use environment variables / runtime integration)
  • Least-privilege roles, per-workspace isolation, and scope control via tags/claims
CloudOIDC Federation Name / MechanismToken Exchange Entry Point (Concept)Session Management Approach
AWSIAM OIDC IdP + STS Web IdentityAssumeRoleWithWebIdentity (STS)Controlled by the role's trust policy and session duration (configured on the role)
AzureMicrosoft Entra ID Federated CredentialToken issuance via the service principal's Federated CredentialControlled by app registration / role assignment and Federated Credential conditions
GCPWorkload Identity FederationSecurity Token Service (STS) → short-lived delegation/impersonation of a service accountControlled by WIF pool/provider conditions and the service account's permissions

End-to-End OIDC Flow Between TFC/TFE and the Cloud

The Terraform run environment (TFC/TFE agent/runner) obtains an OIDC token, exchanges it at each cloud's STS/token endpoint to obtain short-lived credentials, and then the provider calls cloud APIs. Trust configuration lives on the cloud side (role, app, WIF pool), and TFC/TFE issues per-run claims.

The network requirement is that the runner can reach the cloud's STS/ID endpoint. Trust conditions (Issuer, Audience, and Subject/claims if needed) must match between the values shown in the TFC/TFE settings screen and the cloud's trust configuration.

  • The runner obtains a token from the TFC/TFE OIDC issuer
  • Present the token to the cloud STS/ID endpoint to exchange it for short-lived credentials
  • The Terraform provider uses the short-lived credentials via environment integration / default credential chain
  • Credentials expire when the run ends (no long-lived keys retained)

OIDC flow between TFC/TFE and the cloud

OIDC tokenexchange (JWT)short-lived credsshort-lived credsuses credsTerraform RunnerTFC/TFE agentTFC/TFE OIDC IssuerJWT claimsCloud STS / IDAWS / Azure / GCPCloud TrustRole / App / WIF ProviderTerraform ProviderCloud APIsIAM / Compute / DBRunner obtains OIDC token → Cloud STS exchanges it for short-lived credentials → Provider calls Cloud APIs

No static keys required for providers (delegate to environment integration)

# Example: main.tf (excerpt). No explicit credentials needed (uses TFC/TFE dynamic credentials)
terraform {
  required_providers {
    aws     = { source = "hashicorp/aws", version = ">= 5.0" }
    azurerm = { source = "hashicorp/azurerm", version = ">= 3.0" }
    google  = { source = "hashicorp/google", version = ">= 5.0" }
  }
}

provider "aws" {
  region = var.aws_region
}

provider "azurerm" {
  features {}
}

provider "google" {
  project = var.gcp_project
  region  = var.gcp_region
}

# Sanity check: who is invoking the run (e.g., AWS)
data "aws_caller_identity" "current" {}
output "aws_caller_arn" { value = data.aws_caller_identity.current.arn }

AWS Integration: IAM OIDC + STS (AssumeRoleWithWebIdentity)

In AWS, register an OIDC provider in IAM and create a role with a trust policy that allows STS AssumeRoleWithWebIdentity. Attach a least-privilege policy to the role and set the session duration on the role side as required.

When you enable AWS dynamic credentials on a TFC/TFE workspace, the run environment is populated with the necessary environment variables (Web Identity token file, role ARN, etc.), and the AWS provider uses them to obtain short-lived credentials automatically. No static access_key/secret_key is needed.

  • IAM: register an OIDC provider (Issuer is the TFC/TFE URL)
  • IAM: create a role with a trust policy whose audience/subject conditions match what TFC/TFE shows
  • Attach a least-privilege policy to the role
  • On the Terraform side, never hard-code credentials in the provider (use environment integration)

AWS provider example (assumes execution with short-lived credentials)

provider "aws" {
  region = var.aws_region
}

# Verify the executing principal
data "aws_caller_identity" "me" {}
output "aws_principal" {
  value = data.aws_caller_identity.me.arn
}

# Best practices:
# - Never write access_key/secret_key here
# - Scope role trust conditions per workspace/organization

Azure Integration: Microsoft Entra ID Federated Credentials

In Azure, create a Federated Credential on an app registration (service principal) and align Issuer/Audience/Subject with the TFC/TFE OIDC configuration. Role assignments should be scope-minimized (resource group level, etc.) and kept to the bare minimum.

When you enable Azure dynamic credentials on a TFC/TFE workspace, the environment variables consumed by the Azure SDK/provider (client ID, tenant ID, federated token file, etc.) are provided at run time, and an explicit client secret becomes unnecessary.

  • Create an app registration (SP) → add a Federated Credential
  • Set Issuer/Audience/Subject exactly as TFC/TFE instructs
  • Use least-privilege role assignments with minimal scope
  • On the Terraform side, hold no secrets and delegate to environment integration

AzureRM provider example (assumes dynamic credentials)

provider "azurerm" {
  features {}
}

# Sanity check (example): the current subscription
data "azurerm_subscription" "current" {}
output "azure_subscription_id" {
  value = data.azurerm_subscription.current.subscription_id
}

# Best practice: do not create a client secret on the SP (use a Federated Credential instead)

GCP Integration: Workload Identity Federation (WIF)

In GCP, create a Workload Identity Pool/Provider and trust the TFC/TFE OIDC Issuer. Combine with service account impersonation as needed, granting only the roles required for the run.

When you enable GCP dynamic credentials on a TFC/TFE workspace, the run-time information consumed by the Google Provider/ADC is provided, and short-lived tokens are exchanged via the external account flow. There is no need to issue or store a long-lived service account JSON key.

  • Create a WIF pool/provider (align Issuer and claim conditions with TFC/TFE)
  • Grant least privilege to the service account and use impersonation when needed
  • Do not issue long-lived keys (JSON keys)
  • Terraform runs use short-lived credentials via ADC / environment integration

Google provider example (assumes dynamic credentials)

provider "google" {
  project = var.gcp_project
  region  = var.gcp_region
}

# Verify the invoking principal (project info)
data "google_project" "current" {}
output "gcp_project_number" {
  value = data.google_project.current.number
}

# Best practice: do not use service account JSON keys (use WIF instead)

Exam Prep and Operational Pitfalls

On the Pro-level exam, recurring themes are: eliminating static keys, the trust boundary of OIDC federation, least privilege, per-workspace scoping, session lifetime, and auditability. The model answer is almost always a configuration where no credentials are written in the Terraform code at all.

Common operational pitfalls include: workspace/environment (prod/stg) isolation, role/identity naming conventions, over- or under-specified claim conditions (too-broad Subject or shared Audience), excessive session durations, retry design after expiration, and centralized audit logging.

  • Separate trust conditions per workspace (prevents prod/staging misuse)
  • Assign roles/apps/SAs with least privilege and the minimal required scope
  • Keep sessions short (default by default); extensions require justification
  • Never leave long-lived credentials in Terraform config or state (or in variables/outputs)
  • Debug points on failure: OIDC Issuer mismatch, Audience/Subject condition mismatch, clock sync, network reachability

Tip for verifying that the run is actually using short-lived credentials (example: AWS)

# After apply, check the role ARN to confirm it's the expected OIDC role
# outputs.tf
output "caller_arn" {
  value = data.aws_caller_identity.me.arn
  description = "The invoking principal at run time (should be a short-lived role)"
}

# If you see an unexpected long-lived user/access key principal, dynamic credentials are NOT in effect

Check Your Understanding

Pro

問題 1

You are using Terraform Cloud and want to eliminate static long-lived credentials and enforce least privilege across AWS, Azure, and GCP. Which approach is most appropriate?

  1. Configure OIDC trust (role / app / WIF) in each cloud and enable Dynamic Provider Credentials on the Terraform Cloud workspace. Write no credentials in the provider; obtain short-lived credentials via environment integration.
  2. Store long-lived keys for each cloud in Vault and check them out from Vault at run time, setting them as environment variables.
  3. Store encrypted long-lived keys in Terraform variables and decrypt them only at apply time.
  4. Log in to the cloud from CI in a Git repository and persist the generated keys as Terraform Cloud environment variables.

正解: A

Using TFC/TFE Dynamic Provider Credentials with OIDC federation, you obtain short-lived credentials that are only valid at run time and pass them to the provider automatically. This satisfies both least privilege and elimination of static keys. Storing and distributing long-lived keys contradicts the best practices on both the exam and in real operations.

Frequently Asked Questions

Does it really work without putting access_key or client secrets in the Terraform code?

Yes. When you enable Dynamic Provider Credentials on a TFC/TFE workspace, the run environment is populated with the appropriate environment variables and token files. Each provider then picks up short-lived credentials automatically via its official default credential chain.

How do I decide on the concrete Audience and Subject values?

The TFC/TFE settings screen shows you the values (Issuer, Audience, and Subject if needed) you must configure on the cloud trust side. Match them in the cloud's trust configuration (AWS role trust policy, Azure Federated Credential, GCP WIF conditions). Scoping per workspace or organization is the safest approach.

Where is the session expiration controlled?

Session expiration is controlled on the cloud side. AWS uses the role's session duration, Azure depends on the token and role assignment, and GCP combines WIF/STS with short-lived service account credentials. Keep the session as short as possible.

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.