Puppetモジュール開発:世界レベルのインフラを構築するための「疎結合・冪等性」の極意
Puppetはレガシーだと揶揄されることもあるが、それは使い方が間違っているからだ。大規模なクラウドインフラにおいて、数千台のノードを宣言的に制御し、かつ「いつ何度実行しても同じ状態になる」冪等性を担保し続けるには、Puppetのモジュール設計思想こそが最も強力な武器になる。
今回は、単なる「動くコード」ではなく、「チームでスケールし、保守コストを極限まで下げる」ためのPuppetモジュール設計の深淵を伝授する。
—
1. モジュール構造の「聖域」:守るべき標準
ディレクトリ構造を適当に扱うエンジニアは、一生障害対応から抜け出せない。Puppetの標準は「再利用性」のためにある。
/my_module
├── manifests/ # 処理の核心。init.ppは名前空間の入り口としてのみ使う
├── lib/ # Puppetの機能を拡張するRubyコード(Facterや関数)
├── templates/ # EPP/ERBテンプレート。ロジックはmanifestに書くな
├── files/ # 静的ファイル
├── metadata.json # モジュールの魂。依存関係とメタデータ
└── README.md # 他のエンジニアが「なぜ」このモジュールを作ったかを記す
鉄則:`init.pp`を肥大化させるな
`init.pp`はクラスの入り口だ。ここにロジックを書くな。`install.pp`, `config.pp`, `service.pp`に分割し、`init.pp`からは`contain`を使って呼び出すのが、堅牢な構成管理の基本である。
—
2. metadata.json:依存関係は「明示」が正義
`metadata.json`は単なる説明書ではない。Puppetが依存関係を解決するための唯一の根拠だ。
{
“name”: “company-nginx”,
“version”: “1.2.0”,
“author”: “SRE Team”,
“summary”: “High-performance Nginx module”,
“dependencies”: [
{ “name”: “puppetlabs/stdlib”, “version_requirement”: “>= 6.0.0” }
],
“operatingsystem_support”: [
{ “operatingsystem”: “Ubuntu”, “operatingsystemrelease”: [“20.04”, “22.04”] }
]
}
神の知見: `dependencies`を省略するな。これをサボると、現場で「依存パッケージが足りない」という理由だけで深夜の緊急対応が発生する。
—
3. 実践:開発スピードを倍速にするツールチェーン
エディタ設定やローカルテストが遅いと、開発の質は下がる。
推奨プラグイン & 設定
- VS Code: `Puppet` 拡張機能(公式)は必須。
- Puppet Lint: `lint`は「警告」ではなく「エラー」として扱え。CIで`–fail-on-warnings`を強制する。
- Puppet-Parser: ファイル保存時に自動チェックする設定を`.vscode/settings.json`に含め、チーム全員で共有せよ。
隠れたショートカット・効率化
- `pdk` (Puppet Development Kit): これを使わず`mkdir`している時点で負けだ。`pdk new module`でテンプレートを生成し、`pdk test unit`で破壊的な変更を即座に検知しろ。
—
4. ローカルテストの極致:`Test Kitchen` + `Vagrant`
Puppetのコードをいきなり本番環境に適用するのは「自殺行為」だ。`.kitchen.yml`を使い、ローカルで本番同様の環境を立ち上げよ。
—
driver:
name: vagrant
provisioner:
name: puppet_apply
manifests_path: manifests
platforms:
- name: ubuntu-22.04
suites:
- name: default
manifest: init.pp
現場の知見: `kitchen test`で、`puppet apply`の冪等性チェックを必ず行うこと。2回目の実行で何も変更が発生しないことが、真のインフラコードの証だ。
—
5. Puppet Forgeへの公開とチーム内再利用
社内モジュールを共有する際、単にリポジトリを置くだけではダメだ。
1. Semantic Versioning (SemVer): バージョン番号は適当に決めるな。破壊的変更はメジャーアップデートだ。
2. `pdk build`でパッケージ化: 圧縮した`.tar.gz`を管理するのではなく、Gitタグと連携したCIパイプラインで自動ビルドする。
3. 社内Forgeの構築: 外部公開できないコードは、`Puppet Enterprise`の機能か、自前の`Artifactory`をPuppetサーバーのプロキシとして利用せよ。
—
最後に:テックリードからのメッセージ
インフラコードは「一度書いて終わり」ではない。「明日、自分以外の人間がこのコードを修正しても壊れない状態」を維持することこそが、SREとしての最高の成果物だ。
- `stdlib`を使い倒せ(`ensure_resource`で重複定義を防げ)。
- テンプレートには`epp`を使え(`erb`よりも遥かに安全で堅牢だ)。
- 設定ファイルはYAMLで管理し、`create_resources`でデータ駆動型設計にせよ。
これらを徹底すれば、あなたの管理するインフラは「自動化されている」というレベルを超え、「自己修復するシステム」へと進化する。健闘を祈る。