🦔

AWSでのCI/CD構築(ECSでのblue/green deployment)

2024/09/20に公開

ECSをソースとしてBlue/Green Deployment環境を構築してみましたが、多くの躓きがあったためまとめます。

https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/tutorials-ecs-ecr-codedeploy.html#tutorials-ecs-ecr-codedeploy-cluster

AWSのリンクはCodeCommitで行っていますが、CodeCommitはなくなる噂もあるため、S3で実施しました。

もし説明がおかしいところがあればご指摘いただければ幸いです。

1. 使用AWSサービス

  • S3:タスク定義とAppSpecソースファイルを保存するために使用します
  • ECR:使用するdocker imageのレポジトリです
  • ECS:docker imageのサービスをここにDeployします
  • Application Load Balancer:デプロイしたサービスにアクセスしてくる割り振ります
  • CodePipeline/CodeDeploy:CI/CDを構築します

2. 手順

2.1. ECRリポジトリの作成

とりあえず、今回はDocker imageにnginxを使用してECRリポジトリを作成します。
リポジトリ名は適当な名前をつけてください。

docker pull nginx

作成したリポジトリに行くと、プッシュコマンドが表示されるので、これに従うと良いです。

2.2. タスク定義とAppSpecソースファイルの作成およびS3へのアップロード

次に、タスク定義ファイル(taskdef.json)およびAppSpecソースファイル(appspec.yaml)を作成します

タスク定義ファイルは、ECSタスク実行時に使用します。
AppSpecソースファイルは、CodeDeployに使用されます。

2.2.1. タスク定義ファイル

taskdef.jsonファイルを作成し、{account_ID}を自身のアカウントIDに、{container_name}はコンテナ名称に変更してください。

{
    "executionRoleArn": "arn:aws:iam::{account_ID}:role/ecsTaskExecutionRole",
    "containerDefinitions": [
        {
            "name": "{container_name}",
            "image": "<IMAGE1_NAME>",
            "essential": true,
            "portMappings": [
                {
                    "hostPort": 80,
                    "protocol": "tcp",
                    "containerPort": 80
                }
            ]
        }
    ],
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "networkMode": "awsvpc",
    "cpu": "256",
    "memory": "512",
    "family": "ecs-demo"
}

2.2.2. AppSpec ファイル

appspec.yamlファイルを作成し、{container_name}はコンテナ名称に変更してください。
AppSpecファイルは、他にも設定可能な項目がありますが、今回は以下のみで大丈夫です。

version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "<TASK_DEFINITION>"
        LoadBalancerInfo:
          ContainerName: "{container_name}"
          ContainerPort: 80

2.2.3. S3へのアップロード

以下のようなフォルダ構成にし、configファイルを含めないようにしてzipファイルに圧縮してください。
別にファイル名称は何でもよいです。

/config
  |-- appspec.yaml
  |-- taskdef.json

その後、S3にアップロードします。

2.3. Application Load Balancerとターゲットグループの作成

次にApplication Load Balancerを作成します。
EC2の左ペインにロードバランサーがあります。
ステップ 3: Application Load Balancer とターゲットグループを作成するを確認し、作成します。

2.4. ECSクラスターとサービスの作成

ステップ4: Amazon ECSクラスターとサービスを作成するを実施します
ECSクラスターを適当な名前で作成し、その後サービスを作成します。

2.4.1. create-service.jsonの作成

私はクラウドシェル上に作成してしまいました・・・
viコマンドで以下に修正します。

{
    "taskDefinition": "{family:revision-number}",
    "cluster": "{my-cluster}",
    "loadBalancers": [
        {
            "targetGroupArn": "{target-group-arn}",
            "containerName": "{container_name}",
            "containerPort": 80
        }
    ],
    "desiredCount": 1,
    "launchType": "FARGATE",
    "schedulingStrategy": "REPLICA",
    "deploymentController": {
        "type": "CODE_DEPLOY"
    },
    "networkConfiguration": {
        "awsvpcConfiguration": {
            "subnets": [
                "{subnet-1}",
                "{subnet-2}"
            ],
            "securityGroups": [
                "{security-group}"
            ],
            "assignPublicIp": "ENABLED"
        }
    }
}

以下コマンドでecsのサービスを作成します。
サービス名{my-service}は適宜変更ください。

aws ecs create-service --service-name {my-service} --cli-input-json file://create-service.json

2.5. CodeDeployでアプリケーションとデプロイグループを作成

ステップ 5: アプリケーションとデプロイグループを作成する CodeDeployを確認しながらCodeDeploy設定を行います

2.6. パイプラインの作成

パイプラインの名称を付けた後、いったんソースにS3を設定します。

S3バケットは#2.2で作成したバケットを、S3オブジェクトキーは作成してアップロードしたconfig.zipを設定してください。

ビルドステージは今回使用しませんので、skipください。

deployステージではデプロイプロパイダーにAmazon ECS(ブルー/グリーン)を選択します。

今まで作成したAWS CodeDeploy アプリケーションやデプロイグループを設定していきます。

「タスク定義の動的な更新イメージ - オプショナル」は次のステップで設定していきます。

2.7. パイプラインに変更を加えてデプロイする

以下のようにしていきます。

2.7.1. ソースアクションの追加

code piplineの画面で、ステージを編集するをクリックします

アクションを追加したい場合は+アクションを追加をクリックします
(編集したい場合はえんぴつボタンをクリックしてください)

以下のようにAmazon ECRを追加します。

2.7.2. デプロイアクションの修正

入力アーティファクトに追加ボタンをクリックし、「MyImage」を追加します

その後、タスク定義の動的な更新イメージに「MyImage」を指定、ファイルで使用されるプレースホルダーテキストを「IMAGE1_NAME」に設定します。

3.まとめ

これでAWSでのCI/CD構築(ECSでのblue/green deployment)が完成しました。
今回はビルドステージを記述不要な構成でしたがビルドステージがあるCI/CDもまた構築してみたいです。

Discussion