参考资料
-
Building a Cross-account CI/CD Pipeline
-
Create a pipeline in CodePipeline that uses resources from another AWS account
通常来说,我们会将代码和pipeline配置不同的账户中,在codepipeline的source阶段指定为另一个账号的codecommit仓库。但codepipeline通常由三个阶段组成,本次模拟极端情况,将三个阶段分别放置在两个账号进行测试。
本次测试的逻辑图示图下
先决条件
a账户
-
pipeline的s3桶(授权b账号访问)
-
用户管理kms(授权pipeline,codebuild和codedeploy)
{ "Sid": "Allow use of the key", "Effect": "Allow", "Principal": { "AWS": [ "arn:aws-cn:iam::<account-A>:role/AWSCodePipelineServiceRole", "arn:aws-cn:iam::<account-B>:root" ] }, "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "*" }
-
创建管道(使用用户管理kms)
-
piprline服务角色,允许codepipeline角色的assume行为
b账号
- 创建codecommit存储库
- 创建codebuild项目,codepipeline会直接覆盖build的source,codebuild角色允许使用kms权限
- 创建codedeploy应用,部署组(如ec2实例),codedeploy角色允许使用kms权限
- 创建crossaccount角色允许a账户assume
- 创建ec2角色允许访问a账号s3桶,获取revision
在b账号配置项目
创建codecommit仓库,这里创建一个简单的javaweb项目,包括完整buildspec.yml
和appspec.yml
$ tree -L 2
├── appspec.yml
├── buildspec.yml
├── scripts
│ ├── install_dependencies.sh
│ ├── start_server.sh
│ └── stop_server.sh
├── src
│ └── main
└── pom.xml
创建codebuild项目,一直下一步即可,构建平台需要选择aws/codebuild/amazonlinux2-x86_64-standard:3.0
创建codedeploy项目,简单部署到ec2实例即可
创建cross角色,信任策略如下,允许a账号assume
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws-cn:iam::037047667284:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
在a账号创建pipeline
source,build和deploy阶段先写a账号下的
配置a账号下对应的pipeline存储桶策略
{
"Sid": "allowputobject",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws-cn:iam::442337510176:root"
},
"Action": [
"s3:Get*",
"s3:Put*"
],
"Resource": "arn:aws-cn:s3:::codepipeline-cn-north-1-482183469511/*"
},
{
"Sid": "allowlistbuckets",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws-cn:iam::442337510176:root"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws-cn:s3:::codepipeline-cn-north-1-482183469511"
}
通过awscli获取pipeline完整配置
pipeline:
artifactStore:
encryptionKey:
id: arn:aws-cn:kms:cn-north-1:<account-A>:key/19841203-6504-4918-b5d8-d7ff47195135 # 指定用户管理kms
type: KMS
location: codepipeline-cn-north-1-xxxxxxxxx
type: S3
name: test-crossaccount
roleArn: arn:aws-cn:iam::<account-A>:role/AWSCodePipelineServiceRole # pipeline角色
stages:
- actions:
- actionTypeId:
category: Source
owner: AWS
provider: CodeCommit
version: '1'
configuration:
BranchName: master
OutputArtifactFormat: CODE_ZIP
PollForSourceChanges: 'false'
RepositoryName: zhaojiew-test
inputArtifacts: []
name: Source
namespace: SourceVariables
outputArtifacts:
- name: SourceArtifact
region: cn-north-1
roleArn: arn:aws-cn:iam::<account-B>:role/zhaojiew-cross #添加soruce阶段需要assume的角色
runOrder: 1
name: Source
- actions:
- actionTypeId:
category: Build
owner: AWS
provider: CodeBuild
version: '1'
configuration:
ProjectName: zhaojiew-test
inputArtifacts:
- name: SourceArtifact
name: Build
namespace: BuildVariables
outputArtifacts:
- name: BuildArtifact
region: cn-north-1
roleArn: arn:aws-cn:iam::<account-B>:role/zhaojiew-cross #添加build阶段需要assume的角色
runOrder: 1
name: Build
- actions:
- actionTypeId:
category: Deploy
owner: AWS
provider: CodeDeploy
version: '1'
configuration:
ApplicationName: zhaojiew-test
DeploymentGroupName: ec2-instance
inputArtifacts:
- name: BuildArtifact
name: Deploy
namespace: DeployVariables
outputArtifacts: []
region: cn-north-1
roleArn: arn:aws-cn:iam::<account-B>:role/zhaojiew-cross #添加deploy阶段需要assume的角色
runOrder: 1
name: Deploy
version: 1
更新pipeline
aws codepipeline update-pipeline --cli-input-yaml file://pipeline.yaml
之后手动触发pipeline进行构建即可
最后总结
最终的运行逻辑仍旧是这张图的内容,跨账号的pipeline配置只需要注意几个要点即可
涉及到的关键点总结
- codepipeline默认使用pipeline角色进行各项操作
- 无法在控制台对codepipeline进行跨账号配置,必须要通过api调用(如awscli)对codepipeline进行配置
- codepipeline将所有中间步骤存储到固定的s3桶中(pipeline所在的账号),强制使用默认kms加密,但是跨账号必须使用用户托管kms密钥加密解密
- source阶段pipeline角色assume到crossrole上获取codecommit,并将artifact回写到s3桶
- build阶段pipeline角色assume到crossrole触发build项目,build阶段由codebuild角色执行build操作,并由crossrole将build的结果回写到s3桶
- deploy阶段pipeline角色assume到crossrole触发deploy项目,build阶段由codedeploy角色执行deploy操作
- 3个阶段的具体项目信息无法在codepipeline中直接看到,需要登录到b账号中查看
本次测试的完成能够对piepleine的权限和阶段之间的关系了解更加深入