前回 に引き続き、Puppetを実践で利用するためのテクニックについて解説します。 
Subversionによる設定ファイル/データファイルの管理  
筆者が勤める( 株) paperboy&co.  では、Puppetの設定ファイルやデータファイル(マニフェスト、テンプレート、配布ファイル、モジュール等)をSubversionで管理しています。 Subversionを利用することにより、誰がどの様な変更を行ったかの記録も残るので、変更履歴の追跡や監査、変更のロールバックが可能になります。         
今回、弊社においてどのようにPuppetとSubversionを組み合わせて、設定ファイルやデータファイルを管理しているのかをご紹介します。このやり方がベストというわけではありませんが、ご参考になれば幸いです。   
Puppetサーバ上でのファイルの配置 
Puppetサーバ上では、以下の図のように、/etc/puppet以下に設定ファイルを、/var/puppet/data以下にデータファイルを置いています。データファイルの配置は、第8回 Puppet実践テクニック(その3)  で解説した、『 データファイルの階層構造』と同じものです。Puppetサーバ上のこの2つのディレクトリには、Subversionで管理しないファイルは置かないようにしています。例えば、証明書用のディレクトリは、デフォルトでは/etc/puppet/sslですが、/var/puppet/ssl に変更しています。               
Puppetサーバ上でのファイルの配置 
 
 
Subversionリポジトリ上でのファイルの配置  
Subversionリポジトリ上では、以下のようなファイル配置としています。弊社では複数のサービスを外部に提供しているため、サービスごとに階層をわけています。各サービスディレクトリの下には、trunk、tags、branchesディレクトリがあります。     
Subversionリポジトリ上でのファイルの配置 
 
 
設定ファイルやデータファイルの作成、編集、削除などは、trunkディレクトリの下で行います。tagsの下にあるファイルは、基本的には直接触ることはありません。trunkディレクトリの下は、設定ファイル用のconfディレクトリとデータファイル用のdataディレクトリに分かれます。     
tagsディレクトリの下には、本番環境へリリースするためのファイルをtrunkからコピーして配置します。弊社ではディレクトリ名にリリース日を入れることによって、特定の日と同じ状態へのロールバックがすぐにできるようにしています。  
branchesは、trunkにあるものとまったく異なる設定やマニフェストを試したい、という場合に、実験用のファイルを置くための場所です。   
テストフェーズ  
弊社ではVMWareにより、テスト用のPuppetクライアントとPuppetサーバをサービスごとに用意しています。 
テストフェーズでは、PuppetクライアントとPuppetサーバにPuppetをインストール後、Puppetサーバ上で以下のように、SVNリポジトリから設定ファイルとデータファイルをチェックアウトします。   
$ sudo svn co http://svn.local/puppet/serviceA/trunk/conf /etc/puppet
$ sudo svn co http://svn.local/puppet/serviceA/trunk/data /var/puppet/data  
 
チェックアウト後、ファイルの修正や追加、削除を行い、動作を確認します。動作に問題がなければ、以下のように、設定ファイルとデータファイルをコミットします。     
$ sudo svn ci /etc/puppet
$ sudo svn ci /var/puppet/data  
 
本番フェーズ  
本番フェーズでは、テストフェーズで動作確認がとれた設定ファイルとデータファイルを本番環境へデプロイします。 
trunkからtagsへのコピー 
まずはtrunkからtagsへコピーします。
$ svn cp http://svn.local/puppet/serviceA/trunk http://svn.local/puppet/servieA/tags/REL-20080117  
 
この作業を「タグづけする」とも呼びます。この作業は、特定の時点でのスナップショットをとることにより、変更がされないことを保証するとともに、何かあった場合にすぐロールバックできるようにしておくという意味合いがあります。     
デプロイサーバ上へのファイルのチェックアウト(はじめて本番環境へデプロイする場合)   
弊社ではデプロイ用のサーバを社内に用意しており、このサーバ上にタグづけしたファイルをチェックアウトします。これははじめて本番環境へデプロイする場合にのみ行います。 
$ svn co http://svn.local/puppet/servieA/tags/REL-20080117/conf /var/tmp/serviceA/puppet/conf
$ svn co http://svn.local/puppet/servieA/tags/REL-20080117/data /var/tmp/serviceA/puppet/data  
 
デプロイサーバ上で新たにタグづけされたファイルへの切り替え(2回目以降の本番環境へのデプロイの場合)  
2回目以降のデプロイの場合、過去にタグづけされたファイルがデプロイサーバ上のチェックアウトディレクトリに保存されています。これを新しくタグづけされたファイルに切り替えるために、svn switchを実行します。  
$ svn switch http://svn.local/puppet/servieA/tags/REL-20080117/conf /var/tmp/serviceA/puppet/conf
$ svn switch http://svn.local/puppet/servieA/tags/REL-20080117/data /var/tmp/serviceA/puppet/data  
 
ryncで本番サーバへアップ  
チェックアウトしたファイルを、デプロイサーバから本番サーバへアップします。 
$ rsync -auvz --exclude=.svn/ -e ssh --delete /var/tmp/serviceA/puppet/conf/ server.example.org:/etc/puppet/
$ rsync -auvz --exclude=.svn/ -e ssh --delete /var/tmp/serviceA/puppet/data/ server.example.org:/var/puppet/data/  
 
puppetmasterdの再起動 
本番環境のPuppetサーバ上のpuppetmasterdを再起動します。
$ sudo /etc/init.d/puppetmaster restart  
 
一部のPuppetクライアントで動作確認 
まずは、本番環境上の一部のPuppetクライアントで動作確認します。以下のように、Puppetサーバ上でpuppetrunを実行します。  
$ sudo puppetrun --host staging.example.org  
 
全Puppetクライアントへの適用 
一部のPuppetクライアントでの動作確認に問題がなければ、全てのPuppetクライアントで新しいマニフェスト等を適用します。 
$ sudo puppetrun --all --parallel 5  
 
Archerによる一連の作業の自動化 
弊社では、タグづけからpuppetmasterdの再起動までの一連の作業を株式会社モバイルファクトリー の松野徳大氏が中心となって開発している、Archer というデプロイツールで自動化しています。これにより、本番サーバへのファイルのアップロードからpuppetmasterdの再起動までコマンド一発で実行しているだけでなく、デプロイの完了をメールやIRCに自動で通知しています。   
Archerのソースコードは現在、Coderepos のSVNリポジトリ 上にあります。
テストと本番の差異の吸収 
puppetmasterdが参照するLDAPサーバの設定など、テスト環境と本番環境とで、設定やマニフェストに差異が出てくる場合があります。このような場合、いちいちファイルの内容を書き換えるのは手間もかかりますし、修正漏れや修正ミスなどの危険性があります。    
弊社では設定ファイルの差異は、テストと本番で別ファイルを用意し、テスト環境では以下のようにpuppetmasterdを実行して、テスト用の設定ファイルを読み込ませるようにしています。テスト用の設定ファイルもSubversionで管理しています。   
$ sudo puppetmasterd --config /etc/puppet/puppet.conf.test  
 
また、マニフェストの差異は、Facter変数を利用して、caseやセレクタでリソースの宣言内容を変えています。たとえば、テスト環境は.localというドメインを利用していますので、Facter変数$domainでテスト環境か本番環境かの区別ができます。     
5回に渡り解説してきたPuppet実践テクニックは、今回で終了です。実践でPuppetを利用するために必要な知識は一通り解説できたと思います。次回はPRMやCftといったPuppet関連ツールをご紹介します。