Terraform
Dynamic Credentials with the AWS Provider
Important: If using self-managed agents, make sure you’re using v1.7.0 or later.
You can use Terraform Cloud’s native OpenID Connect integration with AWS to get dynamic credentials for the AWS provider in your Terraform Cloud runs. Configuring the integration requires the following steps:
- Configure AWS: Set up a trust configuration between AWS and Terraform Cloud. Then, you must create AWS roles and policies for your Terraform Cloud workspaces.
- Configure Terraform Cloud: Add environment variables to the Terraform Cloud workspaces where you want to use Dynamic Credentials.
Once you complete the setup, Terraform Cloud automatically authenticates to AWS during each run. The AWS provider authentication is valid for the length of the plan or apply.
Configure AWS
You must enable and configure an OIDC identity provider and accompanying role and trust policy on AWS. These instructions use the AWS console, but you can also use Terraform to configure AWS. Refer to our example Terraform configuration.
Create an OIDC Identity Provider
AWS documentation for setting this up through the AWS console or API can be found here: Creating OpenID Connect (OIDC) identity providers - AWS Identity and Access Management.
The provider URL
should be set to the address of Terraform Cloud (e.g., https://app.terraform.io without a trailing slash), and the audience
should be set to aws.workload.identity
or the value of TFC_AWS_WORKLOAD_IDENTITY_AUDIENCE
, if configured.
Configure a Role and Trust Policy
You must configure a role and corresponding trust policy. Amazon documentation on setting this up can be found here: Creating a role for web identity or OpenID Connect Federation (console) - AWS Identity and Access Management. The trust policy will be of the form:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "OIDC_PROVIDER_ARN"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"SITE_ADDRESS:aud": "AUDIENCE_VALUE",
"SITE_ADDRESS:sub": "organization:ORG_NAME:project:PROJECT_NAME:workspace:WORKSPACE_NAME:run_phase:RUN_PHASE"
}
}
}
]
}
with the capitalized values replaced with the following:
- OIDC_PROVIDER_ARN: The ARN from the OIDC provider resource created in the previous step
- SITE_ADDRESS: The address of Terraform Cloud with
https://
stripped, (e.g.,app.terraform.io
) - AUDIENCE_VALUE: This should be set to
aws.workload.identity
unless a non-default audience has been specified in TFC - ORG_NAME: The organization name this policy will apply to, such as
my-org-name
- PROJECT_NAME: The project name that this policy will apply to, such as
my-project-name
- WORKSPACE_NAME: The workspace name this policy will apply to, such as
my-workspace-name
- RUN_PHASE: The run phase this policy will apply to, currently one of
plan
orapply
.
Note: if different permissions are desired for plan and apply, then two separate roles and trust policies must be created for each of these run phases to properly match them to the correct access level.
If the same permissions will be used regardless of run phase, then the condition can be modified like the below to use StringLike
instead of StringEquals
for the sub and include a *
after run_phase:
to perform a wildcard match:
{
"Condition": {
"StringEquals": {
"SITE_ADDRESS:aud": "AUDIENCE_VALUE"
},
"StringLike": {
"SITE_ADDRESS:sub": "organization:ORG_NAME:project:PROJECT_NAME:workspace:WORKSPACE_NAME:run_phase:*"
}
}
}
Warning: you should always check, at minimum, the audience and the name of the organization in order to prevent unauthorized access from other Terraform Cloud organizations!
A permissions policy needs to be added to the role which defines what operations within AWS the role is allowed to perform. As an example, the below policy allows for fetching a list of S3 buckets:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "*"
}
]
}
Configure Terraform Cloud
You’ll need to set some environment variables in your Terraform Cloud workspace in order to configure Terraform Cloud to authenticate with AWS using dynamic credentials. You can set these as workspace variables, or if you’d like to share one AWS role across multiple workspaces, you can use a variable set.
Required Environment Variables
Variable | Value | Notes |
---|---|---|
TFC_AWS_PROVIDER_AUTH | true | Must be present and set to true , or Terraform Cloud will not attempt to authenticate to AWS. |
TFC_AWS_RUN_ROLE_ARN | The ARN of the role to assume in AWS. | Optional if TFC_AWS_PLAN_ROLE_ARN and TFC_AWS_APPLY_ROLE_ARN are both provided. These variables are described below |
Optional Environment Variables
You may need to set these variables, depending on your use case.
Variable | Value | Notes |
---|---|---|
TFC_AWS_WORKLOAD_IDENTITY_AUDIENCE | Will be used as the aud claim for the identity token. Defaults to aws.workload.identity . | |
TFC_AWS_PLAN_ROLE_ARN | The ARN of the role to use for the plan phase of a run. | Will fall back to the value of TFC_AWS_RUN_ROLE_ARN if not provided. |
TFC_AWS_APPLY_ROLE_ARN | The ARN of the role to use for the apply phase of a run. | Will fall back to the value of TFC_AWS_RUN_ROLE_ARN if not provided. |
Configure the AWS Provider
Make sure that you’re passing a value for the region
argument into the provider configuration block or setting the AWS_REGION
variable in your workspace.
Make sure that you’re not using any of the other arguments or methods mentioned in the authentication and configuration section of the provider documentation as these settings may interfere with dynamic provider credentials.