

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

# 使用代码存储库在中 AWS Service Catalog 配置 Terraform 产品
<a name="provision-a-terraform-product-in-aws-service-catalog-by-using-a-code-repository"></a>

*Rahul Sharad Gaikwad 博士和 Tamilselvan P，Amazon Web Services*

## Summary
<a name="provision-a-terraform-product-in-aws-service-catalog-by-using-a-code-repository-summary"></a>

AWS Service Catalog 支持自助服务配置，并管理您的 [HashiCorp Terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started) 配置。如果您使用 Terraform，则可以使用 Service Catalog 作为单一工具，在其中大规模组织、管理和分发 Terraform 配置。 AWS 您可以访问 Service Catalog 的主要功能，包括对标准化和预先批准的基础架构即代码 (IaC) 模板进行编目、访问控制、使用最低权限访问的云资源配置、版本控制、与数 AWS 账户千人共享以及标记。最终用户（例如工程师、数据库管理员和数据科学家）会看到其有权访问的产品和版本列表，并且只需一个操作即可完成部署。

此模式可帮助您使用 Terraform 代码部署 AWS 资源。 GitHub 存储库中的 Terraform 代码可通过 Service Catalog 进行访问。借助此方法，您可以将产品整合到现有的 Terraform 工作流中。管理员可以使用 Terraform 创建 Service Catalog AWS Launch Wizard 产品组合并向其中添加产品。

这种解决方案的优点如下：
+ 由于 Service Catalog 中具有回滚功能，因此如果在部署过程中出现任何问题，可以将产品恢复到以前的版本。
+ 您可以轻松识别不同产品版本之间的差异。这有助于在部署期间解决问题。
+ 您可以在 Service Catalog 中配置存储库连接，例如到 GitHub 或 GitLab。您可以直接通过存储库更改产品。

有关总体优势的信息 AWS Service Catalog，请参阅[什么是 Service Catalog](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/introduction.html)。

## 先决条件和限制
<a name="provision-a-terraform-product-in-aws-service-catalog-by-using-a-code-repository-prereqs"></a>

**先决条件**
+ 活跃 AWS 账户的.
+  GitHub BitBucket、或其他包含 ZIP 格式的 Terraform 配置文件的存储库。
+ AWS Serverless Application Model [已安装](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html)命令行界面 (AWS SAM CLI)。
+ AWS Command Line Interface (AWS CLI)，[已安装](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)并[配置](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)。
+ [已安装](https://go.dev/doc/install) Go。
+ Python 版本 3.9，[已安装](https://www.python.org/downloads/release/python-3913/)。 AWS SAM CLI 需要这个版本的 Python。
+ 编写和运行 AWS Lambda 函数的权限以及访问和管理 Service Catalog 产品和产品组合的权限。

## 架构
<a name="provision-a-terraform-product-in-aws-service-catalog-by-using-a-code-repository-architecture"></a>

![通过代码存储库在 Service Catalog 中预调配 Terraform 产品的架构图](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/7d0d76e8-9485-4b3f-915f-481b6a7cdcd9/images/e83fa44a-4ca6-4438-a0d1-99f09a3541bb.png)


下图显示了如下工作流：

1. 当 Terraform 配置准备就绪后，开发人员会创建一个包含所有 Terraform 代码的 .zip 文件。开发人员将 .zip 文件上传至连接到 Service Catalog 的代码存储库中。

1. 管理员将 Terraform 产品与 Service Catalog 中的产品组合关联。管理员还会创建启动约束，以便最终用户预调配产品。

1. 在 Service Catalog 中，最终用户使用 Terraform 配置启动 AWS 资源。他们可以选择要部署的产品版本。

## 工具
<a name="provision-a-terraform-product-in-aws-service-catalog-by-using-a-code-repository-tools"></a>

**AWS 服务**
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 是一项计算服务，可帮助您运行代码，无需预调配或管理服务器。它只在需要时运行您的代码，并自动进行扩展，因此您只需为使用的计算时间付费。
+ [AWS Service Catalog](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/introduction.html)帮助您集中管理已获批准的 IT 服务目录。 AWS最终用户可在遵循组织设定约束的情况下快速部署他们所需已获得批准的 IT 服务。

**其他服务**
+ [Go](https://go.dev/doc/install) 是谷歌支持的开源编程语言。
+ [Python](https://www.python.org/) 是通用的计算机编程语言。

**代码存储库**

如果您需要可通过 Service Catalog 部署的 Terraform 示例配置，则可以使用 [Amazon Mac GitHub ie 组织设置](https://github.com/aws-samples/aws-macie-customization-terraform-samples)使用 Terraform 存储库中的配置。并非必须使用此存储库中的代码示例。

## 最佳实践
<a name="provision-a-terraform-product-in-aws-service-catalog-by-using-a-code-repository-best-practices"></a>
+ 在通过 Service Catalog 启动产品时配置变量值，而不是在 Terraform 配置文件 (`terraform.tfvars`) 中提供变量的值。
+ 仅向特定用户或管理员授予对产品组合的访问权限。
+ 遵循最低权限原则，并授予执行任务所需的最低权限。有关更多信息，请参阅 AWS Identity and Access Management (IAM) 文档中的[授予最低权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#grant-least-priv)和[安全最佳实践](https://docs.aws.amazon.com/IAM/latest/UserGuide/IAMBestPracticesAndUseCases.html)。

## 操作说明
<a name="provision-a-terraform-product-in-aws-service-catalog-by-using-a-code-repository-epics"></a>

### 设置本地工作站
<a name="set-up-your-local-workstation"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| （可选）安装 Docker。 | 如果要在开发环境中运行这些 AWS Lambda 函数，请安装 Docker。有关说明，请参阅 Docker 文档中的[安装 Docker 引擎](https://docs.docker.com/engine/install/)。 | DevOps 工程师 | 
| 为 Terraform 安装 AWS Service Catalog 引擎。 | 1. 输入以下命令克隆 [AWS Service Catalog Engine for Terraform](https://github.com/aws-samples/service-catalog-engine-for-terraform-os) 存储库。<pre>git clone https://github.com/aws-samples/service-catalog-engine-for-terraform-os.git</pre><br />2. 导航到包含已克隆存储库的根目录。<br />3. 输入如下命令。这将安装引擎。<pre>run ./bin/bash/deploy-tre.sh -r</pre><br />自动安装期间不使用默认配置文件中 AWS 区域 设置的内容。相反，在运行此命令时，您需要提供区域。 | DevOps 工程师，AWS 管理员 | 

### Connect GitHub 存储库
<a name="connect-the-github-repository"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建与 GitHub 存储库的连接。 | 1. 登录 AWS 管理控制台，然后打开**开发者工具**控制台。您可以通过选择诸如 AWS CodePipeline 或之类的服务来访问开发者工具控制台 AWS CodeDeploy。<br />2. 在左侧导航栏上，选择**设置**，然后选择**连接**。<br />3. 选择**创建连接**。<br />4. 选择用于维护 Terraform 源代码的存储库。例如，您可以选择 **Bitbucket **GitHub****、或**GitHub 企业服务器**。<br />5. 输入连接的名称，然后选择**连接**。<br />6. 出现系统提示时，对存储库进行身份验证。<br />身份验证完成后，连接即创建完毕，状态将更改为**活动**。 | AWS 管理员 | 

### 在 Service Catalog 中创建 Terraform 产品
<a name="create-a-terraform-product-in-service-catalog"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建 Service Catalog 产品。 | 1. 打开 [AWS Service Catalog 控制台](https://console.aws.amazon.com/servicecatalog/)。<br />2. 导航到**管理**部分，然后选择**产品列表**。<br />3. 选择**创建产品**。<br />4. 在**创建产品**页面的**产品详细信息**部分，选择**外部**产品类型。Service Catalog 使用此产品类型来支持 Terraform Community Edition 产品。<br />5. 输入 Service Catalog 产品的名称和所有者。<br />6. 选择 “**使用 CodeStar 提供程序指定您的代码存储库**”。<br />7. 输入存储库的以下信息：**使用连接您的提供商 AWS CodeConnections** — 选择您之前创建的连接。**存储库** – 选择存储库。**分支** – 选择分支。**模板文件路径** – 选择存储代码模板文件的路径。文件名应以 `tar.gz` 结尾。<br />8. 在**版本名称和描述**下，提供有关产品版本的信息。<br />9. 选择**创建产品**。 | AWS 管理员 | 
| 创建产品组合。 | 1. 打开 [AWS Service Catalog 控制台](https://console.aws.amazon.com/servicecatalog/)。<br />2. 导航到**管理**部分，然后选择**产品组合**。<br />3. 选择**创建产品组合**。<br />4. 输入以下值：**产品组合名称** – `Sample terraform`**产品组合描述** — `Sample portfolio for Terraform configurations`**所有者** – 您的联系信息，例如电子邮件地址<br />5. 选择**创建**。 | AWS 管理员 | 
| 将 Terraform 产品添加到产品组合中。 | 1. 打开 [AWS Service Catalog 控制台](https://console.aws.amazon.com/servicecatalog/)。<br />2. 导航到**管理**部分，然后选择**产品列表**。<br />3. 选择之前创建的 Terraform 产品。<br />4. 选择**操作**，然后选择**将产品添加到产品组合**。<br />5. 选择 `Sample terraform` 产品组合。<br />6. 选择**将产品添加到产品组合**。 | AWS 管理员 | 
| 创建访问策略。 | 1. 打开 [AWS Identity and Access Management （IAM）控制台](https://console.aws.amazon.com/iam/)。<br />2. 在导航窗格中，选择**策略**。<br />3. 在内容窗格中，选择**创建策略**。<br />4. 选择 **JSON** 选项。<br />5. 在此模式[其他信息](#provision-a-terraform-product-in-aws-service-catalog-by-using-a-code-repository-additional)部分的*访问策略*中，输入示例 JSON 策略。<br />6. 选择**下一步**。<br />7. 在**审核和创建**页面上的**策略名称**框中，输入 `TerraformResourceCreationAndArtifactAccessPolicy`。<br />8. 选择**创建策略**。 | AWS 管理员 | 
| 创建自定义信任策略。 | 1. 打开 [IAM 控制台](https://console.aws.amazon.com/iam/)。<br />2. 在导航窗格中，选择**角色**。<br />3. 选择**创建角色**。<br />4. 对于**可信实体类型**，选择**自定义信任策略**。<br />5. 在 JSON 策略编辑器中，在此模式[其他信息](#provision-a-terraform-product-in-aws-service-catalog-by-using-a-code-repository-additional)部分的*信任策略*中，输入示例 JSON 策略。<br />6. 选择**下一步**。<br />7. 在**权限策略**下，选择您之前创建的 `TerraformResourceCreationAndArtifactAccessPolicy`。<br />8. 选择**下一步**。<br />9. 在**角色详细信息**下的**角色名称**框中，输入 `SCLaunch-product`。  角色名称必须以 `SCLaunch` 开头。<br />10. 选择**创建角色**。 | AWS 管理员 | 
| 向 Service Catalog 产品添加启动约束。 | 1. 以具有管理权限的用户身份登录。 AWS 管理控制台 <br />2. 打开 [AWS Service Catalog 控制台](https://console.aws.amazon.com/servicecatalog/)。<br />3. 在导航窗格中，选择**产品组合**。<br />4. 选择您之前创建的产品组合。<br />5. 在**产品组合详细信息页面**上，选择**约束**选项卡，然后选择**创建约束**。<br />6. 对于**产品**，选择您之前创建的 Terraform 产品。<br />7. 在**启动约束**下的**方法**中，选择**输入角色名称**。<br />8. 在**角色名称**框中，输入 `SCLaunch-product`。<br />9. 选择**创建**。 | AWS 管理员 | 
| 授予对产品的访问权限。 | 1. 打开 [AWS Service Catalog 控制台](https://console.aws.amazon.com/servicecatalog/)。<br />2. 在导航窗格中，选择**产品组合**。<br />3. 选择您之前创建的产品组合。<br />4. 选择**访问权限**选项卡，然后选择**授予访问权限**。<br />5. 选择**角色**选项卡，然后选择应有权部署此产品的角色。<br />6. 选择 **Grant access (授予访问权限)**。 | AWS 管理员 | 
| 启动产品。 | 1. 以有权部署 Service Catalog 产品的用户 AWS 管理控制台 身份登录。<br />2. 打开 [AWS Service Catalog 控制台](https://console.aws.amazon.com/servicecatalog/)。<br />3. 在导航窗格中，选择**产品**。<br />4. 选择您之前创建的产品，然后选择**启动产品**。<br />5. 输入产品名称并定义任何必要的参数。<br />6. 选择**启动产品**。 | DevOps 工程师 | 

### 验证部署
<a name="verify-the-deployment"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 验证部署。 | Service Catalog 配置工作流程有两台 AWS Step Functions 状态机：+ `ManageProvisionedProductStateMachine` – 在预调配新的 Terraform 产品以及更新现有 Terraform 预调配产品时，Service Catalog 会调用此状态机。<br />+ `TerminateProvisionedProductStateMachine` – 在终止现有 Terraform 预调配产品时，Service Catalog 将调用此状态机。<br />您可以检查 `ManageProvisionedProductStateMachine` 状态机的日志，以确认产品已预调配。1. 登录 AWS 管理控制台，然后打开[AWS Step Functions 控制台](https://console.aws.amazon.com/states/home)。<br />2. 在左侧导航面板中，选择**状态机**。<br />3. 选择 `ManageProvisionedProductStateMachine`。<br />4. 在**执行**列表中，输入预调配的产品 ID 以找到您执行项。状态文件后端存储桶名称以 `sc-terraform-engine-state-` 开头。<br />5. 验证账户中是否已创建所有必要的资源。 | DevOps 工程师 | 

### 清理基础设施
<a name="clean-up-infrastructure"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 删除预调配产品。 | 1. 以有权部署 Service Catalog 产品的用户 AWS 管理控制台 身份登录。<br />2. 打开 [AWS Service Catalog 控制台](https://console.aws.amazon.com/servicecatalog/)。<br />3. 在左侧导航栏中，选择**预调配产品**。<br />4. 选择您已创建的产品。<br />5. 在**操作**列表中，选择**终止**。<br />6. 在确认文本框中，输入 `terminate`，然后选择**终止预调配的产品**。<br />7. 重复这些步骤以终止所有预调配的产品。 | DevOps 工程师 | 
| 移除 Terraform 的 AWS Service Catalog 引擎。 | 1. 以具有管理权限的用户身份登录。 AWS 管理控制台 <br />2. 打开 [Amazon Simple Storage Service（Amazon S3）控制台](https://console.aws.amazon.com/s3/)。<br />3. 在导航窗格中，选择**存储桶**。<br />4. 选择 `sc-terraform-engine-logging-XXXX` 存储桶。<br />5. 选择**空白**。<br />6. 对以下存储桶重复第 4–5 步：`sc-terraform-engine-state-XXXX``terraform-engine-bootstrap-XXXX`<br />7. 打开[AWS CloudFormation 控制台](https://console.aws.amazon.com/cloudformation/)，然后验证您的操作是否正确 AWS 区域。<br />8. 在左侧导航栏中，选择**堆栈**。<br />9. 选择 `SAM-TRE`，然后选择**删除**。等待堆栈删除完成。<br />10. 选择 `Bootstrap-TRE`，然后选择**删除**。等待堆栈删除完成。 | AWS 管理员 | 

## 相关资源
<a name="provision-a-terraform-product-in-aws-service-catalog-by-using-a-code-repository-resources"></a>

**AWS 文档**
+ [开始使用 Terraform 产品](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/getstarted-Terraform.html)

**Terraform 文档**
+ [Terraform installation](https://learn.hashicorp.com/tutorials/terraform/install-cli)（Terraform 安装）
+ [Terraform 后端配置](https://developer.hashicorp.com/terraform/language/backend)
+ [Terraform AWS 提供者文档](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)

## 附加信息
<a name="provision-a-terraform-product-in-aws-service-catalog-by-using-a-code-repository-additional"></a>

**访问策略**

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "s3:ExistingObjectTag/servicecatalog:provisioning": "true"
                }
            }
        },
        {
            "Action": [
                "s3:CreateBucket*",
                "s3:DeleteBucket*",
                "s3:Get*",
                "s3:List*",
                "s3:PutBucketTagging"
            ],
            "Resource": "arn:aws:s3:::*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "resource-groups:CreateGroup",
                "resource-groups:ListGroupResources",
                "resource-groups:DeleteGroup",
                "resource-groups:Tag"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "tag:GetResources",
                "tag:GetTagKeys",
                "tag:GetTagValues",
                "tag:TagResources",
                "tag:UntagResources"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}
```

**信任策略**

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "GivePermissionsToServiceCatalog",
            "Effect": "Allow",
            "Principal": {
                "Service": "servicecatalog.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::account_id:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringLike": {
                    "aws:PrincipalArn": [
                        "arn:aws:iam::accounti_id:role/TerraformEngine/TerraformExecutionRole*",
                        "arn:aws:iam::accounti_id:role/TerraformEngine/ServiceCatalogExternalParameterParserRole*",
                        "arn:aws:iam::accounti_id:role/TerraformEngine/ServiceCatalogTerraformOSParameterParserRole*"
                    ]
                }
            }
        }
    ]
}
```