

# チュートリアル: Blue/Green デプロイを使用するサービスの作成
<a name="create-blue-green"></a>

Amazon ECS では、Blue/Green デプロイが Amazon ECS コンソールのサービスの作成ウィザードに統合されています。詳細については、「[Amazon ECS のローリング更新デプロイの作成](create-service-console-v2.md)」を参照してください。

以下のチュートリアルでは、AWS CLI で ブルー/グリーンデプロイタイプを使用する Fargate タスクを含む、Amazon ECS サービスを作成する方法を示します。

**注記**  
ブルー/グリーンデプロイを実行するためのサポートが CloudFormation に追加されています。詳細については、[*AWS CloudFormationユーザーガイド*]の[[CloudFormationを使用した CodeDeploy による Perform Amazon ECS ブルー/グリーンデプロイの実行](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/blue-green.html)]を参照してください。

## 前提条件
<a name="create-blue-green-prereqs"></a>

このチュートリアルでは、以下の前提条件をすでに満たしているものとします。
+ AWS CLI の最新バージョンがインストールされ、設定されていること。AWS CLI のインストールまたはアップグレードの詳細については、「[AWS Command Line Interface のインストール](https://docs.aws.amazon.com/cli/latest/userguide/installing.html)」を参照してください。
+ 「[Amazon ECS を使用するようにセットアップする](get-set-up-for-amazon-ecs.md)」のステップを完了していること。
+ IAM ユーザーに [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM ポリシー例で指定されている必要なアクセス権限があること。
+ VPC およびセキュリティグループが使用できるように作成されていること。詳細については、「[仮想プライベートクラウドを作成する](get-set-up-for-amazon-ecs.md#create-a-vpc)」を参照してください。
+ Amazon ECS CodeDeploy IAM ロールが作成されます。詳細については、「[Amazon ECS CodeDeploy IAM ロール](codedeploy_IAM_role.md)」を参照してください。

## ステップ 1: Application Load Balancer の作成
<a name="create-blue-green-loadbalancer"></a>

ブルー/グリーンデプロイタイプを使用する Amazon ECS サービスは、Application Load Balancer または Network Load Balancer のいずれかを使用する必要があります。このチュートリアルでは、Application Load Balancer を使用します。

**Application Load Balancer を作成するには**

1. [create-load-balancer](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-load-balancer.html) コマンドを使用して、Application Load Balancer を作成します。異なるアベイラビリティーゾーンにある 2 つのサブネット、およびセキュリティグループを指定します。

   ```
   aws elbv2 create-load-balancer \
        --name bluegreen-alb \
        --subnets subnet-abcd1234 subnet-abcd5678 \
        --security-groups sg-abcd1234 \
        --region us-east-1
   ```

   出力には、次の形式でロードバランサーの Amazon リソースネーム (ARN) が含まれます。

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642
   ```

1. ターゲットグループを作成するには、[create-target-group](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-target-group.html) コマンドを使用します。このターゲットグループは、サービスで設定されている元のタスクにトラフィックをルーティングします。

   ```
   aws elbv2 create-target-group \
        --name bluegreentarget1 \
        --protocol HTTP \
        --port 80 \
        --target-type ip \
        --vpc-id vpc-abcd1234 \
        --region us-east-1
   ```

   出力には、以下の形式でターゲットグループの ARN が含まれます。

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4
   ```

1. ターゲットグループにリクエストを転送するデフォルトルールが関連付けられた、ロードバランサーのリスナーを作成するには、[create-listener](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-listener.html) コマンドを使用します。

   ```
   aws elbv2 create-listener \
        --load-balancer-arn arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642 \
        --protocol HTTP \
        --port 80 \
        --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4 \
        --region us-east-1
   ```

   出力には、以下の形式でリスナーの ARN が含まれます。

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:listener/app/bluegreen-alb/e5ba62739c16e642/665750bec1b03bd4
   ```

## ステップ 2: Amazon ECS クラスターを作成する
<a name="create-blue-green-cluster"></a>

[create-cluster](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-cluster.html) コマンドを使用して、使用する`tutorial-bluegreen-cluster`という名前のクラスターを作成します。

```
aws ecs create-cluster \
     --cluster-name tutorial-bluegreen-cluster \
     --region us-east-1
```

出力には、以下の形式でクラスターの ARN が含まれます。

```
arn:aws:ecs:region:aws_account_id:cluster/tutorial-bluegreen-cluster
```

## ステップ 3: タスク定義を登録する
<a name="create-blue-green-taskdef"></a>

[register-task-definition](https://docs.aws.amazon.com/cli/latest/reference/ecs/register-task-definition.html) コマンドを使用して、Fargate と互換性のあるタスク定義を登録します。これには、`awsvpc` ネットワークモードを使用する必要があります。このチュートリアルで使用するタスク定義の例を以下に示します。

まず、以下の内容で `fargate-task.json` というファイルを作成します。タスク実行ロールの ARN を使用していることを確認します。詳細については、「[Amazon ECS タスク実行IAM ロール](task_execution_IAM_role.md)」を参照してください。

```
{
    "family": "sample-fargate", 
    "networkMode": "awsvpc", 
    "containerDefinitions": [
        {
            "name": "sample-app", 
            "image": "public.ecr.aws/docker/library/httpd:latest", 
            "portMappings": [
                {
                    "containerPort": 80, 
                    "hostPort": 80, 
                    "protocol": "tcp"
                }
            ], 
            "essential": true, 
            "entryPoint": [
                "sh",
		"-c"
            ], 
            "command": [
                "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
            ]
        }
    ], 
    "requiresCompatibilities": [
        "FARGATE"
    ], 
    "cpu": "256", 
    "memory": "512"
}
```

次に、作成した `fargate-task.json` ファイルを使用して、タスク定義を登録します。

```
aws ecs register-task-definition \
     --cli-input-json file://fargate-task.json \
     --region us-east-1
```

## ステップ 4: Amazon ECS サービスを作成する
<a name="create-blue-green-service"></a>

サービスを作成するには、[create-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-service.html) コマンドを使用します。

まず、以下の内容で `service-bluegreen.json` というファイルを作成します。

```
{
    "cluster": "tutorial-bluegreen-cluster",
    "serviceName": "service-bluegreen",
    "taskDefinition": "tutorial-task-def",
    "loadBalancers": [
        {
            "targetGroupArn": "arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4",
            "containerName": "sample-app",
            "containerPort": 80
        }
    ],
    "launchType": "FARGATE",
    "schedulingStrategy": "REPLICA",
    "deploymentController": {
        "type": "CODE_DEPLOY"
    },
    "platformVersion": "LATEST",
    "networkConfiguration": {
       "awsvpcConfiguration": {
          "assignPublicIp": "ENABLED",
          "securityGroups": [ "sg-abcd1234" ],
          "subnets": [ "subnet-abcd1234", "subnet-abcd5678" ]
       }
    },
    "desiredCount": 1
}
```

次に、作成した `service-bluegreen.json` ファイルを使用してサービスを作成します。

```
aws ecs create-service \
     --cli-input-json file://service-bluegreen.json \
     --region us-east-1
```

出力には、以下の形式でサービスの ARN が含まれます。

```
arn:aws:ecs:region:aws_account_id:service/service-bluegreen
```

## ステップ 5: AWS CodeDeploy リソースを作成する
<a name="create-blue-green-codedeploy"></a>

次のステップに従って、CodeDeploy アプリケーション、CodeDeploy デプロイグループのApplication Load Balancer ターゲットグループ、および CodeDeploy デプロイグループを作成します。

**CodeDeploy リソースを作成するには**

1. [create-application](https://docs.aws.amazon.com/cli/latest/reference/deploy/create-application.html) コマンドを使用して、CodeDeploy アプリケーションを作成します。`ECS` コンピューティングプラットフォームを指定します。

   ```
   aws deploy create-application \
        --application-name tutorial-bluegreen-app \
        --compute-platform ECS \
        --region us-east-1
   ```

   出力には、以下の形式でアプリケーションの ID が含まれます。

   ```
   {
       "applicationId": "b8e9c1ef-3048-424e-9174-885d7dc9dc11"
   }
   ```

1. [create-target-group](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-target-group.html) コマンドを使用して、CodeDeploy デプロイ グループの作成時に使用される 2 つ目のApplication Load Balancer ターゲットグループを作成します。

   ```
   aws elbv2 create-target-group \
        --name bluegreentarget2 \
        --protocol HTTP \
        --port 80 \
        --target-type ip \
        --vpc-id "vpc-0b6dd82c67d8012a1" \
        --region us-east-1
   ```

   出力には、以下の形式でターゲットグループの ARN が含まれます。

   ```
   arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget2/708d384187a3cfdc
   ```

1. [create-deployment-group](https://docs.aws.amazon.com/cli/latest/reference/deploy/create-deployment-group.html) コマンドを使用して CodeDeploy デプロイ グループを作成します。

   まず、以下の内容で `tutorial-deployment-group.json` というファイルを作成します。この例では、作成したリソースを使用します。`serviceRoleArn` には、Amazon ECS CodeDeploy IAM ロールの ARN を指定します。詳細については、「[Amazon ECS CodeDeploy IAM ロール](codedeploy_IAM_role.md)」を参照してください。

   ```
   {
      "applicationName": "tutorial-bluegreen-app",
      "autoRollbackConfiguration": {
         "enabled": true,
         "events": [ "DEPLOYMENT_FAILURE" ]
      },
      "blueGreenDeploymentConfiguration": {
         "deploymentReadyOption": {
            "actionOnTimeout": "CONTINUE_DEPLOYMENT",
            "waitTimeInMinutes": 0
         },
         "terminateBlueInstancesOnDeploymentSuccess": {
            "action": "TERMINATE",
            "terminationWaitTimeInMinutes": 5
         }
      },
      "deploymentGroupName": "tutorial-bluegreen-dg",
      "deploymentStyle": {
         "deploymentOption": "WITH_TRAFFIC_CONTROL",
         "deploymentType": "BLUE_GREEN"
      },
      "loadBalancerInfo": {
         "targetGroupPairInfoList": [
           {
             "targetGroups": [
                {
                    "name": "bluegreentarget1"
                },
                {
                    "name": "bluegreentarget2"
                }
             ],
             "prodTrafficRoute": {
                 "listenerArns": [
                     "arn:aws:elasticloadbalancing:region:aws_account_id:listener/app/bluegreen-alb/e5ba62739c16e642/665750bec1b03bd4"
                 ]
             }
           }
         ]
      },
      "serviceRoleArn": "arn:aws:iam::aws_account_id:role/ecsCodeDeployRole",
      "ecsServices": [
          {
              "serviceName": "service-bluegreen",
              "clusterName": "tutorial-bluegreen-cluster"
          }
      ]
   }
   ```

   次に、CodeDeploy デプロイ グループを作成します。

   ```
   aws deploy create-deployment-group \
        --cli-input-json file://tutorial-deployment-group.json \
        --region us-east-1
   ```

   出力には、以下の形式でデプロイグループの ID が含まれます。

   ```
   {
       "deploymentGroupId": "6fd9bdc6-dc51-4af5-ba5a-0a4a72431c88"
   }
   ```

## ステップ 6: CodeDeploy デプロイを作成してする
<a name="create-blue-green-verify"></a>

以下のステップを従って、アプリケーション仕様ファイル (AppSpec ファイル) と CodeDeploy デプロイを作成してアップロードします。

**CodeDeploy デプロイを作成してモニタリングするには**

1. 以下の手順を使用して、AppSpec ファイルを作成してアップロードします。

   1. CodeDeploy デプロイグループの内容で `appspec.yaml` というファイルを作成します。この例では、チュートリアルの前半で作成したリソースを使用します。

      ```
      version: 0.0
      Resources:
        - TargetService:
            Type: AWS::ECS::Service
            Properties:
              TaskDefinition: "arn:aws:ecs:region:aws_account_id:task-definition/first-run-task-definition:7"
              LoadBalancerInfo:
                ContainerName: "sample-app"
                ContainerPort: 80
              PlatformVersion: "LATEST"
      ```

   1. [s3 mb](https://docs.aws.amazon.com/cli/latest/reference/s3/mb.html) コマンドを使用して、AppSpec ファイルの Amazon S3 バケットを作成します。

      ```
      aws s3 mb s3://tutorial-bluegreen-bucket
      ```

   1. [s3 cp](https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html) コマンドを使用して、AppSpec ファイルを Amazon S3 バケットにアップロードします。

      ```
      aws s3 cp ./appspec.yaml s3://tutorial-bluegreen-bucket/appspec.yaml
      ```

1. 以下のステップを使用して、CodeDeploy デプロイを作成します。

   1. CodeDeploy デプロイの内容で `create-deployment.json` というファイルを作成します。この例では、チュートリアルの前半で作成したリソースを使用します。

      ```
      {
          "applicationName": "tutorial-bluegreen-app",
          "deploymentGroupName": "tutorial-bluegreen-dg",
          "revision": {
              "revisionType": "S3",
              "s3Location": {
                  "bucket": "tutorial-bluegreen-bucket",
                  "key": "appspec.yaml",
                  "bundleType": "YAML"
              }
          }
      }
      ```

   1. デプロイを作成するには、[create-deployment](https://docs.aws.amazon.com/cli/latest/reference/deploy/create-deployment.html) コマンドを使用します。

      ```
      aws deploy create-deployment \
           --cli-input-json file://create-deployment.json \
           --region us-east-1
      ```

      出力には、以下の形式でデプロイの ID が含まれます。

      ```
      {
          "deploymentId": "d-RPCR1U3TW"
      }
      ```

   1. デプロイの詳細を取得するには、[get-deployment-target](https://docs.aws.amazon.com/cli/latest/reference/deploy/get-deployment-target.html) コマンドで、前の出力からの `deploymentId` を指定します。

      ```
      aws deploy get-deployment-target \
           --deployment-id "d-IMJU3A8TW" \
           --target-id tutorial-bluegreen-cluster:service-bluegreen \
           --region us-east-1
      ```

      以下の出力に示しているように、ステータスが `Succeeded` になるまで、デプロイの詳細が取得され続けます。

      ```
      {
          "deploymentTarget": {
              "deploymentTargetType": "ECSTarget",
              "ecsTarget": {
                  "deploymentId": "d-RPCR1U3TW",
                  "targetId": "tutorial-bluegreen-cluster:service-bluegreen",
                  "targetArn": "arn:aws:ecs:region:aws_account_id:service/service-bluegreen",
                  "lastUpdatedAt": 1543431490.226,
                  "lifecycleEvents": [
                      {
                          "lifecycleEventName": "BeforeInstall",
                          "startTime": 1543431361.022,
                          "endTime": 1543431361.433,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "Install",
                          "startTime": 1543431361.678,
                          "endTime": 1543431485.275,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "AfterInstall",
                          "startTime": 1543431485.52,
                          "endTime": 1543431486.033,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "BeforeAllowTraffic",
                          "startTime": 1543431486.838,
                          "endTime": 1543431487.483,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "AllowTraffic",
                          "startTime": 1543431487.748,
                          "endTime": 1543431488.488,
                          "status": "Succeeded"
                      },
                      {
                          "lifecycleEventName": "AfterAllowTraffic",
                          "startTime": 1543431489.152,
                          "endTime": 1543431489.885,
                          "status": "Succeeded"
                      }
                  ],
                  "status": "Succeeded",
                  "taskSetsInfo": [
                      {
                          "identifer": "ecs-svc/9223370493425779968",
                          "desiredCount": 1,
                          "pendingCount": 0,
                          "runningCount": 1,
                          "status": "ACTIVE",
                          "trafficWeight": 0.0,
                          "targetGroup": {
                              "name": "bluegreentarget1"
                          }
                      },
                      {
                          "identifer": "ecs-svc/9223370493423413672",
                          "desiredCount": 1,
                          "pendingCount": 0,
                          "runningCount": 1,
                          "status": "PRIMARY",
                          "trafficWeight": 100.0,
                          "targetGroup": {
                              "name": "bluegreentarget2"
                          }
                      }
                  ]
              }
          }
      }
      ```

## ステップ 7: クリーンアップする
<a name="create-blue-green-cleanup"></a>

このチュートリアルが終了したら、使用していないリソースに対する料金が発生しないように、チュートリアルに関連付けられたリソースをクリーンアップします。

**チュートリアルに関連付けられたリソースのクリーンアップ**

1. [delete-deployment-group](https://docs.aws.amazon.com/cli/latest/reference/deploy/delete-deployment-group.html) コマンドを使用して、CodeDeploy デプロイグループを削除します。

   ```
   aws deploy delete-deployment-group \
        --application-name tutorial-bluegreen-app \
        --deployment-group-name tutorial-bluegreen-dg \
        --region us-east-1
   ```

1. [delete-application](https://docs.aws.amazon.com/cli/latest/reference/deploy/delete-application.html) コマンドを使用して、 CodeDeploy アプリケーションを削除します。

   ```
   aws deploy delete-application \
        --application-name tutorial-bluegreen-app \
        --region us-east-1
   ```

1. [delete-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/delete-service.html) コマンドを使用して、Amazon ECS サービスを削除します。`--force` フラグを使用すると、タスクがゼロになっていなくてもサービスを削除できます。

   ```
   aws ecs delete-service \
        --service arn:aws:ecs:region:aws_account_id:service/service-bluegreen \
        --force \
        --region us-east-1
   ```

1. [delete-cluster](https://docs.aws.amazon.com/cli/latest/reference/ecs/delete-cluster.html) コマンドを使用して、Amazon ECS クラスターを削除します。

   ```
   aws ecs delete-cluster \
        --cluster tutorial-bluegreen-cluster \
        --region us-east-1
   ```

1. [s3 rm](https://docs.aws.amazon.com/cli/latest/reference/s3/rm.html) コマンドを使用して、Amazon S3 バケットから AppSpec ファイルを削除します。

   ```
   aws s3 rm s3://tutorial-bluegreen-bucket/appspec.yaml
   ```

1. [s3 rb](https://docs.aws.amazon.com/cli/latest/reference/s3/rb.html) コマンドを使用して、 Amazon S3 バケットを削除します。

   ```
   aws s3 rb s3://tutorial-bluegreen-bucket
   ```

1. [delete-load-balancer](https://docs.aws.amazon.com/cli/latest/reference/elbv2/delete-load-balancer.html) コマンドを使用して、Application Load Balancerを削除します。

   ```
   aws elbv2 delete-load-balancer \
        --load-balancer-arn arn:aws:elasticloadbalancing:region:aws_account_id:loadbalancer/app/bluegreen-alb/e5ba62739c16e642 \
        --region us-east-1
   ```

1. [delete-target-group](https://docs.aws.amazon.com/cli/latest/reference/elbv2/delete-target-group.html) コマンドを使用して、2 つのApplication Load Balancer ターゲットグループを削除します。

   ```
   aws elbv2 delete-target-group \
        --target-group-arn arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget1/209a844cd01825a4 \
        --region us-east-1
   ```

   ```
   aws elbv2 delete-target-group \
        --target-group-arn arn:aws:elasticloadbalancing:region:aws_account_id:targetgroup/bluegreentarget2/708d384187a3cfdc \
        --region us-east-1
   ```