上次更新时间:2020 年 11 月 2 日
我想要使用 AWS CodePipeline 在不同的账户中部署 AWS CloudFormation 堆栈。
简短描述要在不同的账户中部署 AWS CloudFormation 堆栈,您必须完成以下操作:
-
在一个账户(账户 A)中创建管道。此账户应该包括客户管理的 AWS Key Management Service (AWS KMS) 密钥、适用于构件的 Amazon Simple Storage Service (Amazon S3) 存储桶,以及允许其他账户(账户 B)访问的 S3 存储桶策略。
在账户 B 中,配置允许以下操作的跨账户服务角色:1) AWS CloudFormation 操作;2) 访问账户 A 中的 S3 存储桶;3) 使用账户 A 中的客户管理的 KMS 密钥进行解密。
在账户 A 中,允许管道服务角色担任账户 B 中的跨账户角色(使用 AssumeRole)。
1.在账户 A中,打开 AWS KMS 控制台。
2.从导航窗格中选择客户管理的密钥。
3.选择创建密钥,然后选择对称。
注意:在高级选项部分,请将源保留为 KMS。
4.对于别名,输入您的密钥的名称。
5.(可选)添加标签,然后选择下一步。
6.在定义密钥管理权限页面上,对于密钥管理员,请选择您的 AWS Identity and Access Management (IAM) 用户以及您希望由其担任密钥管理员的任何其他用户或组,然后选择下一步。
7.在定义密钥使用权限页面上,对于此账户,请在该账户中添加应拥有该密钥的访问权限的 IAM 用户(如 CodePipeline 服务角色)。
8.在其他 AWS 账户部分,选择添加其他 AWS 账户,然后输入账户 B 中的 IAM 角色的 Amazon 资源名称 (ARN)。
9.选择下一步,然后选择完成。
10.在客户管理的密钥部分,选择您刚刚创建的密钥,然后复制该密钥的 ARN。
注意:当您编辑您的管道和配置您的策略时,必须使用您的密钥的 ARN。
在账户 A 中,选择或创建一个 Amazon S3 存储桶以作为 SourceArtifact 存储桶的管道,然后创建一个存储桶策略账户 A 中的 S3 存储桶策略必须授予账户 B 访问权限。
1.在账户 A 中,打开 Amazon S3 控制台。
2.选择现有的 S3 存储桶或创建新的 S3 存储桶以用作 CodePipeline 的 ArtifactStore。
注意:构件可包含一个堆栈模板文件、一个模板配置文件或两者皆有。CodePipeline 将使用这些构件来处理 AWS CloudFormation 堆栈和更改集。在您的模板配置文件中,您必须指定模板参数值、堆栈策略和标签。
3.在存储桶的 Amazon S3 详细信息页面中,选择权限。
4.选择存储桶策略。
5.在存储桶策略编辑器中,输入以下代码:
{
"Id": "Policy1553183091390",
"Version": "2012-10-17",
"Statement": ,
"Effect": "Allow",
"Resource": "arn:aws:s3:::codepipeline-source-artifact/*",
"Principal": {
"AWS":
}
},
{
"Sid": "",
"Action": ,
"Effect": "Allow",
"Resource": "arn:aws:s3:::codepipeline-source-artifact",
"Principal": {
"AWS":
}
}
]
}
6.在上述代码中,将 codepipeline-source-artifact 替换为 CodePipeline 的 SourceArtifact 存储桶名称。
7.在上述代码中,将 ACCOUNT_B_NO 替换为账户 B 的账号。
8.选择保存。
在账户 B 中,创建一个允许账户 A 在 SourceArtifact 中执行 S3 和 AWS KMS 相关操作的跨账户角色 (CROSS_ACCOUNT_ROLE)此跨账户角色策略允许账户 A 中的管道代入账户 B 中的角色。此策略还允许 AWS CloudFormation 操作,以及对 SourceArtifact 和 AWS KMS 相关操作的访问权限。
1.在账户 B 中,打开 IAM 控制台。
2.在导航窗格中,选择策略。
3.选择创建策略。
4.选择 JSON 视图,然后在代码编辑器中输入以下策略:
{
"Version": "2012-10-17",
"Statement": ,
"Resource": "*"
},
{
"Effect": "Allow",
"Action": ,
"Resource":
}
]
}
5.将上述代码中的 codepipeline-source-artifact 替换为管道的 ArtifactStore 存储桶名称。
6.选择审核策略,然后创建该策略。
7.在导航窗格中,选择策略。
8.选择创建策略。
9.选择 JSON 视图,然后在代码编辑器中输入以下策略:
{
"Version": "2012-10-17",
"Statement": ,
"Resource":
}]
}
10.将上述代码中的 arn:aws:kms:REGION:ACCOUNT_A_NO:key/key-id 替换为您之前在在账户 A 中创建客户管理的密钥部分创建的密钥的 ARN。
11.选择审核策略,然后创建该策略。
12.在导航窗格中,选择角色。
13.选择创建角色。
14.选择其他 AWS 账户。
15.对于账户 ID,输入账户 A 的账户 ID。
16.选择下一步: 权限,然后完成相关步骤以创建该角色。
17.将跨账户角色策略和 KMS 密钥策略附加到您创建的角色。
在账户 A 中,将 AssumeRole 权限添加到 CodePipeline 服务角色您的策略允许账户 A 中的 CodePipeline 服务角色代入您之前在账户 B 中创建的跨账户角色。
1.在账户 A 中,打开 IAM 控制台。
2.在导航窗格中,选择角色。
3.选择您正在用于 CodePipeline 的 IAM 服务角色。
4.选择添加内联策略。
5.选择 JSON 视图,然后在代码编辑器中输入以下策略:
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource":
}
}
6.将上述代码中的 ACCOUNT_B_NO 替换为账户 B 的账号。
7.选择审核策略,然后创建该策略。
在账户 B 中,创建为 AWS CloudFormation 堆栈创建一个角色 (CFN_STACK_ROLE)此服务角色直接在账户 B 中的 AWS CloudFormation 堆栈上配置,必须包含对该堆栈部署的服务的权限。
1.在账户 B 中,打开 IAM 控制台。
2.在导航窗格中,选择角色。
3.为 AWS CloudFormation 创建代表您启动服务时将使用的角色。
4.根据您的需要对您的角色应用权限。
重要提示:确保您的信任策略适用于 AWS CloudFormation,并且您的角色有权访问由堆栈部署的服务。
在账户 A 中更新 CodePipeline 配置注意:如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请确保您运行的是最新版本的 AWS CLI。
您不能通过 CodePipeline 控制台来创建或编辑将使用与其他账户相关联的资源的管道。但是,您可以通过控制台来创建管道的一般结构。然后,您可以使用 AWS CLI 来编辑管道并添加与其他账户关联的资源。您也可以使用新管道的资源来更新当前管道。
1.在 AWS CLI 中,运行以下命令以获取管道 JSON 结构:
aws codepipeline get-pipeline --name MyFirstPipeline >pipeline.json
2.在您的本地 pipeline.json 文件中,确认 encryptionKey ID 包含您之前创建的密钥的 ID 和 ARN。
3.在 pipeline.json 文件中,更新 AWS CloudFormation 操作配置。
注意:管道的操作配置 JSON 结构内的 RoleArn 是用于 AWS CloudFormation 堆栈的角色 (CFN_STACK_ROLE)。操作配置 JSON 结构外的 roleArn 是管道运行 AWS CloudFormation 堆栈时将代入的跨账户角色 (CROSS_ACCOUNT_ROLE)。
4.验证 RoleArn 和 roleArn 的角色都已更新。
在以下代码示例中,RoleArn 是传递给 AWS CloudFormation 用于启动堆栈的角色。CodePipeline 使用 roleArn 来运行 AWS CloudFormation 堆栈。
{
"name": "Prod_Deploy",
"actions": ,
"name": "test-cfn-x",
"actionTypeId": {
"category": "Deploy",
"owner": "AWS",
"version": "1",
"provider": "CloudFormation"
},
"outputArtifacts": [],
"configuration": {
"ActionMode": "CHANGE_SET_REPLACE",
"ChangeSetName": "test",
"RoleArn": "ARN_FOR_CFN_STACK_ROLE",
"Capabilities": "CAPABILITY_IAM",
"StackName": "test-cfn-sam",
"TemplatePath": "MyApp::template.yaml"
},
"roleArn": "ARN_FOR_CROSS_ACCOUNT_ROLE",
"runOrder": 1
}]
}
5.从 pipeline.json 文件删除 metadata 配置:
"metadata": {
"pipelineArn": "arn:aws:codepipeline:REGION:ACC:my_test",
"updated": 1551216777.183,
"created": 1551207202.964
}
重要提示:为了符合正确的 JSON 格式,请删除元数据部分之前的逗号。
6.(可选)要创建管道并更新 JSON 结构,请运行以下命令以使用新配置文件更新管道:
aws codepipeline update-pipeline --cli-input-json file://pipeline.json
7.(可选)要使用当前管道并更新 JSON 结构,请运行以下命令以创建新管道:
aws codepipeline create-pipeline --cli-input-json file://pipeline.json
注意:在您的 pipeline.json 文件中,请更改新管道的名称。