

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

# 教學課程：使用 CodePipeline 進行 Amazon ECS 標準部署
<a name="ecs-cd-pipeline"></a>

本教學課程可協助您使用 CodePipeline 的 Amazon ECS 建立完整的end-to-end持續部署 (CD) 管道。

**重要**  
在主控台中建立管道時，CodePipeline 將使用 S3 成品儲存貯體做為成品。（這與用於 S3 來源動作的 儲存貯體不同。) 如果 S3 成品儲存貯體位於與管道帳戶不同的帳戶中，請確定 S3 成品儲存貯體由 所擁有 AWS 帳戶 ，安全且可靠。

**注意**  
本教學課程適用於 CodePipeline 的 Amazon ECS 標準部署動作。如需在 CodePipeline 中使用 Amazon ECS 到 CodeDeploy 藍/綠部署動作的教學課程，請參閱 [教學課程：使用 Amazon ECR 來源和 ECS-to-CodeDeploy 部署建立管道](tutorials-ecs-ecr-codedeploy.md)。 CodePipeline

**注意**  
本教學課程適用於具有來源動作之 CodePipeline 的 Amazon ECS 標準部署動作。如需使用 Amazon ECSstandard 部署動作以及 CodePipeline 中的 ECRBuildAndPublish 建置動作來推送映像的教學課程，請參閱 [教學課程：使用 CodePipeline (V2 類型） 建置 Docker 映像並將其推送至 Amazon ECR](tutorials-ecr-build-publish.md)。

## 先決條件
<a name="ecs-cd-prereqs"></a>

您必須先有幾個資源，才能使用此教學來建立 CD 管道。以下是在開始使用前需準備的事項：

**注意**  
所有這些資源都應在相同區域內建立 AWS 。
+ 來源控制儲存庫 （本教學課程使用 CodeCommit) 搭配您的 Dockerfile 和應用程式來源。如需詳細資訊，請參閱*AWS CodeCommit 《 使用者指南*》中的[建立 CodeCommit 儲存庫](https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-create-repository.html)。
+ Docker 映像儲存庫 （本教學課程使用 Amazon ECR)，其中包含您從 Dockerfile 和應用程式來源建置的映像。如需詳細資訊，請參閱《*Amazon Elastic Container Registry 使用者指南*》中的[建立儲存庫](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html)和[推送映像](https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html)。
+ 參考映像儲存庫中託管之 Docker 映像的 Amazon ECS 任務定義。如需詳細資訊，請參閱《*Amazon Elastic Container Service 開發人員指南*》中的[建立任務定義](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create-task-definition.html)。
**重要**  
CodePipeline 的 Amazon ECS 標準部署動作會根據 Amazon ECS 服務所使用的修訂來建立任務定義的專屬修訂。如果您為任務定義建立新的修訂，但未更新 Amazon ECS 服務，部署動作會忽略這些修訂。

  以下是本教學課程使用的範例任務定義。您用於 `name`和 的值`family`將用於建置規格檔案的下一個步驟。

  ```
  {
    "ipcMode": null,
    "executionRoleArn": "{{role_ARN}}",
    "containerDefinitions": [
      {
        "dnsSearchDomains": null,
        "environmentFiles": null,
        "logConfiguration": {
          "logDriver": "awslogs",
          "secretOptions": null,
          "options": {
            "awslogs-group": "/ecs/{{hello-world}}",
            "awslogs-region": "us-west-2",
            "awslogs-stream-prefix": "ecs"
          }
        },
        "entryPoint": null,
        "portMappings": [
          {
            "hostPort": 80,
            "protocol": "tcp",
            "containerPort": 80
          }
        ],
        "command": null,
        "linuxParameters": null,
        "cpu": 0,
        "environment": [],
        "resourceRequirements": null,
        "ulimits": null,
        "dnsServers": null,
        "mountPoints": [],
        "workingDirectory": null,
        "secrets": null,
        "dockerSecurityOptions": null,
        "memory": null,
        "memoryReservation": 128,
        "volumesFrom": [],
        "stopTimeout": null,
        "image": "{{image_name}}",
        "startTimeout": null,
        "firelensConfiguration": null,
        "dependsOn": null,
        "disableNetworking": null,
        "interactive": null,
        "healthCheck": null,
        "essential": true,
        "links": null,
        "hostname": null,
        "extraHosts": null,
        "pseudoTerminal": null,
        "user": null,
        "readonlyRootFilesystem": null,
        "dockerLabels": null,
        "systemControls": null,
        "privileged": null,
        "name": "{{hello-world}}"
      }
    ],
    "placementConstraints": [],
    "memory": "2048",
    "taskRoleArn": null,
    "compatibilities": [
      "EC2",
      "FARGATE"
    ],
    "taskDefinitionArn": "{{ARN}}",
    "family": "{{hello-world}}",
    "requiresAttributes": [],
    "pidMode": null,
    "requiresCompatibilities": [
      "FARGATE"
    ],
    "networkMode": "awsvpc",
    "cpu": "1024",
    "revision": 1,
    "status": "ACTIVE",
    "inferenceAccelerators": null,
    "proxyConfiguration": null,
    "volumes": []
  }
  ```
+ 執行使用您先前提及之任務定義的服務的 Amazon ECS 叢集。如需詳細資訊，請參閱《Amazon Elastic Container Service 開發人員指南》中的[建立叢集](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html)和[建立](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/create-service-console-v2.html)服務。 **

滿足這些先決條件之後，即可繼續教學並建立 CD 管道。

## 步驟 1：將組建規格檔案新增至來源儲存庫
<a name="cd-buildspec"></a>

本教學課程使用 CodeBuild 建置您的 Docker 映像並將映像推送至 Amazon ECR。將`buildspec.yml`檔案新增至您的原始程式碼儲存庫，以告知 CodeBuild 如何執行此操作。下面的範例組建規格執行下列動作：
+ 預先建置階段：
  + 登入 Amazon ECR。
  + 將儲存庫 URI 設定為 ECR 映像，並新增具有來源 Git 遞交 ID 之前七個字元的映像標籤。
+ 建置階段：
  + 建置 Docker 影像，並將映像標記為 `latest` 且具有 Git 遞交 ID。
+ 後置建置階段：
  + 使用兩個標籤將映像推送至 ECR 儲存庫。
  + 在具有 Amazon ECS 服務容器名稱和映像和標籤的建置根`imagedefinitions.json`中寫入名為 的檔案。您 CD 管道的部署階段使用此資訊來建立服務之任務定義的新修訂，接著將服務更新為使用新的任務定義。`imagedefinitions.json` 是 ECS 任務工作者所需的檔案。

貼上此範例文字以建立 `buildspec.yml` 檔案，並取代映像和任務定義的值。此文字使用範例帳戶 ID 111122223333。

```
version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-west-2.amazonaws.com
      - REPOSITORY_URI=012345678910.dkr.ecr.us-west-2.amazonaws.com/hello-world
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - echo Writing image definitions file...
      - printf '[{"name":"hello-world","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
    files: imagedefinitions.json
```

組建規格是針對 中提供的範例任務定義所撰寫[先決條件](#ecs-cd-prereqs)，由 Amazon ECS 服務在本教學課程中使用。`REPOSITORY_URI` 值對應至 `image` 儲存庫 (不含任何映像標籤)，而接近檔案結尾的 `{{hello-world}}` 值對應至服務任務定義中的容器名稱。

**將 `buildspec.yml` 檔案新增至來源儲存庫**

1. 開啟文字編輯器，然後將上面的建置規格複製並貼入新的檔案。

1. 將`REPOSITORY_URI`值 (`{{012345678910.dkr.ecr.us-west-2.amazonaws.com/hello-world}}`) 取代為您的 Docker 映像的 Amazon ECR 儲存庫 URI （不含任何映像標籤）。將 `{{hello-world}}` 取代為服務任務定義中參考您 Docker 影像的容器名稱。

1. 遞交您的 `buildspec.yml` 檔案並將之推送至來源儲存庫。

   1. 新增檔案。

      ```
      git add .
      ```

   1. 遞交變更。

      ```
      git commit -m "Adding build specification."
      ```

   1. 推送認可。

      ```
      git push
      ```

## 步驟 2：建立持續部署管道
<a name="pipeline-wizard"></a>

使用 CodePipeline 精靈建立管道階段，並將來源儲存庫連線至 ECS 服務。

**建立管道**

1. 前往 [https://console.aws.amazon.com/codepipeline/](https://console.aws.amazon.com/codepipeline/) 開啟 CodePipeline 主控台。

1. 在 **Welcome** (歡迎使用) 頁面上，選擇 **Create pipeline** (建立管道)。

   如果這是您第一次使用 CodePipeline，則會顯示簡介頁面，而不是**歡迎**。選擇 **Get Started Now** (立即開始)。

1. 在**步驟 1：選擇建立選項**頁面的**建立選項**下，選擇**建置自訂管道**選項。選擇**下一步**。

1. 在**步驟 2：選擇管道設定**中，在**管道名稱**中輸入管道的名稱。在此教學中，管道名稱為 **hello-world**。

1. 在**管道類型**中，將預設選擇保留在 **V2**。管道類型在特性和價格方面有所不同。如需詳細資訊，請參閱[管道類型](pipeline-types.md)。選擇**下一步**。

1. 在**步驟 3：新增來源階段**頁面上，針對**來源提供者**選擇 ** AWS CodeCommit**。

   1. 針對**儲存庫名稱**，選擇要用作管道來源位置的 CodeCommit 儲存庫名稱。

   1. 針對 **Branch name (分支名稱)**，選擇要使用的分支，然後選擇 **Next (下一步)**。

1. 在**步驟 4：新增建置階段**頁面上，針對**建置提供者**選擇 **AWS CodeBuild**，然後選擇**建立專案**。

   1. 針對 **Project name** (專案名稱)，選擇您組建專案的唯一名稱。在此教學中，專案名稱為 **hello-world**。

   1. 針對 **Environment image (環境映像)**，選擇 **Managed image (受管映像)**。

   1. 針對 **Operating system** (作業系統)，請選擇 **Amazon Linux 2**。

   1. 針對 **Runtime(s) (執行時間)**，選擇 **Standard (標準)**。

   1. 針對**映像**，選擇 **`aws/codebuild/amazonlinux2-x86_64-standard:3.0`**。

   1. 針對 **Image version (映像版本)** 和 **Environment type (環境類型)**，請使用預設值。

   1. 選取 **Enable this flag if you want to build Docker images or want your builds to get elevated privileges (若想建置 Docker 影像或讓您的建置提升權限，請啟用此標記)**。

   1. 取消選取 **CloudWatch logs (CloudWatch 日誌)**。您可能需要展開**進階**。

   1. 選擇 **Continue to CodePipeline (繼續 CodePipeline)**。

   1. 選擇**下一步**。
**注意**  
精靈會為您的建置專案建立 CodeBuild 服務角色，稱為 **codebuild-{{build-project-name}}-service-role**。請記下此角色名稱，稍後再新增 Amazon ECR 許可。

1. 在**步驟 5：新增部署階段**頁面上，針對**部署提供者**選擇 **Amazon ECS**。

   1. 針對**叢集名稱**，選擇服務執行所在的 Amazon ECS 叢集。在此教學中，叢集是 **default**。

   1. 針對 **Service name (服務名稱)**，選擇要更新的服務，然後選擇 **Next (下一步)**。在此教學中，服務名稱為 **hello-world**。

1. 在 **Step 6: Review** (步驟 6：檢閱) 頁面上，檢閱您的管道組態，然後選擇 **Create pipeline** (建立管道) 來建立管道。
**注意**  
現在已建立管道，將會嘗試執行不同的管道階段。不過，精靈建立的預設 CodeBuild 角色沒有執行 `buildspec.yml` 檔案中包含之所有命令的許可，因此建置階段會失敗。下節會新增建置階段的許可。

## 步驟 3：將 Amazon ECR 許可新增至 CodeBuild 角色
<a name="code-build-perms"></a>

CodePipeline 精靈為 CodeBuild 組建專案建立 IAM 角色，稱為 **codebuild-{{build-project-name}}-service-role**。在本教學課程中，名稱為 **codebuild-hello-world-service-role**。由於 `buildspec.yml` 檔案會呼叫 Amazon ECR API 操作，因此該角色必須具有允許進行這些 Amazon ECR 呼叫許可的政策。下列程序可協助您將適當的許可連接至角色。

**將 Amazon ECR 許可新增至 CodeBuild 角色**

1. 前往 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 開啟 IAM 主控台。

1. 在左側導覽窗格中，選擇 **Roles** (角色)。

1. 在搜尋方塊中，輸入 **codebuild-**，然後選擇 CodePipeline 精靈建立的角色。在此教學中，角色名稱為 **codebuild-hello-world-service-role**。

1. 在 **Summary (摘要)** 頁面上，選擇 **Attach policies (連接政策)**。

1. 選取 **AmazonEC2ContainerRegistryPowerUser** 政策左側的方塊，然後選擇 **Attach policy** (連接政策)。

## 步驟 4：測試管道
<a name="commit-change"></a>

您的管道應具備執行end-to-end原生 AWS 持續部署所需的一切。現在，將程式碼變更推送至來源儲存庫，以測試其功能。

**測試管道**

1. 對設定的來源儲存庫進行程式碼變更、遞交並推送變更。

1. 前往 [https://console.aws.amazon.com/codepipeline/](https://console.aws.amazon.com/codepipeline/) 開啟 CodePipeline 主控台。

1. 從清單中選擇管道。

1. 觀看管道階段的管道進度。您的管道應該完成，Amazon ECS 服務會執行從程式碼變更建立的 Docker 映像。