如何使用 CodePipeline 在不同账户中部署 AWS CloudFormation 堆栈?

5 分钟阅读
0

我想要使用 AWS CodePipeline 在不同的 AWS 账户中部署 AWS CloudFormation 堆栈。

简短描述

要使用 CodePipeline 在不同 AWS 账户中部署 CloudFormation 堆栈,请执行以下操作:

**注意:**将使用两个账户创建管道并在其中部署 CloudFormation 堆栈。账户 1 用于创建管道,账户 2 用于在其中部署 CloudFormation 堆栈。

1.    (账户 1)创建一个客户管理的 AWS Key Management Service(AWS KMS)密钥,用于向以下对象授予密钥使用权限:

  • 账户 1 CodePipeline 服务角色
  • 账户 2

2.    (账户 1)创建一个 Amazon Simple Storage Service(Amazon S3)存储桶,该存储桶包含用于授予账户 2 访问存储桶权限的存储桶策略。

3.    (账户 2)创建一个跨账户 AWS Identity and Access Management(IAM)角色,该角色允许以下操作:

  • CloudFormation API 操作
  • 访问账户 1 中的 Amazon S3 存储桶
  • 使用账户 1 中的客户管理的 AWS KMS 密钥进行解密

4.    (账户 1)为账户 1 的 CodePipeline 服务角色添加 AssumeRole 权限,以允许其代入账户 2 中的跨账户角色。

5.    (账户 2)为 CloudFormation 堆栈创建一个服务角色,其中包含该堆栈部署的服务所需的权限。

6.    (账户 1)更新账户 1 中的 CodePipeline 配置,以包括与账户 2 关联的资源。

解决方法

(账户 1 )创建一个客户管理的 AWS KMS 密钥,用于向账户 1 中的 CodePipeline 服务角色和账户 2 授予使用权限

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

2.    从导航窗格中选择客户管理的密钥

3.    选择 Create key(创建密钥)。然后选择 Symmetric(对称)。

**注意:**在 Advanced options (高级选项)部分,将源保留为 KMS

4.    对于别名,输入您的密钥的名称。

5.    (可选)根据您的用例添加标签。然后,选择 Next(下一步)。

6.    在 Define key administrative permissions(定义密钥管理权限)页面上,对于 Key administrators(密钥管理员),选择 AWS Identity and Access Management (IAM) 用户。此外,添加您想要其充当该密钥管理员的任何其他用户或组。然后选择 Next(下一步)。

7.    在 Define key usage permissions(定义密钥使用权限)页面上,对于 This account(此账户),添加您想要其访问该密钥的 IAM 实体。例如,CodePipeline 服务角色。

8.    在 Other AWS accounts(其他 AWS 账户)部分,选择 Add another AWS account(添加其他 AWS 账户)。然后,输入账户 2 中的 IAM 角色的 Amazon Resource Name (ARN)

9.    选择 Next(下一步)。然后选择 Finish(完成)。

10.    在 Customer managed keys(客户管理的密钥)部分,选择您刚刚创建的密钥然后,复制该密钥的 ARN。

**重要提示:**更新管道和配置 IAM policy 时,您必须拥有此 AWS KMS 密钥的 ARN。

(账户 1)创建一个 Amazon S3 存储桶,该存储桶包含用于授予账户 2 访问存储桶权限的存储桶策略

1.    在账户 1 中,打开 Amazon S3 console(Amazon S3 控制台)。

2.    选择现有的 Amazon S3 存储桶或创建新的 S3 存储桶用作 CodePipeline 的 ArtifactStore

**注意:**构件可包含一个堆栈模板文件、一个模板配置文件或两者皆有。CodePipeline 将使用这些构件来处理 CloudFormation 堆栈和更改集。在您的模板配置文件中,您必须指定模板参数值、堆栈策略和标签。

3.    在存储桶的 Amazon S3 详细信息页面中,选择权限

4.    选择存储桶策略

5.    在存储桶策略编辑器中,输入以下策略:

重要提示:codepipeline-source-artifact 替换为 CodePipeline 的 SourceArtifact 存储桶名称。将 ACCOUNT_B_NO 替换为账户 2 的账号。

{
  "Id": "Policy1553183091390",
  "Version": "2012-10-17",
  "Statement": [{
      "Sid": "",
      "Action": [
        "s3:Get*",
        "s3:Put*"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::codepipeline-source-artifact/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::ACCOUNT_B_NO:root"
        ]
      }
    },
    {
      "Sid": "",
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::codepipeline-source-artifact",
      "Principal": {
        "AWS": [
          "arn:aws:iam::ACCOUNT_B_NO:root"
        ]
      }
    }
  ]
}

6.    选择 Save(保存)。

(账户 2)创建跨账户 IAM 角色

创建一个类似于以下的 IAM policy:

  • 账户 1 中用于代入账户 2 中的跨账户 IAM 角色的管道
  • CloudFormation API 操作
  • SourceArtifact 相关的 Amazon S3 API 操作

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

2.    在导航窗格中,选择策略。然后选择创建策略

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

**重要提示:**将 codepipeline-source-artifact 替换为管道构件存储的存储桶名称。

{
  "Version": "2012-10-17",
  "Statement": [{
      "Effect": "Allow",
      "Action": [
        "cloudformation:*",
        "iam:PassRole"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:Get*",
        "s3:Put*",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::codepipeline-source-artifact/*"
      ]
    }
  ]
}

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

5.    在 Name(名称)中,输入策略的名称。

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

创建另一个允许 AWS KMS API 操作的 IAM 策略

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

2.    在导航窗格中,选择策略。然后选择创建策略

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

**重要提示:**将 arn:aws:kms:REGION:ACCOUNT_A_NO:key/key-id 替换为您先前复制的 AWS KMS 密钥的 ARN。

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "kms:DescribeKey",
      "kms:GenerateDataKey*",
      "kms:Encrypt",
      "kms:ReEncrypt*",
      "kms:Decrypt"
    ],
    "Resource": [
      "arn:aws:kms:REGION:ACCOUNT_A_NO:key/key-id"
    ]
  }]
}

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

5.    在 Name(名称)中,输入策略的名称。

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

使用您创建的策略创建跨账户 IAM 角色

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

2.    在导航窗格中,选择角色

3.    选择 Create Role(创建角色)。

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

5.    对于Account ID(账户 ID),输入账户 1 的账户 ID。

6.    选择 Next: Permissions(下一步:权限)。然后,完成创建 IAM 角色的步骤

7.    将跨账户角色策略和 KMS 密钥策略附加到您创建的角色。有关说明,请参阅添加和删除 IAM 身份权限

(账户 1)向账户 1 的 CodePipeline 服务角色添加 AssumeRole 权限,以允许其代入账户 2 中的跨账户角色

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

2.    在导航窗格中,选择角色

3.    选择您正在用于 CodePipeline 的 IAM 服务角色。

4.    选择添加内联策略

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

重要提示:ACCOUNT_B_NO 替换为账户 2 的账号。

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

6.    选择 Review policy(审核策略),然后创建策略。

(账户 2)为 CloudFormation 堆栈创建一个服务角色,其中包含该堆栈部署的服务所需的权限

**注意:**可以直接在账户 2 中的 CloudFormation 堆栈上直接配置此服务角色。该角色必须包括堆栈部署的服务的权限。

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

2.    在导航窗格中,选择角色

3.    为 AWS CloudFormation 创建代表您启动服务时将使用的角色

4.    根据您的使用案例对您的角色应用权限

重要提示:请确保您的信任策略适用于 AWS CloudFormation,并且您的角色有权访问由堆栈部署的服务。

(账户 1)更新 CodePipeline 配置,以包括与账户 2 关联的资源

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

您不能通过 CodePipeline 控制台来创建或编辑将使用与其他账户相关联的资源的管道。但是,您可以通过控制台来创建管道的一般结构。然后,您可以使用 AWS CLI 来编辑管道并添加与其他账户关联的资源。您也可以使用新管道的资源来更新当前管道。有关更多信息,请参阅在 CodePipeline 中创建管道

1.    通过运行以下 AWS CLI 命令获取管道 JSON 结构:

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

2.    在您的本地 pipeline.json 文件中,确认 artifactStore 下的 encryptionKey ID 包含 ID 及 AWS KMS 密钥的 ARN。

**注意:**有关管道结构的更多信息,请参阅《AWS CLI 命令参考》中的 create-pipeline

3.    在 pipeline.json 文件中,更新 AWS CloudFormation 操作配置

**注意:**管道的操作配置 JSON 结构内的 RoleArn 是用于 CloudFormation 堆栈的角色 (CFN_STACK_ROLE)。操作配置 JSON 结构外的 roleArn 是管道运行 CloudFormation 堆栈时将代入的跨账户角色 (CROSS_ACCOUNT_ROLE)。

4.    验证是否已针对以下对象更新角色:

  • 管道的操作配置 JSON 结构内的 RoleArn
  • 管道的操作配置 JSON 结构外的 roleArn

**注意:**在以下代码示例中,RoleArn 是传递给 AWS CloudFormation 用于启动堆栈的角色。CodePipeline 使用 roleArn 来运行 AWS CloudFormation 堆栈。

{
  "name": "Prod_Deploy",
  "actions": [{
    "inputArtifacts": [{
      "name": "MyApp"
    }],
    "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 文件中,请确保已更改新管道的名称。


相关信息

在使用来自另一个 AWS 账户的资源的 CodePipeline 中创建管道

CodePipeline 管道结构参考

AWS 官方
AWS 官方已更新 1 年前