kakakakakku blog

Weekly Tech Blog: Keep on Learning!

CircleCI + ecs-deploy で ECS にデプロイをする

引き続き ECS のデプロイを調査していて,今回は導入された話を比較的よく聞く ecs-deploy を試した.AWS CLI と jq に依存しているけど,Shell 100% で実装されているため,実行環境の構築が不要という手軽さが1番のメリットだと思う.

github.com

ちなみに前回試したのは CircleCI + AWS CLI で ECS にデプロイする方法で,今回の ecs-deploy も構成としては似ているため,deploy.sh で ecs-deploy を使う形を実装してみた.

kakakakakku.hatenablog.com

構成

f:id:kakku22:20170427104839j:plain

前提

動かす API は前回と同じ CircleCI の circleci/go-ecs-ecr で使った main.go を使う.

  • ECR リポジトリ名 : test
  • クラスタ名 : test-cluster
  • サービス名 : test-service
  • タスク定義名 : test-task

また今回も CircleCI の Environment Variables で,以下の環境変数を設定しておく.

  • AWS_ACCOUNT_ID
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

circle.yml

machine:
  services:
    - docker

dependencies:
  post:
    - docker build -t $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/test:$CIRCLE_SHA1 .

deployment:
  prod:
    branch: master
    commands:
      - ./deploy.sh

deploy.sh

AWS CLI の細かな制御は ecs-deploy で考慮されているため,非常にシンプルにデプロイすることができる.

#!/bin/sh

eval $(aws ecr get-login --region ap-northeast-1)
docker push $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/test:$CIRCLE_SHA1
./ecs-deploy --cluster test-cluster --service-name test-service --image $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/test:$CIRCLE_SHA1

ecs-deploy の解説

デプロイをする場合

デプロイをする場合,以下の必須オプションを設定する必要がある.また,個人的にオプション名が省略されているとすぐわからないため,フルネームのオプションを使うようにしている.以下のコマンドを実行すると,まず,タスク定義の新規リビジョンを作成し,コンテナイメージのタグを --image 引数で与えられた値に更新する.今回の例で言うと $CIRCLE_SHA1 の値がタグなので,この値に更新する.次にサービスのタスク定義を更新し,デプロイが完了する.

  • --cluster ... クラスタ名
  • --service-name ... サービス名
  • --image ... コンテナイメージ(${ECR_URL}/${IMAGE_NAME}:${TAG_NAME} というフォーマットになる)
./ecs-deploy --cluster test-cluster --service-name test-service --image $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/test:$CIRCLE_SHA1

Desired Count を変更する場合

タスクの Desired Count を変更する場合,--desired-count オプションを使うと,自動的にサービスに反映される.ただし,通常のデプロイも行われるため,Desired Count だけを変更するということはできなかった.これができると良いのになーとは思う.

  • --desired-count ... サービスに紐付くタスクの Desired Count
./ecs-deploy --cluster test-cluster --service-name test-service --image $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/test:$CIRCLE_SHA1 --desired-count 4

その他

他にも Minimum Healthy Percent (--min)Maximum Percent (--max) なども,オプションで指定をしてデプロイすることができる.詳しくは README を参照で!

トラブルシューティング

--image で指定したコンテナイメージがタスク定義に反映されない場合

仕様として,現在設定されているタスク定義のコンテナイメージの表記が,--image で指定したものと前方一致(タグ以外の部分が一致)になっている必要がある.最初のリビジョンで,適当なコンテナ名を入力していたため,ずっと反映されず,ハマった.createNewTaskDefJson 関数の中に以下の実装があり,ここを読んで気付いた.

DEF=$( echo "$TASK_DEFINITION" \
        | sed -e "s|\"image\": *\"${imageWithoutTag}:.*\"|\"image\": \"${useImage}\"|g" \
        | sed -e "s|\"image\": *\"${imageWithoutTag}\"|\"image\": \"${useImage}\"|g" \
        | jq '.taskDefinition' )

ecs-deploy の不満

ecs-deploy にバージョンの概念があったら良いのにと思う.GitHub のリリースを見ても去年10月から作成されていないし,日々変更が develop ブランチに取り込まれているため,自分が今どのバージョンを使っているのかがよくわからなくなってしまう.

まとめ

  • ECS にシンプルにデプロイするなら ecs-deploy は便利
  • Shell 100% で実装されているのも個人的には好印象だった
  • オプション次第では Desired Count なども変更できるため,運用でも使えそう
  • 個別要件がある場合は AWS CLI で実装する必要がある(結局何かしらありそう)

関連記事

kakakakakku.hatenablog.com

実際に試したリポジトリ

以下のリポジトリで試した.既に ECS クラスタは削除してある.

github.com