Fix Terraform Error - IAM EntityAlreadyExists
Fix the Terraform IAM EntityAlreadyExists error for roles, users, and policies. Covers import, unique naming, cross-workspace coordination, and cleanup.
Troubleshooting
Fix the Terraform AssumeRole AccessDenied error for cross-account deployments. Covers trust policies, STS permissions, MFA, and external ID configuration.
Your IAM identity can't assume the target role. Either the role's trust policy doesn't list your identity as a principal, your identity lacks sts:AssumeRole permission, or the role requires MFA/external ID conditions you haven't met.
Error: error configuring Terraform AWS Provider: IAM Role (arn:aws:iam::123456789012:role/terraform-deploy)
cannot be assumed.
There are a number of possible causes of this - the most common are:
* The credentials used in order to assume the role are invalid
* The IAM Role (arn:aws:iam::123456789012:role/terraform-deploy) does not exist
* The IAM Role (arn:aws:iam::123456789012:role/terraform-deploy) does not have a valid trust policyError: AccessDenied: User: arn:aws:iam::111111111111:user/ci-user
is not authorized to perform: sts:AssumeRole on resource:
arn:aws:iam::222222222222:role/terraform-deployThe role in the target account must explicitly trust your IAM identity:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:user/ci-user"
},
"Action": "sts:AssumeRole"
}]
}Your IAM identity needs permission to call sts:AssumeRole in its own account.
The trust policy has an MFA condition but you're not passing an MFA token.
The trust policy requires an ExternalId condition — common for third-party access.
Typo in the account ID, role name, or using the wrong region's role.
In the target account (222222222222), update the role's trust policy:
# Check the current trust policy
aws iam get-role --role-name terraform-deploy \
--query 'Role.AssumeRolePolicyDocument' --profile target-account
# Update to allow the source account
cat > trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111111111111:root",
"arn:aws:iam::111111111111:role/ci-pipeline"
]
},
"Action": "sts:AssumeRole"
}]
}
EOF
aws iam update-assume-role-policy \
--role-name terraform-deploy \
--policy-document file://trust-policy.json \
--profile target-accountIn the source account (111111111111), give your user/role permission to assume:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::222222222222:role/terraform-deploy"
}]
}provider "aws" {
region = "us-east-1"
assume_role {
role_arn = "arn:aws:iam::222222222222:role/terraform-deploy"
session_name = "terraform-ci"
external_id = var.external_id # If required by trust policy
}
}If the role requires MFA, you can't use it directly in CI. Options:
# Option A: Remove MFA condition for CI roles (recommended for automation)
# In the trust policy, don't require MFA for the CI role
# Option B: Use a session token with MFA (manual/local only)
# First, get temporary credentials with MFA:
# aws sts get-session-token --serial-number arn:aws:iam::111:mfa/user --token-code 123456
# Option C: Use separate roles — MFA for humans, no MFA for CI
provider "aws" {
assume_role {
role_arn = var.is_ci ? var.ci_role_arn : var.human_role_arn
}
}# Test assuming the role
aws sts assume-role \
--role-arn arn:aws:iam::222222222222:role/terraform-deploy \
--role-session-name test \
--profile source-account
# Check your current identity
aws sts get-caller-identity
# Check what permissions you have
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::111111111111:user/ci-user \
--action-names sts:AssumeRole \
--resource-arns arn:aws:iam::222222222222:role/terraform-deploy# Check CloudTrail in the TARGET account for denied AssumeRole calls
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRole \
--max-results 10 \
--profile target-accountBoth sides must be configured:
| Step | Account | Action |
|---|---|---|
| 1. Create role | Target (222) | Create IAM role with trust policy |
| 2. Trust policy | Target (222) | Allow source account principal |
| 3. Attach policies | Target (222) | Attach permissions the role needs |
| 4. Grant AssumeRole | Source (111) | Allow sts:AssumeRole on target role |
| 5. Configure provider | Terraform | Set assume_role block |
sts:AssumeRole permission?aws sts assume-role?AssumeRole failures need fixes on both sides: the trust policy in the target account must allow your identity, and your identity in the source account must have sts:AssumeRole permission. Test with the AWS CLI first, check CloudTrail for the exact denial reason, and use OIDC federation in CI/CD to avoid managing static credentials entirely.
Fix the Terraform IAM EntityAlreadyExists error for roles, users, and policies. Covers import, unique naming, cross-workspace coordination, and cleanup.
Fix the Terraform InvalidAMIID.NotFound error. Covers region-specific AMIs, data source lookups, deregistered images, and cross-account AMI sharing.
How to manage AWS IAM roles, policies, and permissions with Terraform following security best practices. Step-by-step guide with code examples and best pract...
Fix the Terraform 'Backend configuration changed' error. Migrate state between backends (local to S3, S3 to S3), resolve lock conflicts