6日目で紹介した External Node Classifiers ですが、実例交えてどんなことが出来るか見てみます。
environmentの自動判定
environment:
という属性を作れば、それがPuppet実行時に --environment
として渡されます。
require 'yaml'
certname = ARGV[0]
hostname = certname.split('.').first
role = case hostname
when /^([-_a-z]+)$/, /^([-_a-z]+)\d{3}$/
$1
else
raise("Invalid hostname %s" % hostname)
end
environment = nil
if hostname =~ /^staging/
role.sub!(/^staging(-)?/, '')
environment = "staging"
else
environment = "production"
end
puts YAML.dump({
'classes' => ['base', role],
'environment' => environment,
})
exit 0
実行結果
$ ruby enc.rb staging-web001.udzura.jp
---
classes:
- base
- web
environment: staging
$ ruby enc.rb web001.udzura.jp
---
classes:
- base
- web
environment: production
staging-
ついてたらステージング、それ以外本番で、ということをやれます。 puppet agent
コマンドにいちいち --environment
を渡すのはミスりやすいので、便利かもです。
ロールに満たないサブロールみたいな変化をつける
parameters:
に任意の変数を渡せます。
require 'yaml'
certname = ARGV[0]
hostname = certname.split('.').first
role = case hostname
when /^([-_a-z]+)$/, /^([-_a-z]+)\d{3}$/
$1
else
raise("Invalid hostname %s" % hostname)
end
sub_role = nil
if role =~ /^log/
case role
when /log-master/
sub_role = 'master'
when /log-slave/
sub_role = 'slave'
else
sub_role = 'unknown'
end
role = 'log'
end
puts YAML.dump({
'classes' => ['base', role],
'parameters' => {'sub_role' => sub_role},
})
exit 0
こんな感じにすると、マニフェスト内で $::sub_role
に値が入るので、あとはそれを見て分岐すればOKです。
ぼくはよくHieraと組み合わせて:
$ssl_certname = hiera("fluentd::certname::${::sub_role}")
なんてやったりします。
Classに直接パラメータを渡す こともできますが、クラスまとめて指定するのは配列の方が楽(というかパラメータ無しの時に、RubyのYAMLライブラリで面倒と思われる)なのでぼくはparameters派です。
なお、ENCをやっていくにあたって必要なのは、「いい感じの規約」です。
あまりに変な規約になる時は、ENCとかより、カスタムファクターやファンクションで頑張る方がいいかと思います。
そんな感じで、次のPuppetカレンダーの更新は......誰だろう......