経緯

現在、複数の案件で Amazon ECS を利用しています。
タスク定義の登録やデプロイについては、私はよく GitHub Actions 上で ecspresso/ecschedule を利用して自動化しています。
Terraform でやってもよかったんですが、インフラリソース作成とアプリケーションの更新はライフサイクルが異なることもあり、ECS への反映についてはあえて特化したツールを使っています。

GitHub Actions については以前の記事でも紹介していますので、興味がある方はそちらもご覧ください。

問題点

ただ、これらの設定変更を検証したい場合、方法が限られてしまいます。

  • ローカルまたは CD ツールから実際にアプリケーションを更新して確認する
  • コードを静的レビューしたうえでマージして試す

前者は実際の運用環境が壊れかねないですし、後者はコードに不備があった場合 CD が失敗し続けることになります。
何か良い方法は無いかと悩んでいる時、先のツールに dry run する仕組みがあることを知り「これだ!」と思いました。

対応内容

アプリケーション更新用コマンドに -dry-run オプションを足すだけです。

$ # ecspresso は -- で指定
$ ecspresso deploy --config {設定ファイルのパス} --dry-run

$ # ecschedule は - で指定
$ ecschedule apply -all -conf {設定ファイルのパス} -dry-run

これをワークフローに組み込みます。

ファイルを分ける(=ワークフロー自体を分ける)という手もありますが、同じワークフローで(例えば実行ブランチによって)制御することもできます。

# .github/workflows 以下に配置した CD 用ファイル
on: push

jobs:
  deploy:
    steps:
      # 必要なステップのみ抜粋
      - name: Set Options
        id: options
        run: |
          # 特定ブランチ(以下例は main ブランチ)以外の場合 dry-run する
          if [ "${GITHUB_REF}" != 'refs/heads/main' ];
          then
            echo "::set-output name=ecspresso-options::--dry-run"
            echo "::set-output name=ecschedule-options::-dry-run"
          fi
      - uses: kayac/ecspresso@v1
        with:
          version: v1.7.10
      - run: ecspresso deploy --config {設定ファイルのパス} ${{ steps.options.outputs.ecspresso-options }} # 前ステップから受け取ったオプションを設定
      - uses: Songmu/ecschedule@main
        with:
          version: v0.5.2
      - run: ecschedule apply -all -conf {設定ファイルのパス} ${{ steps.options.outputs.ecschedule-options }} # 前ステップから受け取ったオプションを設定

何をやっているか

  • 後続ステップで参照したいステップに id を設定する
  • 上記ステップ内のコマンドで set-output を利用して値を格納する
  • 後続ステップで上記 id を指定して値を取得する

具体的には steps.{前ステップで指定した id}.outputs.{set-output で指定した name} で前ステップで設定した値を参照することができます。

まとめ

dry-run を実行したからといって先の問題を完全に防げるとは限らないものの、構文エラーや考慮漏れなどには気づきやすい状態を作ることができるので、あって困るものではないと思っています。
他にも良い方法をご存じの方がいればぜひ教えてください。