一个模块中多个 类 的 Puppet 配置

Puppet configuration for multiple classes in a module

我想使用和配置 puppet-nginx 模块,尽管这是关于 Puppet 配置的一般性问题。

Exec { path => [ "/bin/", "/sbin/" , "/usr/bin/", "/usr/sbin/" ] }

class nginx-setup {
    class { 'nginx': }
}

include nginx-setup

效果很好! 现在,如果我按照文档进行配置,我最终会得到这样的结果:

Exec { path => [ "/bin/", "/sbin/" , "/usr/bin/", "/usr/sbin/" ] }

class nginx-setup {
    class { 'nginx': }

    class { 'nginx::package':
        package_source => 'nginx-mainline'
    }
}

include nginx-setup

错误:重复声明:Class[Nginx::Package] 已声明

我尝试了 include nginx 而不是我的第一个 class 声明,但我认为模块的 init.pp 已经在声明 nginx::package class 而我仍然得到重复声明错误。即使这样可行,如果我想将更多配置应用于 nginx 模块中的另一个 class 怎么办?例如:

Exec { path => [ "/bin/", "/sbin/" , "/usr/bin/", "/usr/sbin/" ] }

class nginx-setup {
    class { 'nginx': }

    class { 'nginx::package':
        package_source => 'nginx-mainline'
    }

    class { 'nginx::config': 
        nginx_error_log => 'syslog:server=localhost',
    }
}

include nginx-setup

许多重复的定义!

所以感觉我应该将所需的一切传递到我最初的 class 声明中,但我似乎无法找到正确的方法来做到这一点。实现此目标的最佳方法是什么?

事实证明它是特定于模块的。 jfryman/puppet-nginx 模块 类 会自动加载 except for nginx::config(除非它尚未声明)并且大多数其他 类 会从 nginx::config 继承它们的设置。此模块的正确解决方案是;

class nginx-setup {
    class { '::nginx::config':
        http_access_log => 'syslog:server=localhost,tag=nginx,severity=info',
        nginx_error_log => 'syslog:server=localhost,tag=nginx,severity=info',
    }

    class { '::nginx':
        package_source => 'nginx-mainline',
    }
}
include nginx-setup

jfryman/puppet-nginx 正朝着 Hiera configurations 迈进,这可能不会长久有效。在集成 Hiera 之前,我想要一个纯 Puppet 解决方案(学习),但我不会向所有人推荐它...

TL;DR

毕竟要考虑使用 Hiera,因为 Puppet 在处理 class 参数时存在一些缺陷,否则这个模块很难使用。


长答案:

实际上,这是一个很重要的问题,尽管它不应该如此。您已经正确地推断出了要点。但是让我们一步一步来吧。

模块结构

现在被认为是最佳实践(需要引用,尽管来自 Puppet Labs 的 Ryan Coleman 在最近在 FOSDEM 的演讲中提到了这一点)在其中央 class(这里,class nginx).

这样一来,用户就很清楚他们需要为此 class 查找合适的参数,而不是继续寻找合适的 class 进行调整。

您选择的 nginx 模块似乎在很大程度上采用了这一点,但结果并非如此。

使用 defined() 进行黑客攻击

正如您所注意到的,模块作者添加了一些快捷方式以允许您声明您的 classes "safely" if 您确保 nginx::config class 出现在 nginx class 词法之前。

这很危险,因为在复杂的清单中,这可能不容易断言。

包括与 class { }

Class 参数是有问题的,因为它们导致 include 不如以前安全,因为它们不能很好地与 class { 'name': ... } 样式声明混合。后者总是坏消息,因为它们必须是独一无二的,正如您现在所经历的那样。

最好尽量坚持include,这就引出了下一期

希拉

有了参数化的 classes,您真的很想尽快采用 Hiera。将 class 参数定义为数据几乎普遍优于在清单中这样做。我理解首先坚持简单构造的愿望,但由于上述问题,它确实会让你的生活变得更加艰难。