Chefの真価は「Ohai」にあり:カスタムプラグインで実現するインフラの「自己認識」
Chefを使っている多くのエンジニアが、`node[‘cpu’][‘total’]` や `node[‘ipaddress’]` といった標準のAutomatic Attributesに頼り切りになっていないだろうか。
はっきり言おう。標準的な属性だけでインフラを語るな。
真のIaCの達人は、インフラが自らの文脈(コンテキスト)を把握している状態を作る。クラウド固有のメタデータ、ビジネスロジックに直結したアプリケーションの稼働状況、あるいは特定のベンダーが提供する特殊なハードウェア情報。これらをChefのノードオブジェクトに統合することで、レシピは劇的に簡素化され、条件分岐の地獄から解放される。
今日は、Chefの心臓部である「Ohai」を拡張し、インフラに「自己認識能力」を持たせるための深淵なるテクニックを伝授する。
—
1. なぜカスタムOhaiプラグインが必要なのか
Chefの実行時、OhaiはハードウェアやOSの情報を収集する。しかし、ビジネス要件が複雑化すればするほど、標準情報だけでは足りなくなる。
- クラウドのタグ情報をノード属性に落とし込みたい
- アプリケーションが依存する固有のデプロイIDを動的に取得したい
- 物理サーバーの特定の管理カード(BMC)情報をChefで見たい
これらをレシピ内で何度もシェルコマンドを実行して取得するのは、冪等性の観点からもパフォーマンスの観点からも「悪手」だ。Ohaiプラグインで一度収集し、ノード属性として固定化することで、レシピは「宣言的」な記述に専念できる。
2. 実践:カスタムOhaiプラグインの開発
OhaiプラグインはRubyで記述する。`Ohai.plugin(:Name)` で定義し、`collect_data` メソッドで属性を生成する。
コード例:クラウドの特定メタデータを取得するプラグイン
`/etc/chef/ohai/plugins/custom_meta.rb` として配置する例だ。
/etc/chef/ohai/plugins/custom_meta.rb
Ohai.plugin(:CustomMeta) do
# プラグインの提供する属性の名前空間
provides ‘custom_meta’
# 収集フェーズ
collect_data(:default) do
custom_meta Mash.new
# 外部APIやシェルコマンドから情報を取得
# 注意:ここはChefの実行毎に動くため、極力軽量にすること
begin
# 例: AWSインスタンスメタデータから特定のタグ情報を取得するダミーロジック
# 実際には net/http などを使ってメタデータサービスを叩く
custom_meta[:deployment_group] = “production-cluster-01”
custom_meta[:is_optimized] = true
rescue => e
Chef::Log.warn(“Failed to collect custom_meta: #{e.message}”)
end
end
end
開発のベストプラクティス
1. 非同期を意識せよ: ネットワークI/Oを伴う処理はタイムアウトを設定する。これがブロッキングするとChefの実行時間全体が死ぬ。
2. `Mash` を使う: Ohaiの属性は必ず `Mash` (Hashの拡張) を使うこと。これで属性へのアクセスが `node[‘custom_meta’][‘deployment_group’]` のように直感的になる。
3. テスト駆動開発(TDD): `ohai` コマンドを使い、プラグイン単体での動作確認を徹底せよ。
# プラグインのパスを指定して実行確認
ohai -d /etc/chef/ohai/plugins/ -p custom_meta
—
3. 現場を加速させる「神」環境設定
Chefの開発スピードを劇的に上げるには、ツールチェインの最適化が不可欠だ。
隠れたキーボードショートカット (VS Code)
- `Cmd + Shift + P` -> `Chef: Preview Policyfile` : 複雑なPolicyfileの依存関係を即座に視覚化する。
- `Cmd + K, Cmd + F` : Rubyコードの自動インデント。ChefのDSLはネストが深くなりがちなので、必須。
絶対に入れるべき神プラグイン
- Chef Extension for VS Code: 構文ハイライトだけでなく、テスト実行(`kitchen test`)をコンテキストメニューから実行できる。
- RuboCop: ChefのDSL特有の記法(例えば `node[‘key’]` ではなく `node.default[‘key’]` を使うべき場面など)を自動で修正させる。
—
4. チーム開発における設定共有のルール
属人化を防ぐための「設定の正規化」はチームの生命線だ。
1. `chef-repo` の構造は「Policyfile」で統一せよ:
従来の `Environment` や `Role` を使った管理はもう古い。すべてを `Policyfile.rb` に集約し、インフラ構成を「コードのバージョン」として管理する。
# Policyfile.rb の基本構成
name ‘web_server’
default_source :supermarket
run_list ‘recipe[my_cookbook::default]’
# 特定の属性固定化もここで完結させる
default[‘my_cookbook’][‘param’] = ‘value’
2. 設定ファイルはJSONではなく、JSON+コメントで「意図」を残せ:
設定ファイル(`attributes/default.rb` 等)には必ず「なぜその値なのか」をコメントで残す。IaCにおける最大の敵は、「なぜこの値になっているのか誰にも分からない」という負債だ。
—
最後に:SREとして生き残るために
Chefは「古いツール」と揶揄されることもある。しかし、OSレイヤーまで制御し、複雑な状態を冪等的に管理できる能力は、コンテナ時代においても決して色褪せない。
Ohaiプラグインを書くということは、単に情報を取得する以上の意味がある。それは、「インフラにどのような文脈を持たせるか」をエンジニア自身が定義する行為だ。
自動化されたインフラは、ただ動くだけではダメだ。自らの状態を語れるインフラを作れ。それが、真のSREへの第一歩だ。
コードを書け。そして、システムを支配しろ。