【发布时间】:2019-09-19 21:15:42
【问题描述】:
在我们的基础架构中引入 Debian 作为硬件操作系统以及 Ganeti 环境中的虚拟机之后,我现在尝试通过在模块中使用本地 hiera.yaml 文件为 Debian 主机部署 apt 源列表自己。
我们正在为 Ubuntu 以及我们的本地存储库部署 apt 源列表,并使用专用模块作为 puppetlabs/apt 模块的包装器。 puppet 服务器上的全局hiera.yaml 如下所示:
---
version: 5
defaults:
datadir: data
data_hash: yaml_data
hierarchy:
- name: "module scope"
paths:
- "%{facts.fqdn}.yaml"
- "%{facts.context}-%{facts.location}-%{facts.hostgroup}.yaml"
- "%{facts.context}-%{facts.datacenter}-%{facts.hostgroup}.yaml"
- "%{facts.context}-%{facts.hostgroup}.yaml"
- "%{facts.context}-%{facts.location}.yaml"
- "%{facts.context}-%{facts.datacenter}.yaml"
- "%{facts.context}.yaml"
- common.yaml
datadir: "/etc/puppetlabs/code/environments/%{environment}/modules/%{module_name}/data"
在apt_sources 模块中,common.yaml 包含我们回购的 apt 密钥。 %{facts.context}.yaml 包含所有 Ubuntu 和我们的 repo 源列表,这在大多数情况下就足够了,因此对于某些主机组,我们需要一些外部 repo,例如 mysql、percona、ceph 等。以及这些源包含在各自的 yaml 文件中,或者在 %{facts.context}-%{facts.hostgroup}.yaml 或其他 yaml 文件中,最后我们只需合并 %{facts.context}.yaml 和其他相关 yaml 文件中的哈希值。
现在 Debian 的事情变得有点复杂了,我不得不在 apt_sources 模块中重组 data 目录,以便 Debian 源列表与 Ubuntu 源列表分开,如下所示:
apt_sources$ tree -L 1 data/
data/
├── common.yaml
├── Debian
└── Ubuntu
2 directories, 1 file
apt_sources$
我创建了一个本地 hiera.yaml 文件,内容如下:
---
version: 5
defaults:
datadir: data
data_hash: yaml_data
hierarchy:
- name: "module scope"
paths:
- "%{facts.operatingsystem}/%{facts.fqdn}.yaml"
- "%{facts.operatingsystem}/%{facts.context}-%{facts.location}-%{facts.hostgroup}.yaml"
- "%{facts.operatingsystem}/%{facts.context}-%{facts.datacenter}-%{facts.hostgroup}.yaml"
- "%{facts.operatingsystem}/%{facts.context}-%{facts.hostgroup}.yaml"
- "%{facts.operatingsystem}/%{facts.context}-%{facts.location}.yaml"
- "%{facts.operatingsystem}/%{facts.context}-%{facts.datacenter}.yaml"
- "%{facts.operatingsystem}/%{facts.context}.yaml"
- common.yaml
datadir: "/etc/puppetlabs/code/environments/%{environment}/modules/%{module_name}/data"
我们init.pp 的相关部分必须与 puppet 3 兼容,因为它与某些 QA 基础架构兼容:
#
class apt_sources (
Hash $gnupg_key = {},
Hash $pin = {},
$proxy = {},
$purge_sources = false,
Hash $settings = {},
Hash $sources = {},
) {
class { 'apt':
update => {
frequency => 'daily',
},
purge => {
'sources.list' => $purge_sources,
'sources.list.d' => $purge_sources,
},
}
create_resources('apt::source', hiera_hash('apt_sources::sources', $sources))
create_resources('apt::setting', hiera_hash('apt_sources::settings', $settings))
create_resources('apt::key', hiera_hash('apt_sources::gnupg_key', $gnupg_key))
create_resources('apt::pin', hiera_hash('apt_sources::pin', $pin))
Apt::Pin <| |> -> Apt::Source <| |> -> Apt::Ppa <| |> -> Exec['apt_update'] -> Package <| |>
}
现在,当为带有额外 %{facts.context}-%{facts.hostgroup}.yaml 文件的主机部署 apt_sources 时,源列表不会被合并,而是只有更具体的 yaml 文件胜出,在这种情况下是 %{facts.context}-%{facts.hostgroup}.yaml 文件,所以主要 repos 在%{facts.context}.yaml 未部署。
在 puppetserver 中,我可以在日志文件中看到 Puppet 如何使用全局 hiera.yaml 和本地 hiera.yaml 查找密钥,但仅针对第一个哈希,然后有这一行:
Hiera configuration recreated due to change of scope variables used in interpolation expressions
Puppet 一直在寻找其他键,但这次只使用全局 hiera.yaml 配置并跳过本地配置,因此 Puppet 找不到任何散列并使用默认的 {} 值。
很遗憾,由于 Puppet 3 的兼容性,我暂时无法将 hiear_hash 替换为 lookup 函数。
编辑
最初只有 Ubuntu 作为操作系统,我在目录 data/ 中拥有所有 hiera 数据,init.pp 看起来像这样:
#
class apt_sources (
$proxy = {},
$purge_sources = false,
$merge_sources = true,
) {
class { 'apt':
update => {
frequency => 'daily',
},
purge => {
'sources.list' => $purge_sources,
'sources.list.d' => $purge_sources,
},
}
if $merge_sources {
$sources = hiera_hash('apt_sources::sources', {})
create_resources('apt::source', $sources)
}
else {
$sources = hiera('apt_sources::sources')
create_resources('apt::source', $sources)
}
$settings = hiera_hash('apt_sources::settings', {})
create_resources('apt::setting', $settings)
$gnupg_key = hiera_hash('apt_sources::gnupg_key', {})
create_resources('apt::key', $gnupg_key)
$pin = hiera_hash('apt_sources::pin', {})
create_resources('apt::pin', $pin)
Apt::Pin <| |> -> Apt::Source <| |> -> Apt::Ppa <| |> -> Exec['apt_update'] -> Package <| |>
}
也许有人可以解释这种行为。
感谢您的帮助。
【问题讨论】: