背景

大型企业中代码仓库通常寄存在各部门开发账户中,而流水线则位于独立 DevOps 账户中。

本文咱们将介绍如何创立跨账号拜访 Codecommit 代码仓库的 Codepipeline 流水线,即 CodePipeline 调用另一个账号中的 Codecommit 代码仓库。

亚马逊云科技开发者社区 为开发者们提供寰球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、流动与比赛等。帮忙中国开发者对接世界最前沿技术,观点,和我的项目,并将中国优良开发者或技术举荐给寰球云社区。如果你还没有关注/珍藏,看到这里请肯定不要匆匆划过,点这里 让它成为你的技术宝库!

部署架构图

权限配置

  1. CodePipeline 执行 role – CodePipelineServiceRole,要害 IAM Policy:容许 CodePipeline assume account B 中的角色 “AssumeAdminRole”。
  2. AssumeAdminRole – CodePipeline-SourceStage 理论执行 role, 增加 policy 以具备以下权限
  • 容许被 Account A 中 CodePipeline Assume
  • 容许拜访本账户中的 CodeCommit
  • 容许拜访 Account A 中的 S3桶(寄存 sourceArtifact)
  • 容许拜访 Account A 中的 KMS
  1. 配置 KMS Policy, 容许 CodePipelineServiceRole 和 AssumeAdminRole 拜访 kms 中相应的key
  2. 配置 S3 Bucket Policy,容许 AssumeAdminRole 拜访 S3中相应的bucket
  3. CodeBuild 执行 role,可配置为主动生成,不是本文重点

流水线执行过程

  1. 触发流水线
  2. SourceStage 中首先 assume AssumeAdminRole,取得拜访 CodeCommit 权限
  3. 从 AccountB CodeCommit 代码仓库拉取代码
  4. 将放 sourceArtifact 存入 S3桶
  5. S3服务端加密
  6. 执行 Build Stage: CodeBuild

账号筹备

抉择您所在的 region,本文以北京 Region 为例。

筹备两个 Amazon 主账号:

  • 代码仓库账号 B:提供 Codecommit 服务,源代码放在这里。
  • pipeline 账号 A:提供 Codepipeline 服务,以及相关联的codebuild、kms 密钥和 s3桶

代码仓库账号 B

一、创立跨账号 IAM Role

该 Role 命名为 assume-admin-role,应用权限如下:

{    "Version": "2012-10-17",    "Statement": [        {            "Sid": "VisualEditor0",            "Effect": "Allow",            "Action": [                "s3:PutObject",                "kms:Decrypt",                "kms:Encrypt",                "kms:DescribeKey",                "s3:GetObject*",                "s3:PutObjectAcl",                "kms:ReEncrypt*",                "kms:GenerateDataKey*"            ],            "Resource": [                " arn:aws-cn:kms:cn-north-1:<Account_A_ID>:key/XXX-XXX-XXX-XXX ",                "arn:aws-cn:s3:::codecommit-sdv-cross-account/*"            ]        },        {            "Sid": "VisualEditor1",            "Effect": "Allow",            "Action": [                "codecommit:List*"            ],            "Resource": "arn:aws-cn:s3:::codecommit-sdv-cross-account/*"        }    ]}

该 Role 的信赖关系如下:

{    "Version": "2012-10-17",    "Statement": [        {            "Effect": "Allow",            "Principal": {                "AWS": [                    "arn:aws-cn:iam::<Account_A_ID>:root"                ]            },            "Action": "sts:AssumeRole"        }    ]}

二、创立 CodeCommit Repository

该 Repo 命名为:cros-account-b-repo,并在该 Repo 中创立文件 demo.txt。

流水线账号 A

三、创立 Codepipeline IAM Role

创立 IAM Role,名为:AWSCodePipelineServiceRole-cn-north-1-sdv-pipeline-cros,为 Codepipeline 的创立做筹备。

该 role 关联 Codepipeline 默认 Role 的权限策略,具体如下:

{    "Statement": [        {            "Effect": "Allow",            "Action": [                "iam:PassRole"            ],            "Resource": "*",            "Condition": {                "StringEqualsIfExists": {                    "iam:PassedToService": [                        "cloudformation.amazonaws.com",                        "elasticbeanstalk.amazonaws.com",                        "ec2.amazonaws.com",                        "ecs-tasks.amazonaws.com"                    ]                }            }        },        {            "Effect": "Allow",            "Action": [                "codecommit:CancelUploadArchive",                "codecommit:GetBranch",                "codecommit:GetCommit",                "codecommit:GetRepository",                "codecommit:GetUploadArchiveStatus",                "codecommit:UploadArchive"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Action": [                "codedeploy:CreateDeployment",                "codedeploy:GetApplication",                "codedeploy:GetApplicationRevision",                "codedeploy:GetDeployment",                "codedeploy:GetDeploymentConfig",                "codedeploy:RegisterApplicationRevision"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Action": [                "elasticbeanstalk:*",                "ec2:*",                "elasticloadbalancing:*",                "autoscaling:*",                "cloudwatch:*",                "s3:*",                "sns:*",                "cloudformation:*",                "rds:*",                "sqs:*",                "ecs:*"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Action": [                "lambda:InvokeFunction",                "lambda:ListFunctions"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Action": [                "cloudformation:CreateStack",                "cloudformation:DeleteStack",                "cloudformation:DescribeStacks",                "cloudformation:UpdateStack",                "cloudformation:CreateChangeSet",                "cloudformation:DeleteChangeSet",                "cloudformation:DescribeChangeSet",                "cloudformation:ExecuteChangeSet",                "cloudformation:SetStackPolicy",                "cloudformation:ValidateTemplate"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Action": [                "codebuild:BatchGetBuilds",                "codebuild:StartBuild",                "codebuild:BatchGetBuildBatches",                "codebuild:StartBuildBatch"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Action": [                "servicecatalog:ListProvisioningArtifacts",                "servicecatalog:CreateProvisioningArtifact",                "servicecatalog:DescribeProvisioningArtifact",                "servicecatalog:DeleteProvisioningArtifact",                "servicecatalog:UpdateProduct"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Action": [                "cloudformation:ValidateTemplate"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Action": [                "ecr:DescribeImages"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Action": [                "states:DescribeExecution",                "states:DescribeStateMachine",                "states:StartExecution"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Action": [                "appconfig:StartDeployment",                "appconfig:StopDeployment",                "appconfig:GetDeployment"            ],            "Resource": "*"        }    ],    "Version": "2012-10-17"}

除了默认权限策略,为了提供跨账号调用,该 Role 还须要退出如下权限策略:

{    "Version": "2012-10-17",    "Statement": {        "Effect": "Allow",        "Action": "sts:AssumeRole",        "Resource": [            "arn:aws-cn:iam::<Account_B_ID>:role/*"        ]    }}

四、创立 KMS 秘钥

创立名为:account_a_cros_kms 的 KMS 秘钥。

在定义秘钥应用权限时,须要退出 Codepipeline 所关联的 Role(上一步创立名为:AWSCodePipelineServiceRole-cn-north-1-sdv-pipeline-cros 的 IAM Role)和 Account B 的账号 ID。记录 KMS ARN 为:arn:aws-cn:kms:cn-north-1:<Account_A_ID>:key/XXX-XXX-XXX-XXX

五、创立 S3桶

这里创立名为:codecommit-sdv-cross-account 的 S3 桶。

这里 S3桶命名为 codecommit-sdv-cross-account。而后编辑存储桶权限,即权限->存储通权限,点击编辑按钮,增加如下 policy json:

{"Version": "2012-10-17",    "Statement": [        {            "Sid": "Statement1",            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws-cn:iam::<Account_B_ID>:root"            },            "Action": [                "s3:Get*",                "s3:Put*"            ],            "Resource": "arn:aws-cn:s3:::codecommit-sdv-cross-account/*"        },        {            "Sid": "Statement2",            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws-cn:iam:: <Account_B_ID>:root"            },            "Action": "s3:ListBucket",            "Resource": "arn:aws-cn:s3:::codecommit-sdv-cross-account"        }    ]}

六、创立 CodeBuild

创立名为:sdv-build 的 codebuild 我的项目,供 codepipeline 调用。

在 Buildspec 中增加命令如下:

七、创立 Codepipeline

对于跨账号调用 Codecommit 的 Codepipeline 只能通过 Amazon CLI 创立,筹备如下 pipeline.json 文件,

{    "pipeline": {        "roleArn": "arn:aws-cn:iam::<Account_A_ID>:role/service-role/AWSCodePipelineServiceRole-cn-north-1-sdv-pipeline-cros",         "stages": [            {                "name": "Source",                 "actions": [                    {                        "inputArtifacts": [],                         "name": "Source",                         "region": "cn-north-1",                         "namespace": "SourceVariables",                         "actionTypeId": {                            "category": "Source",                             "owner": "AWS",                             "version": "1",                             "provider": "CodeCommit"                        },                         "outputArtifacts": [                            {                                "name": "SourceArtifact"                            }                        ],                         "roleArn":"arn:aws-cn:iam::<Account_B_ID>:role/assume-admin-role",                        "configuration": {                            "BranchName": "master",                             "PollForSourceChanges": "false",                             "RepositoryName": "cros-account-b-repo"                        },                         "runOrder": 1                    }                ]            },             {                "name": "Build",                 "actions": [                    {                        "inputArtifacts": [                            {                                "name": "SourceArtifact"                            }                        ],                         "name": "Build",                         "region": "cn-north-1",                         "namespace": "BuildVariables",                         "actionTypeId": {                            "category": "Build",                             "owner": "AWS",                             "version": "1",                             "provider": "CodeBuild"                        },                         "outputArtifacts": [                            {                                "name": "BuildArtifact"                            }                        ],                         "configuration": {                            "ProjectName": "sdv-build"                        },                         "runOrder": 1                    }                ]            }        ],         "artifactStore": {            "type": "S3",             "location": "codecommit-sdv-cross-account",            "encryptionKey": {               "id": " arn:aws-cn:kms:cn-north-1:<Account_A_ID>:key/XXX-XXX-XXX-XXX ",               "type": "KMS"            }       },        "name": "pipeline-cros",         "version": 1    }}

这里打算在 Account A 创立名为 pipeline-cros的codepipeline,该 pipeline 以 Account B 的 codecommit repo: cros-account-b-repo (master branch) 作为源,并利用事后筹备好的位于 Account A 的 codebuild 进行流水线的执行。

应用如上 Json,并利用 Amazon cli 执行命令如下:

amazon codepipeline create-pipeline –cli-input-json file://pipeline.json # 创立 pipeline

同时 codebuild 会打印日志如下:

……[Container] 2022/07/18 03:23:11 Entering phase BUILD[Container] 2022/07/18 03:23:11 Running command lsdemo.txt[Container] 2022/07/18 03:23:11 Phase complete: BUILD State: SUCCEEDED……

本篇作者

王帅
Amazon 业余服务团队 Devops 参谋。提倡交融文化,实际和工具的 Devops 理念,致力于帮忙客户使组织可能以更高的速度和可靠性交付产品并取得业务价值。善于平台布局,迁徙和工具链设计。对陈腐事物充满热情。

冯霄鹏
Amazon 业余服务团队高级 DevOps 参谋。次要负责 DevOps 征询和技术施行。在 DevSecOps 减速企业数字化转型方面畛域领有多年教训,对私有云、DevOps、基于云原生的微服务架构、麻利减速研发效力等有深刻的钻研和激情。

文章起源:https://dev.amazoncloud.cn/column/article/630a07ad86218f3ca3e8f822