如何将AWS CodeStar项目生成的包部署至其他AWS账户?
刚好碰过类似的需求,我来一步步给你拆解怎么做——核心要解决两个问题:跨账户的权限信任配置,以及扩展CodePipeline来把构建好的包部署到目标账户,毕竟你用的这个CodeStar模板没自带跨账户部署的Pipeline配置,得手动补全。
1. 先给目标账户配置可被源账户调用的IAM角色
假设你的CodeStar项目在「账户A」,要部署到「账户B」,首先得在账户B里创建一个IAM角色,允许账户A的服务(CodePipeline/CloudFormation)来扮演它完成部署:
- 登录账户B的AWS控制台,进入IAM服务,新建角色:
- 信任实体类型选「AWS账户」,输入账户A的账号ID
- 附加权限策略:如果只是部署Lambda,至少要加
AWSLambdaFullAccess,要是你的模板里还有IAM角色、CloudFormation栈这些资源,就再加CloudFormationFullAccess或者更精细的权限(推荐最小权限原则,比如只允许创建/更新Lambda、指定的IAM角色等) - 记下来这个角色的ARN,比如
arn:aws:iam::ACCOUNT_B_ID:role/CodeStarCrossAccountDeployRole
2. 给源账户的CodePipeline角色加跨账户扮演权限
回到账户A,找到你的CodeStar项目对应的CodePipeline服务角色(名字一般是codestar-<你的项目名>-pipeline-role),编辑它的权限策略,添加允许扮演账户B那个角色的权限:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::ACCOUNT_B_ID:role/CodeStarCrossAccountDeployRole" } ] }
3. 扩展CodePipeline,添加跨账户部署阶段
因为你的CodeStar项目里没带Pipeline的配置文件,有两种方式来加部署阶段:
方法一:控制台手动改(快速上手)
- 进入账户A的CodePipeline控制台,找到你的项目对应的Pipeline
- 点击「编辑」,在现有的Build阶段后面新增一个部署阶段,比如叫
DeployToAccountB - 给这个阶段加一个动作组:
- 动作名称:
DeployLambdaToB - 提供程序选「CloudFormation」
- 部署模式选「创建或更新栈」
- 模板路径选Build阶段输出的
packaged-template.yml(CodeStar的Build阶段会把打包好的模板传到S3,你可以在Build阶段的输出设置里找到对应的S3路径) - 角色ARN填刚才在账户B创建的那个角色的ARN
- 栈名称随便起,比如
CodeStar-Python-Lambda-AccountB - 如果你的模板里包含IAM角色,记得勾选「允许IAM角色创建/更新」
- 动作名称:
方法二:用CloudFormation定义(适合版本控制)
要是想把Pipeline的配置也纳入代码管理,就写个pipeline.yml,大概内容如下:
AWSTemplateFormatVersion: '2010-09-09' Resources: CrossAccountDeployPipeline: Type: AWS::CodePipeline::Pipeline Properties: RoleArn: !GetAtt PipelineServiceRole.Arn Stages: # 源阶段:对接你的CodeStar CodeCommit仓库 - Name: Source Actions: - Name: PullCodeFromCodeCommit ActionTypeId: Category: Source Owner: AWS Provider: CodeCommit Version: '1' Configuration: RepositoryName: <你的CodeStar仓库名> BranchName: main OutputArtifacts: - Name: SourceCodeArtifact # 构建阶段:复用CodeStar的Build项目 - Name: Build Actions: - Name: BuildLambdaPackage ActionTypeId: Category: Build Owner: AWS Provider: CodeBuild Version: '1' Configuration: ProjectName: <你的CodeStar Build项目名> InputArtifacts: - Name: SourceCodeArtifact OutputArtifacts: - Name: BuiltPackageArtifact # 跨账户部署阶段 - Name: DeployToAccountB Actions: - Name: DeployWithCloudFormation ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: '1' Configuration: ActionMode: CREATE_UPDATE StackName: CodeStar-Python-Lambda-AccountB TemplatePath: BuiltPackageArtifact::packaged-template.yml RoleArn: arn:aws:iam::ACCOUNT_B_ID:role/CodeStarCrossAccountDeployRole InputArtifacts: - Name: BuiltPackageArtifact # 定义Pipeline的服务角色 PipelineServiceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: codepipeline.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: CrossAccountDeployPermissions PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: sts:AssumeRole Resource: arn:aws:iam::ACCOUNT_B_ID:role/CodeStarCrossAccountDeployRole # 加上CodeCommit、CodeBuild、S3等必要权限,根据你的项目调整 - Effect: Allow Action: - codecommit:* - codebuild:* - s3:* Resource: "*"
然后用AWS CLI或者控制台把这个CloudFormation栈部署到账户A就行。
4. 调整BuildSpec(可选,按需修改)
默认的buildspec.yml已经能打包Lambda代码,但如果要适配跨账户部署,可以微调一下,比如确保打包后的模板路径正确,或者添加依赖安装:
version: 0.2 phases: install: runtime-versions: python: 3.9 commands: - pip install -r requirements.txt -t . # 如果有依赖的话 build: commands: - zip -r lambda-package.zip . -x "tests/*" "README.md" "buildspec.yml" - aws cloudformation package --template-file template.yml --s3-bucket <账户A的S3桶名> --output-template-file packaged-template.yml artifacts: files: - packaged-template.yml
注意这里的S3桶需要给账户B的部署角色加读取权限,要么在桶的权限策略里加允许账户B的角色访问,要么让桶公开(不推荐)。
5. 测试部署
配置完之后,手动触发一次CodePipeline执行,看看能不能在账户B里成功创建Lambda函数和相关资源。如果遇到权限报错,先检查两个账户的IAM角色权限是否配全,S3桶的跨账户访问是否开启。
内容的提问来源于stack exchange,提问作者user3002273

