【入門編】Chefリソースの実行順序でハマる人続出!notifiesとsubscribes、delayedとimmediateの挙動を完全理解する – インフラ構成管理(IaC)活用バイブル

Chefの「実行順序」で夜を明かさないために:notifiesとsubscribesの深淵を解き明かす

こんにちは。インフラをコードで支配するSREの世界へようこそ。

Chefを触り始めたエンジニアが必ずぶつかる壁、それは「なぜか設定ファイルが書き換わったのに、サービスが再起動しない」あるいは「サービスが再起動するはずのないタイミングで落ちた」という怪奇現象です。

これ、実はChefの「収束フェーズ(Convergence Phase)」における通知の仕組みを理解できていないことが原因です。今日は、Chefの心臓部である `notifies` と `subscribes`、そして実行タイミングの魔術である `delayed` と `immediate` を完全攻略しましょう。

—

1. Chefの「実行順序」の基本原則を理解する

まず大前提として、Chefは「宣言的」なツールです。しかし、レシピ内のリソースは「上から順に実行」されます。

ここで重要なのは、Chefには「Compileフェーズ(コードを解析する)」と「Convergeフェーズ(実際にリソースを適用する)」の2段階があることです。`notifies` は、この「Convergeフェーズ」でリソースの状態が変化(updated)した瞬間に発火するトリガーです。

なぜ `notifies` が必要なのか?

設定ファイル(例: `nginx.conf`)を書き換えるだけでは、サービスは新設定を読み込みません。Chefに「変更があったら、あわせてこれも実行してくれ」と伝えるための糊(のり)、それが通知機能なのです。

—

2. 実践!通知の魔術:notifiesとsubscribes

A. `notifies`(能動的な通知)

「私が変わったら、お前も動け」というプッシュ型のアプローチです。

/etc/nginx/nginx.conf が変更されたら、nginxサービスをリロードする
template ‘/etc/nginx/nginx.conf’ do
source ‘nginx.conf.erb’
# :restart ではなく :reload が推奨(ダウンタイムを最小化するため)
notifies :reload, ‘service[nginx]’, :delayed
end

service ‘nginx’ do
action [:enable, :start]
end

B. `subscribes`(受動的な監視)

「私はあいつを監視する。あいつが変わったら、私は動く」というプル型のアプローチです。

逆の書き方:サービス側から設定ファイルを監視する
service ‘nginx’ do
action [:enable, :start]
subscribes :reload, ‘template[/etc/nginx/nginx.conf]’, :delayed
end

どちらを使うべきか?現場のベストプラクティスとしては、「変更の発生源(templateやpackage)に `notifies` を書く」方が、コードの依存関係が直感的になり、可読性が高まります。

—

3. 「即時」か「遅延」か:ここがバグの温床だ

ここが今回のハイライトです。通知には2つのタイミングが選べます。

  • :delayed (デフォルト)
  • 挙動: Chefの全リソース処理が終わった「最後」に実行される。
  • メリット: 複数箇所で同じ通知が発生しても、実行は「1回」にまとめられる。効率的で安全。
  • :immediate
  • 挙動: リソースが変化した「その瞬間」に実行される。
  • メリット: 設定反映を即座に行いたい場合。ただし、依存関係が複雑な場合に予期せぬ挙動を生む。

現場で震えるほど役立つTIPS:なぜ :delayed を使うべきか

例えば、`template` を3箇所で更新したとします。もし通知が `:immediate` だと、サービスは3回再起動します。これではダウンタイムの嵐です。`:delayed` なら、Chefは賢く「最後の一回だけ」再起動してくれます。

—

4. 精度高い「HelloWorld」的セットアップ

実際に手を動かしてみましょう。まずはChef Workstationをインストールし、ローカルで実行を確認します。

1. インストール (macOSの場合)

brew install –cask chef-workstation

2. 動作確認用ディレクトリ作成

mkdir chef-test && cd chef-test
# 最小構成のレシピファイルを作成
vi recipe.rb

3. レシピ(recipe.rb)の記述

# ファイル作成
file ‘/tmp/hello.txt’ do
content ‘Hello, Chef World!’
notifies :run, ‘execute[log_message]’, :immediate
end

# 実行ログ出力
execute ‘log_message’ do
command ‘echo “Change detected!”‘
action :nothing # 明示的に指示されるまで実行しない
end

4. 実行!

chef-apply recipe.rb

初回実行時はファイルが作られ、即座にログが出ます。2回目に実行すると、ファイルに変化がないため、`execute` は実行されません。これが「冪等性(べきとうせい)」の真髄です。

—

最後に:先輩からのアドバイス

「なぜか動かない」と感じた時は、`chef-apply` に `-l debug` オプションをつけて実行してみてください。Chefがどのリソースで何を感じ取り、どの通知をキューに入れたのかが、詳細に表示されます。

Chefは決して難しい魔法ではありません。リソースの状態を記述し、その連鎖を `notifies` で繋ぐ。この設計思想さえ掴めば、あなたはインフラの混沌をコントロールするマスターになれます。

さあ、次はどんなインフラをコードで自動化しましょうか?応援していますよ。

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