我想编写一个 Puppet 清单来在目标服务器上安装和配置应用程序。
此清单的某些部分应可重复使用。因此我使用它define
来定义我的可重复使用功能。这样做时,我总是遇到定义中有些部分不可重复使用的问题。
一个简单的例子就是要创建一堆配置文件。这些文件必须放在同一个目录中。这个目录只需创建一次。
例子:
节点.pp
node 'myNode.in.a.domain' {
mymodule::addconfig {'configfile1.xml':
param => 'somevalue',
}
mymodule::addconfig {'configfile2.xml':
param => 'someothervalue',
}
}
我的模块.pp
define mymodule::addconfig ($param) {
$config_dir = "/the/directory/"
#ensure that directory exits:
file { $config_dir:
ensure => directory,
}
#create the configuration file:
file { $name:
path => "${config_dir}/${name}"
content => template('a_template.erb'),
require => File[$config_dir],
}
}
这个例子将失败,因为现在资源file {$config_dir:
被定义了两次。
据我了解,需要将这些部分提取到 中class
。然后它看起来像这样:
节点.pp
node 'myNode.in.a.domain' {
class { 'mymodule::createConfigurationDirectory':
}
mymodule::addconfig {'configfile1.xml':
param => 'somevalue',
require => Class ['mymodule::createConfigurationDirectory'],
}
mymodule::addconfig {'configfile2.xml':
param => 'someothervalue',
require => Class ['mymodule::createConfigurationDirectory'],
}
}
但这使得我的界面难以使用。我的模块的每个用户都必须知道,有一个额外需要的类。对于这个简单的用例,额外的类可能是可以接受的。但随着模块复杂性的增加(大量定义),我有点担心模块用户会感到困惑。
所以我想知道是否有更好的方法来处理这种依赖关系。理想情况下,像这样的类createConfigurationDirectory
对模块 api 的用户是隐藏的。
或者是否存在其他处理此类依赖关系的“最佳实践”/模式?
答案1
将所有功能分解为单独的文件在模块中,每个文件包含一个类或已定义类型。使用资源 订购以正确的顺序管理资源。
在您的节点定义中:
class {'mymodule':
conffile => 'file_name',
}
在您的模块清单目录中:
初始化.pp:
# This class does basic setup,
# and optionally allows you to define a config file
class mymodule ( $conffile = undef ) {
include mymodule::confdir
if $conffile {
mymodule::conffile { $conffile: }
}
}
参数.pp:
# This class defines variables
class mymodule::params {
$confdir = '/path/to/dir'
}
confdir.pp:
# This class creates a conf dir
class mymodule::confdir {
include mymodule::params
file { $mymodule::params::confdir:
ensure = directory,
}
}
conf文件.pp:
# This define creates a config file
define mymodule::conffile($file=$title) {
include mymodule::params
file { "${mymodule::params::confdir}/${file}":
ensure => present,
require => Class['mymodule::confdir'],
}
}
答案2
最好能从定义中取出配置目录。这是一个例子
class def($config_dir) {
file { $config_dir:
ensure => directory
}
}
define def::template($file_location) {
file { $file_location:
path => "${def::config_dir}/${file_location}",
content => 'hi',
require => Class['def'],
}
}
if $fqdn == 'my_host' {
class { 'def':
config_dir => '/tmp/d1'
}
def::template { 'f1.txt':
file_location => "f1.txt"
}
def::template { 'f2.txt':
file_location => "f2.txt"
}
}
ls /tmp/d1/
f1.txt f2.txt