Introduction
Problem
When using Vault-Backed Dynamic Credentials with the AWS Provider with multiple configuration aliases a run fails with the following error:
Operation failed: auth type for Vault-backed AWS authentication must be one of: iam_user, assumed_role, federation_token
A related error message you might encounter is:
│ Error: failed to load shared config file, /home/tfc-agent/.tfc-agent/component/terraform/runs/run-4By5oNPaWF89NcpL/tfc-vault-backed-aws-shared-credentials, invalid state with ASTKind and TokenType none
│
│ with provider["registry.terraform.io/hashicorp/aws"],
│ on main.tf line 45, in provider "aws":
│ 45: provider "aws" {
Please see the example configuration below.
Solutions:
There was a bug that needed to be fixed in two places, Terraform Enterprise and the Agent.
- Upgrade Terraform Enterprise to version v202312-1 or higher.
- If using external agents, also upgrade to 1.14.1 or higher
Example configuration:
In the example below, we have created an AWS provider alias 'north'.
- Workspace variables
Added the following environment workspace variables:
TFC_VAULT_PROVIDER_AUTH = true
TFC_VAULT_ADDR = https://<your_vault_host>:8200
TFC_VAULT_RUN_ROLE = tfc-role
TFC_VAULT_BACKED_AWS_AUTH = true
TFC_VAULT_BACKED_AWS_AUTH_TYPE = iam_user
TFC_VAULT_BACKED_AWS_RUN_VAULT_ROLE = my-role
TFC_VAULT_BACKED_AWS_AUTH_north = true
TFC_VAULT_BACKED_AWS_AUTH_TYPE_north = iam_user
TFC_VAULT_BACKED_AWS_RUN_VAULT_ROLE_north = my-role-north
- Terraform configuration
Added the AWS provider alias for 'north'.
Added the 'shared_credentials_files' argument to all AWS providers, and added the required variable 'tfc_vault_backed_aws_dynamic_credentials'.
terraform {
cloud {
hostname = "<your tfe host>"
organization = "<your org>"
workspaces {
name = "<your workspace>"
}
}
required_providers {
vault = {
source = "hashicorp/vault"
version = "3.21.0"
}
aws = {
source = "hashicorp/aws"
version = "5.22.0"
}
}
}
provider "vault" {
// skip_child_token must be explicitly set to true as TFC manages the token lifecycle
skip_child_token = true
address = var.tfc_vault_dynamic_credentials.default.address
namespace = var.tfc_vault_dynamic_credentials.default.namespace
auth_login_token_file {
filename = var.tfc_vault_dynamic_credentials.default.token_filename
}
}
provider "aws" {
region = "us-east-1"
shared_credentials_files = [var.tfc_vault_backed_aws_dynamic_credentials.default.shared_credentials_file]
}
provider "aws" {
alias = "north"
region = "us-east-1"
shared_credentials_files = [var.tfc_vault_backed_aws_dynamic_credentials.aliases["north"].shared_credentials_file]
}
variable "tfc_vault_dynamic_credentials" {
description = "Object containing Vault dynamic credentials configuration"
type = object({
default = object({
token_filename = string
address = string
namespace = string
ca_cert_file = string
})
})
}
variable "tfc_vault_backed_aws_dynamic_credentials" {
description = "Object containing Vault-backed AWS dynamic credentials configuration"
type = object({
default = object({
shared_credentials_file = string
})
aliases = map(object({
shared_credentials_file = string
}))
})
}
# your resources for the different providers below