Terraform AWS Provider忽略指定Profile与Role的问题排查
执行terraform apply时,所有资源均返回权限错误:
AccessDenied: User: arn:aws:iam::123456789:user/me@my-org.com is not authorized to perform: iam:GetPolicy on resource: policy arn:aws:iam::123456789:policy/my-policy
该用户本身无对应资源访问权限,已在Terraform中配置使用指定角色,但错误显示仍以当前用户身份执行操作。AWS Provider版本从v5.12到v5.38均存在此问题,且已通过AWS CLI验证角色权限正常,设置AWS_PROFILE和AWS_SDK_LOAD_CONFIG=1环境变量无效。
相关配置
根模块配置
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.12" configuration_aliases = [aws.us_west_1, aws.us_west_2] } } required_version = ">= 1.5.5" backend "s3" { profile = "my-profile" bucket = "terraform" key = "terraform.tfstate" region = "us-west-2" role_arn = "arn:aws:iam::123456789:role/superuser" } } provider "aws" { allowed_account_ids = ["1234566789"] region = "us-west-1" alias = "us_west_1" profile = "my-profile" assume_role { role_arn = "arn:aws:iam::1234566789:role/listening-superuser" } } provider "aws" { allowed_account_ids = ["987654321"] region = "us-west-2" alias = "us_west_2" profile = "my-profile" assume_role { role_arn = "arn:aws:iam::987654321:role/superuser" } } module "child_module" { source = "./child_module" providers = { aws.us_west_1 = aws.us_west_1 aws.us_west_2 = aws.us_west_2 } }
子模块配置(child_module.tf)
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.12" configuration_aliases = [aws.us_west_1, aws.us_west_2] } } required_version = ">= 1.5.5" } resource "aws_iam_user" "my_user" { name = "my-user" } ...
AWS凭证配置
~/.aws/credentials:
[source-profile] output=json region=us-west-1 aws_access_key_id=AK123456789 aws_secret_access_key=abcdefghijklmnop
~/.aws/config:
[profile my-profile] region=us-west-1 role_arn = arn:aws:iam::123456789:role/superuser source_profile = source-profile
核心原因
子模块中的aws_iam_user.my_user资源未指定使用的Provider别名,Terraform会默认尝试使用无别名的aws Provider,但根模块并未定义默认的aws Provider,最终导致直接使用本地环境的用户身份而非配置的角色。
修复步骤
为子模块资源指定Provider别名
修改子模块中的资源,明确指定要使用的Provider:resource "aws_iam_user" "my_user" { provider = aws.us_west_1 # 可根据实际需求替换为aws.us_west_2 name = "my-user" }若子模块中有多个资源需使用不同Provider,可分别为其指定对应的别名。
验证Provider传递有效性
确认根模块中module "child_module"的providers块已正确传递别名Provider,当前配置此部分无误,但需确保子模块确实在使用这些传递的Provider。清理冗余配置
根模块backend配置中同时指定了profile和role_arn,虽不影响资源操作,但建议保持配置一致:要么通过profile读取config中的role_arn,要么直接在backend中指定source_profile和role_arn,避免重复配置。
内容的提问来源于stack exchange,提问作者jtschoonhoven

