Terraform
Use dynamic credentials with module testing
Dynamic credentials in module testing let you use OpenID Connect (OIDC) to authenticate to your cloud provider during test runs. Instead of storing long-lived, static cloud credentials as environment variables, HCP Terraform generates unique, short-lived tokens for each test run. This improves security by eliminating the need to manage and rotate static credentials.
Overview
When you configure dynamic credentials for a registry module's tests, HCP Terraform generates a unique OIDC token at the start of each test run. The token contains claims that identify your organization, module, and test run. You configure your cloud provider to trust HCP Terraform's OIDC tokens and grant them specific permissions.
Workflow
Complete the workflow to use dynamic credentials in your module tests:
- Configure your cloud provider to trust tokens from HCP Terraform's OIDC issuer.
- Configure your registry module's test configuration to use dynamic credentials
The specific configuration steps depend on your cloud provider. Refer to the provider-specific guides:
- AWS configuration for module tests
- GCP configuration for module tests
- Azure configuration for module tests
- Vault configuration for module tests
After configuring dynamic credentials, starting a test run triggers the following actions:
1. HCP Terraform generates a unique OIDC token specific to that test and provides the token to your test run through a secure mechanism.
1. Your cloud provider verifies the token and grants temporary credentials based on your trust configuration
The token automatically expires after the configured time-to-live (TTL).
Subject claim format
For module test runs, HCP Terraform uses the following subject claim format in OIDC tokens:
organization:{ORGANIZATION_NAME}:module:{MODULE_NAME}:operation:test_run
For example: organization:my-org:module:terraform-aws-vpc:operation:test_run
This unique format allows you to create trust policies that scope permissions to specific organizations and modules.
Custom claims
In addition to standard JWT claims, tokens for module test runs include these custom claims:
terraform_run_phase: Always"plan"for module test runs, since test runs are read-only operationsterraform_organization_id: Your organization's unique identifierterraform_organization_name: Your organization's nameterraform_run_id: The test run's unique identifier
Refer to Workload Identity Tokens for complete token specifications.
Token lifetime
OIDC tokens for module tests have a configurable time-to-live (TTL). The default TTL is 10 minutes (600 seconds), with a valid range of 5 to 30 minutes (300 to 1,800 seconds). Organization owners can adjust the TTL using the Organizations API by setting the module_test_token_ttl attribute.
Each token includes clock skew mitigation (30 seconds) to account for time differences between systems.
Differences from workspace dynamic credentials
Module test dynamic credentials work similarly to workspace dynamic credentials, but with key differences:
| Feature | Workspace Dynamic Credentials | Module Test Dynamic Credentials |
|---|---|---|
| Subject claim | Contains workspace and project information | Contains module name with operation:test_run suffix |
| Configuration location | Workspace settings | Registry module test configuration |
terraform_run_phase claim | plan or apply | Always plan |
| TTL configuration | Per-workspace or organization | Organization-level setting |
| Use case | Plans and applies | Module testing |
Requirements
To use dynamic credentials for module testing, you need:
- An HCP Terraform account with Standard, Plus, or Enterprise tier
- A private registry module with module testing enabled
- Access to configure trust relationships in your cloud provider (AWS, GCP, Azure, or Vault)
- Appropriate permissions in your HCP Terraform organization to configure test settings
Configuration scope
Module test dynamic credentials are configured independently for each module's test configuration. Unlike workspace runs, test runs do not inherit OIDC configuration from workspaces.
Test-specific configuration
You can use the HCP Terraform UI, the /test-configuration API endpoint, or environment variables in the test configuration to set the OIDC configuration for module tests directly on the module's test configuration.
In the HCP Terraform UI:
- Choose Registry, then click on your module.
- Click Tests, then Configuration.
For instructions on how to use the API, refer to Test Configuration API.
For instructions on using environment variables in the test configuration, refer to Configure environment variables.
Each test configuration maintains its own independent OIDC settings, which are not shared with or inherited from workspace configurations.
Organization defaults
The only organization-level setting that applies to module tests is the token TTL, represented in the API by the module_test_token_ttl attribute. This setting determines how long OIDC tokens remain valid and applies to all module tests in the organization unless you encounter a configuration error.
Configuration example
The following example configurations shows the environment variables required for each cloud provider after configuring your cloud provider's OIDC trust relationship:
TFC_AWS_PROVIDER_AUTH=true
TFC_AWS_RUN_ROLE_ARN=<role-arn>
Module test configurations do not inherit OIDC settings from workspace dynamic credentials. You must configure dynamic credentials separately for each module's test configuration that requires them.
Best practices
We recommend that you adhere to the following best practices when using dynamic credentials to run your module tests.
Enforce OIDC for all test runs
Use Sentinel policies or OPA policies to require OIDC authentication for module tests. This prevents tests from using static credentials:
import "tfrun"
# Require OIDC for test runs
main = rule {
tfrun.is_test_run implies tfrun.oidc_enabled
}
Set appropriate token TTL
Configure your organization's module_test_token_ttl based on your typical test duration. Shorter TTLs improve security but may cause issues for long-running tests:
| Test duration | Recommended TTL |
|---|---|
| Less than five minutes | 300-600 seconds |
| 5-15 minutes | 900-1200 seconds |
| Longer than five minutes | 1200-1800 seconds (maximum) |
Use condition-based trust policies
Limit your cloud provider's trust to specific modules or organizations using token claims. For example, in AWS IAM trust policies:
{
"Condition": {
"StringEquals": {
"app.terraform.io:aud": "aws.workload.identity"
},
"StringLike": {
"app.terraform.io:sub": "organization:my-org:module:terraform-aws-*:operation:test_run"
}
}
}
This policy only trusts tokens for AWS module test runs in your organization.
Monitor token usage
Enable audit logging in your cloud provider to track when HCP Terraform assumes roles or generates credentials. This helps detect:
- Unexpected token usage patterns
- Failed authentication attempts
- Tests using excessive permissions
Implement least-privilege access
Grant test runs only the minimum permissions needed for testing. For example:
- Use separate IAM roles for different modules
- Scope permissions to specific resources or regions
- Use resource tags to limit access
- Avoid granting administrative permissions
Rotate trust configurations regularly
Periodically review and update your cloud provider's trust policies:
- Remove trust for deprecated modules
- Update subject claim patterns as your module naming changes
- Audit which roles have been assumed
- Verify trust policies match your current security requirements
Policy enforcement for module tests
Organizations should enforce custom policies for module tests to ensure consistent security practices.
Sentinel policies for module testing
Create Sentinel policies that validate OIDC configuration:
import "tfrun"
# Require OIDC for all test runs
require_oidc_for_tests = rule {
tfrun.is_test_run implies tfrun.oidc_enabled
}
# Enforce minimum token TTL
minimum_ttl = 300 # 5 minutes
require_minimum_ttl = rule when tfrun.is_test_run and tfrun.oidc_enabled {
tfrun.oidc_token_ttl >= minimum_ttl
}
main = rule {
require_oidc_for_tests and require_minimum_ttl
}
OPA policies for module testing
Similarly, create OPA policies to enforce OIDC requirements:
package terraform.cloud
import future.keywords.if
import future.keywords.in
# Require OIDC for test runs
deny[msg] if {
input.run.is_test_run == true
input.run.oidc_enabled == false
msg := "Module tests must use OIDC dynamic credentials"
}
# Enforce provider configuration
deny[msg] if {
input.run.is_test_run == true
input.run.oidc_enabled == true
not input.run.oidc_configuration.provider in ["aws", "gcp", "azure", "vault"]
msg := "Module tests must specify a valid OIDC provider"
}
Policy best practices
- Enforce OIDC for all test runs: Disable static credentials to reduce security risks
- Set organizational token TTL: Configure an appropriate TTL based on typical test duration
- Validate provider configuration: Ensure tests specify the correct provider type
- Require specific provider settings: Enforce role ARNs, service accounts, or other provider-specific settings match organizational standards
- Monitor policy violations: Track and alert on policy failures
- Document policy requirements: Provide clear guidance to module authors on required configurations
Troubleshooting
Implement the following troubleshooting guidance if you experience issues.
Token expiration errors
If your tests fail with token expiration errors:
- Check the test run duration against your configured TTL
- Increase the organization's
module_test_token_ttlif needed - Optimize your tests to run faster
- Ensure your cloud provider's clock is synchronized
Trust relationship errors
If your cloud provider rejects the OIDC token:
- Verify the OIDC provider is configured correctly in your cloud platform
- Check that the trust policy includes the correct subject claim pattern
- Confirm the audience claim matches your provider's requirements
- Review the token claims in test run logs
Permission denied errors
If the test run receives a token but lacks permissions:
- Verify the IAM role/service account has necessary permissions
- Check that resource policies don't block the assumed role
- Review condition statements in trust policies
- Ensure the role/account isn't restricted by organizational policies
For more troubleshooting guidance, refer to the provider-specific configuration pages.
Next steps
- Configure dynamic credentials for your cloud provider:
- Learn about workload identity tokens
- Configure module testing for your registry modules
- Set up policy enforcement for your organization