ecspressoを導入してみた

## これは何?
この記事は、 [FOLIO Advent calendar 2021](https://adventar.org/calendars/6253) の3日目の記事です。

2日目は、Yuko Keanさんの[また犬の話で恐縮ですが](https://note.com/chaipin0731/n/n295d0a247e41)です。

4日目は、Iku さんの[MySQL 8.0 compatibleがAmazon Auroraにやってきた！](https://zenn.dev/iku/articles/23920aa6669f97)です。

今回は　[kayac/ecspresso](https://github.com/kayac/ecspresso) を導入した際に得た気づきについて書いていこうかと思います。

## 導入した経緯

各種マスターデータをS3に配置するためのバッチをECSで稼働させることになったのでリリースする方法を探していました。
現在、AWSのリソースをterraformで管理しているので全てをterraformに任せるのが理想でしたが、アプリケーションの更新タイミングとterraformのapplyするタイミングがどうしても一致しないので様々なツールを探していたところ、terraformとの親和性が高いecspressoが挙げられていたので検証しました。

検証した結果、以下の点が自分たちのチームにマッチしていたので導入を決めました。

- アプリケーションの更新タイミングをコントロール出来る仕組みを整えやすい
- terraformとの役割分担が明確にできる
- awsの仕様から離れすぎていない

最終的にバッチは定期的に動かす必要があったのでecspressoだけでは解決できませんでした。

将来的にはデータワークフローなりデータパイプラインに組み込む予定はあるものの、初めのうちはAmazon EventBridgeで動かすことにしました。

その後の検証で [Songmu/ecschedule](https://github.com/Songmu/ecschedule) を導入することでコード化することは出来ました。
ecscheduleについては今回は割愛しますがこちらも導入して良かったと思っています。

## ローカルで開発する際に得たこと

既にECSにデプロイされているものを取り込んでコード化していく記事はよく見かけるのですが、新規でタスクやサービスを定義していきたい場合は、テストコードを参考に変更していくのが一番早いと思います。

タスク定義やサービス定義のjsonはaws cliから生成できる内容とほぼ一緒なので、以下のAWSのドキュメントは見ておく必要があります。

- タスク定義のパラメータ: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html
- サービス定義のパラメータ: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_definition_parameters.html

ecspressoで扱う定義ファイルはテンプレート記法が使える ( https://zenn.dev/fujiwara/articles/ecspresso-20201205 )ので、どこを環境変数で変更すれば汎用性が上がるか考える必要があります。

テンプレートがどのように展開されたか確認したい場合は `render` コマンド( https://zenn.dev/fujiwara/articles/ecspresso-20201212 )を利用すると、それぞれの定義ファイル毎に確認できるのでありがたいです。

定義ファイルが書けたら検証するための `verify` コマンド( https://zenn.dev/fujiwara/articles/ecspresso-20201211 )を実行することで間違えている箇所が分かるので開発が捗りました。

`verify` コマンドが利用するIAMは https://zenn.dev/fujiwara/articles/ecspresso-20201221 に記載してあるので自分で調べながら追加する手間が減ってありがたいです。

`verify` の際に定義に記載されたタスク実行ロールに assume role を試みて、成功したらタスク実行ロールで、失敗したら現在の権限で検証を実施するので、失敗時にINFOログが表示されるが問題はないと思います。
しかし、タスク実行ロールで検証しているわけではないので必ず動作する保証はないので注意が必要です。
実際に動かして検証するか、タスク実行ロールにassume role出来るようにIAMを別途定義する必要があります。

既にデプロイが終わった後に変更を加えた場合は、 `diff` コマンド( https://zenn.dev/fujiwara/articles/ecspresso-20201210 )で実際に稼働している内容との差分を確認した方が良いと思います。

## terraformと組み合わせる際に気をつけること

https://zenn.dev/fujiwara/articles/ecspresso-20201219 の記事を見ればどのように書けばいいかは知れるので予めみておいた方が良いです。

ecspressoの設定ファイルであるconfig.ymlではtfstateが利用できないので環境変数で変更する必要があります。

output.tfの内容を利用する場合は、https://github.com/fujiwara/tfstate-lookup/blob/master/tfstate/lookup_test.go を参考にすると良いです。
特にlistの特定のindexの値を利用したい場合などは参考になりました。

可能であればecspressoで利用したい値を内包した専用のtfstateファイルを用意しておくことが望ましいです。
terraformの変更による影響を明確にすることでアプリケーションへの影響を最小限にすることが出来ます。

## 参考になった資料について

検証している際に様々な先駆者の記事が参考になったのでリストアップしておきました。

- https://github.com/kayac/ecspresso
  - 詳細な挙動やアップデートがあった際に対応が必要か確認できます
- https://adventar.org/calendars/5916 
  - 記事を一通り読むことでなんとなく何が出来るのかを理解できました
- https://sfujiwara.hatenablog.com/
  - 作者の人の解説等もあるので、困ったときに見にいくと解決できるかもしれません
- https://github.com/hxrxchang/ecspresso-example
  - terraformとecspressoを利用したサンプルで参考になりました
- https://github.com/fujiwara/tfstate-lookup
  - ecspressoが内部で利用しているtfstateを参照するモジュールなので挙動を確認する際に参考になりました
- https://github.com/kayac/go-config
  - ecspressoが内部で利用してる環境変数をテンプレートとして利用できるようにするモジュールなので環境変数をどう使えばいいのか参考になりました