【入門編】ChefカスタムHandlerの完全開発ガイド:インフラ変更検知をSlackやDatadogにリアルタイム通知する仕組みの作り方 – インフラ構成管理(IaC)活用バイブル

ChefカスタムHandler完全開発ガイド:インフラ変更を「可視化」し、運用を自動化する極意

こんにちは。インフラエンジニアの皆さん、日々の運用で「誰が、いつ、どのサーバーに、どんな変更を加えたのか?」を追いかけるために、ログを漁って疲弊していませんか?

Chefを使っているなら、「カスタムHandler」をマスターしてください。これができると、Chefが実行されるたびに、その結果(成功・失敗・変更箇所)をSlackやDatadogへ自動的に飛ばすことができます。運用者が寝ている間も、インフラの状態を常に監視し、異常があれば即座に検知する。これこそが、SREとして自動化の恩恵を最大化するための第一歩です。

今回は、Chefの深淵に触れる「カスタムHandler」の開発手法を、現場でそのまま使えるレベルで解説します。

—

1. カスタムHandlerとは何か?

ChefのカスタムHandlerは、`chef-client`の実行サイクル(Converge)の終了直後に呼び出される「フック機能」です。

  • 成功時: 何が変更されたのか(updated_resources)を通知する。
  • 失敗時: どのリソースでエラーが起きたのか(backtrace)を通知する。

これらをフックすることで、Chefの実行結果をただのログファイルに閉じ込めるのではなく、「生きたデータ」として外部システムに送ることができるようになります。

—

2. 開発準備:環境を整える

まずは、Handlerを置くためのディレクトリをChefの構成内に用意します。

1. ディレクトリ作成: `files/default/handler` というディレクトリをクックブック内に作成します。
2. 構成: 最終的に以下のような構造になります。

my_notifier/
├── files/default/handler/slack_handler.rb
└── recipes/default.rb

—

3. HelloWorld:シンプルなカスタムHandlerの実装

まずは、Chefの実行終了時にコンソールにメッセージを出すだけの「Hello World」を作成しましょう。

`files/default/handler/slack_handler.rb` を作成します。

require ‘chef/handler’

class SlackHandler < Chef::Handler # reportメソッドがChef実行終了時に自動で呼ばれます def report if failed? Chef::Log.error("Chefの実行が失敗しました: #{run_status.exception}") else Chef::Log.info("Chef実行完了!変更されたリソース数: #{run_status.updated_resources.length}") end end end

このコードのポイント

  • `Chef::Handler` を継承します。
  • `run_status` オブジェクトには、実行結果の全て(例外、変更されたリソース、実行時間など)が詰まっています。これを使い倒すのがSREの腕の見せ所です。

—

4. 現場で使える「Slack通知Handler」の実装

次に、実際にSlackへ通知を送るための少し高度な実装例です。`net/http` を使い、JSONをペイロードとして送信します。

require ‘chef/handler’
require ‘net/http’
require ‘uri’
require ‘json’

class SlackHandler < Chef::Handler def initialize(webhook_url) @webhook_url = webhook_url end def report # 変更があった場合、または失敗した場合のみ通知する(ノイズを減らす) return unless failed? || updated_resources.any? message = failed? ? "🚨 Chef Failure: #{node.name}" : "✅ Chef Success: #{node.name}" payload = { text: "#{message}\n変更リソース数: #{updated_resources.length}" } uri = URI.parse(@webhook_url) Net::HTTP.post_form(uri, {'payload' => payload.to_json})
end
end

—

5. HandlerをChefに登録する

作成したHandlerを有効化するために、レシピ(`recipes/default.rb`)で登録処理を書きます。

Handlerファイルをクライアントノードに配布
cookbook_file “/var/chef/handlers/slack_handler.rb” do
source “handler/slack_handler.rb”
mode “0644”
end

Handlerを登録
chef_handler “SlackHandler” do
source “/var/chef/handlers/slack_handler.rb”
arguments [node[‘slack_webhook_url’]] # 設定値はAttributeから渡す
action :enable
end

—

6. 実戦投入のための「極限の知見」

初心者から脱却し、現場で信頼されるSREになるための3つのアドバイスです。

1. 非同期処理を意識する:
外部API(SlackやDatadog)への通信が遅いと、Chef全体の実行時間が伸びてしまいます。もし大規模な環境であれば、通知をバックグラウンドジョブとして処理するアーキテクチャを検討してください。
2. 例外処理を忘れない:
Handler自体がエラーを起こすと、Chefの実行全体が止まるリスクがあります。`begin-rescue`ブロックで、通信エラーが発生してもChefの実行には影響を与えない設計にしましょう。
3. テストには `ChefSpec` を活用:
`chef-client`をいちいち実行してテストするのは非効率です。ChefSpecを使って、Handlerが期待通りに`report`メソッドを呼び出すか、ユニットテストを書いてください。

—

最後に:なぜこれをするのか

インフラの変更を「黙って行う」のは、過去の遺物です。「変更を即座に可視化し、異常を即座に検知する」。このサイクルを作ることが、チームの心理的安全性を高め、障害発生時の初動を劇的に速くします。

今日からあなたのChefは、ただの構成管理ツールではなく、「インフラの番人」へと進化します。ぜひ、自分の環境で試してみてください。もし詰まったら、Chefのログを見ればすべてが書いてあります。それがChefの最高の教科書ですから。

さあ、自動化の世界へようこそ。またお会いしましょう。

タイトルとURLをコピーしました