トップ «前の日記(2013-02-08) 最新 次の日記(2013-02-12)» 編集

人徳ゼロ日記


2013-02-10 Puppet3.0の新機能Hiera auto-lookupの使い方

私はPuppet を結構使っていました(最近は設定作業してないので遠ざかっている)。 設定の作業を手続的にスクリプトとして記載するのではなく、 宣言的に理想状態を記載する、と言う考えは非常に良いと思っています。

ずっとPuppetはウォッチしたりちょっと動かしたりして遊んでいましたが、 昨年2012年10月に出たメジャーバージョンアップPuppet3.0 (リリースノート)に 「Hiera(設定値をマニフェストの外部ファイルに書ける仕組み)をPuppet本体に標準搭載」「パラメタのHiera Auto-lookup機能」と言う かなり重要な機能が追加になりました。

何が重要かと言うと、いままで設定パラメタがロジックの中に混在していたのですが、これがロジックと設定値の分離ができて、ロジックから即値を排除し設定値だけ別ファイルにかけるようになったことです。

ただ、全然ドキュメントがなく、本家Puppetlabsでもわずかしかありません。 唯一書いてあるのは、Language: Classes のInclude-Like Behaviorという所です。 あとはPuppet User Groupメーリングリストで語られているくらいですね。 ましてや、日本語の資料は皆無です。

せっかく手元で試してみたので紹介します。

クラス定義

クラスの書き方はPuppet2.7までと変わりません。 クラスはparameterized classとしてパラメタを受けるようにします。

ファイル: /etc/puppet/modules/mymodule/manifests/conf.pp

class mymodule::conf(
    $p1,
    $p2="p2 default"
) {
    file { "/tmp/mymodule.txt":
        ensure => present,
        mode => 600,
        owner => root,
        group => root,
        content => template("mymodule.txt.template"),
    }
}

クラスのパラメタはテンプレート内で使用します。

ファイル: /etc/puppet/modules/mymodule/templates/mymodule.txt.template

****mymodule test file
p1:<%= p1 %>
p2:<%= p2 %>
name:<%= name %>

site.ppでのクラス適用

Puppet2.7までの例

ノード別に、どのクラスを適用するのか、その際どのようなパラメタにするのか、 site.ppに記載します。 Puppet2.7まではクラス呼び出しの引数でパラメタを指定します。 今回の例では、クラス引数に指定したパラメタがテンプレートに埋め込まれます。

ファイル: /etc/puppet/manifests/site.pp

node mgcent61 {
    class { "mymodule::conf":
        p1=>"puppet2.7 example p1",
        p2=>"puppet2.7 example p2"
    }
}

Puppet適用結果例

# puppet apply -v /etc/puppet/manifests/site.pp 

適用結果のファイル/tmp/mymodule.txt

****mymodule test file
p1:puppet2.7 example p1
p2:puppet2.7 example p2
name:mymodule::conf

Puppet3.0でのHieraを使った例

HieraはPuppet2.7の頃から存在はしていましたが、 Puppet本体とは別でインストールする必要があったのと、 値を取得するところは

  $v = hiera("keyname")

と言うように、明示的にHieraから値を取得するように記載する必要がありました。 そのため、Hieraを使うようにするにはsite.ppでパラメタを渡すところすべてで hiera()を呼び出すように書き換える必要があり、使うまでのしきいが高かったです。

しかし、Puppet3.0からはHieraが標準搭載になったのと、 クラス呼び出しのところで暗黙のうちに Hieraから情報を取って与えてくれる、Auto-lookup機能が追加になりました。

これを使うと、以下のうれしいことがあります。

  • site.pp内でクラスを呼び出す時は、パラメタを指定しなくても良くなるので、 site.pp内のnode定義は、単なるinclude文の羅列で良くなるので非常にシンプルになる。
  • site.pp内でhiera()関数を明示的に呼び出すように書き換える手間がなくなる。

site.ppでのクラスの呼び出し方法は以下のようにincludeを書くだけのシンプルなものになります。 パラメタ値はHieraファイルから自動的に読み込まれます。(Hieraファイルの内容は後ろで書きます)

ファイル: /etc/puppet/manifests/site.pp

node mgcent61 {
    include 'mymodule::conf'
}

参考: 注意: ResourceはHieraのAuto lookupできない と言う記事を追加しました

これでもマニフェストから値が分離できてsite.ppがシンプルになり非常に良いのですが、 さらに、「どのノードにどのクラスを適用するか」をHieraに切り出す方法があります。 Puppet3.0にはhiera_include()という、クラスのincludeをHieraの情報を参照して まとめて行う機能が追加になりました。 これを使えばノード定義はわずか1行になり、 どのノードにどのクラスを適用するかもHiera化できます。(具体的なHieraの書き方は後ろで書きます)

node mgcent61 {
  hiera_include(classes)
}

ノード別Hieraパラメタファイル

Hieraのファイルは、YAMLかjsonで記述します。今回はYAMLを使いました。 ファイルの単位は、PuppetのFacterで取得するfact値ベースで好きに指定できますが、 今回はオーソドックスにノード名単位にファイルを作ることにしました。

例の内容:

  • ノードmgcent61にmymodule::confクラスを適用します。 site.ppのhiera_include(classes)で指定したclassesと言う引数が キーになってHieraからリストを取得し、それをクラス名とみなしてincludeします。
  • mymodule::confの引数p1,p2に値をセットします。

ファイル: /etc/puppet/hieradata/mgcent61.yaml

---
mymodule::conf::p1: hiera test p1
mymodule::conf::p2: hiera test p2
classes:
  - mymodule::conf

Puppet適用結果例

# puppet apply -v /etc/puppet/manifests/site.pp 

適用結果のファイル: /tmp/mymodule.txt

****mymodule test file
p1:hiera test p1
p2:hiera test p2
name:mymodule::conf

Hieraのデータファイルで指定した設定値が、テンプレートに埋め込まれています。 これで、PuppetでのHiera Auto-lookupの動作が確認できました。

参考: Hiera自体の設定hiera.yaml

Hieraの設定は、hiera.yamlで行います。 hiera.yamlの中で出てくる%{::clientcert}という部分は、 PuppetのFacterで取得したFact値のことです。 実際のシステムでどのような値になっているのかは、 /var/lib/puppet/yaml/facts/ホスト名.yamlを参照してください。 以下に、hiera.yamlの内容を解説します。

  • Hieraの記述にYAMLを使う
    :backends:
      - yaml
    
  • Hieraを探す順序の指定
    1. ホスト名.yamlのファイル(fact値としては、clientcertを使う)
    2. common.yamlのファイル(全ノード共通の設定値を記述する。今回の例では特に使用していない)
    :hierarchy:
      - %{::clientcert}
      - common
    
  • Hieraのファイルを配置するディレクトリの指定
    :yaml:
       :datadir: /etc/puppet/hieradata
    
  • ファイル: /etc/puppet/hiera.yaml

    ---
    :backends:
      - yaml
    :logger: console
    :hierarchy:
      - %{::clientcert}
      - common
    :yaml:
       :datadir: /etc/puppet/hieradata