跨账号S3模板通过CloudFormation CLI访问遇权限拒绝问题
解决跨账号S3模板创建CloudFormation栈的权限问题
针对你遇到的问题——在CLI中使用跨账号S3模板创建CloudFormation栈时提示Access Denied,但控制台和同账号CLI操作正常,我整理了几个关键的排查和解决方向:
1. 验证当前调用身份的S3直接访问权限
先排除CloudFormation本身的逻辑问题,测试当前assumed角色是否能直接访问目标模板:
- 执行
aws sts get-caller-identity确认当前身份是你所assume的账号123的delegate-access-to-infrastructure-account-role角色 - 尝试直接下载模板:
aws s3 cp s3://cloudformation.template.eberry.digital/[你的模板文件名] ./local-test.yaml- 如果这个命令失败,说明问题出在S3权限配置上,而非CloudFormation;如果成功,则问题聚焦在CloudFormation的调用逻辑上。
2. 优化桶策略的Principal配置
你的桶策略中Principal指定的是账号123的root用户(arn:aws:iam::123:root),理论上该账号下的所有IAM实体都能继承权限,但实际场景中有时会存在隐性的权限边界限制。建议尝试更明确的Principal配置:
- 修改账号456的S3桶策略,将Principal替换为你assume的角色ARN:
(调试完成后建议将Action从{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAssumedRoleAccess", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123:role/delegate-access-to-infrastructure-account-role" }, "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::cloudformation.template.eberry.digital/*" } ] }s3:*缩小为s3:GetObject,遵循最小权限原则)
3. 显式指定CloudFormation服务角色
控制台创建栈时,CloudFormation可能默认使用了具备跨账号访问权限的服务角色,但CLI调用时如果未指定--role-arn参数,CloudFormation会使用当前调用者的身份去访问S3模板。你可以尝试显式指定服务角色:
- 在CLI命令中添加服务角色参数(复用你当前的assumed角色即可):
aws cloudformation create-stack --debug --stack-name ${stackName} --template-url ${s3TemplatePath} --parameters '${parameters}' --region eu-west-1 --role-arn arn:aws:iam::123:role/delegate-access-to-infrastructure-account-role
4. 检查CLI参数的格式正确性
你的命令中--parameters '${parameters}'使用了单引号包裹变量,这可能导致shell无法正确解析参数中的JSON格式(如果${parameters}是JSON字符串)。建议改为双引号包裹,确保变量正常展开:
aws cloudformation create-stack --debug --stack-name ${stackName} --template-url ${s3TemplatePath} --parameters "${parameters}" --region eu-west-1
同时验证${parameters}的格式是否符合CloudFormation要求,例如:
[{"ParameterKey":"Key1","ParameterValue":"Value1"},{"ParameterKey":"Key2","ParameterValue":"Value2"}]
5. 使用预签名的S3模板URL
如果以上方法都无效,可以尝试生成带签名的S3模板URL,让CloudFormation通过签名直接访问模板:
- 生成预签名URL(有效期1小时):
aws s3 presign s3://cloudformation.template.eberry.digital/[你的模板文件名] --expires-in 3600 --region eu-west-1 - 将生成的URL替换到
--template-url参数中执行创建栈命令。
内容的提问来源于stack exchange,提问作者Jonatan
相关产品推荐
相关产品推荐

