如何使用 CodePipeline 在不同的 AWS 账户中将构件部署到 Amazon S3?

5 分钟阅读
0

我想将构件部署到另一个账户中的 Amazon Simple Storage Service (Amazon S3) 存储桶。我还想使用带有 Amazon S3 部署操作提供程序的 AWS CodePipeline 将目标账户设置为对象所有者。

解决方法

**注意:**以下示例过程假设如下:

  • 你有两个账户:一个开发账户和一个生产账户。
  • 开发账户中的输入存储桶名为 ** codepipeline-input-bucket**(已激活版本控制)。
  • 开发账户中的默认构件存储桶名为 codepipeline-us-east-1-0123456789
  • 生产账户中的输出存储桶名为 codepipeline-output-bucket
  • 您正在将构件从开发账户部署到生产账户中的 S3 存储桶。
  • 您假设在生产账户中创建了跨账户角色来部署构件。该角色使生产账户成为对象所有者,而不是开发账户。要向生产账户中的存储桶所有者提供对开发账户拥有的对象的访问权限,请参阅以下文章:如何使用 CodePipeline 和标准 ACL 在不同的 AWS 账户中将构件部署到 Amazon S3?

在开发账户中创建 AWS KMS 密钥来用于 CodePipeline

**重要事项:**您必须使用 AWS Key Management Service (AWS KMS) 客户自主管理型密钥进行跨账户部署。如果未配置密钥,则 CodePipeline 使用默认加密对对象进行加密,目标账户中的角色无法解密这些对象。

1.在开发账户中打开 AWS KMS 控制台

2.    在导航窗格中,选择客户自主管理型密钥

3.选择 Create Key(创建密钥)。

4.对于 Key type(密钥类型),选择 Symmetric Key(对称密钥)。

5.展开 Advanced Options(高级选项)。

6.对于 Key material origin(密钥材料来源),选择 KMS。然后,选择 Next(下一步)。

7.对于 Alias(别名),输入密钥的别名。例如:s3deploykey

8.选择 Next(下一步)。将打开 Define key administrative permissions(定义密钥管理权限)页面。

9.在 Key administrators(密钥管理员)部分中,选择 AWS Identity and Access Management (IAM) 用户或角色作为您的密钥管理员。

10.选择 Next(下一步)。将打开 Define key usage permissions(定义密钥使用权限)页面。

11.在 Other AWS accounts(其他 AWS 账户)部分中,选择 Add another AWS account(添加其他 AWS 账户)。

12.在出现的文本框中,添加生产账户的账户 ID。然后,选择 Next(下一步)。

**注意:**您也可以在 This Account(此账户)部分中选择现有的服务角色。如果您选择现有服务角色,请跳过 Update the KMS usage policy in the development account(在开发账户中更新 KMS 使用策略)部分中的步骤。

13.查看密钥策略。然后,选择 Finish(完成)。

在开发账户中创建 CodePipeline

1.打开 CodePipeline 控制台。然后,选择 Create pipeline(创建管线)。

2.对于 Pipeline name(管线名称),输入管线的名称。例如:crossaccountdeploy

**注意:**Role name(角色名称)文本框自动填充服务角色名称 AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy。您也可以选择其他可以访问 KMS 密钥的现有服务角色。

3.展开 Advanced settings(高级设置)部分。

4.对于 Artifact store(构件存储),选择 Default location(默认位置)。
**注意:**如果您的用例需要,可以选择 Custom location(自定义位置)。

5.对于 Encryption key(加密密钥),选择 Customer Managed Key(客户自主管理型密钥)。

6.对于 KMS customer managed key(KMS 客户自主管理型密钥),从列表中选择密钥的别名(在本示例中为 s3deploykey)。然后,选择 Next(下一步)。将打开 Add source stage(添加源阶段)页面。

7.对于 Source provider(源提供程序),选择 Amazon S3

8.对于 Bucket(存储桶),输入您的开发输入 S3 存储桶的名称。例如:codepipeline-input-bucket

**重要事项:**输入存储桶必须激活版本控制才能使用 CodePipeline。

9.对于 S3 object key(S3 对象密钥),输入 sample-website.zip

**重要事项:**要使用示例 AWS 网站而不是您自己的网站,请参阅“教程: 创建使用 Amazon S3 作为部署提供程序的管线”。然后,在“先决条件”(“1: 将静态网站文件部署到 Amazon S3”部分)中搜索“sample static website”。

10.对于 Change detection options(更改检测选项),选择 Amazon CloudWatch Events (recommended)(Amazon CloudWatch Events (推荐))。然后,选择 Next(下一步)。

11.在 Add build stage(添加构建阶段)页面上,选择 Skip build stage(跳过构建阶段)。然后,选择 Skip(跳过)。

12.在 Add deploy stage(添加部署阶段)页面上,对于 Deploy provider(部署提供程序),选择 Amazon S3

13.对于 Region(区域),选择您的生产输出 S3 存储桶所在的 AWS 区域。例如: US East (N. Virginia)(美国东部(弗吉尼亚州北部))

**重要事项:**如果生产输出存储桶的区域与管线的区域不同,则您还必须验证以下内容:

14.对于 Bucket(存储桶),输入您的生产输出 S3 存储桶的名称。例如:codepipeline-output-bucket

15.选中 Extract file before deploy(在部署前提取文件)复选框。
**注意:**如果需要,请为 Deployment path(部署路径)输入一个路径。

16.选择 Next(下一步)。

17.选择 Create pipeline(创建管线)。管线将运行,但源阶段将失败。出现以下错误: “The object with key 'sample-website.zip' does not exist”(具有“sample-website.zip”密钥的对象不存在)。

本文的“将示例网站上传到输入存储桶”部分介绍了如何解决此错误。

更新开发账户中的 KMS 使用策略

**重要事项:**如果您使用的是现有的 CodePipeline 服务角色,请跳过此部分。

1.在开发账户中打开 AWS KMS 控制台

2.选择您的密钥的别名(在本示例中为 s3deploykey)。

3.    在密钥用户部分中,选择添加

4.在搜索框中,输入服务角色 AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy

5.选择 Add(添加)。

在生产账户中配置跨账户角色

为角色创建 IAM 策略以向您的生产输出 S3 存储桶授予 Amazon S3 权限

1.在生产账户中打开 IAM 控制台

2.在导航窗格中,选择 Policies(策略)。然后,选择 Create policy(创建策略)。

3.选择 JSON 选项卡。然后,在 JSON 编辑器中输入以下策略:

**重要事项:**将 codepipeline-output-bucket 替换为您的生产输出 S3 存储桶的名称。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:Put*"
      ],
      "Resource": [
        "arn:aws:s3:::codepipeline-output-bucket/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::codepipeline-output-bucket"
      ]
    }
  ]
}

4.选择查看策略

5.对于 Name(名称),输入策略的名称。例如:outputbucketdeployaccess

6.选择 Create policy(创建策略)。

为角色创建 IAM 策略以授予所需 KMS 权限

1.在 IAM 控制台中,选择 Create policy(创建策略)。

2.选择 JSON 选项卡。然后,在 JSON 编辑器中输入以下策略:

**注意:**替换您创建的 KMS 密钥的 ARN。将 codepipeline-us-east-1-0123456789 替换为开发账户中构件存储桶的名称。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "kms:DescribeKey",
        "kms:GenerateDataKey*",
        "kms:Encrypt",
        "kms:ReEncrypt*",
        "kms:Decrypt"
      ],
      "Resource": [
        "arn:aws:kms:us-east-1:<dev-account-id>:key/<key id>"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:Get*"
      ],
      "Resource": [
        "arn:aws:s3:::codepipeline-us-east-1-0123456789/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::codepipeline-us-east-1-0123456789"
      ]
    }
  ]
}

3.选择 Review policy(查看策略)。

4.对于 Name(名称),输入策略的名称。例如:devkmss3access

5.选择 Create policy(创建策略)。

创建跨账户角色,开发账户可以代入该角色来部署构件

1.在生产账户中打开 IAM 控制台

  1. 在导航窗格中,选择角色。然后,选择创建角色

3.选择 Another AWS account(其他 AWS 账户)。

4.对于 Account ID(账户 ID),输入开发账户的 AWS 账户 ID。

5.    选择下一步: 权限

6.从策略列表中,选择 outputbucketdeployaccessdevkmss3access

7.选择下一步: 标签

8.(可选)添加标签,然后选择 Next: Review(下一步:审核)。

9.对于 Role name(角色名称),输入 prods3role

10.选择 Create role(创建角色)。

11.从角色列表中选择 prods3role

12.选择 Trust relationship(信任关系)。然后,选择 Edit Trust relationship(编辑信任关系)。

13.在 Policy Document(策略文档)编辑器中,输入以下策略:

**重要事项:**将 dev-account-id 替换为开发账户的 AWS 账户 ID。将 AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy 替换为管线的服务角色的名称。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::<dev-account-id>:role/service-role/AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy"
        ]
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

14.选择 Update Trust Policy(更新信任策略)。

更新开发账户中 CodePipeline 构件存储桶的存储桶策略

1.在开发账户中打开 Amazon S3 控制台

2.在 Bucket name(存储桶名称)列表中,选择开发账户中的构件存储桶的名称(在本示例中为 codepipeline-us-east-1-0123456789)。

3.选择 Permissions(权限)。然后选择 Bucket Policy(存储桶策略)。

4.在文本编辑器中,更新您的现有策略,以加入以下策略语句:

**重要事项:**要与正确的 JSON 格式保持一致,请在现有语句后添加逗号。将 prod-account-id 替换为您的生产账户的 AWS 账户 ID。将 codepipeline-us-east-1-0123456789 替换为您的构件存储桶的名称。

{
    "Sid": "",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::<prod-account-id>:root"
    },
    "Action": [
        "s3:Get*",
        "s3:Put*"
    ],
    "Resource": "arn:aws:s3:::codepipeline-us-east-1-0123456789/*"
},
{
    "Sid": "",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::<prod-account-id>:root"
    },
    "Action": "s3:ListBucket",
    "Resource": "arn:aws:s3:::codepipeline-us-east-1-0123456789"
}

5.选择 Save(保存)。

为开发账户中的 CodePipeline 服务角色附加策略,允许其代入您创建的跨账户角色

1.在开发账户中打开 IAM 控制台

2.在导航窗格中,选择 Policies(策略)。然后,选择 Create policy(创建策略)。

3.选择 JSON 选项卡。然后,在 JSON 编辑器中输入以下策略:

**重要事项:**将 prod-account-id 替换为您的生产账户的 AWS 账户 ID。

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": [
      "arn:aws:iam::<prod-account-id>:role/prods3role"
    ]
  }
}

4.选择查看策略

5.对于 Name(名称),输入 assumeprods3role

6.选择 Create policy(创建策略)。

7.在导航窗格中,选择 Roles(角色)。然后,为您的管线选择服务角色的名称(例如,AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy)。

8.选择 Attach Policies(附加策略)。然后,选择 assumeprods3role

9.选择 Attach Policy(附加策略)。

更新您的管线以使用开发账户中的跨账户角色

**注意:**如果在运行 AWS 命令行界面(AWS CLI)命令时收到错误,请确保您使用的是最新的 Amazon CLI 版本

1.通过运行以下 AWS CLI 命令,以名为 codepipeline.json 的文件检索管线定义:

**重要事项:**将 crossaccountdeploy 替换为您的管线名称。

aws codepipeline get-pipeline --name crossaccountdeploy > codepipeline.json

2.将跨账户 IAM 角色 ARN (roLearn) 添加到 codepipeline.json 文件的部署操作部分。有关详细信息,请参阅 CodePipeline 用户指南中的 CodePipeline 管线结构参考

跨账户 IAM roleArn 示例

"roleArn": "arn:aws:iam::your-prod-account id:role/prods3role",

包含跨账户 IAM 角色 ARN 的部署操作示例

**重要事项:**将 prod-account-id 替换为您的生产账户的 AWS 账户 ID。

{
  "name": "Deploy",
  "actions": [
    {
      "name": "Deploy",
      "actionTypeId": {
        "category": "Deploy",
        "owner": "AWS",
        "provider": "S3",
        "version": "1"
      },
      "runOrder": 1,
      "configuration": {
        "BucketName": "codepipeline-output-bucket",
        "Extract": "true"
      },
      "outputArtifacts": [],
      "inputArtifacts": [
        {
          "name": "SourceArtifact"
        }
      ],
      "roleArn": "arn:aws:iam::<prod-account-id>:role/prods3role",
      "region": "us-east-1",
      "namespace": "DeployVariables"
    }
  ]
}

3.删除位于 codepipeline.json 文件末尾的元数据部分。

**重要事项:**确保同时删除元数据部分之前的逗号。

元数据部分示例

"metadata": {
    "pipelineArn": "arn:aws:codepipeline:us-east-1:<dev-account-id>:crossaccountdeploy",
    "created": 1587527378.629,
    "updated": 1587534327.983
}

4.通过运行以下命令更新管线:

aws codepipeline update-pipeline --cli-input-json file://codepipeline.json

将示例网站上传到输入存储桶

1.在开发账户中打开 Amazon S3 控制台

2.在 Bucket name(存储桶名称)列表中,选择您的开发输入 S3 存储桶。例如:codepipeline-input-bucket

3.选择 Upload(上传)。然后,选择 Add files(添加文件)。

4.选择您之前下载的 sample-website.zip 文件。

5.选择 Upload(上传)以运行管线。当管线运行时,会出现以下情况:

  • 源操作将从开发输入 S3 存储桶 (codepipeline-input-bucket) 中选择 sample-website.zip。然后,源操作会将 zip 文件作为源构件放入开发账户 (codepipeline-us-east-1-0123456789) 的构件存储桶中。
  • 在部署操作中,CodePipeline 服务角色 (AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy) 会代入生产账户中的跨账户角色 (prods3role)。
  • CodePipeline 使用跨账户角色 (prods3role) 访问开发账户中的 KMS 密钥和构件存储桶。然后,CodePipeline 将提取的文件部署到生产账户中的生产输出 S3 存储桶 (codepipeline-output-bucket)。

**注意:**生产账户是生产输出 S3 存储桶 (codepipeline-output-bucket) 中提取的对象的拥有者。

AWS 官方
AWS 官方已更新 5 个月前