ECS で複数のサービスを 1 個の ALB に共有してコスト最適化を実施する (異なるドメイン)

# はじめに

1 個の ALB を複数の ECS サービスで共有したい時ありませんか？私はあります。ECS サービスごとに ALB を立てると、ALB そのものの料金が気になったりしますし、[Public IPv4 アドレスの新しい料金について](https://aws.amazon.com/jp/blogs/news/identify-and-optimize-public-ipv4-address-usage-on-aws/)も気になります。

![image-20230905223453028.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/48dcbe07-f02e-5aed-4860-d5ef98a6f2ec.png)



そこで、ALB を共有してコスト最適化をする選択肢があります。ここで疑問に思ったのが、ECS のデプロイ方式には、Blue/Green Deployment や Rolling Update がありますが、ALB を共有した時に問題なく動作するのか不安でした。結果、動作検証して問題なく動いたので、その設定方法などを紹介します。この記事は Blue/Green Deployment で ALB を共有する方法を紹介します。



# 忙しい人に向けて

- 1 個の ALB を複数の ECS Service で共有してコスト最適化を図る
- ECS のデプロイタイプについて、Rolling Update・Blue/Green Deployment の両方とも可能
- Blue/Green Deployment は GUI を使った設定は出来ないので、AWS CLI や CloudFormations などの API 経由で行う



# ALB を共有する際の上限について

ALB を複数のサービスで共有する際に、認識した方がよい上限についてです。ALB の Service Quota を全般的にご確認いただいた方が良いですが、とくに意識した方が良いと思うものを以下に記載します。

- Application Load Balancer あたりの証明書 : 25
- Application Load Balancer あたりのターゲットグループ : 100
- Application Load Balancer あたりのルール (デフォルトルールを除く) : 100

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-limits.html



ACM で証明書を発行する and ホストヘッダーを使用し異なるドメインを利用する場合は、25 ドメインが上限となる場合があります。上限緩和申請が可能なものもありますが、ある程度の数で ALB を分割するのも良いと思います。



# 構成図

次の構成図のように、ホストヘッダーを使い異なるドメインへのアクセスを利用しながら、ALB を共有する構成を確認していきます。ECS Service 1 と 2 の両方で Blue/Green の構成を作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/7ae03386-4579-b226-0b26-eca64aa1732b.png)



# ALB の作成

まず共有する ALB を作成します。

![image-20230905132242613.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/3acc560a-5178-2207-dc87-5c6cc279846f.png)



ALB を選択して Create

![image-20230905132302808.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/589a118c-d78c-5f2b-c067-9fb56dc38d71.png)



ALB のパラメータを指定します。ターゲットグループは、この後の手順で削除するので、適当にダミーを指定します。

![image-20230905171858721.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/28241221-f256-6b09-220f-4254b6c86dcb.png)



ダミーのリスナーは削除します。

![image-20230905134915973.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/9be057dc-6b2e-5b87-5a3f-731ecc866169.png)



# ECR にコンテナイメージを作成

動作確認に必要な 2 種類 x 2 バージョンのコンテナイメージを ECR に格納します。



App1 のコンテナイメージ

![image-20230905160039743.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/96f8acfe-2532-3a74-be43-607141ea9d24.png)



App2 のコンテナイメージ

![image-20230905160027426.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/df69da69-d901-0c68-97ba-9e93b54414a6.png)



# タスク定義作成

ECS で利用するタスク定義を作成します。

![image-20230905135640434.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/8b643dc9-1196-dd91-693f-5335623d13db.png)



Create

app01-ver1

![image-20230905161514435.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/48f7cbc9-cf22-283d-9383-4919fcc605fa.png)



同様に、以下のタスク定義も作成します。

- app1-ver2
- app2-ver1
- app2-ver2



# ECS Service 1 個目に関する設定

ECS Service 1 個目を作成し、Blue/Green Deployment を有効化していきます。

## Blue/Green 用の Target Group を 2 個作成し、ALB に紐づけ

AWS CLI から作成

1 個目

```
aws elbv2 create-target-group \
     --name hostbased-bluegreen-app01-a \
     --protocol HTTP \
     --port 80 \
     --target-type ip \
     --vpc-id vpc-0b8b2123a16d03528 \
     --region ap-northeast-1
```



2 個目

```
aws elbv2 create-target-group \
     --name hostbased-bluegreen-app01-b \
     --protocol HTTP \
     --port 80 \
     --target-type ip \
     --vpc-id vpc-0b8b2123a16d03528 \
     --region ap-northeast-1
```



1 個目の Target Group を、ALB のリスナーに紐づける

```
aws elbv2 create-listener \
     --load-balancer-arn arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxxxx:loadbalancer/app/ecs-hostbased-bluegreen/fbb38640ab7af2b9 \
     --protocol HTTP \
     --port 80 \
     --default-actions Type=forward,TargetGroupArn="arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxxxx:targetgroup/hostbased-bluegreen-app01-a/baa95a555069b8fb" \
     --region ap-northeast-1
```



コマンドの実行結果

![image-20230905183526108.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/7f0ac76d-bcfc-d8c7-b1b3-278d1d800a4b.png)



## ECS Service 1個目の作成

Service の定義ファイルを作成します。deploymentController で `CODE_DEPLOY` を指定するのがポイントです。

```
cat <<'EOF' > ecs-service-hostbased-bluegreen-app01.json
{
    "cluster": "test-cluster01",
    "serviceName": "hostbased-bluegreen-app01",
    "taskDefinition": "hostbased-hello-ver-app01:1",
    "loadBalancers": [
        {
            "targetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxxxx:targetgroup/hostbased-bluegreen-app01-a/baa95a555069b8fb",
            "containerName": "app1-ver1",
            "containerPort": 8080
        }
    ],
    "launchType": "FARGATE",
    "schedulingStrategy": "REPLICA",
    "deploymentController": {
        "type": "CODE_DEPLOY"
    },
    "platformVersion": "LATEST",
    "networkConfiguration": {
       "awsvpcConfiguration": {
          "assignPublicIp": "ENABLED",
          "securityGroups": [ "sg-0fbfac9c258b61337" ],
          "subnets": [ "subnet-0c4b7c352a610baf4", "subnet-0d9a1ae8571fa7c30", "subnet-0355f72e6534092bf" ]
       }
    },
    "desiredCount": 2
}
EOF
```



Service を作成します。

```
aws ecs create-service \
     --cli-input-json file://ecs-service-hostbased-bluegreen-app01.json \
     --region ap-northeast-1
```



作成されました

![image-20230905181216109.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/1aa2a022-673b-f883-f478-8deff0c3a81f.png)



## CodeDeploy に関するリソース作成

CodeDeploy で 「Application」というリソースを定義します。

```
aws deploy create-application \
     --application-name ecs-hostbased-bluegreen-app01 \
     --compute-platform ECS
```





CodeDeploy で Deployment Group を作成します。ALB のリスナーを指定しつつ、2 つの Target Group を指定することで、Blue/Green の動作を指定しています。

```
cat <<'EOF' > ecs-hostbased-bluegreen-app01-deployment-group.json
{
    "applicationName": "ecs-hostbased-bluegreen-app01",
    "autoRollbackConfiguration": {
        "enabled": true,
        "events": [
            "DEPLOYMENT_FAILURE"
        ]
    },
    "blueGreenDeploymentConfiguration": {
        "deploymentReadyOption": {
            "actionOnTimeout": "CONTINUE_DEPLOYMENT",
            "waitTimeInMinutes": 0
        },
        "terminateBlueInstancesOnDeploymentSuccess": {
            "action": "TERMINATE",
            "terminationWaitTimeInMinutes": 1
        }
    },
    "deploymentGroupName": "ecs-hostbased-bluegreen-app01-dg",
    "deploymentStyle": {
        "deploymentOption": "WITH_TRAFFIC_CONTROL",
        "deploymentType": "BLUE_GREEN"
    },
    "loadBalancerInfo": {
        "targetGroupPairInfoList": [
            {
                "targetGroups": [
                    {
                        "name": "hostbased-bluegreen-app01-a"
                    },
                    {
                        "name": "hostbased-bluegreen-app01-b"
                    }
                ],
                "prodTrafficRoute": {
                    "listenerArns": [
                        "arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxxxx:listener/app/ecs-hostbased-bluegreen/fbb38640ab7af2b9/4cccf92c5a04b5cd"
                    ]
                }
            }
        ]
    },
    "serviceRoleArn": "arn:aws:iam::xxxxxxxxxxxx:role/AWSCodeDeployRoleForECS",
    "ecsServices": [
        {
            "serviceName": "hostbased-bluegreen-app01",
            "clusterName": "test-cluster01"
        }
    ]
}
EOF
```



Deployment Group の作成

```
aws deploy create-deployment-group \
     --cli-input-json file://ecs-hostbased-bluegreen-app01-deployment-group.json
```



## Route 53 の設定

Route 53 で、DNS 名を付与します。

![image-20230905184109695.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/eca709af-6104-f996-4678-730d9d3b6c5b.png)



# ECS Service 2 個目に関する設定

同様に、ECS Service 1 個目の設定を進めていきます。

## Blue/Green 用の Target Group を 2 個作成し、ALB に紐づけ

AWS CLI から作成



1 個目

```
aws elbv2 create-target-group \
     --name hostbased-bluegreen-app02-a \
     --protocol HTTP \
     --port 80 \
     --target-type ip \
     --vpc-id vpc-0b8b2123a16d03528 \
     --region ap-northeast-1
```



2 個目

```
aws elbv2 create-target-group \
     --name hostbased-bluegreen-app02-b \
     --protocol HTTP \
     --port 80 \
     --target-type ip \
     --vpc-id vpc-0b8b2123a16d03528 \
     --region ap-northeast-1
```



ALB リスナールールを作成して、Target Group1 を紐づけます。リスナーを選択します。

![image-20230905184458251.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/2e7772a7-eaf7-3bf3-e821-b5e90960603c.png)



ALB の共有を行うために、ホストヘッダー ( host header ) で分岐をするため、リスナールールを追加します。

![image-20230905184520554.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/217bb332-8877-085d-ab7a-3b0f3fe85811.png)



好きなルール名を指定します。

![image-20230905184539997.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/03c177b4-341f-9b90-24c5-9e10106e939b.png)



Add condition を押します。

![image-20230905184555335.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/9428fadb-81b5-2159-c46a-d6b431c1a46a.png)



Host Header を選択し、「ecs-bluegreen-app02.sugiaws.tokyo」でアクセスしてきたことを条件に分岐ルールを指定します。

![image-20230905184627870.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/1d6f1165-1db9-6a5c-9f79-88662cdf35b8.png)



Next を押します。

![image-20230905184638215.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/a4243de0-343d-a971-ed68-23f0072df951.png)



ECS Service 2 側の Target Group を指定します。

![image-20230905184658042.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/8032b154-46e5-f713-839d-e42f17f75036.png)



Next

![image-20230905184710954.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/29d17fc3-29d0-7079-ff84-47ae53f9ef26.png)



Create

![image-20230905184719111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/0b96b5f6-19a4-32e7-03ba-85f33dbde266.png)



## ECS Service 2個目の作成

ECS Service を作成するために定義ファイルを作成します

```
cat <<'EOF' > ecs-service-hostbased-bluegreen-app02.json
{
    "cluster": "test-cluster01",
    "serviceName": "hostbased-bluegreen-app02",
    "taskDefinition": "hostbased-hello-ver-app02:1",
    "loadBalancers": [
        {
            "targetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxxxx:targetgroup/hostbased-bluegreen-app02-a/babcc21f145a8a4c",
            "containerName": "app2-ver1",
            "containerPort": 8080
        }
    ],
    "launchType": "FARGATE",
    "schedulingStrategy": "REPLICA",
    "deploymentController": {
        "type": "CODE_DEPLOY"
    },
    "platformVersion": "LATEST",
    "networkConfiguration": {
       "awsvpcConfiguration": {
          "assignPublicIp": "ENABLED",
          "securityGroups": [ "sg-0fbfac9c258b61337" ],
          "subnets": [ "subnet-0c4b7c352a610baf4", "subnet-0d9a1ae8571fa7c30", "subnet-0355f72e6534092bf" ]
       }
    },
    "desiredCount": 2
}
EOF
```



Service の作成

```
aws ecs create-service \
     --cli-input-json file://ecs-service-hostbased-bluegreen-app02.json \
     --region ap-northeast-1
```



作成されました

![image-20230905184904288.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ad5ec2db-afbe-49c6-35b9-c768b92aeaac.png)



## CodeDeploy の リソース 作成

CodeDeploy で 「Application」というリソースを定義します。

```
aws deploy create-application \
     --application-name ecs-hostbased-bluegreen-app02 \
     --compute-platform ECS
```





CodeDeploy で Deployment Group を作成します。ALB のリスナーを指定しつつ、2 つの Target Group を指定することで、Blue/Green の動作を指定しています。

```
cat <<'EOF' > ecs-hostbased-bluegreen-app02-deployment-group.json
{
    "applicationName": "ecs-hostbased-bluegreen-app02",
    "autoRollbackConfiguration": {
        "enabled": true,
        "events": [
            "DEPLOYMENT_FAILURE"
        ]
    },
    "blueGreenDeploymentConfiguration": {
        "deploymentReadyOption": {
            "actionOnTimeout": "CONTINUE_DEPLOYMENT",
            "waitTimeInMinutes": 0
        },
        "terminateBlueInstancesOnDeploymentSuccess": {
            "action": "TERMINATE",
            "terminationWaitTimeInMinutes": 1
        }
    },
    "deploymentGroupName": "ecs-hostbased-bluegreen-app02-dg",
    "deploymentStyle": {
        "deploymentOption": "WITH_TRAFFIC_CONTROL",
        "deploymentType": "BLUE_GREEN"
    },
    "loadBalancerInfo": {
        "targetGroupPairInfoList": [
            {
                "targetGroups": [
                    {
                        "name": "hostbased-bluegreen-app02-a"
                    },
                    {
                        "name": "hostbased-bluegreen-app02-b"
                    }
                ],
                "prodTrafficRoute": {
                    "listenerArns": [
                        "arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxxxx:listener/app/ecs-hostbased-bluegreen/fbb38640ab7af2b9/4cccf92c5a04b5cd"
                    ]
                }
            }
        ]
    },
    "serviceRoleArn": "arn:aws:iam::xxxxxxxxxxxx:role/AWSCodeDeployRoleForECS",
    "ecsServices": [
        {
            "serviceName": "hostbased-bluegreen-app02",
            "clusterName": "test-cluster01"
        }
    ]
}
EOF
```



Deployment Group の作成

```
aws deploy create-deployment-group \
     --cli-input-json file://ecs-hostbased-bluegreen-app02-deployment-group.json
```



## Route 53 の設定

Route 53 で、DNS 名を付与します。

![image-20230905185107199.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/0fb6b737-ea2f-5c7a-9955-c863d9eb99bb.png)





# 動作確認 : Blue/Green Deployment を Service 1 個目に対して行う

ECS Service 1 に対して、Blue/Green Deployment を実施します。この時に、以下を確認します。

- ECS Service 1 が切り替わること
- ECS Service 2 は引き続き利用できること

![image-20230906131840389.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c2882f9b-9ba8-984d-2af7-6777f1560c95.png)



## 1 回目

ALB のリスナールールで見たときに、Default で指定されてる Target Group が「hostbased-bluegreen-app01-a」から、「hostbased-bluegreen-app01-b」に切り替わってほしいです。

![image-20230905204804177.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/7b618b37-270a-76c8-f712-78c1573b7f25.png)



Blue/Green Deployment を行う前の curl です。ホストヘッダーで適切に分岐されています。

```
$ curl http://ecs-bluegreen-app01.sugiaws.tokyo/
Hello, App1 Version1
```

```
$ curl http://ecs-bluegreen-app02.sugiaws.tokyo/
Hello, App2 Version1
```



CodeDeploy 用の AppSpec ファイルを作成して、S3 にアップロードします。

```
cat <<'EOF' > appspec.yaml
version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/hostbased-hello-ver-app01:3"
        LoadBalancerInfo:
          ContainerName: "app1-ver1"
          ContainerPort: 8080
        PlatformVersion: "LATEST"
EOF
```



S3 Bucket にアップロードします。

```
aws s3 cp ./appspec.yaml s3://awscli-ecs-bluegreen-bucket01/appspec.yaml
```



CodeDeploy 上で、Deployment を作成するためのファイルを作成

```
cat <<'EOF' > create-deployment.json
{
    "applicationName": "ecs-hostbased-bluegreen-app01",
    "deploymentGroupName": "ecs-hostbased-bluegreen-app01-dg",
    "revision": {
        "revisionType": "S3",
        "s3Location": {
            "bucket": "awscli-ecs-bluegreen-bucket01",
            "key": "appspec.yaml",
            "bundleType": "YAML"
        }
    }
}
EOF
```



Blue/Green Deployment を開始します。

```
aws deploy create-deployment \
     --cli-input-json file://create-deployment.json
```



CodeDeploy が動作する様子が見えます。

![image-20230905205319948.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/fed65157-71ab-c051-c77f-33bccfeaa878.png)



一定時間後、Deploy が完了しています。

![image-20230905205537744.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/5c97f332-f378-2613-b7b4-516efc68735c.png)



ALB のリスナーを見ると、無事に Default の方の Target Group が入れ替わっています。

![image-20230905205556184.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/72d7787a-8805-1ab4-9269-07c74a58d62b.png)



curl でアクセスした結果です。「ecs-bluegreen-app01.sugiaws.tokyo」の方は version2 にバージョンアップできました。

```
$ curl http://ecs-bluegreen-app01.sugiaws.tokyo/
Hello, App1 Version2
```

```
$ curl http://ecs-bluegreen-app02.sugiaws.tokyo/
Hello, App2 Version1
```





## 2 回目

同じく、ECS Service 1 個目に対して、2 回目の Blue/Green Deployment を試してみます。ALB リスナールールの、次の Target Group が切り替わることを確認します。

![image-20230905210928127.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/4bcb8232-b21c-1be8-11e9-71831cdf65d9.png)



curl のレスポンスです。

```
$ curl http://ecs-bluegreen-app01.sugiaws.tokyo/
Hello, App1 Version2
```

```
$ curl http://ecs-bluegreen-app02.sugiaws.tokyo/
Hello, App2 Version1
```



CodeDeploy 用の AppSpec ファイルを作成して、S3 にアップロードします。

```
cat <<'EOF' > appspec.yaml
version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/hostbased-hello-ver-app01:1"
        LoadBalancerInfo:
          ContainerName: "app1-ver1"
          ContainerPort: 8080
        PlatformVersion: "LATEST"
EOF
```



S3 Bucket にアップロード

```
aws s3 cp ./appspec.yaml s3://awscli-ecs-bluegreen-bucket01/appspec.yaml
```



CodeDeploy 上で、Deployment を作成するためのファイルを作成

```
cat <<'EOF' > create-deployment.json
{
    "applicationName": "ecs-hostbased-bluegreen-app01",
    "deploymentGroupName": "ecs-hostbased-bluegreen-app01-dg",
    "revision": {
        "revisionType": "S3",
        "s3Location": {
            "bucket": "awscli-ecs-bluegreen-bucket01",
            "key": "appspec.yaml",
            "bundleType": "YAML"
        }
    }
}
EOF
```



Blue/Green Deployment を開始します。

```
aws deploy create-deployment \
     --cli-input-json file://create-deployment.json
```



CodeDeploy が動作

![image-20230905211132880.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/4068f8e2-7969-b391-afa3-c53230da8e3c.png)



Deploy が完了

![image-20230905211609430.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d1751bac-cc3f-35ba-89fe-655a120d5b9b.png)



無事に入れ替わっている

![image-20230905211627169.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/42b81115-653b-0423-6fda-b3e92ed86524.png)



curl の結果で、App1 だけ切り替わりました。

```
$ curl http://ecs-bluegreen-app01.sugiaws.tokyo/
Hello, App1 Version1
```

```
$ curl http://ecs-bluegreen-app02.sugiaws.tokyo/
Hello, App2 Version1
```



# 動作確認 : Blue/Green Deployment を Service 2 個目に対して行う

ECS Service 2 に対して、Blue/Green Deployment を実施します。この時に、以下を確認します。

- ECS Service 2 が切り替わること
- ECS Service 1 は引き続き利用できること

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/a163477d-0487-3aaf-06b2-2fba2b6ee809.png)




## 1 回目

ALB のリスナールールで見たときに、host header のリスナールールで指定されてる Target Group が「hostbased-bluegreen-app02-a」から、「hostbased-bluegreen-app02-b」に切り替わってほしいです。

![image-20230905203446809.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d83b0624-050d-3e78-ed1e-c9afdc384b1f.png)



デプロイ前の curl

```
$ curl http://ecs-bluegreen-app01.sugiaws.tokyo/
Hello, App1 Version1
```

```
$ curl http://ecs-bluegreen-app02.sugiaws.tokyo/
Hello, App2 Version1
```





CodeDeploy 用の AppSpec ファイルを作成して、S3 にアップロードします。

```
cat <<'EOF' > appspec.yaml
version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/hostbased-hello-ver-app02:3"
        LoadBalancerInfo:
          ContainerName: "app2-ver1"
          ContainerPort: 8080
        PlatformVersion: "LATEST"
EOF
```



S3 Bucket にアップロード

```
aws s3 cp ./appspec.yaml s3://awscli-ecs-bluegreen-bucket01/appspec.yaml
```



CodeDeploy 上で、Deployment を作成するためのファイルを作成

```
cat <<'EOF' > create-deployment.json
{
    "applicationName": "ecs-hostbased-bluegreen-app02",
    "deploymentGroupName": "ecs-hostbased-bluegreen-app02-dg",
    "revision": {
        "revisionType": "S3",
        "s3Location": {
            "bucket": "awscli-ecs-bluegreen-bucket01",
            "key": "appspec.yaml",
            "bundleType": "YAML"
        }
    }
}
EOF
```



Blue/Green Deployment を開始します。

```
aws deploy create-deployment \
     --cli-input-json file://create-deployment.json
```



CodeDeploy が動作する様子が確認できます。

![image-20230905203409047.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/3b0f9e23-85b8-7468-2714-b80f61a6e956.png)



正常終了します。

![image-20230905203833876.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e6940e8f-d768-de73-2e76-4a205205a213.png)



デプロイ後の curl です。App 2 側のみ切り変わっています。

```
$ curl http://ecs-bluegreen-app01.sugiaws.tokyo/
Hello, App1 Version1
```

```
$ curl http://ecs-bluegreen-app02.sugiaws.tokyo/
Hello, App2 Version2
```



想定通り、ALB のリスナールールを見ると、Host Header 側が切り替わっています。

![image-20230905204033976.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/97f45fb8-3352-cf91-7f88-1cf7488f0f41.png)



## 2 回目

同じく、ECS Service 2 個目に対して、2 回目の Blue/Green Deployment を試してみます。ALB リスナールールの、次の Target Group が切り替わることを確認します。

![image-20230905204033977.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/49f30276-5da1-35b2-10c0-cfb05d2f6f4f.png)



CodeDeploy 用の AppSpec ファイルを作成して、S3 にアップロードします。

```
cat <<'EOF' > appspec.yaml
version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/hostbased-hello-ver-app02:1"
        LoadBalancerInfo:
          ContainerName: "app2-ver1"
          ContainerPort: 8080
        PlatformVersion: "LATEST"
EOF
```



S3 Bucket にアップロード

```
aws s3 cp ./appspec.yaml s3://awscli-ecs-bluegreen-bucket01/appspec.yaml
```



CodeDeploy 上で、Deployment を作成するためのファイルを作成

```
cat <<'EOF' > create-deployment.json
{
    "applicationName": "ecs-hostbased-bluegreen-app02",
    "deploymentGroupName": "ecs-hostbased-bluegreen-app02-dg",
    "revision": {
        "revisionType": "S3",
        "s3Location": {
            "bucket": "awscli-ecs-bluegreen-bucket01",
            "key": "appspec.yaml",
            "bundleType": "YAML"
        }
    }
}
EOF
```



Blue/Green Deployment を開始します。

```
aws deploy create-deployment \
     --cli-input-json file://create-deployment.json
```



デプロイ後の curl です。App 2 側のみ切り変わっています。

```
$ curl http://ecs-bluegreen-app01.sugiaws.tokyo/
Hello, App1 Version1
```

```
$ curl http://ecs-bluegreen-app02.sugiaws.tokyo/
Hello, App2 Version1
```



ALB のリスナールールも切り替わっています。

![image-20230905203446810.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/7d691003-2cf2-a1d6-6b1a-e2302152e9cb.png)