先ほど書きました、HTTPサーバーをインストールする手順を、もう一度思い出してみましょう。
Puppetでは「パッケージのインストール」「設定ファイルの作成」「サービスの設定」といった作業を「リソース」という概念で管理しています。パッケージの管理はpackageリソース、ファイルの管理はfileリソース、サービスの管理はserviceリソースという具合です。マニフェストではリソースに“属性”の情報を与えてシステムの“あるべき姿”を指示します。以下にリソースの中でも特に重要な「Core Types」と呼ばれる8種類のリソースを紹介します。
file | ローカルファイルシステム上のファイルを管理 |
---|---|
package | ソフトウェアパッケージを管理。CentOSなどRed Hat系のOSではyumコマンドを呼び出す形で動作するため、パッケージのインストールにはインストールDVDなど必要なパッケージに対して連載第2回で紹介したようなYumリポジトリとしてアクセスできる準備が必要になる |
service | サービスの起動/停止/再起動や、自動起動の設定を行う |
notify | ログにメッセージを出力 |
exec | 指定のコマンドを実行 |
cron | cronのジョブを管理 |
user | ユーザーアカウントを管理 |
group | グループを管理 |
使い方などの詳細は『Core Types Cheat Sheet』(PDF)を参照してください |
それでは先ほどの作業手順を実行するマニフェストを作ってみましょう。基本形は以下のようになります。
[リソース名] { 'インスタンス名称':
属性名 => 属性値,
: (繰り返し)
}
作業手順のうち「1. HTTPサーバーのパッケージをインストール」をマニフェストで表現してみます。packageリソースは先ほど紹介した『Core Types Cheat Sheet』を参照すると、『パッケージをインストールするには「ensure」属性で「present」を指定』とあります。パッケージ名は「name」属性で指定しますが、デフォルトでインスタンス名称が使われますので、ここではCentOSでのパッケージ名である「httpd」を指定します。では実際に記述してみましょう。入力が終わりましたら「test.pp」などのファイル名で保存してください。
package { 'httpd': ensure => present, }
これだけでHTTPサーバーのパッケージをインストールできます。
実際に試してみたいところですが、いきなり本当にインストールしてしまうのではなく、マニフェストを実行はしますがシステムへの変更はしない「ドライラン」で動かしてみましょう。
前回少し紹介しましたが、ドライランの場合は「--noop」オプションを付けて実行します。また、ローカルのファイルに保存されたマニフェストを実行するので「puppet apply」コマンドで実行します。このコマンドは構築対象のサーバー上で実行してください。それでは試してみましょう。以下のようにコマンドを実行してください(本連載で筆者はCentOS 6.5とPuppet 3.7.3を用いています)。
# puppet apply --noop test.pp Notice: Compiled catalog for dock01 in environment production in 0.58 seconds Notice: /Stage[main]/Main/Package[httpd]/ensure: current_value absent, should be present (noop) Notice: Class[Main]: Would have triggered 'refresh' from 1 events Notice: Stage[main]: Would have triggered 'refresh' from 1 events Notice: Finished catalog run in 0.26 seconds
このような結果になりましたか?環境によっては「Warning: Could not retrieve fact fqdn」という警告が出るかもしれません。この警告はFQDN名が取得できなかった場合に出ますが、実行には影響ありませんので無視して構いません。エラーが出た場合はマニフェストを見直してください。
動作が確認できたら、作業手順の残りもマニフェスト化しましょう。設定ファイルはfileリソース、サービス設定はserviceリソースを使います。結果、以下のようなマニフェストになります。
package { 'httpd': ensure => present, } file { '/etc/httpd/conf/httpd.conf': ensure => present, content => template('/root/httpd.conf.erb'), } service { 'httpd': ensure => running, enable => true, }
ここで属性について簡単に説明します。詳細は先ほど紹介した『Core Types Cheat Sheet』を参照してください。
fileリソースではensure属性とcontent属性を指定しています。fileリソースでのensure属性は、作成するもの(ファイル、ディレクトリ、シンボリックリンクなど)を指定します。
content属性は作成するファイルの中身を記述できます。ここでは「テンプレート」を指定していますが、テンプレートについては詳細は後述します。“インスタンス名称”では対象をフルパスで指定します。
serviceリソースではensure属性とenable属性を指定しています。serviceリソースでのensure属性はサービスのあるべき状態(実行中、停止中)を指定します。enable属性ではサービスの自動実行設定を指定します。インスタンス名称では対象サービスを指定します。
さて、このマニフェスト、一見問題なさそうに見えますが、このままだと不具合があります。先ほど手順には“依存関係”があるというお話をしましたが、このマニフェストには“依存関係”が記述されていません。マニフェスト上は順番通りになっているのにと思われたかもしれませんが、Puppet言語での記述順と実際に実行される順番は一致しません。依存関係は各リソースで属性として、以下を指定します。
require | 指定したリソースが適用された後に実行 |
---|---|
before | 指定したリソースが適用される前に実行 |
ここで特定のリソースを指定する必要がありますが、Puppet言語ではある特定のリソースを指定(「リソース参照」と言います)するにはリソース名の先頭を大文字にします。
これでは分かりにくいので具体的に書いてみます。先ほどのpackageリソース、fileリソース、serviceリソースは以下のように記述します。
Package['httpd'] File['/etc/httpd/conf/httpd.conf'] Service['httpd']
リソース名の先頭が大文字になる以外に、括弧の記号が波括弧{}ではなく角括弧[]になっていることに注意してください。またインスタンス名の後にあったコロン:は不要です。では先ほどのマニフェストに依存関係を追加してみましょう。
package { 'httpd': ensure => present, } file { '/etc/httpd/conf/httpd.conf': ensure => present, content => template('/root/httpd.conf.erb'), require => Package['httpd'], } service { 'httpd': ensure => running, enable => true, require => File['/etc/httpd/conf/httpd.conf'], }
これで各作業の依存関係を記述できました。
このままでも動作しますが、より良くするため運用に入ってからのことを考えてみましょう。K男さんからの指示でも「設定変更はマニフェストの変更で対応とすること」とありましたので、マニフェスト側の変更だけで対応できなくてはなりませんので。
運用に入ってからメンテナンスする際に、設定ファイルを変更するのはよくあることですが、設定ファイルを変更するとサービスの再起動が必要ですね。今のマニフェストを見ると、serviceリソースでは単に“サービスが起動しており、自動起動設定になっていること”だけ定義しています。運用中だと、すでに定義されている“あるべき状態”になっているので、fileリソースで何か変更があってもserviceリソースでは何もしません。
それだと運用などのシーンでは困ってしまいますので、そのような用途にPuppet言語ではリソースに変更があったときにイベントを送出して、再起動などのリフレッシュ動作をさせる機能があります。依存関係の記述に以下を指定します。
subscribe | 指定したリソースからリフレッシュイベントを受け取る。それ以外の動作はrequireと同様 |
---|---|
notify | 指定したリソースにリフレッシュイベントを送出する。それ以外の動作はbeforeと同様 |
ちなみに先ほどリソース名としてのnotifyを紹介していますが、ここで紹介したのは属性のnotifyです。名称は同じですが別物です。ちょっと混同しやすいので注意してください。
それではserviceリソースがfileリソースからイベントを受け取るので、マニフェストを修正しましょう。
package { 'httpd': ensure => present, } file { '/etc/httpd/conf/httpd.conf': ensure => present, content => template('/root/httpd.conf.erb'), require => Package['httpd'], } service { 'httpd': ensure => running, enable => true, subscribe => File['/etc/httpd/conf/httpd.conf'], }
こうすると、運用に入ってからメンテナンスなどで設定ファイルを修正した場合でも、サービスが自動的に再起動するようになります。
デフォルトの設定でPuppetを動かすと、以下のようなdeprecated警告が表示されることがあります。
Warning: Setting modulepath is deprecated in puppet.conf. See http://links.puppetlabs.com/env-settings-deprecations (at /usr/lib/ruby/site_ruby/1.8/puppet/settings.rb:1119:in `issue_deprecation_warning') package {'httpd': ensure => present, }
これは将来のリリースで廃止される予定の機能を使った場合に出ます。現行バージョンを使っている分には特に問題ないので、deprecated警告を表示させないようにするには、「/etc/puppet/puppt.conf」の[main]に以下の設定を追加してください。
disable_warnings = deprecations
Copyright © ITmedia, Inc. All Rights Reserved.