

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 透過 EC2 Image Builder 建置自訂的 Amazon ECS 最佳化 AMI
<a name="image-builder-tutorial"></a>

AWS 建議您使用 Amazon ECS 最佳化 AMIs因為它們已預先設定執行容器工作負載的需求和建議。在某些情況下，您可能需要自訂 AMI 來新增額外軟體。您可以透過 EC2 Image Builder 來建立、管理與部署伺服器映像。您將保留帳戶中所建立自訂映像的所有權。您可透過 EC2 Image Builder 管道，自動化執行映像的更新與系統修補作業；也可以使用獨立命令，建立包含所定義組態資源的映像。

您需要為映像建立一份配方。該配方包含父映像以及任何額外元件。您也需要建立一個用於分發自訂 AMI 的管道。

您需要為映像建立一份配方。Image Builder 映像配方是一個文件，用於定義基礎映像與要套用至基礎映像的元件，以便產生輸出 AMI 映像所需的組態。您也需要建立一個用於分發自訂 AMI 的管道。如需詳細資訊，請參閱 *EC2 Image Builder User Guide* 中的 [How EC2 Image Builder works](https://docs.aws.amazon.com/imagebuilder/latest/userguide/how-image-builder-works.html)。

建議使用下列任一 Amazon ECS 最佳化 AMI 作為 EC2 Image Builder 中的「父映像」：
+ Linux
  + Amazon ECS 最佳化 AL2023 x86
  + Amazon ECS 最佳化 Amazon Linux 2023 (arm64) AMI
  + Amazon ECS 最佳化 Amazon Linux 2 核心 5 AMI
  + Amazon ECS 最佳化 Amazon Linux 2 x86 AMI
+ Windows
  + Amazon ECS 最佳化 Windows 2022 Full x86
  + Amazon ECS 最佳化 Windows 2022 Core x86
  + Amazon ECS 最佳化 Windows 2019 Full x86
  + Amazon ECS 最佳化 Windows 2019 Core x86
  + Amazon ECS 最佳化 Windows 2016 Full x86

我們也建議選取「使用最新可用的作業系統版本」。該管道將對父映像採用語意版本控制，此舉有助於在自動排程任務中偵測相依性更新。如需詳細資訊，請參閱 *EC2 Image Builder User Guide* 中的 [Semantic versioning](https://docs.aws.amazon.com/imagebuilder/latest/userguide/ibhow-semantic-versioning.html)。

AWS 會使用安全性修補程式和新的容器代理程式版本定期更新 Amazon ECS 最佳化 AMI 映像。在映像配方中使用 AMI ID 作為父映像時，需定期檢查是否有父映像的更新。若有更新，必須使用更新後的 AMI 建立新的配方版本。此舉可確保自訂映像包含最新版本的父映像。如需有關如何建立工作流程來使用新建立的 AMI 自動更新 Amazon ECS 叢集中 EC2 執行個體的資訊，請參閱 [How to create an AMI hardening pipeline and automate updates to your ECS instance fleet](https://aws.amazon.com/blogs/security/how-to-create-an-ami-hardening-pipeline-and-automate-updates-to-your-ecs-instance-fleet/)。

您也可以指定透過受管 EC2 Image Builder 管道發布之父映像的 Amazon Resource Name (ARN)。Amazon 會透過受管管道，定期發布 Amazon ECS 最佳化 AMI 映像。這些映像可公開存取。您必須具備正確的許可，才能存取映像。在 Image Builder 配方中使用映像 ARN 而非 AMI 時，管道會在每次執行時自動使用最新版本的父映像。此方法可免除每次更新時手動建立新配方版本的需求。

## 清理 Amazon ECS 最佳化 AMI
<a name="cleanup-ecs-optimized-ami"></a>

使用 Amazon ECS 最佳化 AMI 作為父映像時，必須清理該映像，以防止暫時性問題。Amazon ECS 最佳化 AMI 已預先設定，可讓 Amazon ECS 代理程式自動啟動，並作為容器執行個體向 Amazon ECS 註冊。若未適當清理就將其用作基礎映像，可能會導致自訂 AMI 出現問題。

若要清理該映像以供日後使用，請建立執行下列命令的元件，停止 ECS-init 套件和 Docker 程序：

```
sudo systemctl stop ecs
sudo systemctl stop docker
```

從目前的執行個體中移除所有日誌檔案，避免在儲存映像時預留這些檔案。使用 [Security best practices for EC2 Image Builder](https://docs.aws.amazon.com/imagebuilder/latest/userguide/security-best-practices.html) 中的範例指令碼，從執行個體清理各種檔案。

若要清理 Amazon ECS 特定資料，請執行下列命令：

```
sudo rm -rf /var/log/ecs/*
sudo rm /var/lib/ecs/data/agent.db
```

如需建立自訂 Amazon ECS 最佳化 AMIs 的詳細資訊，請參閱[如何從 Amazon ECS 最佳化 AMI 建立自訂 AMI？](https://forums.aws.amazon.com/knowledge-center/ecs-create-custom-amis/) AWS 知識中心的 。

## 在基礎結構即程式碼 (IaC) 中使用映像 ARN
<a name="infrastructure-as-code-arn"></a>

您可以使用 EC2 Image Builder 主控台或基礎設施做為程式碼 （例如 CloudFormation) 或 AWS SDK 來設定配方。當您在配方中指定父系映像時，您可以指定 EC2 AMI ID、映像建置器映像 ARN、 AWS Marketplace 產品 ID 或容器映像。 AWS 會公開發佈 Amazon ECS 最佳化 AMI 的 AMI IDs 和映像建置器映像 AMIs ARNs。映像 ARN 的格式如下：

```
arn:${Partition}:imagebuilder:${Region}:${Account}:image/${ImageName}/${ImageVersion}
```

`ImageVersion` 採用下列格式。將 {{major}}、{{minor}} 與 {{patch}} 分別取代為最新值。

```
<{{major}}>.<{{minor}}>.<{{patch}}>
```

您可以將 `major`、`minor` 與 `patch` 取代為特定值，也可以使用映像的無版本 ARN，如此一來，管道就能總是與父映像的最新版本保持同步。無版本 ARN 使用萬用字元格式 ‘x.x.x’ 來表示映像版本。此方法可讓 Image Builder 服務自動解析至映像的最新版本。使用無版本 ARN 可確保參考一律指向可用的最新映像，簡化在部署中維護最新映像的程序。透過主控台建立配方時，EC2 Image Builder 會自動識別父映像的 ARN。透過基礎結構即程式碼 (IaC) 建立配方時，必須自行識別 ARN，並選取所需的映像版本，或使用無版本 ARN 指定可用的最新映像。建議您建立自動化指令碼來篩選並僅顯示符合條件的映像。下列 Python 指令碼示範如何擷取 Amazon ECS 最佳化 AMI 的清單。

指令碼接受兩個選用引數：`owner` 與 `platform`，預設值分別為 "Amazon" 與 "Windows"。owner 引數的有效值包括：`Self`、`Amazon`、`Shared` 與 `ThirdParty`。platform 引數的有效值為 `Windows` 與 `Linux`。例如，若執行指令碼時，將 `owner` 引數設定為 `Amazon`、`platform` 引數設定為 `Linux`，該指令碼會產生一份由 Amazon 發布的映像清單，內含 Amazon ECS 最佳化映像。

```
import boto3
import argparse

def list_images(owner, platform):
    # Create a Boto3 session
    session = boto3.Session()
    
    # Create an EC2 Image Builder client
    client = session.client('imagebuilder')

    # Define the initial request parameters
    request_params = {
        'owner': owner,
        'filters': [
            {
                'name': 'platform',
                'values': [platform]
            }
        ]
    }

    # Initialize the results list
    all_images = []

    # Get the initial response with the first page of results
    response = client.list_images(**request_params)

    # Extract images from the response
    all_images.extend(response['imageVersionList'])

    # While 'nextToken' is present, continue paginating
    while 'nextToken' in response and response['nextToken']:
        # Update the token for the next request
        request_params['nextToken'] = response['nextToken']

        # Get the next page of results
        response = client.list_images(**request_params)

        # Extract images from the response
        all_images.extend(response['imageVersionList'])

    return all_images

def main():
    # Initialize the parser
    parser = argparse.ArgumentParser(description="List AWS images based on owner and platform")
    
    # Add the parameters/arguments
    parser.add_argument("--owner", default="Amazon", help="The owner of the images. Default is 'Amazon'.")
    parser.add_argument("--platform", default="Windows", help="The platform type of the images. Default is 'Windows'.")

    # Parse the arguments
    args = parser.parse_args()

    # Retrieve all images based on the provided owner and platform
    images = list_images(args.owner, args.platform)

    # Print the details of the images
    for image in images:
        print(f"Name: {image['name']}, Version: {image['version']}, ARN: {image['arn']}")

if __name__ == "__main__":
    main()
```

## 搭配 使用映像 ARN CloudFormation
<a name="arn-with-cloudformation"></a>

Image Builder 映像配方是一份藍圖，其中指定了實現輸出映像的目標組態所需的父映像與元件。您需要使用 `AWS::ImageBuilder::ImageRecipe` 資源。將 `ParentImage` 值設定為映像 ARN。請使用目標映像的無版本 ARN，確保管道一律使用最新版本的映像。例如 `arn:aws:imagebuilder:us-east-1:aws:image/amazon-linux-2023-ecs-optimized-x86/x.x.x`。下列 `AWS::ImageBuilder::ImageRecipe` 資源定義使用 Amazon 受管映像 ARN：

```
ECSRecipe:
    Type: AWS::ImageBuilder::ImageRecipe
    Properties:
      Name: MyRecipe
      Version: '1.0.0'
      Components:
        - ComponentArn: [<The component arns of the image recipe>]
      ParentImage: "arn:aws:imagebuilder:us-east-1:aws:image/amazon-linux-2023-ecs-optimized-x86/x.x.x"
```

如需有關 [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html) 資源的詳細資訊，請參閱 *AWS CloudFormation User Guide*。

您可以透過設定 `AWS::ImageBuilder::ImagePipeline` 資源的 `Schedule` 屬性，在管道中自動建立新映像。排程包含開始條件與 Cron 表達式。如需詳細資訊，請參閱《AWS CloudFormation 使用者指南》**中的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html)。

 下列 `AWS::ImageBuilder::ImagePipeline` 範例中，管道會於每日協調世界時 (UTC) 上午 10:00 執行一次建置作業。設定下列 `Schedule` 值：
+ 將 `PipelineExecutionStartCondition` 設定為 `EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE`。僅當父映像、元件等依賴資源 (其語意版本中使用萬用字元 ‘x’) 發生更新時，才會啟動建置作業。此設定可確保建置作業包含這些資源的最新更新。
+ 將 ScheduleExpression 設定為 Cron 表達式 `(0 10 * * ? *)`。

```
ECSPipeline:
    Type: AWS::ImageBuilder::ImagePipeline
    Properties:
      Name: my-pipeline
      ImageRecipeArn: <arn of the recipe you created in previous step>
      InfrastructureConfigurationArn: <ARN of the infrastructure configuration associated with this image pipeline>
      Schedule:
        PipelineExecutionStartCondition: EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE
        ScheduleExpression: 'cron(0 10 * * ? *)'
```

## 在 Terraform 中使用映像 ARN
<a name="arn-with-terraform"></a>

在 Terraform 中指定管道父映像及排程的方法，與 AWS CloudFormation中的方法一致。您需要使用 `aws_imagebuilder_image_recipe` 資源。將 `parent_image` 值設定為映像 ARN。請使用目標映像的無版本 ARN，確保管道一律使用最新版本的映像。如需詳細資訊，請參閱 Terraform 文件中的 [https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_recipe#argument-reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_recipe#argument-reference)。

在 `aws_imagebuilder_image_pipeline resource` 的排程組態區塊中，將 `schedule_expression` 引數值設定為您選擇的 Cron 表達式 (用於指定管道的執行頻率)，並將 `pipeline_execution_start_condition` 設定為 `EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE`。如需詳細資訊，請參閱 Terraform 文件中的 [https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_pipeline#argument-reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_pipeline#argument-reference)。