Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

参考

kijibato
2018年も6投稿を目標に。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away