puppetのclass間依存の話

最近chefに押され気味な気がしないでもないpuppetのことでも書こうかな。

puppetでは各種リソース(file、package、service 等など)間の依存関係を定義出来るのですが、class(複数リソースをまとめたセットみたいなもの)間でも依存を定義することができます。

class間でそれが出来るとなにが嬉しいかというのは、mizzyさんのこのエントリが具体的で分かりやすいです。http://mizzy.org/blog/2011/07/10/ProPuppet00/

で、自分も最近ようやくpro puppetをちゃんと読んでみたわけなんですが、classの依存を宣言するには、実は4っつの方法があるんですね。

一つ目は普通にリソースのrequireパラメータで指定する方法。例えばfileだったら。

file { '/etc/sshd/sshd_config':
  source  => 'puppet:///ssh/config/etc/sshd_config',
  require => Class['ssh::install']
}

こんな感じで、別でsshをインストールさせるclassを定義しておいて、sshd_configはそっちの処理が全部終わってからぶっこもうねって感じ。

2つ目は、カレントclass内のリソース全てに上記と同じ内容をデフォルトで突っ込んでしまえるやり方。metaparameter defaults と言うらしいです。

class ssh::config {
  @require => Class['ssh::install']

  file { '/etc/ssh/sshd_confg':
    source  => 'puppet:///ssh/config/etc/sshd_config',
    # ここでは ssh::install に対する依存を明示する必要がない。
  }
}

3つ目はrequire functionを使った方法。2つ目と同じような感じだけど、こっちは同時にincludeと同等の処理をしてくれる。

class ssh {
  require ssh::install
  include ssh::config
}
class ssh::config {
  ...
}
class ssh::install {
  ...
}

4つ目は、いままでのやり方やシンタックスとはかなり異色な方法。arrow operator でClass間の依存を定義します。

class ssh {
  Class['sshg::install'] -> Class['ssh::config']
  include ssh::install
  include ssh::config
}

以上です。

一つ目は知っていたんだけど、他は今回はじめて知って便利そうだったので検証してみることにしました。

こんな感じで /tmp/relation.pp というmanifestを作ります。

class aaa {
  notify {'aaa':}
}

class aaa_with_meta_param {
  notify {'aaa': require => Class['bbb'] }
}

class aaa_with_metaparam_default {
  $require = Class['bbb']
  notify {'aaa':}
}

class bbb {
  notify {'bbb':}
}

##--------------------------
class normal {
  include aaa
  include bbb
}

class resource_level_require {
  include aaa_with_meta_param
  include bbb
}

class metaparam_default {
  include aaa_with_metaparam_default
  include bbb
}

class require_function {
  include aaa
  require bbb
}

class arrow {
  Class['bbb'] -> Class['aaa']
  include aaa
  include bbb
}

##--------------------------
include normal
#include resource_level_require
#include metaparam_default
#include require_function
#include arrow

で、最後のセクションをコメントアウトしたり、コメントしたりして1つずつ実行。puppet 2.7.9の環境でやってます。

puppet apply /tmp/relation.pp

期待する結果としては、一番上のnormal以外は全て'aaa'より'bbb'を先に出力して欲しいのですが、どういうわけか実際には、2つ目と4目(resource_level_require、arrow)しかそのようになりませんでした。

他にも別のパターンでmanifestを作成して色々試してみましたが、同様でした。

ただし、詳しく切り分けできていないのですが、うまくいかなかったrequire functionとmetaparameter defaoutも場合によっては順番を制御してくれるようです。

    • -

というわけで自分が検証した限りではclass間の依存定義で当てになるのは、arrow operatorだけどいう結果になしました。

本当はrequire functionが見た目的に一番馴染みやすそうだったので、残念です。何か全然勘違いしてるのかな?ツッコミや情報がありましたら教えてほしいです。