跨账号ECR源的CodeBuild无法从S3获取对象的解决方法
我正在创建一条包含ECR Source Action、CodeBuild Action和ECS Deploy Action的AWS流水线。ECR源位于另一个AWS账号(账号E),流水线与CodeBuild位于账号P。流水线已成功创建,且当带有“latest”标签的新镜像推送到ECR时会触发执行。源构件已生成在账号P的S3存储桶中,跨账号KMS密钥共享也正常。
但在CodeBuild Action的下载源阶段,尝试获取源构件时出现以下错误:
CLIENT_ERROR: AccessDenied: Access Denied status code: 403, request id: XXXX, host id: XXXX for primary source and source version arn:aws:s3:::XXX-pipeline-artefact-bucket/mypipeline/Artifact_e/vA9hDcq
账号P的构件存储桶有如下桶策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::<ACC-P>:root", "arn:aws:iam::<ACC-P>:role/CodeBuildRoleXXXXX" ] }, "Action": "s3:*", "Resource": [ "arn:aws:s3:::XXX-pipeline-artefact-bucket", "arn:aws:s3:::XXX-pipeline-artefact-bucket/*" ] }, { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<ACC-E>:role/XXXecrsourceactionrole406755410defee62c0ca" }, "Action": [ "s3:DeleteObject*", "s3:PutObject", "s3:PutObjectLegalHold", "s3:PutObjectRetention", "s3:PutObjectTagging", "s3:PutObjectVersionTagging", "s3:Abort*" ], "Resource": [ "arn:aws:s3:::XXX-pipeline-artefact-bucket", "arn:aws:s3:::XXX-pipeline-artefact-bucket/*" ] } ] }
CodePipeline角色与CodeBuild角色均包含AWS S3全访问权限策略,且拥有KMS密钥访问权限。
我可以移除CodeBuild Action直接使用ECS Deploy Action,但肯定会遇到同样问题。保留CodeBuild Action的原因是构建imageDetail.json,将应用版本设为特定标签而非“latest”,避免ECS创建新任务时意外部署新版本。
1. 补充CodePipeline角色的S3桶访问权限
当前桶策略仅允许账号P的root、CodeBuild角色以及账号E的角色访问,缺少CodePipeline角色的读取权限。CodePipeline在向CodeBuild传递构件时,会使用自身角色生成临时凭证供CodeBuild读取S3对象,因此必须在桶策略中添加CodePipeline角色的访问规则:
{ "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<ACC-P>:role/CodePipelineRoleXXXXX" }, "Action": [ "s3:GetObject", "s3:GetObjectVersion", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::XXX-pipeline-artefact-bucket", "arn:aws:s3:::XXX-pipeline-artefact-bucket/*" ] }
2. 确认CodeBuild的源配置逻辑
确保CodeBuild项目的源类型选择为CodePipeline,而非直接指定S3桶。当通过CodePipeline触发CodeBuild时,CodeBuild会自动使用CodePipeline传递的临时凭证访问构件,无需单独配置S3权限;若手动指定S3源,可能因凭证传递逻辑错误导致权限拒绝。
3. 验证KMS密钥的解密权限
如果S3桶启用了KMS加密,需确认CodePipeline角色和CodeBuild角色都拥有该KMS密钥的kms:Decrypt权限。检查KMS密钥的密钥策略,添加如下规则:
{ "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::<ACC-P>:role/CodePipelineRoleXXXXX", "arn:aws:iam::<ACC-P>:role/CodeBuildRoleXXXXX" ] }, "Action": "kms:Decrypt", "Resource": "*" }
4. 检查角色信任关系
- 确认CodePipeline角色的信任策略允许
codepipeline.amazonaws.com服务扮演该角色:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "codepipeline.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } - 确认CodeBuild角色的信任策略允许
codepipeline.amazonaws.com服务传递角色:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "codebuild.amazonaws.com", "codepipeline.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }
内容的提问来源于stack exchange,提问作者Sri

