Puppet 解析顺序说明

Puppet Parse Order Explanation

我正在基于软件包提供的 30-stig.rules 文件构建 auditd audit.rules 文件。

stig.rules 文件位于 /usr/share/doc/audit-<版本>/rules/30-stig.rules。但是,事先很难知道安装了哪个版本的 auditd,因此我想使用 exec 资源将此文件复制到标准位置:

exec { 'Copy stig.rules to /tmp/stig.rules':
  command  => 'cp $(rpm -qf auditd | grep stig.rules) /tmp/stig.rules',
  unless   => 'cmp /tmp/stig.rules $(rpm -qf auditd | grep stig.rules)',
}

file { '/etc/audit/audit.rules':
  ensure  => file,
  content => template('auditd/audit.rules.erb'),
}

模板(audit.rules.erb)包含:

scope.function_file(['/tmp/stig.rules'])

我最初收到模板无法定位 /tmp/stig.rules 的错误。因此,我补充说:

Exec['Copy stig.rules to /tmp/stig.rules'] -> File['/etc/audit/audit.rules']

即使在这个明确的命令之后,我也会得到同样的错误,即 /tmp/stig.rules 找不到。似乎在解析文件资源期间,它甚至在执行应该在其后排序的 'exec' 之前就进行了一些预验证。谁能解释这种行为?

如评论中所述,您遇到的问题是 Puppet 函数在 Puppet Master 上执行。

通常,可以通过创建 return 审计版本的 custom fact 来解决此问题。

在您的模块中创建一个文件,内容如下:

# lib/facter/auditd_version.rb

Facter.add(:auditd_version) do
  confine :osfamily => 'RedHat'
  setcode do
    Facter::Core::Execution.exec('rpm -q --queryformat "%{VERSION}\n" audit')
  end
end

然后您可以使用以下方式在清单中引用您的文件路径:

$file_path = "/usr/share/doc/audit-${facts['auditd_version']}/rules/30-stig.rules"

或(旧版):

$file_path = "/usr/share/doc/audit-${::auditd_version}/rules/30-stig.rules"

您可以使用以下方法在 ERB 模板中访问它:

/usr/share/doc/audit-<%= @auditd_version %>/rules/30-stig.rules

如果您随后需要清单中的 stig 规则文件的内容,您通常会将该内容传输到您的 Puppet 清单中,并允许 Puppet 管理该文件:

$stig_rules = template('mymodule/stig_rules.erb')
file { "/usr/share/doc/audit-${facts['auditd_version']}/rules/30-stig.rules":
  ensure  => file,
  content => $stig_rules,
}

然后在您的模板中,您现在可以作为 @stig_rules.

访问该内容

如果 RPM 偶尔会更改该文件的内容,那么您将需要更新 Puppet 清单 - 是的,这并不理想。

另一种方法是简单地 return 自定义事实中的整个文件内容。

# lib/facter/stig_rules.rb

Facter.add(:stig_rules) do
  confine :osfamily => 'RedHat'
  setcode do
    Facter::Core::Execution.exec("cat \
      /usr/share/doc/audit-#{Facter.value(:auditd_version)}/stig.rules")
  end
end