search
LoginSignup
5

More than 5 years have passed since last update.

posted at

PuppetのHieraで同じリソースを複数定義する(create_resources)

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で直接複数定義したい場合、まず次のようなクラス用意します。

/etc/puppet/modules/base/manifests/account.pp
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でリソース定義に変換されます。

/etc/puppet/hieradata/sample.yaml
---
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定義で指定するには、

/etc/puppet/hieradata/sample.yaml
---
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して、

/etc/puppet/modules/vsftpd/manifests/def_user_conf.pp
define vsftpd::def_user_conf(
  $user,
  $content,
){

  file { "/etc/vsftpd/user_conf/${user}":
    content => $content,
    owner   => 'root',
    group   => 'root',
    mode    => '644',
  }

}

create_resourcesで展開する、ラッパークラスみたいなものを用意すればよいです。

/etc/puppet/modules/vsftpd/manifests/config_user_conf.pp
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から強化されたループの文法を使う方が主流になるかもしれませんが、こんなやり方もあったりします。

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
5