如何用AWS CDK为账号2的CodeDeploy部署组授权访问账号1的制品桶
基于AWS CDK的跨账号CodePipeline制品S3桶访问授权配置
问题本质
你遇到的downloadBundle阶段Access Denied,核心是实际发起S3制品拉取的主体是CodeDeploy的部署服务角色,而非EC2实例本身的IAM角色、也非CodePipeline的执行角色。当前双账号架构下,账号1的流水线制品桶默认不会给账号2的任何IAM角色开放访问权限,只要给这个CodeDeploy部署角色授予对应制品桶的只读权限即可解决问题。
分场景实现方案
场景1:同栈内直接创建EC2部署组
如果props.ec2DeploymentGroup是你在当前CDK栈内直接实例化的ServerDeploymentGroup实体对象,可以直接通过该类公开的role属性拿到CodeDeploy关联的服务角色,直接执行授权即可:
// 直接从部署组对象提取CodeDeploy服务角色 const codeDeployRole = props.ec2DeploymentGroup.role; // 给该角色授予流水线制品桶的只读权限 pipeline.artifactBucket.grantRead(codeDeployRole);
场景2:跨账号/跨栈传入的部署组(适配你的当前架构)
你的双账号架构中,EC2部署组部署在账号2的基础设施栈,再通过跨栈引用传到账号1的流水线栈。此时props.ec2DeploymentGroup是CDK生成的跨栈代理对象,仅为IServerDeploymentGroup接口类型,无法直接读取内部的role属性,需要调整传参逻辑:
- 在账号2创建部署组的基础设施栈内,将部署组的关联服务角色和部署组对象一起作为参数,传给账号1的流水线栈
// 账号2基础设施栈内创建部署组 const ec2DeployGroup = new codedeploy.ServerDeploymentGroup(this, 'AppEc2DeployGroup', { // 部署组其他配置... }); // 把部署组本体、关联的服务角色 一并注入到给流水线栈的props中 pipelineStackProps.ec2DeploymentGroup = ec2DeployGroup; pipelineStackProps.codeDeployServiceRole = ec2DeployGroup.role; - 在账号1的流水线栈内,直接使用传入的角色对象执行制品桶授权
// 授权跨账号的CodeDeploy服务角色访问流水线制品桶 pipeline.artifactBucket.grantRead(props.codeDeployServiceRole);
场景3:非CDK管理的存量部署组
如果目标EC2部署组是手动在控制台创建、未纳入CDK管理,无法拿到角色实体,可以直接给制品桶追加跨账号资源策略,手动允许对应角色访问:
pipeline.artifactBucket.addToResourcePolicy( new iam.PolicyStatement({ effect: iam.Effect.ALLOW, // 替换为账号2内对应CodeDeploy部署组的服务角色ARN principals: [new iam.ArnPrincipal('arn:aws:iam::<账号2ID>:role/<CodeDeploy部署角色名称>')], actions: ['s3:GetObject', 's3:ListBucket'], resources: [ pipeline.artifactBucket.bucketArn, `${pipeline.artifactBucket.arnForObjects('*')}` ] }) )
避坑提示
- 不要错授权限对象:如果给EC2实例角色、CodePipeline执行角色授权,依然会触发权限报错,因为这些主体都不是CodeDeploy拉取制品时的请求发起方
- 权限校验:
grantRead()方法会自动给目标角色附加拉取制品所需的全部S3权限(包含桶内对象读取、桶列表读取),无需手动配置细粒度权限 - 桶策略拦截检查:如果授权完成后依然报权限错误,需要检查S3桶的资源策略是否配置了跨账号访问拒绝规则,特别是开启了S3阻断公共访问配置的桶,要确保不会拦截账号2的CodeDeploy服务角色请求
内容的提问来源于stack exchange,提问作者Dhiraj
相关产品推荐
相关产品推荐

