入門 Puppet ダイジェスト

入門 Puppet ダイジェスト


(ダイジェスト版を)書いた人:柴田博志 (@hsbt)

ダイジェスト版によせて

本書は @kentaro 氏の「入門 Puppet」を著者の許諾を得て、@hsbt が前半の数章を抜粋し編集したものです。

はじめに

クラウドが一般的になってきた昨今、サーバ構成管理の自動化は、もはやそれなしでは考えられないほど当たり前のものになっています。Puppet は、そのためのフレームワークのひとつです。

Puppet は 2005 年のリリース以来、後発の Chef とともに、サーバ構成管理の自動化に欠かせないフレームワークとして広く利用されてきました。とはいえ、ドキュメントが非常に充実してはいるもののその機能は膨大で、初心者にとって決してとっつきやすいものでないことは確かでしょう。現に、筆者の周りでも「Puppet を学習してみたいけど、どこから手をつけたらいいのか……」という声をよくききます。

クラウドの一般化によって、物理的な制約から離れ、サーバをあたかもプログラム上のオブジェクトであるかのように扱えるようになった現在、エンジニアにとって、Puppet のような自動化ツールを使いこなせるようになることは、技術スキルの向上に大きく寄与するでしょう。この本は、既に Puppet などの自動化ツールを使いこなしているオペレーションエンジニアよりもむしろ、技術向上への意欲を燃やすアプリケーション開発者への入門となることを目指しています。

本書の目標は、この本を読んだ読者が Puppet の基本についてひととおり知り、オペレーションエンジニアの書いた manifest (サーバのあるべき状態を記述した設定ファイルのようなもの。後述) に変更を加えたり、ある程度の規模のものなら自力でいちから書けるようになったりすることです。そのため、本書はあえてリファレンスとしての網羅性を目指しません。実際の学習段階で必要となる知識にしぼって説明します。

是非、本書を読みながら自分でも手を動かしてみて、一歩先行くエンジニアになってみませんか。

システム環境

本書執筆時の、筆者のシステム環境は以下の通りです。

  • 作業環境: Mac OSX 10.8.2 + ruby 2.0.0
  • 本番環境: Amazon Linux AMI 2013.03 + ruby 1.8.7
  • 開発環境: Vagrant 1.1.5 + CentOS 6.4 + ruby 1.8.7
  • Puppet: 3.1.1

現状、最も広く使われている Puppet のバージョンは 2.7 系だと思われますが、本書における説明の範囲内では、3.1 系でもたいした違いはありませんので、ご安心ください。

Vagrant で開発環境を用意する

本書では、「はじめに」で述べたように、Puppet の実行環境として Linux (Amazon Linux と CentOS) を使用します。といっても、いますぐ手元に、自分の自由になる Linux 環境を用意できないという読者も多いでしょう。

そこで、Puppet の実践に入る前に、まずは Vagrant というツールを使って、開発環境を用意してみましょう。

Vagrant とは?

Vagrantは、VirtualBoxVMwareAmazon EC2といった仮想化ツールを、簡単にコントロールするためのラッパツールです。元々は VirtualBox 専用に開発されたものでしたが、本書で使用するバージョン 1.1 以降は、Providers という仕組みを導入したことで、プラグインによって VirtualBox 以外の仮想化ツールにも対応するようになりました。

本書では、これまで Vagrant での利用実績が豊富な VirtualBox を使っていくことにします。

ちなみに、Vagrant には Puppet と連携できる機能があり、仮想ホストの起動時や起動後に、指定した設定をもとに manifest を適用する仕組みがあります。しかし、本書は現場で使える Puppet 入門を目指しており、より実践的な方法を採るため、その機能は使いません。

Vagrant のインストール

まずは VirtualBox をインストールしましょう。VirtualBox のダウンロードページからお使いの環境にあったパッケージをダウンロードし、インストーラの指示に従ってインストールしてください。

VirtualBox のインストールが終わったら、今度は Vagrant をインストールします。Vagrant のダウンロードページからお使いの環境にあったパッケージをダウンロードしてください。その際、本書の環境と合わせるため、1.1.0 以上のバージョンをダウンロードするようにしてください。その後、インストーラの指示に従ってインストールします。

仮想ホストの起動

Vagrant で利用できる仮想ホストのひな形 (box といいます) は、有志により様々なディストリビューションのものが用意されています http://www.vagrantbox.es/ 。また、Puppet 提供元の Puppet Labs からも、様々なディストリビューションの box が提供されています http://puppet-vagrant-boxes.puppetlabs.com/

本書では、Puppet Labs が提供する CentOS 6.4 の box を利用します。

http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210.box

仮想ホストを起動するための設定は、非常に簡単です。適当なディレクトリで、以下のコマンドを実行します。

 $ vagrant init

すると、コマンドを実行したディレクトリに Vagrantfile というファイルが作成されます。中を見てみるといろいろ書かれていますが、本書の範囲内で必要とする設定はわずかです。設定の詳細については Vagrant のドキュメントを見ていただくとして、ここではまず、以下の内容に変更してください。

 Vagrant.configure("2") do |config|
   config.vm.box      = "centos-6.4-puppet"
   config.vm.box_url  = "http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210.box"
   config.vm.hostname = "puppet-book.local"
 end

このファイルでは、以下の設定を行っています。

  • 仮想ホストに使用する box 名の指定
  • box が存在しなかった場合に取得する先の URL
  • 仮想ホストの hostname の指定

ファイルを作成したのと同じディレクトリで、vagrant up コマンドを実行すると、仮想ホストが起動します。

 $ vagrant up
 Bringing machine 'default' up with 'virtualbox' provider...
 [default] Box 'centos-6.4-puppet' was not found. Fetching box from specified URL for
 the provider 'virtualbox'. Note that if the URL does not have
 a box for this provider, you should interrupt Vagrant now and add
 the box yourself. Otherwise Vagrant will attempt to download the
 full box prior to discovering this error.
 Downloading with Vagrant::Downloaders::HTTP...
 Downloading box: http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210.box
 Extracting box...
 Cleaning up downloaded box...
 Successfully added box 'centos-6.4-puppet' with provider 'virtualbox'!
 [default] Importing base box 'centos-6.4-puppet'...
 [default] Matching MAC address for NAT networking...
 [default] Setting the name of the VM...
 [default] Clearing any previously set forwarded ports...
 [default] Creating shared folders metadata...
 [default] Clearing any previously set network interfaces...
 [default] Preparing network interfaces based on configuration...
 [default] Forwarding ports...
 [default] -- 22 => 2222 (adapter 1)
 [default] Booting VM...
 [default] Waiting for VM to boot. This can take a few minutes.
 [default] VM booted and ready for use!
 [default] Setting hostname...
 [default] Configuring and enabling network interfaces...
 [default] Mounting shared folders...
 [default] -- /vagrant

以下、本書の説明を通じて、vagrant コマンドは、Vagrantfile のあるディレクトリで実行してください。

初回実行時には、box をダウンロードするために時間がかかりますが、次回からは既にダウンロードした box を使用するため、すぐに起動します。

仮想ホストに SSH ログインする

以下のコマンドを実行すると、仮想ホストに SSH でログインできます。

 $ vagrant ssh

また、のちの章では通常の ssh コマンドによるログインが必要になりますので、以下のようにコマンドを実行して、準備しておいてください。

 $ vagrant ssh-config --host puppet-book.local >> ~/.ssh/config

これで、いつものように ssh コマンドで仮想ホスト (ここでは puppet-book.local というホスト名を指定) にログインできます。

 $ ssh puppet-book.local

ログインしたら、適当にコマンドを実行してみたりして、触ってみてください。ふだん使っている Linux と変わらない環境が簡単にできてしまったことに、驚くことでしょう。

また、あれこれといじってみた結果、たとえ壊してしまったとしても、後述の通り簡単にリセットして元通りにできますので、安心です。

仮想ホストの停止・破棄

仮想ホストを停止するには halt サブコマンドを、破棄 (リセット) するには destroy サブコマンドを使います。

 $ vagrant halt

を実行すると一時停止、

 $ vagrant destroy

で破棄 (リセット) されます。再度、仮想ホストを起動したい場合は、最初と同じく

 $ vagrant up

を実行してください。

Vagrant には、上記で紹介したものの他にもたくさんの便利なサブコマンドがありますが、本書の範囲内では、以上で十分です。より詳しく知りたい方は、Vagrant のドキュメントを参照するとよいでしょう。

Vagrant を使うと、仮想ホストを vagrant up で起動し、あれこれいじった後に気に入らなくなってきたら vagrant destroy でまっさらなんてことも、簡単にできてしまいます。これから Puppet でこの仮想ホストをいじり倒していくには、もってこいの機能です。

manifest を書いていく途上で、何度も仮想ホストを作り直していくことになるでしょう。言葉を変えていえば、何度作り直しても manifest さえあればすぐに元通りになるという状態を作っていくことが「あるべき状態を記述する」ということになるのです。

Hello, Puppet!

開発環境も整ったところで、さっそく Puppet を始めましょう。本章では、定番の “Hello, World!” を Puppet で実行してみます。さらに、もうすこし実践的な例として、Puppet を使ってパッケージをインストールする方法を紹介します。

まずはざっくりと、Puppet を使う最初の一歩を簡単な例から始めることにしましょう。

Puppet のインストール

実は、前章で準備した Vagrant の仮想ホストには、最初から Puppet がインストールされています。そのため、Puppet を特別にインストールする必要はありません。vagrant ssh で仮想ホストにログインして、確かめてみましょう。

 $ vagrant ssh
 Welcome to your Vagrant-built virtual machine.
 [vagrant@puppet-book ~]$ puppet --version
 3.1.1

本書執筆時点で最新のバージョン、3.1.1 が既に入っているのを確認できます。

以下、本書全体を通して、次の表記によりホスト OS 上と仮想ホスト上とでのコマンド実行を区別します (Vagrant を使わずに本書を読み進める場合は、適宜読み替えてください)。

  • $ のみで始まる行はホスト OS でのコマンド実行
  • [vagrant@puppet-book ~]$ のように、[vagrant@ホスト名 ディレクトリ名]$ から始まる行は仮想ホストでのコマンド実行

本書の前提とする以外の、Puppet がインストールされていない環境では、以下のように gem コマンドによってインストールできます。

 [vagrant@puppet-book ~]$ sudo gem install puppet --no-rdoc --no-ri
 Successfully installed facter-1.6.18
 Successfully installed json_pure-1.7.7
 Successfully installed hiera-1.2.0
 Successfully installed puppet-3.1.1
 4 gems installed

ちなみに、Vagrant で起動した仮想ホストでは、デフォルトのログインユーザである vagrant ユーザが、パスワードの入力なしに sudo コマンドを実行できるよう設定されています。

manifest を置く場所

さて、さっそく manifest を書いていきましょう。とはいっても、どこにファイルを置けばいいのでしょうか。ここでも Vagrant がその便利さを発揮します。

仮想ホストにログインした状態で、/vagrant ディレクトリに移動し、ls コマンドを実行してみてください。

 [vagrant@puppet-book ~]$ cd /vagrant
 [vagrant@puppet-book vagrant]$ ls
 Vagrantfile  puppet

Vagrantfile が見えますね。Vagrant は、特に指定しなくても、仮想ホストの /vagrant ディレクトリに、ホスト OS 上の Vagrantfile のあるディレクトリをマウントしてくれます。また、サンプルコードを git clone した場合は、puppet ディレクトリも見えているはずです。

これから manifest を書いていく際は、ホスト OS 上でファイルの作成・編集を行い、Puppet の実行のみを仮想ホスト上で行うことにします。そうすることで、ファイルの編集をホスト OS 上でいつも使っているエディタで行いつつ、Puppet の実行は仮想ホストで、といったことが可能になり、とても便利です。

manifest を書いてみる

まずはホスト OS 上で、manifest を置くためのディレクトリを作成しましょう。なお、このディレクトリの作成は必須ではなく、単純に、のちの章で作成するものとわけて置くほうが整理されていいだろうというだけの理由です。

 $ mkdir -p puppet/hello_puppet
 $ cd puppet/hello_puppet/

次に、以下の内容で、hello_world.pp というファイルを作成します。

 notice("Hello, World!")

このように、Puppet の manifest ファイルは、.pp という拡張子をつけることになっています。

manifest を適用する

この manifest を適用してみましょう。今度は、仮想ホスト上で manifest ファイルのあるディレクトリに移動してから、puppet apply コマンドを実行します。

 [vagrant@puppet-book ~]$ cd /vagrant/puppet/hello_puppet/
 [vagrant@puppet-book hello_puppet]$ puppet apply hello_world.pp
 Notice: Scope(Class[main]): Hello, World!
 Notice: Finished catalog run in 0.03 seconds

“Hello, World!” と表示されています。簡単ですね。

パッケージをインストールする

さて、”Hello, World!” の表示からもう一歩すすんで、今度は実際にシステムの状態を変更する操作を行ってみましょう。ここでは zsh を、Puppet を使ってインストールします。

さきほどの hello_world.pp と同階層に、以下の内容で zsh.pp というファイルを作成してください。

 package { 'zsh':
   ensure => installed,
 }

今度は、新しく作成したファイルを引数にして puppet apply を実行します。今度は、ログの表示だけではなく、システムへの変更 (yum コマンドによるパッケージのインストール) も行うので、sudo 権限で実行する必要があります。

 [vagrant@puppet-book hello_puppet]$ sudo puppet apply zsh.pp
 Notice: /Stage[main]//Package[zsh]/ensure: created
 Notice: Finished catalog run in 9.76 seconds

意図した通り、zsh パッケージがインストールされたようですね。

 [vagrant@puppet-book hello_puppet]$ which zsh
 /bin/zsh

ここで注目したいのは、CentOS 上でパッケージをインストールするに際して、yum コマンドのような、プラットフォーム固有のコマンドを指定していないということです。

Puppet には、RAL (Resource Abstraction Layer) という仕組みがあり、プラットフォーム固有の事情を抽象化することで、差異を吸収してくれます。この仕組みのおかげで、どのプラットフォームに manifest を適用するかを気にすることなく、システム構成の記述という本質に注力することができるのです。

manifest の作成・適用の流れ

このように、Puppet で manifest を作成・適用する流れは、

  1. 適当な場所に manifest を書く
  2. manifest をシステムに適用する

という流れを繰り返していくことに他なりません。のちのちの説明では、さらに規模の大きな manifest を書いていくために様々な記述方法を説明していきますが、本質的には上記の流れをくりかえしていくだけということに変わりありません。

どんどん書いて、どんどん apply していきましょう。

Function

さて、今回書いてみた manifest について、その中身をもうすこしくわしく見ていきましょう。”Hello, World!” を出力する箇所は、こういう内容でしたね。

 notice("Hello, World!")

この notice は、一般的な言語でいうところの「関数」と同じ働きをするもので、Puppet では function と呼ばれています。この notice のように、Puppet はあらかじめいくつかの function を提供しています。どのようなものがあるのか、その一覧については、以下のドキュメントをご参照ください。

http://docs.puppetlabs.com/references/latest/function.html

Resource Type

zsh パッケージをインストールする箇所は、こうでした。

 package { 'zsh':
   ensure => installed,
 }

Puppet では、manifest によって記述する「システムのあるべき状態」を構成するひとつひとつを、resource と呼びます。ここでは package とそれに続く記述によって、zsh パッケージのインストールを行ってます。この場合の package を、resource の具体的な種類という意味で、resource type と呼びます。

resource type には、package 以外にも、たとえば fileuser など、システムの構成要素の多様性に応じて、たくさんのものが用意されています。どのようなものがあるのか、その一覧については、以下のドキュメントをご参照ください。

http://docs.puppetlabs.com/references/latest/type.html

また、ここで 'zsh': と記述されている箇所を title、ensure => installed を attributes といいます。title は、resource type を一意に決定するための名前を、attributes はどういう状態であるべきかを記述するために使われます。

実際に Puppet の manifest を書いて、”Hello, World!” を表示してみたり、パッケージをインストールしてみたりすることで、ひととおりの manifest の作成から、システムへの適用の流れまでを体験してみました。

また、今回書いた manifest には、function や resource type という、Puppet 言語の構成要素が使われていることも学びました。このように本書では、Puppet 言語の構成要素をまとめて網羅的に解説するというよりもむしろ、必要に応じて解説していきます。その方が、記憶への定着が行われやすいだろうからです。

nginx の manifest を書く

前章では、簡単な manifest を作成し、システムへ適用することを通して、Puppet での作業の流れを体験してみました。本章では、さらに実践的な manifest の作成に挑戦してみましょう。

今回取り上げるのは、HTTP サーバの nginx です。

「nginx が使える状態」とは?

CentOS に nginx をインストールし、実際に HTTP サーバとしてユーザからのリクエストに応答できるようにするまでのステップを、まずはあらためて考えてみましょう。

  1. 必要に応じて、yum パッケージを提供するリポジトリをシステムに登録する
  2. yum コマンドを使って nginx をインストールする
  3. 設定ファイルを記述する
  4. nginx を起動する
  5. nginx がシステム起動時に自動的に起動するよう設定する

「nginx が使える状態」であるといえるためには、最低限これぐらいのことをする必要があります。実際、みなさんがこれまで nginx をシステムにインストールしてきた際には、同様のことを行ってきたことでしょう。

manifest に落とす

次に、上記の 1 〜 5 を、manifest に落としていきます。まずは、本章で作成する manifest を置くためのディレクトリを作成しましょう。

 $ cd puppet/
 $ mkdir nginx
 $ cd nginx/

以下の内容で、nginx.pp というファイルを作成してください。

 yumrepo { 'nginx':
   descr    => 'nginx yum repository',
   baseurl  => 'http://nginx.org/packages/centos/6/$basearch/',
   enabled  => 1,
   gpgcheck => 0,
 }

 package { 'nginx':
   ensure  => installed,
   require => Yumrepo['nginx'],
 }

 $port = 80

 file { '/etc/nginx/conf.d/my.conf':
   ensure  => present,
   owner   => 'root',
   group   => 'root',
   mode    => '0644',
   content => template('my.conf'),
   require => Package['nginx'],
   notify  => Service['nginx'],
 }

 $target = 'Puppet'

 file { '/usr/share/nginx/html/index.html':
   ensure  => present,
   owner   => 'root',
   group   => 'root',
   mode    => '0644',
   content => template('index.html'),
   require => Package['nginx'],
 }

 service { 'nginx':
   enable     => true,
   ensure     => running,
   hasrestart => true,
   require    => File['/etc/nginx/conf.d/my.conf'],
 }

manifest の内容

作成した manifest を、上から見ていきましょう。package については前章で紹介したので、省略します。今回はあらたに yumrepofile、そして service という resource type が使われています。これら resource type についてはあとの章でより詳しく見ていきますので、ここでは簡単な説明にとどめます。

yumrepo は、システムへの yum リポジトリの登録状態を記述するための resource type です。ここでは nginx のインストールマニュアルに掲載されている公式の yum リポジトリを登録し、使用可能な状態にしています。

ちなみに、ここでは gpgcheck0 とし、チェックしないよう設定していますが、これは nginx のリポジトリが GPG キーを提供していないためです。EPEL のように GPG キーを合わせて提供しているリポジトリを利用する場合は、極力 GPG キーのチェックも行うほうがよいでしょう。詳しくは「第 7 章 yum リポジトリを登録する - yumrepo」で解説します。

file は、ファイルやディレクトリに関する resource type です。ファイルやディレクトリが、指定された attribute 通りに存在しする (あるいは存在しない) という状態を記述するために使います。ownergroup などの各 attribute がどのような意味を持つかは、想像がつくでしょう。template()、および requirenotify の各 Attribute については、後述します。

$port = 80$target = 'Puppet' という箇所は、見ての通り、変数への代入を行っています。Puppet ではこのように、manifest の中で変数を使えます。後述の template() といっしょに説明します。

service は、今回の例の nginx のような、サービスを提供するデーモンのあるべき状態を記述するための resource type です。enable は、システム起動時にサービスとして起動するかどうかを、ensure は、常に起動した状態を保っているべきかどうかを記述するのに使います。nginx のようなデーモンは常に起動しておきたいのがふつうでしょうから、このように記述します。

テンプレートを用意する

yum コマンドによってインストールされる nginx は、/etc/nginx/conf.d/*.conf をロードするよう設定されています。そこで、自分用にカスタマイズした設定を /etc/nginx/conf.d/my.conf として配置し、自動的にロードされるよう manifest を記述しています。その箇所をもう一度見てみましょう。

 file { '/etc/nginx/conf.d/my.conf':
   ensure  => present,
   owner   => 'root',
   group   => 'root',
   mode    => '0644',
   content => template('my.conf'),
   require => Package['nginx'],
   notify  => Service['nginx'],
 }

ここでは template() という function を用いて、設定ファイルの内容を生成しています。ここであえて「生成」と述べたのにはわけがあります。template() は、引数に渡されたファイルの内容を、Ruby のテンプレートエンジン erb の形式で書かれたものとして評価し、その結果として生成された文字列を返す関数だからです。

以下の内容で、my.conf というファイルを nginx.pp と同じディレクトリに作成してください。

 server {
   listen       <%= port %>;
   server_name  localhost;

   location / {
     root  /usr/share/nginx/html;
     index index.html;
   }
 }

この <%= port %> の箇所が、erb の変数展開の記法として評価され、manifest で $port = 80 と記述されている内容がうめこまれます。

同様に、index.html というファイルを、以下の通り作成してください。

 Hello, <%= target %>!

このファイル内の <%= target %> も、同名変数 $target の値に展開されます。

manifest を適用する

さて、manifest を作成したら、システムに適用してみましょう。今回は前回と違ってテンプレートも使うので、puppet apply コマンド実行時に、–templatedir オプションでカレントディレクトリ (.) を指定します。

 [vagrant@puppet-book ~]$ cd /vagrant/puppet/nginx
 [vagrant@puppet-book nginx]$ sudo puppet apply --templatedir=. nginx.pp
 Notice: /Stage[main]//Yumrepo[nginx]/descr: descr changed '' to 'nginx yum repository'
 Notice: /Stage[main]//Yumrepo[nginx]/baseurl: baseurl changed '' to 'http://nginx.org/packages/centos/6/$basearch/'
 Notice: /Stage[main]//Yumrepo[nginx]/enabled: enabled changed '' to '1'
 Notice: /Stage[main]//Yumrepo[nginx]/gpgcheck: gpgcheck changed '' to '0'Notice: /Stage[main]//Package[nginx]/ensure: created
 Notice: /Stage[main]//File[/usr/share/nginx/html/index.html]/content: content changed '{md5}e3eb0a1df437f3f97a64aca5952c8ea0' to '{md5}1db16ebfb21d376e5b2ae9d1eaf5b3c8'
 Notice: /Stage[main]//File[/etc/nginx/conf.d/my.conf]/ensure: created
 Notice: /Stage[main]//Service[nginx]/ensure: ensure changed 'stopped' to 'running'
 Notice: /Stage[main]//Service[nginx]: Triggered 'refresh' from 1 events
 Notice: Finished catalog run in 33.69 seconds

エラーなく終了したら、nginx が実際に起動しているかどうか、確認してみましょう。

 [vagrant@puppet-book nginx]$ curl http://localhost:80/
 Hello, Puppet!

変数に代入した値がきちんと展開された文字列が、nginx によって返されました。

Relationship

さて、nginx の manifest を無事に適用できたところで、説明を先送りにした requirenotify について、見ていきましょう。

今回は、yumrepopackagefileservice という、4 つの resource type を使って manifest を記述しました。それぞれの resource type によって記述された resource は、任意の順番で個別に存在するのはなく、次の順番で依存関係を持っています。

  1. yum リポジトリを登録する
  2. nginx パッケージをインストールする
  3. 設定ファイルを配置する
  4. サービスを起動する

1 から 4 までが順番通りに実行されないと、正しく nginx を起動できません。このような依存関係のことを dependency relationship と呼び、require によって記述します。

 package { 'nginx':
   ensure  => installed,
   require => Yumrepo['nginx'],
 }

これは、nginx パッケージをインストールする前に、nginx の yum リポジトリを登録する必要がある、ということを意味します。

「関係」にはもうひとつ種類があります。nginx のインストール時のみならず、nginx の設定ファイルを変更した場合にも、nginx にその設定を再読み込みさせる必要があります。このような、ある resource の変更にともなって再読み込みのようなアクションが必要となる関係を refresh relationship と呼び、notify によって記述します。

 file { '/etc/nginx/conf.d/my.conf':
   ensure  => present,
   owner   => 'root',
   group   => 'root',
   mode    => '0644',
   content => template('my.conf'),
   require => Package['nginx'],
   notify  => Service['nginx'],
 }

Puppet の manifest は、ファイル内の記述順で処理が実行されるわけではありません。Puppet 言語は、これまで何度も述べている通り「システムのあるべき状態」を記述するためのものですから、ファイル内での記述の順序によって実行順が変わるのは好ましくありません。今回行ったように、明示的に relationship を記述してやる必要があります。

Resource Reference

上記で、package を宣言する際にはすべて小文字で書いていた一方で、require によって依存関係を記述する際には Package[‘nginx’] と、最初の 1 文字を大文字で書いていたことに気付いたでしょうか?

このように、resource の宣言時にはすべて小文字を使い、relationship のある resource への参照時には、最初の文字を大文字にした名前を使います。他の resource への参照を、resource reference と呼びます。宣言時はすべて小文字で、それ以外は最初の 1 文字を大文字にする、と憶えておいてください。

すこし大変だったかもしれませんが、ここで学んだことをきちんと理解しておけば、Puppet の本質の、多くの部分を把握したことになります。本章をよく読み返してみて、いまいちど理解を確かめてみてください。

完全版の入手方法

今回るびまでご紹介したのは全 23 章の中の 5 章分です。電子書籍版では td-agent のインストールから serverspec の使い方まで、実践的に使える内容が多数含まれています。本書は puppet を用いてシステムの構成管理を行う際に必要とされるものを網羅している唯一の日本語の書籍と言っても過言ではありません。本書が皆さんのソフトウェア開発の手助けとなれば幸いです。

本書は以下の電子書籍販売サイトより購入可能です。

筆者について

栗林健太郎。ネット上では「antipop/kentaro/あんちぽ」として知られる。市役所職員、株式会社はてな勤務を経て、現在は株式会社 paperboy&co. で技術基盤整備エンジニアとして勤務。Perl Monger で Rubyist、時々ぺちぱー。 http://kentarok.org/