51
Help us understand the problem. What are the problem?

posted at

updated at

【備忘録】AWS ECS Blue / Green Deploy 実現のために学んだこと

ざっくりまとめた図

以下は各機能やファイルがどのように連携するのかを自分なりにまとめた図です。
これから ECS Blue / Green Deploy に着手する方の助けになれば幸いです🙇‍♂️

CodePipeline-Flow.png


はじめに

本投稿では私自身が AWS ECS の Blue / Green Deploy を実現できるようになるために学んだことを備忘録として投稿させていただきます。

前提知識

  • ECSのデプロイはCodePipelineで自動化していた(Blue / Green は利用してない)

背景

  • エンドユーザが新しいバージョンのアプリを操作可能となる前に本番環境で動作確認できるようにしたかった
  • ECS Blue / Green Deploy であれば容易に実現可能だと思った

学習

ECS Blue / Green Deploy の 学習に参考としたサイト

以下のサイトでは「80ポートでリクエストを受け付けるNginxコンテナ を ECS Blue / Green Deploy する手順」が解説されてます。

自分が知らなかった機能(ワード)

これまでの ECS Deploy では利用してなかった

  • SourceArtifact
  • BuildArtifact
  • appspec.yaml
  • taskdef.json
  • imageDetail.json

という機能(ワード)が出てきたため、調べつつ 環境構築を行いました。

理解

機能(ワード) 自分の理解
SourceArtifact CodeCommit で Source に含まれるファイル(?)。
BuildArtifac CodeBuild で artifacts として出力したファイル(?)。
appspec.yaml ECSサービスに含めるタスク定義の設定を記述したファイル
事前に作成しておき、ソースコードと一緒にCodeCommitへプッシュしておく
taskdef.json デプロイするタスク定義の設定を記述したファイル
事前に作成しておき、ソースコードと一緒にCodeCommitへプッシュしておく
imageDetail.json デプロイするタスク定義で利用するコンテナイメージが記載されたファイル
CodeBuildのビルド成果物として出力させる

補足:
(?)部分は自分でも理解が怪しいと思っている箇所です。
誤りがありましたらご指摘いただけると助かります


実践

参考サイトを参照しつつ、以下のことを行った。

  1. リポジトリにappspec.yamlを追加する
  2. リポジトリにtaskdef.jsonを追加する
  3. buildspec.ymlimageDetail.jsonを出力するようにする

1. リポジトリにappspec.yamlを追加する

ECSを利用していれば難しくない準備です。
appspec.yamlを作成して、リポジトリ直下に配置しました。

/xxx
  |-- appspec.yaml

appspec.yamlのサンプル

以下はAWSのチュートリアルに記載されていたappspec.yamlです。
ContainerNameContainerPortを適切な値に変更します。
<TASK_DEFINITION>については変更せず、そのままにします。

appspec.yaml
version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: <TASK_DEFINITION>
        LoadBalancerInfo:
          ContainerName: "sample-website"
          ContainerPort: 80

2. リポジトリにtaskdef.jsonを追加する

Blue / Green Deploy を行う前は作成してなかったため、少し手間かと思いましたが、タスク定義のコンソールにjsonを表示する機能があったため、あまり手間はかかりませんでした。

taskdef.jsonの作り方

1. タスク定義のコンソールからjsonをコピペする

CodePipeline-TaskDefinition.png

2. json内のimageの値を"<IMAGE1_NAME>"に書き換える

修正前

taskdef.json
"image": "xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxxxx:latest",

修正後

taskdef.json
"image": "<IMAGE1_NAME>",

3. taskdef.jsonという名前でリポジトリ直下に保存する

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

3. buildspec.ymlimageDetail.jsonを出力するようにする

buildspec.ymlを修正して、CodeBuildでのビルド時にimageDetail.jsonを出力するようにしました。
Blue / Green Deploy を利用しないケースも想定して、通常のDeployに利用するimagedefinitions.jsonの出力も残しました。

imageDetail.jsonのサンプル

buildspec.yml
version: 0.2

env:
  # 省略
phases:
  install:
    # 省略
  pre_build:
    commands:
      - # 省略
      - REPOSITORY_URI=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_NAME}
      - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - # 省略
  build:
    commands:
      # 省略
  post_build:
    commands:
      - # 省略
      - echo "[{\"name\":\"${IMAGE_NAME}\",\"imageUri\":\"${REPOSITORY_URI}:${IMAGE_TAG}\"}]" > imagedefinitions.json
      - printf '{"Version":"1.0","ImageURI":"%s"}' $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json
artifacts:
    files:
      - imagedefinitions.json
      - imageDetail.json

まとめ

以上の準備を行った上で、参考サイトの手順に従って Blue / Green Deploy の環境構築を行ったところ、ECS Blue / Green Deploy を実現することができました。

以下は各機能やファイルがどのように連携するのかを自分なりにまとめた図です。
これから ECS Blue / Green Deploy に着手する方の助けになれば幸いです🙇‍♂️

CodePipeline-Flow.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
51
Help us understand the problem. What are the problem?