Chef Custom Handlerの真髄:インフラ変更の「沈黙」を終わらせ、リアルタイム監視を実現する
Chefによる構成管理の究極の目的は、「宣言的なインフラ」を維持することだ。しかし、多くの現場でChefがブラックボックス化しているのはなぜか? それは、「誰が、いつ、どのノードで、何を書き換えたか」という実行結果が、ログの海に埋もれて誰にも観測されていないからだ。
今日は、Chef Infra Clientの実行を「観測」し、SlackやDatadogへ通知を飛ばすカスタムHandlerの実装を深掘りする。単なる通知ではない。SREとしてインフラの「健全性」を可視化するための、実務直結のテクニックを授ける。
—
1. なぜカスタムHandlerなのか?
Chefの実行結果を外部から監視(`chef-client`のプロセス監視だけ)するのは素人だ。真のプロは、Chefの内部状態(成功/失敗/変更リソース数)をフックして、意味のあるメタデータと共に通知を送る。
これにより、「どのリソースが失敗したのか」をSlackで即座に特定し、障害対応の初動を数十分短縮できる。
—
2. カスタムHandlerの実装:Chefのライフサイクルをハックする
Handlerは `Chef::Handler` を継承して作成する。重要なのは `report` メソッドだ。
実装例: `MyCompany::SlackHandler`
require ‘chef/handler’
require ‘net/http’
require ‘json’
module MyCompany
class SlackHandler < Chef::Handler
def initialize(webhook_url)
@webhook_url = webhook_url
end
def report
# 変更があったリソースだけを抽出する重要ロジック
updated_resources = run_status.updated_resources
if failed?
send_to_slack("❌ Chef Failed: #{node.name}\nError: #{run_status.exception}")
elsif !updated_resources.empty?
# 変更されたリソースの詳細を可視化
details = updated_resources.map { |r| "#{r.resource_name}[#{r.name}]" }.join(", ")
send_to_slack("✅ Chef Updated: #{node.name}\nResources: #{details}")
end
end
private
def send_to_slack(message)
# 非同期送信が理想だが、Chef実行後の後処理なので同期送信でOK
uri = URI.parse(@webhook_url)
Net::HTTP.post_form(uri, {'payload' => {text: message}.to_json})
end
end
end
【現場の極意】非同期処理とタイムアウト制御
大規模環境では、通知先(Slack/Datadog)のレスポンス遅延がChef全体の実行時間を阻害してはならない。必ず `Net::HTTP` に `open_timeout` と `read_timeout` を設定せよ。
—
3. ベストプラクティス:設定の共有化と管理
ChefのHandler定義を各レシピにベタ書きするのはアンチパターンだ。`chef-client` クックブックの属性経由で注入せよ。
設定ファイルのベストプラクティス(`attributes/default.rb`)
ハンドラーのロード設定
default[‘chef_client’][‘handler’][‘slack’][‘webhook_url’] = ‘https://hooks.slack.com/…’
`client.rb` への注入ルール
`chef-client` クックブックの `resource` を利用し、実行時に動的に `handler` を登録するのが最もクリーンだ。
チーム開発での共有ルール:
秘匿情報は Chef Vault か AWS SSM Parameter Store を経由してロードすること
chef_handler ‘MyCompany::SlackHandler’ do
source ‘my_company/slack_handler’
arguments [node[‘chef_client’][‘handler’][‘slack’][‘webhook_url’]]
action :enable
end
—
4. 開発スピードを劇的に高めるプロの環境構築
絶対入れるべき神プラグイン (VS Code)
- Chef Extension for VS Code: 構文チェックだけでなく、`Test Kitchen` の実行をGUIから操作できる。
- Ruby Solargraph: ChefのDSLは動的すぎて補完が効きにくい。Solargraphを入れ、`.solargraph.yml` を適切に設定することで、Chefリソースの補完精度が別次元になる。
隠れたキーボードショートカット (Test Kitchen編)
- `Cmd + Shift + P` -> `Test Kitchen: Converge` : 直前のテストを再実行。
- 重要: `kitchen verify` で `InSpec` を回す際、テストが落ちたら即座に修正するサイクルを回せ。「コードを書く時間より、テスト結果を待つ時間を減らす」のがテックリードの仕事だ。
—
5. チーム開発における「冪等性」の死守
Handlerで通知を飛ばす際、「変更がないのに通知が飛ぶ」のは最悪のノイズだ。
以下のルールをチームの憲法とせよ。
1. 冪等性の証明: `chef-client` を2回連続で回し、2回目に `Updated 0 resources` となることをテスト(`InSpec`)で強制する。
2. 通知のフィルタリング: `run_status.updated_resources` が空の場合は通知しない。
3. 例外のキャッチ: `begin-rescue` を `report` メソッド内で適切に行い、通知機能自体のエラーでChef全体の実行結果を破壊しないこと。
—
最後に:インフラエンジニアの矜持
ChefのHandlerは、単なる通知ツールではない。それは「インフラの状態を常に観測可能にする(Observability)」ための第一歩だ。
「Chefが勝手に動いて何かが変わった」という恐怖を、「Chefが変更を検知し、即座にSlackで共有する」という安心感へ変える。この仕組みを導入することで、あなたのチームは「修正」から「改善」へリソースを割けるようになるはずだ。
さあ、今すぐコードを書き、Slackの通知音でチームに「インフラの平和」を伝えよう。