

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Terraform 动态管理 AWS 权限集
<a name="manage-aws-permission-sets-dynamically-by-using-terraform"></a>

*Vinicius Elias 和 Marcos Vinicius Pinto Jordao，Amazon Web Services*

## Summary
<a name="manage-aws-permission-sets-dynamically-by-using-terraform-summary"></a>

AWS IAM Identity Center 通过提供一个用于管理对云应用程序的单点登录访问 AWS 账户 和云应用程序的集中式中心来增强 AWS Identity and Access Management (IAM)。但是，随着组织的发展，手动管理 IAM Identity Center [权限集](https://docs.aws.amazon.com/singlesignon/latest/userguide/permissionsetsconcept.html)可能变得越来越复杂和容易出错。这种复杂性可能导致潜在的安全漏洞和管理开销。

这个解决方案可助你使用基于原生 AWS 服务的持续集成和持续交付（CI/CD）管道，通过基础设施即代码（IaC）管理权限集。它可以将权限集分配机制与 AWS Control Tower 生命周期事件或 Acco [unt Factory for Terraform (AFT)](https://docs.aws.amazon.com/controltower/latest/userguide/aft-overview.html) 环境无缝集成。这种方法为新增和现有身份提供了动态身份配置 AWS 账户。

Amazon EventBridge 规则监控 AWS 账户 创建和更新，这有助于您的身份配置与您的组织结构保持同步。在或 AFT 中创建 AWS Control Tower 或更新账户后，将触发管道。它会评估一组包含权限集定义和分配规则的 JSON 文件。随后，管道将应用这些设置并同步至所有账户。

此方法具有以下优势：
+ **一致性** — 消除整个 AWS 组织的手动配置偏差
+ **可审计性** – 维护所有身份管理变更的完整历史记录
+ **可扩展性** — 随着 AWS 环境的增长自动应用配置
+ **安全性** – 减少权限分配中的人为错误
+ **合规性** – 通过记录在案的变更和分配规则，助力满足监管要求

## 先决条件和限制
<a name="manage-aws-permission-sets-dynamically-by-using-terraform-prereqs"></a>
+ 带有 AWS Control Tower 和 AWS Organizations 设置的多账户环境。或者，您可以将 AFT 与配合使用 AWS Control Tower。
+ IAM 身份中心委 AWS 账户 托管理员接收解决方案。有关更多信息，请参阅 IAM Identity Center 文档中的[委派管理](https://docs.aws.amazon.com/singlesignon/latest/userguide/delegated-admin.html)。
+ 一个用于处理主代码的版本控制系统（VCS）存储库。有关示例，请参阅解决方案的 GitHub [存储库](https://github.com/aws-samples/sample-terraform-aws-permission-sets-pipeline/tree/main/samples/basic)。
+ Terraform 后端管理所需的 AWS 资源，例如亚马逊简单存储服务 (Amazon S3) Service 存储桶和亚马逊 DynamoDB 表。

**限制**
+ 该管道使用 AWS 原生资源和开源 Terraform。管道目前不支持调用第三方生态系统。
+ 有些 AWS 服务 并非全部可用 AWS 区域。有关区域可用性，请参阅[按区域划分的AWS 服务](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/)。有关特定端点，请参阅[服务端点和配额](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html)，然后选择相应服务的链接。

## 架构
<a name="manage-aws-permission-sets-dynamically-by-using-terraform-architecture"></a>

下图显示了此模式的组件和工作流。

![\[使用 Terraform 管理 AWS 权限集的组件和工作流。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/69dc79c7-b4cd-4ad0-b0d2-d58cf0c7adaa/images/649e299c-1142-405a-8982-4a6b2e595d53.png)


**AWS Control Tower 事件流**

解决方案从整合来自任一方 AWS Control Tower 或 AFT 的事件开始。并在实施阶段通过变量定义选择使用其中一项服务。无论使用哪种方法，只要创建或更新账户，管道就会被触发。管道将协调存储在权限集管理存储库中的策略。

以下是 AWS Control Tower 生命周期事件：
+ `CreateManagedAccount` – 创建新账户时
+ `UpdateManagedAccount` – 现有账户更新时

**事件路由**

EventBridge 用作中央事件处理服务，用于捕获 AWS Control Tower 账户中生成的事件。事件发生时， EventBridge 智能地将其路由到解决方案帐户中的集中式事件总线。 AWS Control Tower 生命周期事件遵循不同的路由模式。如果将 AFT 定义为事件源，则由 AFT 管理账户而不是 AWS Control Tower 账户处理事件。这种事件驱动型架构能够自动响应组织变更，无需人工干预。

**AFT 集成流程**

当 AWS Control Tower 生命周期事件到达AFT管理账户时，它们会自动触发AFT固有的多个下游流程。AFT 账户自定义工作流完成后，会将消息发布到专用的 `aft-notifications` Amazon Simple Notification Service（Amazon SNS）主题。该主题会触发此解决方案实现的`aft-new-account-forward-event` AWS Lambda 函数。Lambda 函数会将事件发送到解决方案账户事件总线，用于启动管道。

**基础设施即代码管道**

解决方案管道作为一个全自动部署机制运行。该 AWS CodePipeline 服务会持续监控存储库中的更改。一旦检测到新的提交，它会自动启动部署工作流，并启动一个包含验证和执行阶段的依序处理流程。系统运行 Terraform `plan` 操作以识别提议的更改，然后运行 Terraform `apply` 命令以在环境中实现这些更改。 AWS 值得注意的是，该管道在运行过程中无任何人工审批环节。这种方法能够助力快速部署基础设施变更，同时通过管道日志和 Terraform 状态文件保持可审计性。

该管道利用 AWS CodeBuild 该管道在具有适当权限的受控环境中运行 Terraform 操作。采用这种 IaC 方法时，管道可以执行全面的权限管理操作，包括：
+ 创建新权限集。
+ 更新现有权限集。
+ 移除不必要的权限集。
+ 管理 AWS 组织内跨账户和群组的这些权限的分配。

为保持基础设施一致性并防止出现冲突的变更，该解决方案使用 Amazon S3 存储桶和专用的 Amazon DynamoDB 表实施 Terraform 后端状态管理系统。这种方法为 Terraform 状态文件提供持久存储位置，并采用状态锁定机制来防止对同一资源进行并发修改。

Terraform 的主代码使用官方的 T AWS `permission-sets` erraform 模块。该模块可以根据权限集模板动态管理 IAM Identity Center 中的权限集。

**源代码控制管理**

权限集模板（JSON 文件）位于外部版本控制系统（例如）中 GitHub，该系统为身份管理配置提供集中存储库。这种方法为权限集定义建立了单一可信数据源，同时通过标准代码审查实践实现协作开发。获授权的用户可以按照组织变更管理流程提交对这些模板的更改。这些提交是自动部署管道的主要触发器，可启动基础设施更新流程。

有关如何使用存储库中的 JSON 文件配置权限集的示例，请参阅[其他信息](#manage-aws-permission-sets-dynamically-by-using-terraform-additional)。

## 工具
<a name="manage-aws-permission-sets-dynamically-by-using-terraform-tools"></a>

**AWS 服务**
+ [AWS CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html) 是一项完全托管式构建服务，可编译源代码、运行单元测试和生成部署就绪的构件。
+ [AWS CodeConnections](https://docs.aws.amazon.com/dtconsole/latest/userguide/welcome-connections.html)使 AWS 资源和服务（例如 CodePipeline）能够连接到外部代码存储库，例如 GitHub。
+ [AWS CodePipeline](https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html) 可帮助您快速对软件发布过程的不同阶段进行建模和配置，并自动执行持续发布软件变更所需步骤。
+ [AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) 是一个开源工具，可帮助您 AWS 服务 通过命令行 shell 中的命令进行交互。
+ [AWS Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html)按照规范性最佳实践，帮助您设置和管理 AWS 多账户环境。
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) 是一项完全托管式 NoSQL 数据库服务，可提供快速、可预测、可扩展的性能。
+ [Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html) 是一项无服务器事件总线服务，可帮助您将应用程序与来自各种来源的实时数据连接起来。例如， AWS Lambda 函数、使用 API 目的地的 HTTP 调用端点或其他 AWS 账户目的地的事件总线。
+ [AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) 通过控制谁经过身份验证并有权使用 AWS 资源，从而帮助您安全地管理对资源的访问权限。
+ [AWS IAM Identity Center](https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html)帮助您集中管理对所有应用程序 AWS 账户 和云应用程序的单点登录 (SSO) 访问权限。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 是一项计算服务，可帮助您运行代码，无需预调配或管理服务器。它只在需要时运行您的代码，并自动进行扩展，因此您只需为使用的计算时间付费。
+ [AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html)是一项账户管理服务，可帮助您将多个账户整合 AWS 账户 到一个由您创建和集中管理的组织中。
+ [Amazon Simple Notification Service（Amazon SNS）](https://docs.aws.amazon.com/sns/latest/dg/welcome.html)可帮助您协调和管理发布者与客户端（包括 Web 服务器和电子邮件地址）之间的消息交换。该功能可为账户管理事件启用推送通知，确保相关方及时获悉系统内的重要变更或操作。
+ [Amazon Simple Storage Service（Amazon S3）](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html)是一项基于云的对象存储服务，可帮助您存储、保护和检索任意数量的数据。

**其他工具**
+ [Terraform](https://www.terraform.io/) 是一款基础设施即代码 (IaC) 工具 HashiCorp ，可帮助您创建和管理云和本地资源。

**代码存储库**

此模式的代码可在 AWS 示例组织中的 [sample-terraform-aws-permission-sets-](https://github.com/aws-samples/sample-terraform-aws-permission-sets-pipeline) pipeline 存储库 GitHub 中找到。

## 最佳实践
<a name="manage-aws-permission-sets-dynamically-by-using-terraform-best-practices"></a>
+ 在生产环境中运行代码时，始终使用固定版本的 Terraform 模块和提供程序。
+ 使用静态代码分析工具（例如 [Checkov](https://www.checkov.io/)）扫描代码，然后解决安全问题。
+ 遵循最低权限原则，并授予执行任务所需的最低权限。有关详情，请参阅 IAM 文档中的[授予最低权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#grant-least-priv)和[安全最佳实践](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)。

## 操作说明
<a name="manage-aws-permission-sets-dynamically-by-using-terraform-epics"></a>

### 创建先决条件（可选）
<a name="create-the-prerequisites-optional"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建 Terraform 后端资源。 | 如果您尚未创建 Terraform 后端 AWS 资源，请使用以下步骤创建 Amazon S3 存储桶 (`s3-tf-backend-{ACCOUNT_ID}`) 和 DynamoDB 表 ()。`ddb-tf-backend`[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/manage-aws-permission-sets-dynamically-by-using-terraform.html)<pre>aws s3api create-bucket --bucket s3-tf-backend-{ACCOUNT_ID}<br />aws s3api put-bucket-versioning --bucket s3-tf-backend-{ACCOUNT_ID} --versioning-configuration Status=Enabled<br />aws dynamodb create-table --table-name ddb-tf-backend --attribute-definitions AttributeName=LockID,AttributeType=S --key-schema AttributeName=LockID,KeyType=HASH --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1</pre> | AWS 管理员 | 
| 创建跨账户角色。 | 您必须在 `event-source-account` Terraform AWS 提供商配置中提供跨账户 IAM 角色。如果尚未创建此角色，请先通过以下步骤创建：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/manage-aws-permission-sets-dynamically-by-using-terraform.html)<pre>aws iam create-role \<br />    --role-name CrossAccountRole \<br />    --assume-role-policy-document '{<br />        "Version": "2012-10-17",		 	 	 <br />        "Statement": [<br />            {<br />                "Effect": "Allow",<br />                "Principal": {<br />                    "AWS": "arn:aws:iam::{ACCOUNT_ID}:root"<br />                },<br />                "Action": "sts:AssumeRole"<br />            }<br />        ]<br />    }'</pre>[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/manage-aws-permission-sets-dynamically-by-using-terraform.html)<pre>aws iam attach-role-policy \<br />    --role-name CrossAccountRole \<br />    --policy-arn arn:aws:iam::aws:policy/AdministratorAccess</pre>此示例使用 AWS 托管 IAM 策略[AdministratorAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AdministratorAccess.html)。如果您愿意，可以使用更具体的策略。 | AWS 管理员 | 

### 准备权限集存储库
<a name="prepare-the-permission-set-repository"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建专用的存储库。 | 此任务假设你正在使用 GitHub。创建专用的存储库来存储 Terraform 主代码和权限集模板 JSON 文件。 | DevOps 工程师 | 
| 准备权限集代码。 | 有关如何架构以下文件的信息，请参阅解决方案存储库中的[示例代码](https://github.com/aws-samples/sample-terraform-aws-permission-sets-pipeline/tree/main/samples/basic)：├── main.tf├── outputs.tf├── providers.jinja└── templates复制内容，保留 `providers.jinja` 值，然后对其他文件进行必要的调整。例如，将权限集模板文件添加到 `templates` 中，或者在 `main.tf` 文件中锁定 `aws-ia/permission-sets/aws` 模块的版本。 | DevOps 工程师 | 
| 提交变更。 | 提交变更并将变更推送到之前创建的存储库。例如，保存存储库名称及其 GitHub 组织`myorg/aws-ps-pipeline`。 | DevOps 工程师 | 

### 准备部署代码
<a name="prepare-the-deployment-code"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 下载内容。 | 从解决方案[存储库](https://github.com/aws-samples/sample-terraform-aws-permission-sets-pipeline)下载（克隆）内容。 | DevOps 工程师 | 
| 填入变量。 | 创建 `terraform.tfvars` 文件并添加以下必要变量：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/manage-aws-permission-sets-dynamically-by-using-terraform.html)<pre>repository_name                 = "myorg/aws-ps-pipeline"<br />branch_name                     = "main"<br />vcs_provider                    = "github"<br />account_lifecycle_events_source = "CT"</pre>有关其他变量选项的信息，请参阅此模式存储库中的 v [ariables.tf](https://github.com/aws-samples/sample-terraform-aws-permission-sets-pipeline/blob/main/variables.tf) 文件。 GitHub  | DevOps 工程师 | 
| 调整 Terraform 后端配置。 | （在 `backend.tf` 文件中，将占位符替换为您自己的值。） 使用 AWS Control Tower 主页 AWS 区域，并提供之前创建的 Amazon S3 存储桶和 DynamoDB 表的名称。<pre>terraform {<br />  required_version = ">=1.6"<br />  backend "s3" {<br />    region         = "{region}"<br />    bucket         = "{bucket_name}"<br />    key            = "terraform.tfstate"<br />    dynamodb_table = "{table_name}"<br />    encrypt        = "true"<br />  }<br />}</pre>如果您愿意，可以使用自己的 Terraform 后端配置。 | DevOps 工程师 | 
| 调整 Terraform Provider 配置。 | 在 `providers.tf` 文件中，将占位符替换为您自己的信息。使用 AWS Control Tower 主区域，为提供商提供先前创建的跨账户 IAM 角色的 ARN。`event-source-account`<pre>provider "aws" {<br />  region = "{region}"<br />}<br /><br />provider "aws" {<br />  alias  = "event-source-account"<br />  region = "{region}"<br />  assume_role {<br />    role_arn = "{role_arn}"<br />  }<br />}<br /></pre> | DevOps 工程师 | 

### 手动部署解决方案
<a name="deploy-the-solution-manually"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 选择 AWS 账户。 | 我们建议您将解决方案部署在 IAM Identity Center 委派管理员账户中。但是，您也可以将其部署到 AWS Organizations 管理账户中。要登录与 IAM Identity Center 实例位于同一区域的选定账户，请使用 AWS CLI。请确保您使用的 IAM 角色具有适当权限，能够担任在前述步骤中为 `event-source-account` 提供者指定的角色。此外，此角色必须有权访问 Terraform 后端配置中使用的 AWS 资源。 | AWS 管理员 | 
| 手动运行 Terraform。 | 要初始化、规划和应用配置，请按所示顺序运行以下 Terraform 命令：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/manage-aws-permission-sets-dynamically-by-using-terraform.html) | DevOps 工程师 | 
| 检查部署结果。 | 在 IAM Identity Center 委托管理员账户中检查 `aws-ps-pipeline` 管道是否已创建。还要检查是否存在处于 “**待**处理” 状态的 AWS CodeConnections 连接。 | AWS DevOps | 
| 完成 CodeConnections 配置。 | 要完成 CodeConnections 配置，请使用以下步骤：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/manage-aws-permission-sets-dynamically-by-using-terraform.html)管道现在应该有权访问权限集存储库。有关详细说明，请参阅开发人员工具控制台文档中的[更新待处理连接](https://docs.aws.amazon.com/dtconsole/latest/userguide/connections-update.html)。 | AWS DevOps | 

### 选择管道执行流程以测试解决方案
<a name="choose-a-pipeline-execution-flow-to-test-the-solution"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 通过 AWS Control Tower 或 AFT 更新运行管道。 | 使用 AWS Control Tower 或 AFT（取决于您选择的生命周期事件类型）创建或更改账户后，管道将启动。 | AWS 管理员 | 
| 通过更改代码来运行管道。 | 更改代码并将其提交到 `main` 分支后，管道将启动。 | AWS DevOps | 
| 手动运行管道。 | 要手动启动管道，请使用中的[版本更改](https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-rerun-manually.html)功能 AWS CodePipeline。 | AWS DevOps | 

## 问题排查
<a name="manage-aws-permission-sets-dynamically-by-using-terraform-troubleshooting"></a>


| 问题 | 解决方案 | 
| --- | --- | 
| 拒绝访问 | 验证您拥有部署解决方案所需的权限。 | 
| CodeConnections 问题 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/manage-aws-permission-sets-dynamically-by-using-terraform.html) | 
| 管道执行问题 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/manage-aws-permission-sets-dynamically-by-using-terraform.html) | 
| 权限集部署问题 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/manage-aws-permission-sets-dynamically-by-using-terraform.html) | 

## 相关资源
<a name="manage-aws-permission-sets-dynamically-by-using-terraform-resources"></a>

**AWS 服务 文档**
+ [AWS IAM Identity Center 用户指南](https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html)
+ [AWS 账户 使用权限集进行管理](https://docs.aws.amazon.com/singlesignon/latest/userguide/permissionsetsconcept.html)（IAM 身份中心文档）

**其他资源**
+ [AWS 权限集模块](https://registry.terraform.io/modules/aws-ia/permission-sets/aws/latest) (Terraform)

## 附加信息
<a name="manage-aws-permission-sets-dynamically-by-using-terraform-additional"></a>

**带示例权限集的 JSON 文件**

以下示例说明如何使用存储库中的 JSON 文件配置权限集：

```
{
  "Name": "ps-billing", // Permission set identifier
  "Comment": "Sample permission set for billing access", // Comment to document the purpose of the permission set
  "Description": "Billing access in AWS", // Detailed description
  "SessionDuration": "PT4H", // Session duration = 4 hours (ISO 8601 format)
  "ManagedPolicies": [ // List of AWS IAM managed policies
    "arn:aws:iam::aws:policy/job-function/Billing",
    "arn:aws:iam::aws:policy/job-function/SupportUser",
    "arn:aws:iam::aws:policy/AWSSupportAccess",
    "arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"
  ],
  "CustomerPolicies": [], // References to IAM policies previously created
  "CustomPolicy": {}, // Inline IAM policy defined directly in the permission set
  "PermissionBoundary": {  // AWS or customer managed IAM policy to be used as boundary
    "ManagedPolicy": "",
    "CustomerPolicy": ""
  },
  "Assignments": [ // Define the assignment rules
    {
      "all_accounts": true, // Apply to ALL active AWS accounts in organization
      "principal": "G_BILLING_USERS", // Group/user name in Identity Center
      "type": "GROUP", // Can be "GROUP" or "USER"
      "account_id": [], // List of AWS account ID (empty since all_accounts=true)
      "account_ou": [], // List of AWS Organizational Unit IDs with target AWS accounts
      "account_tag": [] // List of tags (key:value) to match AWS Organization accounts tags
    }
  ]
}
```

有关更多信息，请参阅 Terraform 网站 [AWS 权限集模块](https://registry.terraform.io/modules/aws-ia/permission-sets/aws/latest#json-file-templates)文档中的 JSON 架构。

**提示**
+ 可以使用 Terraform [导入块](https://developer.hashicorp.com/terraform/language/import)将现有权限集导入解决方案。
+ 您可以使用 AFT 在委托账户中实现 AWS 权限集管道。有关更多信息，请参阅 [AFT 蓝图](https://awslabs.github.io/aft-blueprints/index.html)。