Puppet Advent Calendar 2015の、5日目です。
Puppetをもりあげていこうということで、参加させてもらいます。
Hieraで同じリソースを複数定義する
Puppetで同じリソースを複数定義したい場合があったりします。
例えば、Apacheのvirtual hostの設定を/etc/httpd/conf.d/の配下に個別に置く定義を何度も使いたいとか、ユーザのアクセス設定をする定義をユーザごとに使いたいとか(ftpの/etc/vsftpd/user_conf/をユーザごとに定義するとか)。
Hieraを使った場合でも、create_resourcesを使うと、同じ定義を何度も使うことができたりします。
create_resources
create_resourceは、ハッシュ情報を指定したリソースに変換する関数です。パラメータに、リソースタイプとハッシュ情報(リソースへのパラメータをハッシュ形式で書いたもの)を指定すると、指定したリソースを複数定義できます。
既存リソースでの例
まずは既存リソースで使う例です。例えば、groupリソースとuserリソースをHieraで直接複数定義したい場合、まず次のようなクラス用意します。
class base::account (
) {
$groups = hiera('base::account::groups', {})
create_resources('group', $groups)
$users = hiera('base::account::users', {}) # (1)
create_resources('user', $users) # (2)
}
(1)はHieraの定義から、base::acount::usersの情報をハッシュとして$usersに格納する行で、(2)はハッシュ情報($users)をcreate_resourcesでuserリソースに変換する行です。base::acount::usersや$usersは変数名を適当に付けているだけなので、好みな変数名でかまいません。
Hiera側は下記のように書きます。ユーザやグループのパラメータをハッシュ形式で列挙するだけです。AnsibleをYAML形式で書いた場合にちょっと似てます。base::account::groupsとbase::account::usersがさきほどのbase::accountクラスにわたって、create_resourcesでリソース定義に変換されます。
---
classes:
- base::account
base::account::groups:
hoge:
ensure: 'present'
gid: '1002'
fuga:
ensure: 'present'
gid: '1003'
base::account::users:
hoge:
ensure: 'present'
gid: '1002'
home: '/home/hoge'
shell: '/bin/bash'
uid: '1002'
fuga:
ensure: 'present'
gid: '1003'
home: '/home/fuga'
shell: '/bin/bash'
uid: '1003'
ちなみに、上の定義は次のマニフェスト定義と等価です。
group { 'hoge':
ensure => 'present',
gid => '1002',
}
group { 'fuga':
ensure => 'present',
gid => '1003',
}
user { 'hoge':
ensure => 'present',
gid => '1002',
home => '/home/hoge',
shell => '/bin/bash',
uid => '1002',
}
user { 'fuga':
ensure => 'present',
gid => '1003',
home => '/home/fuga',
shell => '/bin/bash',
uid => '1003',
}
defineしたリソースでも
ちなみに、既存のリソースだけでなく、defineで独自に作ったリソースでも同様です。例えば、/user/vsftpd/user_conf/ユーザ名を、次のようなHiera定義で指定するには、
---
classes:
- vsftpd::config_user_conf
vsftpd::config_user_conf::hash:
hoge:
user: 'hoge'
content: 'local_root=/home/ftp/hoge'
fuga:
user: 'fuga'
content: 'local_root=/home/ftp/fuga'
このような"/etc/vsftpd/user_conf/ユーザ名"を配布するリソースをdefineして、
define vsftpd::def_user_conf(
$user,
$content,
){
file { "/etc/vsftpd/user_conf/${user}":
content => $content,
owner => 'root',
group => 'root',
mode => '644',
}
}
create_resourcesで展開する、ラッパークラスみたいなものを用意すればよいです。
class vsftpd::config_user_conf (
) {
$user_conf_hash = hiera('vsftpd::config_user_conf::hash', {})
create_resources('vsftpd::def_user_conf', $user_conf_hash)
}
実際にPuppet適用後の結果はこんな感じです。
[root@localhost ~]# grep local /etc/vsftpd/user_conf/*
/etc/vsftpd/user_conf/fuga:local_root=/home/ftp/fuga
/etc/vsftpd/user_conf/hoge:local_root=/home/ftp/hoge
もしかすると
Puppet4から強化されたループの文法を使う方が主流になるかもしれませんが、こんなやり方もあったりします。