ようへいの日々精進XP

よかろうもん

ecs-deploy をインストールする CircleCI orbs を作ってリリースしました

tl;dr

ECS クラスタのタスク定義を作成して ECS サービスを更新する (ECS にアプリケーションをデプロイする) ecs-deploy というシェルスクリプトで実装されたツールをインストールする CircleCI orbs を作ってリリースしたのでメモしておきます.

CircleCI orbs とは

すごくざっくり言うと, CircleCI のワークフローで実行する各種ジョブをまとめて再利用出来るようにしたものです.

circleci.com

.circleci/config.yml には以下のように指定することで利用です.

---
version: 2.1

orbs:
  aws-cli: circleci/aws-cli@1.2.1
  ecs-deploy: inokappa/ecs-deploy-install@dev:0.0.3

jobs:
  integration:
    docker:
      - image: cimg/base:2020.01
    steps:
      - aws-cli/install
      - ecs-deploy/install:
          latest: true
      - run:
          name: Get ecs-deploy version
          command: |
            ecs-deploy --version

workflows:
  integration_test:
     jobs:
       - integration

但し, デフォルトではサードパーティ製の orbs は利用出来ない設定になっている (?) ようなので, 設定で有効にしてあげる必要があります.

f:id:inokara:20200712231536p:plain

作ったもの

github.com

以下のように利用されることを想定しています.

---
version: 2.1

orbs:
  aws-cli: circleci/aws-cli@x.y
  ecs-deploy: inokappa/ecs-deploy-install@x.y

jobs:
  build:
    docker:
      - image: cimg/base:2020.01
    steps:
      - aws-cli/install
      - ecs-deploy/install:
          latest: true
        - run:
            command: |
              ecs-deploy --cluster your-ecs-cluster \
                --image your-container-image \
                --service-name your-ecs-service-name \
                --region ap-northeast-1 \
                --timeout 300 \
                --enable-rollback

latest:true を付与することで, 常に最新の ecs-deploy がインストールされます. また, version: x.x.x を指定することで任意のバージョンを指定することが出来ますが, わざわざ古いバージョンを指定して利用することはあまりないと思いますので, 基本的には latest:true で良いと思います.

この orbs がもたらしたメリット

従来は, .circleci/config.yml 内に以下のように ecs-deploy をインストールする各種コマンドを記述していました.

version: 2.1
...
commands:
  setup_ecs_deploy:
    steps:
      - run:
          name: Setup ecs-deploy
          command: |
            latest=$(curl -s 'https://api.github.com/repos/silinternational/ecs-deploy/tags' | jq -r '.[].name' | head -1 || true)
            curl -s https://raw.githubusercontent.com/silinternational/ecs-deploy/${latest}/ecs-deploy | tee -a /usr/local/bin/ecs-deploy \
              && chmod +x /usr/local/bin/ecs-deploy

jobs:
  deploy:
    executor: default
    steps:
      - checkout
      - setup_remote_docker:
          docker_layer_caching: true
...
      - setup_ecs_deploy 
...

これを orbs に変更することで, 以下のように commands.setup_ecs_deploy が丸っと無くなっているので, .circleci/config.yml が少しだけシンプルになりました.

version: 2.1
...
orbs:
  ecs-deploy: inokappa/ecs-deploy-install@0.0.1

jobs:
  deploy:
    executor: default
    steps:
      - checkout
      - setup_remote_docker:
          docker_layer_caching: true
...
      - ecs-deploy/install
...

実装

とてもシンプルなシェルスクリプト

YAML の中に複数行のシェルスクリプトを書くのに違和感を感じつつも, この orbs のコアとなるのが src/commands/install.yml となります. 以下, 抜粋です.

---
description: |
  Installing ecs-deploy.

parameters:
  version:
    description: ecs-deploy version.
    type: string
    default: ""
  latest:
    description: install latest version.
    type: boolean
    default: true
...
  - run:
      name: "Install ecs-deploy"
      command: |
        set +e
        VERSION=<<parameters.version>>
        if [ "${VERSION}" == "" ]; then
          VERSION=$(curl -s 'https://api.github.com/repos/silinternational/ecs-deploy/tags' | jq -r '.[].name' | head -1 || true)
        fi

        if [ -z "${VERSION}" ];then
          echo "Please specify 'version'."
          exit 1
        fi

        curl -s https://raw.githubusercontent.com/silinternational/ecs-deploy/${VERSION}/ecs-deploy | sudo tee -a /usr/local/bin/ecs-deploy \
          && sudo chmod +x /usr/local/bin/ecs-deploy
...

<<parameters.xxxx>> で orbs に指定するパラメータを取得することが出来ます.

orbs ソースコードを分割する

orbs は一枚の YAML で記述することが出来ますが, 以下のようなディレクトリ構成で分割して実装することが出来るようです.

$ tree src
src
├── @orb.yml
├── commands
│   └── install.yml
└── examples
    └── example.yml

2 directories, 3 files

分割することで, circleci/orb-tools という orbs のテストやデプロイまで一気通貫で行える, これまた orbs のワークフローに載せやすくなるとのことで, それにならってみました. 尚, 分割した YAML ファイルは, circleci コマンドを利用して結合することが出来ます.

$ circleci config pack --skip-update-check src > orb.yml

テスト

先述の circleci/orb-tools を使えば, 簡単に orbs の動作確認を行うことが出来ました. 以下は本 orbs 自体の .circleci/config.yml です.

---
version: 2.1

orbs:
  orb-tools: circleci/orb-tools@9.1.1

workflows:
  lint_pack_test_publish-dev:
    jobs:
      - orb-tools/lint
      - orb-tools/pack:
          requires:
            - orb-tools/lint
      - orb-tools/test-in-builds:
          name: test-latest-version
          attach-workspace: true
          orb-name: ecs-deploy
          test-steps:
            - orb-tools/local-test-build:
                test-config-location: test/latest.yml
          requires:
            - orb-tools/pack
      - orb-tools/publish-dev:
          name: test-specify-version
          attach-workspace: true
          orb-name: ecs-deploy
          test-steps:
            - orb-tools/local-test-build:
                test-config-location: test/version.yml
          requires:
            - test-latest-version
      - orb-tools/publish-dev:
          orb-name: inokappa/ecs-deploy-install
          requires:
            - test-specify-version

orb-tools/test-in-builds を利用することで, circleci local execute を実行して実際に orbs を使った動作確認を走らせることが出来ます. 以下は実際の実行されたジョブです.

circleci.com

参考にさせて頂いた記事では, バージョン番号を指定して orbs Registry に Publish するところまでを orb-tools に任せていてよく出来た orbs だなーと感激した次第です. 尚, 本 orbs ではテストまでで Publish 自体は手動でやっています. すいません. これは追々対応したいと思います.

以上

実は, この orbs を作ったきっかけとなったプロジェクトでは, サードパーティ製 orbs が利用出来ない設定になっていて切なくなってしまいましたが, orbs について色々と学ぶことが出来て良かったです.

参考

以下の記事を参考にさせて頂きました. ありがとうございました.

circleci.com

github.com

masutaka.net