/var/www/yatta47.log

/var/www/yatta47.log

やったのログ置場です。スクラップみたいな短編が多いかと。

ecspressoとlambrollのdiffコマンドでデプロイ前の設定差分を確認する

ecspressoとlambrollには diff というサブコマンドがあって、ローカルの定義ファイルとAWS上の現行設定の差分を出してくれる。

Terraformでいう plan と同じ感覚で使える。デプロイ前に「何が変わるか」を確認できるので、事故防止にかなり効く。

ecspressoとlambrollのdiffコマンドとは

ECSやLambdaをコードで管理してると、「ローカルの定義ファイルを変更したけど、実際にデプロイしたら何が変わるんだっけ」っていう場面がけっこうある。AWS consoleで目視確認するのも限界があるし、そもそもJSON同士の差分を人間が見比べるのはつらい。

そこで使えるのが diff サブコマンド。ecspressoはunified diff形式、lambrollはJSON差分表示で、ローカルの定義ファイルとAWS上のリソースの差分を出してくれる。

ecspressoの場合はこう。

ecspresso diff

これだけでECSのタスク定義とサービス定義の両方について差分を出してくれる。シンプル。

lambroll diffのオプションが地味に豊富

lambrollの方はオプションがいろいろあって、細かい使い分けができるようになってる。

lambroll diff                        # 基本の設定diff
lambroll diff --code                 # コードのSHA256ハッシュも比較
lambroll diff --qualifier current    # alias/バージョン指定(例: lambrollがデフォルトで作るcurrent alias)
lambroll diff --ignore '.Environment.Variables.TIMESTAMP'  # jqクエリで除外フィールドを指定
lambroll diff --exit-code            # 差分があればexit code 2(CI向き)

--code をつけるとデプロイパッケージのハッシュまで比較してくれるので、「設定は同じだけどコードだけ変わった」みたいなケースも拾える。

--ignore は地味にありがたくて、デプロイのたびに変わるタイムスタンプ系の環境変数とかを除外できる。これがないとdiffが毎回出てしまってノイズになるんですよね。

CI/CDパイプラインでの活用パターン

diff コマンドが本当に活きるのはCI/CDに組み込んだとき。自分が調べた限り、3パターンくらいある。

1つ目はPRレビュー用。PR作成をトリガーにしてdiffを実行して、結果をPRコメントに貼る。レビュアーが「このPRをマージしたら何が変わるか」をコードの差分だけじゃなくてインフラの差分でも確認できる。

2つ目はドリフト検知。cronで定期的に diff --exit-code を回して、exit code 2が返ってきたら誰かがconsoleから手動で変更したということ。Slack通知を飛ばせば「誰かconsoleいじった?」がすぐわかる。

3つ目はデプロイゲート。diff → 人間が確認 → approveしたらdeploy、という流れ。Terraformの planapply と同じ運用ができる。

個人的には2つ目のドリフト検知が刺さった。consoleからのちょっとした変更って、気づかないまま放置されがちなので。

diffコマンドに必要なIAM権限

diffコマンドはAWSのAPIを叩いて現行設定を取得するので、当然IAM権限が必要になる。

ツール 必要な権限
ecspresso ecs:DescribeServices, ecs:DescribeTaskDefinition
lambroll lambda:GetFunction, lambda:ListTags(Function URLのdiffには lambda:GetFunctionUrlConfig も必要)

CI/CDで使う場合はこのへんの権限をちゃんとつけておかないと、diffの段階で権限エラーになって意味がなくなる。デプロイ用のIAMロールにはだいたい含まれてるはずだけど、diff専用のロールを作る場合は ReadOnly 系の権限だけで足りるので、最小権限の原則的にもやりやすい。

注意点

diffコマンドはあくまでローカルの定義ファイルとAWS上の設定を比較するものなので、テンプレート変数(ecspressoの {{ must_env }} とか)が未解決だと正しいdiffが出ない。CI環境で動かすなら、環境変数をちゃんとセットしておく必要がある。

あと、lambrollの --exit-code はexit code 2で差分ありを返すので、CIのスクリプトで set -e してると差分があるだけでパイプラインが落ちる。ドリフト検知として使うなら、exit codeのハンドリングを入れておかないとハマる。

まとめ

ecspressoとlambrollのdiffコマンドは、Terraformの plan に相当する機能。ローカルの定義ファイルとAWS上の現行設定を比較して差分を出してくれる。

デプロイ前の確認だけじゃなくて、PRレビューへの差分貼り付けやドリフト検知にも使える。特にドリフト検知は、consoleからの手動変更を拾えるので運用が安定する。

ecspressoはKAYAC Inc.が管理するツールで、lambrollは藤原さんの個人OSS。どちらも藤原さんが主要開発者で、この手の運用に必要な機能がちゃんと揃ってるのがありがたい。

参考