Opt Technologies Magazine

オプトテクノロジーズ 公式Webマガジン

ecs-cli compose runの挙動を勘違いして全てのコードがCIをすり抜ける状態になっていた話

alt

ecs-cliの把握していなかった挙動により、問題があるコードでもCIをすり抜ける状態になってしまったので、その詳細と対処として行ったことについて紹介します。

あいさつ

こんにちは、20年新卒入社の u1 です。昨年入社し研修を受けていた私も8月にチームに配属され、広告実績を可視化するためのダッシュボード開発に勤しんでいます。React, Redux と Rails に苦しめられながらがんばっています。最近はもっぱらウマ娘をしてましたが、ちょっとモチベーションが落ちてきました。新シナリオ実装はよ。 書いてから公開されるまでに実装されてしまいました。シナリオは楽しいので満足ですが、特定の因子を出すことをミッションに入れるのはやめてくださいお願いします。

今回と直接的な関係はありませんが、以前に昨年度私が受講した新卒研修の振り返り記事を書いているので、もしよければそちらもご覧ください。

tech-magazine.opt.ne.jp

今回は、ECS, ecs-cliを使って起こった問題、そしてその対処として行ったことについて紹介します。

問題の紹介

私のチームではECSを使用しており、CI/CDでecs-cliを使用しています。以下のようなフローでCIは動いています。

  1. コードpush
  2. imageをbuildし、ECRにpush
  3. ecs-cliでpushしたimageにテスト、マイグレーションなどの事前処理を実行させる

このうち3の部分で問題が起きており、どんなコードでもテスト・マイグレーションなどの事前処理が正常に完了していることにされてしまう、状態になってしまっていました。非常に危険な状態だったので、軽微なミスで発覚できて本当に良かったなあと改めて思います。対応中はやばさに気づいていなかった思い出。

原因はなんだったのか?

ずばり、ecs-cli composeでコマンドを実行したときの挙動を把握していなかったから、でした。

ecs-cli compose は以下のようにして、指定したimageで任意のコマンドを実行することができます。これは app image に対して、rails db:migrateを実行したい時の例です。

> ecs-cli compose run app 'rails db:migrate'

この時、開発者(自分)はimageに実行させたいコマンド(rails db:migrate)が正常に終わったときに完了となる、と考えていましたが、実際の挙動はimageにコマンドを実行する命令を投げたときに完了となる、というものでした。ちょっとわかりにくいので説明用の画像を作りました。

期待した動作

期待した動作

このように、ecs-cliがimageに対して実行した処理が終了してから、CIにその実行ステータスが返っています。この実行ステータスはimageに対して実行したコマンドのステータスが返ってくることを期待していました。

実際の動作

実際の動作

実際にはimageにコマンド実行指示を出した時点で処理が終了し、肝心の実行したいコマンドのステータスは返ってこない状態になっていました。

対処法 + ecspresso の使い方紹介

問題がわかったところで対処していきましょう。ecs-cli compose run ~では、imageで実行させたいコマンドの実行ステータスが取れないことが問題なので、それを取れるツールを使えば良いです。今回は先輩に紹介していただいた、ecspresso というツールを使用させていただきました。

github.com

この記事では「どうecs-cliをecspressoに置き換えたか」のみを記載します。ecspressoのインストールやプロダクトに導入する手順などは、作者様が公開しているブログ記事をご覧ください。

adventar.org

書き換えた部分

今回はコマンド実行さえ書き換えればよかったので、ecs-cli compose run ~ の部分を ecspresso run ~ に置き換えました。以下は rails db:migrate を実行する際の例です。

変更前
> ecs-cli compose run app 'rails db:migrate'
変更後
overrides=$(cat << OVERRIDES
{
  "ContainerOverrides": [
    {
      "Command": [
        "rails", "db:migrate"
      ],
      "Name": "app"
    }
  ]
}
OVERRIDES)
ecspresso run --config ./config.yml -- overrides="$overrides"

開発当時はecspressoには直接特定のコマンドを実行するようなコマンドは無かったはずなので、以下の記事を参考に ContainerOverrides を作っています。

qiita.com

まとめ

今回は、ecs-cli起因の問題が発生したため、ecspressoで書き換えた、という内容の記事でした。修正当時は問題の大きさに全く気づいていなかったですが、改めて考えると比較的軽微な影響(半日ほど本番環境が止まったのでそこまで軽微ではないですが)で対処できて本当によかったです。結構簡単に発生する問題だと思うので、ecs-cliを使用している方は一度確認してみることをおすすめします。

また今回使用させていただいたecspressoですが、使用させていただいた当時はバージョン0.17.1だったところが現在は1.6.0まで進んでおり、リリースされたばかりの機能にいち早く対応したりと、精力的に開発をされています。今回はContainerOverridesを作って実行させるということをしていましたが、現時点では不要になっているかもしれません。そのうち最新バージョンのecspressoを使ってリファクタしたいなと考えているので、その時に合わせて自分のチームではどのようにecspressoを使っているか、という記事を書きたいと思います。時がきたらそちらも合わせて読んでいただけると嬉しいです。

最後まで読んでいただきありがとうございました。

Opt Technologies ではエンジニアを募集中です。カジュアル面談も可能ですので、下記リンク先よりお気軽にご応募ください。