我有大约200多个或更less的相同的Linux虚拟机。 所有常见configuration都有一个类:
class my_packages { class { "::ntp": servers => [ "de.pool.ntp.org" ], } .... }
我将其包含在site.pp的每个节点中。
现在我想运行我自己的本地时间服务器,这是微不足道的使用puppetlabs / ntp包。 我只需要使用新的时间服务器虚拟机的IP地址replacemy_packages中的服务器条目,并且该虚拟机现在具有与先前在my_packages中使用的相同的ntp类条目。
node 'mytime' { # include my_packages class { '::ntp': servers => [ 'de.pool.ntp.org', 'ptbtime1.ptb.de', 'ptbtime2.ptb.de', 'ptbtime3.ptb.de', ], } ... }
然而,由于现在在节点中定义了类“:: ntp”项,所以我不能在我的新时间服务器虚拟机的节点条目中包含my_packages,因为在这种情况下我得到了“重复声明”错误。
使用本地名称服务器时发生类似的问题。 每个VM都有一个指向本地名称服务器的/etc/resolv.conf文件,因此在my_packages中有一个文件资源。 但本地名称服务器本身必须具有不同的/etc/resolv.conf文件 – 在安装完成之前,它不能指向自己,安装过程中并不是这样。
使用一套通用资源的最佳做法是什么,但考虑到偶尔的例外情况?
如果您使用Puppet 3或更高版本,最好的办法是使用hiera来执行自动参数查找 。 简而言之,它允许您使用包含语法而不是资源样式语法来声明类,这意味着您可以为该类声明多个声明。 请注意,不能将类和包含资源样式的声明混合使用。
通常,如果使用include语法来声明一个类,如果它有任何必需的参数,它将会失败。 当您使用自动参数查找时,puppet将尝试通过hiera查找参数的值。
Hiera是如此命名的,因为它会尝试通过数据源的层次结构来查找值。 您可以在hiera.yaml中指定此层次结构,并且可以匹配各种事实(主机名,自定义事实等)或检查硬编码的文件。
这里有一个简单的例子,可以在你的情况下工作:
类定义:
class my_packages { include ::ntp ... }
mytime.yaml:
---- ntp::servers: - 'de.pool.ntp.org' - 'ptbtime1.ptb.de' - 'ptbtime2.ptb.de' - 'ptbtime3.ptb.de'
common.yaml:
--- ntp::servers: ['de.pool.ntp.org']
hiera.yaml:
... :hierarchy: - "${::fqdn}" - common ...
在这种情况下,hiera会尝试使用键ntp :: servers来查找ntp类中服务器参数的值。 它将首先在与主机名相匹配的任何yaml文件中查找该关键字,然后在common.yaml中查找该关键字。
在大多数情况下,它将使用common.yaml中的键,但是对于mytime节点,它会在层次结构中find更高的值,并停止在那里查找。
这是一个完整例子的链接,这个例子偶然地覆盖了ntp模块。