

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

# 使用 Image Builder 和 Terraform 为经过强化的容器 EC2 镜像构建管道
<a name="build-a-pipeline-for-hardened-container-images-using-ec2-image-builder-and-terraform"></a>

*Mike Saintcross 和 Andrew Ranes，Amazon Web Services*

## Summary
<a name="build-a-pipeline-for-hardened-container-images-using-ec2-image-builder-and-terraform-summary"></a>

这种模式构建了一个 [EC2 Image Builder 管道](https://docs.aws.amazon.com/imagebuilder/latest/userguide/start-build-image-pipeline.html)，用于生成经过强化的 [Amazon Linux 2](https://aws.amazon.com/amazon-linux-2/) 基础容器映像。Terraform 用作基础设施即代码（IaC）工具，它可配置和预调配基础设施用于创建经过强化的容器映像。该配方可帮助您部署基于 Docker 的 Amazon Linux 2 容器映像，该映像已根据 Red Hat Enterprise Linux (RHEL) 7 STIG 版本 3 第 7 版—Medium 进行了强化。（参见 Im EC2 age Builder 文档的 *Linux STIG 组件*部分中的 [2022.2.1 STIG-Build-Linux-Medium 版](https://docs.aws.amazon.com/imagebuilder/latest/userguide/toe-stig.html#linux-os-stig)。） 这被称为*黄金*容器映像。

该版本包括两[ EventBridge 条 Amazon 规则](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-rules.html)。一条规则是，当 [Amazon Inspector 调查发现](https://docs.aws.amazon.com/inspector/latest/user/findings-managing.html)为**高**或**严重**时，将启动容器映像管线，以便替换不安全的映像。这条规则要求同时启用 Amazon Inspector 和 Amazon Elastic Container Registry (Amazon ECR) [增强型扫描](https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning-enhanced.html)。另一条规则在成功将映像推送到 Amazon ECR 存储库后，向 Amazon Simple Queue Service (Amazon SQS) [队列](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-queue-types.html)发送通知，以帮助您使用最新的容器映像。

**注意**  
即将终止对 Amazon Linux 2 的支持。有关更多信息，请参阅[亚马逊 Linux 2 FAQs](https://aws.amazon.com/amazon-linux-2/faqs/)。

## 先决条件和限制
<a name="build-a-pipeline-for-hardened-container-images-using-ec2-image-builder-and-terraform-prereqs"></a>

**先决条件**
+ 一个 [AWS 账户](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/)，您可在其中部署基础设施。
+ [AWS 命令行界面（AWS CLI）已安装](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)用于设置您的 AWS 凭证以供本地部署。
+ 已按照 Terraform 文档中的[说明](https://developer.hashicorp.com/terraform/tutorials/aws-get-started)[下载](https://developer.hashicorp.com/terraform/downloads) Terraform 并设置。
+ [Git](https://git-scm.com/)（如果您从本地计算机进行预调配）。
+ AWS 账户中的[角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)，可用于创建 AWS 资源。
+ [.tfvars](https://developer.hashicorp.com/terraform/tutorials/configuration-language/variables) 文件中定义的所有变量。 或者，您可在应用 Terraform 配置时定义所有变量。

**限制**
+ 该解决方案创建了一个 Amazon Virtual Private Cloud (Amazon VPC) 基础设施，其中包括一个 [NAT 网关](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html)和一个用于从其私有子网连接互联网的[互联网网关](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html)。您不能使用 [VPC 终端节点](https://docs.aws.amazon.com/whitepapers/latest/aws-privatelink/what-are-vpc-endpoints.html)，因为 [AWS Task Orchestrator 和 Executor () 的引导过程](https://aws.amazon.com/premiumsupport/knowledge-center/image-builder-pipeline-execution-error/)会从AWSTOE互联网上安装 AWS CLI 版本 2。

**产品版本**
+ Amazon Linux 2
+ AWS CLI 版本 1.1 或更高版本

## 架构
<a name="build-a-pipeline-for-hardened-container-images-using-ec2-image-builder-and-terraform-architecture"></a>

**目标技术堆栈**

这种模式创建 43 项资源，包括：
+ 两个 Amazon Simple Storage Service (Amazon S3) [存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html)：一个用于管线组件文件，一个用于服务器访问和 Amazon VPC 流日志
+ [Amazon ECR 存储库](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html)
+ 包含一个公有子网、一个私有子网、一个私有子网、路由表、一个 NAT 网关以及一个互联网网关的虚拟私有云（VPC）
+ I EC2 mage Builder 管道、配方和组件
+ 容器映像
+ AWS Key Management Service (AWS KMS) [密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#kms_keys)，用于映像加密
+ SQS 队列
+ 三个角色：一个用于运行 EC2 Image Builder 管道，一个用于 EC2 Image Builder 的实例配置文件，一个用于 EventBridge 规则
+ 两 EventBridge 条规则

**Terraform 模块结构**

有关源代码，请参阅 GitHub 存储库 [Terraform EC2 Image Builder 容器强化](https://github.com/aws-samples/terraform-ec2-image-builder-container-hardening-pipeline)管道。

```
├── components.tf
├── config.tf
├── dist-config.tf
├── files
│   └──assumption-policy.json
├── hardening-pipeline.tfvars
├── image.tf
├── infr-config.tf
├── infra-network-config.tf
├── kms-key.tf
├── main.tf
├── outputs.tf
├── pipeline.tf
├── recipes.tf
├── roles.tf
├── sec-groups.tf
├── trigger-build.tf
└── variables.tf
```

**模块详细信息**
+ `components.tf` 包含用于上传 `/files` 目录内容的 Amazon S3 上传资源。您也可在此处以模块化方式添加自定义组件 YAML 文件。
+ `/files` 包含用来定义 `components.tf` 中所用组件的 `.yml` 文件。
+ `image.tf` 包含基本映像操作系统的定义。在这里，您可修改不同基础映像管线的定义。
+ `infr-config.tf` 和 `dist-config.tf` 包含启动和分发映像所需最低 AWS 基础设施所需资源。
+ `infra-network-config.tf` 包含要将容器映像部署到的最低 VPC 基础设施。
+ `hardening-pipeline.tfvars` 包含要在应用时所用的 Terraform 变量。
+ `pipeline.tf`在 Terraform 中创建和管理 EC2 Image Builder 管道。
+ `recipes.tf` 是您可以指定不同的组件混合物来创建容器配方的位置。
+ `roles.tf`包含亚马逊弹性计算云 (Amazon) 实例配置文件和管道部署角色的 AWS Identity and Access Management (IAM EC2) 策略定义。
+ `trigger-build.tf`包含 EventBridge 规则和 SQS 队列资源。

**目标架构**

![\[用于为经过强化的容器映像构建管线的架构和工作流程\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/4b16bdfa-4f34-41e9-a69a-d023253c8585/images/23443eca-132f-46ac-98bd-32a9e9359a77.png)


该图说明了以下工作流程：

1. EC2 Image Builder 使用定义的配方构建容器映像，该配方安装操作系统更新并将 RHEL Medium STIG 应用于 Amazon Linux 2 基础映像。

1. 经过强化的映像将发布到私有 Amazon ECR 注册表，成功发布映像后， EventBridge 规则会向 SQS 队列发送一条消息。

1. 如果 Amazon Inspector 配置为增强扫描，它将扫描 Amazon ECR 注册表。

1. 如果 Amazon Inspector 为图像生成了 “**临**界” 或 “**高**” 严重性发现， EventBridge 则规则会触发 EC2 Image Builder 管道再次运行并发布经过强化处理的新图像。

**自动化和扩缩**
+ 此模式描述了如何在计算机上预调配基础设施并构建管线。但是它旨在大规模使用。[与其在本地部署 Terraform 模块，不如在多账户环境中使用它们，例如带有 Account Factory for Terraform](https://aws.amazon.com/blogs/aws/new-aws-control-tower-account-factory-for-terraform/) 环境的 [AWS Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html)。在这种情况下，您应该使用[后端状态 S3 存储桶](https://developer.hashicorp.com/terraform/language/settings/backends/s3)管理 Terraform 状态文件，而不是在本地管理配置状态。
+ 为了扩大使用范围，可将解决方案从 Control Tower 或登录区账户模型部署到一个中央账户，例如共享服务或公共服务账户，并授予消费者账户访问 Amazon ECR 存储库和 AWS KMS 密钥的权限。有关设置的更多信息，请参阅 re:Post 文章[如何允许辅助账户在我的 Amazon ECR 映像存储库中推送或拉取图片？](https://repost.aws/knowledge-center/secondary-account-access-ecr) 例如，在[账户自动售卖机](https://www.hashicorp.com/resources/terraform-landing-zones-for-self-service-multi-aws-at-eventbrite)或 Account Factory for Terraform 中，向每个账户基准或账户自定义基准添加权限，以提供对该 Amazon ECR 存储库和加密密钥的访问权限。
+ 部署容器镜像管道后，您可以使用 Im EC2 age Builder 功能（例如[组件](https://docs.aws.amazon.com/imagebuilder/latest/userguide/manage-components.html)）对其进行修改，这些功能可以帮助您将更多组件打包到 Docker 版本中。
+ 用于加密容器映像的 AWS KMS 密钥应在要使用该映像的账户之间共享。
+ 您可通过复制整个 Terraform 模块并修改以下 `recipes.tf` 属性来添加对其他映像的支持：
  + 将 `parent_image = "amazonlinux:latest"` 修改为其他映像类型。
  + 将 `repository_name` 修改为指向现有的 Amazon ECR 存储库。这将创建另一个管线，该管线将不同的父映像类型部署到您现有的 Amazon ECR 存储库。

## 工具
<a name="build-a-pipeline-for-hardened-container-images-using-ec2-image-builder-and-terraform-tools"></a>

**工具**
+ Terraform（IaC 预调配）
+ Git（如果在本地预调配）
+ AWS CLI 版本 1 或版本 2（如果在本地预调配）

**代码**

此模式的代码位于 GitHub 存储库 [Terraform EC2 Image Builder 容器强化](https://github.com/aws-samples/terraform-ec2-image-builder-container-hardening-pipeline)管道中。要使用示例代码，请按照下一部分中的说明进行操作。

## 操作说明
<a name="build-a-pipeline-for-hardened-container-images-using-ec2-image-builder-and-terraform-epics"></a>

### 预调配基础设施
<a name="provision-the-infrastructure"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 设置本地凭证。 | 设置您的 AWS 临时凭证。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/build-a-pipeline-for-hardened-container-images-using-ec2-image-builder-and-terraform.html) | AWS DevOps | 
| 克隆存储库。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/build-a-pipeline-for-hardened-container-images-using-ec2-image-builder-and-terraform.html) | AWS DevOps | 
| 更新变量。 | 更新 `hardening-pipeline.tfvars` 文件中的变量以匹配您的环境和所需配置。您必须自己提供 `account_id`。但是，您还应该修改其余变量，以适应所需部署。所有变量均为必需项。<pre>account_id     = "<DEPLOYMENT-ACCOUNT-ID>"<br />aws_region     = "us-east-1"<br />vpc_name       = "example-hardening-pipeline-vpc"<br />kms_key_alias = "image-builder-container-key"<br />ec2_iam_role_name = "example-hardening-instance-role"<br />hardening_pipeline_role_name = "example-hardening-pipeline-role"<br />aws_s3_ami_resources_bucket = "example-hardening-ami-resources-bucket-0123"<br />image_name = "example-hardening-al2-container-image"<br />ecr_name = "example-hardening-container-repo"<br />recipe_version = "1.0.0" <br />ebs_root_vol_size = 10</pre>以下是关于每个变量的描述：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/build-a-pipeline-for-hardened-container-images-using-ec2-image-builder-and-terraform.html) | AWS DevOps | 
| 初始化 Terraform。 | 更新变量值后，您可初始化 Terraform 配置目录。初始化配置目录会下载并安装配置中定义的 AWS 提供程序。<pre>terraform init</pre>您应该看到一条消息，指出 Terraform 已成功初始化并标识了已安装的提供程序的版本。 | AWS DevOps | 
| 部署基础设施并创建容器映像。 | 使用以下命令通过使用 `.tfvars` 文件中定义的变量来初始化、验证 Terraform 模块并将其应用于环境：<pre>terraform init && terraform validate && terraform apply -var-file *.tfvars -auto-approve</pre> | AWS DevOps | 
| 自定义容器。 | 在 EC2 Image Builder 部署管道和初始配方后，您可以创建容器配方的新版本。您可以添加 EC2 Image Builder 中可用的 31 个以上组件中的任何一个来自定义容器构建。有关更多信息，请参阅 I EC2 mage Builder 文档中[创建新版本的容器配方](https://docs.aws.amazon.com/imagebuilder/latest/userguide/create-container-recipes.html)的 “*组件*” 部分。 | AWS 管理员 | 

### 验证资源
<a name="validate-resources"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 验证 AWS 基础设施预调配。 | 成功完成第一个 Terraform `apply` 命令后，如果您在本地预调配，则应在本地计算机的终端中看到以下片段：<pre>Apply complete! Resources: 43 added, 0 changed, 0 destroyed.</pre> | AWS DevOps | 
| 验证各个 AWS 基础设施资源。 | 要验证已部署的各个资源，如果您在本地预调配，则可以运行以下命令：<pre>terraform state list</pre>此命令将返回 43 项资源列表。 | AWS DevOps | 

### 删除资源
<a name="remove-resources"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 移除基础设施和容器映像。 | 使用 Terraform 配置后，可运行以下命令来移除资源：<pre>terraform init && terraform validate && terraform destroy -var-file *.tfvars -auto-approve</pre> | AWS DevOps | 

## 问题排查
<a name="build-a-pipeline-for-hardened-container-images-using-ec2-image-builder-and-terraform-troubleshooting"></a>


| 问题 | 解决方案 | 
| --- | --- | 
| 验证提供商凭证时出错 | 在本地计算机上运行 Terraform `apply` 或 `destroy` 命令时，可能会遇到类似以下内容的错误：<pre>Error: configuring Terraform AWS Provider: error validating provider <br />credentials: error calling sts:GetCallerIdentity: operation error STS: <br />GetCallerIdentity, https response error StatusCode: 403, RequestID: <br />123456a9-fbc1-40ed-b8d8-513d0133ba7f, api error InvalidClientTokenId: <br />The security token included in the request is invalid.</pre>此错误是由本地计算机配置中使用的凭证安全令牌过期引起的。要解决该错误，请参阅 AWS CLI 文档中的[设置和查看配置设置](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-methods)。 | 

## 相关资源
<a name="build-a-pipeline-for-hardened-container-images-using-ec2-image-builder-and-terraform-resources"></a>
+ [Terraform EC2 Image Builder 容器强化管道（存储库](https://github.com/aws-samples/terraform-ec2-image-builder-container-hardening-pipeline)）GitHub 
+ [EC2 Image Builder 文档](https://docs.aws.amazon.com/imagebuilder/latest/userguide/what-is-image-builder.html)
+ [适用于 Terraform 的 AWS Control Tower Account Factory](https://aws.amazon.com/blogs/aws/new-aws-control-tower-account-factory-for-terraform/)（AWS Blog 文章）
+ [后端状态 S3 存储桶](https://developer.hashicorp.com/terraform/language/settings/backends/s3)（Terraform 文档）
+ [安装或更新最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)（AWS CLI 文档）
+ [下载 Terraform](https://developer.hashicorp.com/terraform/downloads)