如何使用带预装 ACL 的 CodePipeline 将构件部署到不同账户中的 Amazon S3?
上次更新时间:2020 年 6 月 24 日
我想要使用带 S3 部署操作提供程序和预装访问控制列表 (ACL) 的 AWS CodePipeline 将构件部署到不同账户中的 Amazon Simple Storage Service (Amazon S3)。
简短描述
下面的解决方法基于假定以下内容的示例场景:
- 您有两个账户:开发 (dev) 账户和生产 (prod) 账户。
- 开发账户中的输入存储桶称为 codepipeline-input-bucket(启用了版本控制)。
- 开发账户中的默认构件存储桶称为 codepipeline-us-east-1-0123456789。
- 生产账户中的输出存储桶称为 codepipeline-output-bucket。
- 您正在将开发账户中的构件部署到生产账户中的 S3 存储桶。
- 您使用预装 ACL 为生产账户中的存储桶拥有者提供归开发账户所有的对象的访问权限。要部署构件并将开发账户设为对象拥有者,请参阅如何使用 CodePipeline 将构件部署到不同账户中的 Amazon S3?
解决方法
在开发账户中创建 CodePipeline
1. 打开 CodePipeline 控制台,然后选择创建管道。
2. 对于管道名称,输入 crossaccountdeploy。
注意:请使用您的管道名称替换 crossaccountdeploy。
角色名称文本框会自动填充服务角色名称 AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy。您也可以选择现有服务角色。
3. 展开高级设置部分。
4. 对于构件存储,请选择默认位置。
注意:如果场景需要,则可以选择自定义位置。
5. 对于加密密钥,选择默认 AWS 托管密钥。
6. 选择下一步。
7. 对于添加源阶段页面上的源提供商,选择 Amazon S3。
8. 对于存储桶,请输入 codepipeline-input-bucket。
注意:请使用输入存储桶名称替换 codepipeline-input-bucket。
重要提示:输入存储桶必须启用版本控制才能使用 CodePipeline。
9. 对于 S3 对象键,输入 sample-website.zip。
重要提示:要使用示例 AWS 网站而不是您自己的网站,请参阅教程:创建一个使用 Amazon S3 作为部署提供程序的管道。然后,在 1:将静态网站文件部署到 Amazon S3 部分的前提条件中搜索“示例静态网站”。
10. 对于更改检测选项,选择 Amazon CloudWatch Events(推荐)。
11. 选择下一步。
12. 在添加构建阶段页面上,选择跳过构建阶段,然后选择跳过。
13. 对于添加部署阶段页面上的部署提供程序,选择 Amazon S3。
14. 对于区域,选择美国东部(弗吉尼亚北部)。
重要提示:请使用输出存储桶所在的 AWS 区域替换美国东部(弗吉尼亚北部)。
15. 对于存储桶,输入生产存储桶名称 codepipeline-output-bucket。
注意:请使用您的输出存储桶的名称替换 codepipeline-output-bucket。
16. 选中在部署前提取文件复选框。
注意:如果需要,请为部署路径输入路径。
17. 展开其他配置。
18. 对于预装 ACL,选择 bucket-owner-full-control。
注意:bucket-owner-full-control 向目标生成账户中的存储桶拥有者授予由开发账户部署并归其所有的对象。有关更多信息,请参阅预装 ACL。
19. 选择下一步。
20. 选择创建管道。
现在,您的管道已触发,但源阶段出现故障。然后,您将收到以下错误信息:
The object with key 'sample-website.zip' does not exist.
上传示例网站至输入存储桶部分将向您展示稍后如何解决此错误。
使用 AWS Identity and Access Management (IAM) 策略配置 CodePipeline 服务角色,为生产账户的输出存储桶添加 S3 访问权限
1. 打开开发账户中的 IAM 控制台。
2. 在导航窗格中,选择策略,然后选择创建策略。
3. 选择 JSON 选项卡,然后在 JSON 编辑器中输入以下策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::codepipeline-output-bucket/*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::codepipeline-output-bucket"
}
]
}
注意:请使用您的输出存储桶的名称替换 codepipeline-output-bucket。
4. 选择查看策略。
5. 对于名称,输入 prodbucketaccess。
注意:请使用您自己的策略名称替换 prodbucketaccess。
6. 选择创建策略。
7. 在导航窗格中,选择角色。
8. 从角色列表中选择 AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy。这是 CodePipeline 使用的服务角色。
注意:如果适用,请使用您自己的服务角色替换 AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy。
9. 选择附加策略。
10. 选择之前创建的 prodbucketaccess 策略,然后选择附加策略。
CodePipeline 现在可以访问生产账户中的输出存储桶了。
配置生产账户中的输出存储桶以允许从开发账户中访问
1. 打开生产账户中的 Amazon S3 控制台。
2. 在存储桶名称列表中,选择 codepipeline-output-bucket。
注意:请使用您的输出存储桶的名称替换 codepipeline-output-bucket。
3. 选择权限,然后选择存储桶策略。
4. 在文本编辑器中,输入以下策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::dev-account-id:root"
},
"Action": "s3:Put*",
"Resource": "arn:aws:s3:::codepipeline-output-bucket/*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::dev-account-id:root"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::codepipeline-output-bucket"
}
]
}
注意:请使用您的开发环境的账户 ID 替换 dev-account-id。使用您的输出存储桶的名称替换 codepipeline-output-bucket。
5. 选择保存。
上传示例网站至输入存储桶
1. 打开开发账户中的 Amazon S3 控制台。
2. 在存储桶名称列表中,选择 codepipeline-input-bucket。
注意:请使用输入存储桶名称替换 codepipeline-input-bucket。
3. 选择上传,然后选择添加文件。
4. 选择之前下载的 sample-website.zip 文件。
5. 选择上传。
现在,CodePipeline 已触发,并发生以下情况:
1. 源操作从 codepipeline-input-bucket 中选择 sample-website.zip,然后将 zip 文件作为源构件放入 codepipeline-us-east-1-0123456789 构件存储桶。
2. 在部署操作中,CodePipeline 服务角色 AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy 使用其访问权限来部署到生产账户中的 codepipeline-output-bucket,并应用预装 ACL bucket-owner-full-control。
开发账户现在是 codepipeline-output-bucket 中已提取对象的所有者,但是生产账户中的存储桶所有者对已部署的构件也拥有完全访问权限。