【実務・中級編】Puppet Manifest(マニフェスト)の書き方入門!基本構文とリソース定義のルール – インフラ構成管理(IaC)活用バイブル

Puppetを「単なる設定ツール」で終わらせるな:堅牢なインフラを構築する「宣言的プログラミング」の極意

Puppetを触り始めたエンジニアの多くは、単に「設定を流し込むスクリプト」として扱いがちだ。だが、それはPuppetが持つ「宣言的モデル」という真の力を放棄しているに等しい。

真のSREは、Puppetを「状態を維持し続ける自律型エージェントの司令塔」として設計する。本稿では、現場の泥臭い運用を自動化し、冪等性(Idempotency)を数学的に担保するための「Puppetマニフェスト設計」の極限を伝授する。

—

1. Puppetマニフェスト:宣言的記述の鉄則

Puppetは「どうやるか(How)」ではなく「どうあるべきか(What)」を記述する。この設計思想を理解していないと、コードはスパゲッティ化し、適用するたびに結果が変わる「非決定的なインフラ」が完成する。

基本構文とリソース定義のルール

リソースは「型(Type)」と「タイトル(Title)」、そして「属性(Attributes)」の集合体だ。

基本形: fileリソースの定義
file { ‘/etc/nginx/nginx.conf’:
ensure => file, # ファイルの存在確認
owner => ‘root’, # 所有者
group => ‘root’, # グループ
mode => ‘0644’, # 権限
source => ‘puppet:///modules/nginx/nginx.conf’, # ソースの指定
notify => Service[‘nginx’], # 変更時にサービスを再起動(重要!)
}

プロの鉄則:

  • 依存関係を明示せよ: `require`や`before`、`notify`を使って、適用順序をグラフ理論として定義する。
  • DRY(Don’t Repeat Yourself): 共通設定は`Class`と`Define`に括り出し、パラメータ化して使い回す。

—

2. 現場で震えるほど役立つ「冪等性」の極意

Puppetの最大の武器は「実行回数に関わらず結果が同じになること」だ。しかし、不用意に`exec`リソース(シェルコマンドの実行)を乱用すると、この牙城は崩壊する。

冪等性を破壊しないための3原則

1. execは最終手段: `package`や`file`で実現できない場合のみ使用する。
2. creates属性の活用: コマンドが実行された証拠となるファイルを`creates`で指定し、存在すればスキップさせる。
3. onlyif/unlessの徹底: 状態をチェックするコマンドを必ず挟む。

悪い例: 毎回実行されてしまう
exec { ‘install-app’:
command => ‘/usr/local/bin/deploy.sh’,
}

良い例: 冪等性が担保されている
exec { ‘install-app’:
command => ‘/usr/local/bin/deploy.sh’,
creates => ‘/opt/app/.installed’, # このファイルがあれば実行しない
}

—

3. 開発スピードを劇的に高める「プロのツールセット」

チームの生産性を上げるには、IDEの環境構築から逃げてはならない。

必須の神プラグイン & 設定

  • VS Code用 Puppet拡張機能: Puppet Labs公式のもの。構文ハイライトだけでなく、リソースのバリデーションまでリアルタイムで行う。
  • Puppet Lint: コミット前に必ず通すこと。コードスタイルを統一し、レビューでの「インデント指摘」という無駄な時間をゼロにする。
  • Hiera活用: 設定(YAML)とコード(Puppet)を完全に分離する。ノードごとの特性は`hiera.yaml`で階層化して管理するのが鉄則だ。

Hieraのベストプラクティス例(`data/common.yaml`):

環境ごとの差異をデータ化して分離する
nginx::worker_processes: 4
nginx::max_connections: 1024

—

4. 実践:高可用性を意識したマニフェストサンプル

以下は、パッケージのインストールから設定、サービス起動までを「冪等性」を担保しつつ記述した例だ。

Class: nginx::install
Nginxのインストールと管理を一手に引き受ける
class nginx (
String $package_name = ‘nginx’,
String $service_name = ‘nginx’,
) {
# パッケージのインストール
package { $package_name:
ensure => installed,
}

# 設定ファイルの管理
file { ‘/etc/nginx/nginx.conf’:
ensure => file,
content => template(‘nginx/nginx.conf.erb’), # ERBテンプレートで動的に生成
require => Package[$package_name], # パッケージ導入後に実行
notify => Service[$service_name], # 変更時はサービスを再起動
}

# サービスの管理
service { $service_name:
ensure => running,
enable => true,
}
}

—

最後に:チームへの提言

Puppetのコードは「ドキュメント」であるべきだ。誰が見ても、「このサーバーがどうあるべきか」が瞬時に理解できる状態を目指してほしい。

1. コードレビューの自動化: `puppet-lint` と `rspec-puppet` をCIに組み込め。人間がコードスタイルを指摘する時代は終わった。
2. モジュール設計: `site.pp`に全てを詰め込むのは初心者のやることだ。役割ごとにモジュールを分け、`roles`と`profiles`のパターンを採用せよ。
3. 常に「破壊」を想定: `puppet agent –test` を実行しても、サーバーの挙動が一切変わらない状態(=収束状態)こそが、インフラエンジニアの目指すべきゴールだ。

この設計思想を胸に、君たちのインフラを「触れるのが怖いモノ」から「何度でも自動再構築できるモノ」へと進化させてくれ。健闘を祈る。

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