after the introduction of Debian to our infrastructure as an OS for hardware as well as for VM's in our Ganeti environment, I am trying now to deploy apt sources lists for Debian hosts by using a local hiera.yaml
file within the module it self.
We are deploying the apt sources lists for Ubuntu as well as our local repo with a dedicated module as a wrapper for puppetlabs/apt module. The global hiera.yaml
on puppet server looks as follows:
---
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"
In the apt_sources
module the common.yaml
contains the apt key of our repo. The %{facts.context}.yaml
contains all Ubuntu and our repo sources lists, which is sufficient in most cases, thus for some host groups we need some external repos, such as mysql
, percona
, ceph
etc.. and these sources are included in the respective yaml file, either in a %{facts.context}-%{facts.hostgroup}.yaml
or on of the other yaml files and at the end we just merge the hashes in %{facts.context}.yaml
and in the other relevant yaml files.
Now with Debian things are getting a bit more complex, I had to restructure the data
directory in our apt_sources
module so Debian sources lists are separated from Ubuntu sources lists as follows:
apt_sources$ tree -L 1 data/
data/
├── common.yaml
├── Debian
└── Ubuntu
2 directories, 1 file
apt_sources$
and I created a local hiera.yaml
file with the following content:
---
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"
The relevant part of our init.pp
which has to stay puppet 3 compatible due compatibility to some QA infrastructure:
#
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 <| |>
}
Now when deploying the apt_sources for a host with an additional %{facts.context}-%{facts.hostgroup}.yaml
file, the sources lists are not getting merged, rather only the more specific yaml file wins, in this case the %{facts.context}-%{facts.hostgroup}.yaml
file, so the main repos in %{facts.context}.yaml
are not deployed.
In puppetserver I can see in the logfile how Puppet looks up for the keys using the global hiera.yaml
and then the local hiera.yaml
but only for the first hash, then there is this line:
Hiera configuration recreated due to change of scope variables used in interpolation expressions
and Puppet keeps looking for the other keys, but this time using only the global hiera.yaml
configuration and skips the local one so Puppet cannot find any hash and using the default {}
value.
Unfortunately I cannot replace hiear_hash
with lookup
function for the moment due Puppet 3 compatibility.
EDIT
Originally with only Ubuntu as OS I had all hiera data in the directory data/
and the init.pp
looked like this:
#
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 <| |>
}
Maybe someone can explain this behavior.
Thank you for your help.