简体   繁体   English

在 puppet 中使用多个 hiera.yaml 文件

[英]using multiple hiera.yaml files with puppet

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.在将 Debian 作为硬件操作系统以及我们 Ganeti 环境中的 VM 引入我们的基础设施之后,我现在正在尝试通过使用模块中的本地hiera.yaml文件为 Debian 主机部署 apt 源列表。

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.我们正在为 Ubuntu 以及我们的本地存储库部署 apt 源列表,并使用专用模块作为 puppetlabs/apt 模块的包装器。 The global hiera.yaml on puppet server looks as follows: 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"

In the apt_sources module the common.yaml contains the apt key of our repo.apt_sources模块中, common.yaml包含我们的 repo 的 apt 密钥。 The %{facts.context}.yaml contains all Ubuntu and our repo sources lists, which is sufficient in moste 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.%{facts.context}.yaml包含了所有Ubuntu和我们的回购来源名单,这是moste情况下已经足够,因此,对于我们需要一些外部回购,比如一些主机组mysqlperconaceph等。而这些来源包含在各自的 yaml 文件中,要么在%{facts.context}-%{facts.hostgroup}.yaml要么在其他 yaml 文件中,最后我们只合并%{facts.context}.yaml的哈希并在其他相关的 yaml 文件中。 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:现在 Debian 的事情变得有点复杂了,我不得不在我们的apt_sources模块中重组data目录,以便 Debian 源列表与 Ubuntu 源列表分开,如下所示:

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:我创建了一个包含以下内容的本地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"

The relevant part of our init.pp wich has to stay puppet 3 compatible due compatibility to some QA infrastructure:由于与某些 QA 基础设施的兼容性,我们的init.pp的相关部分必须保持 puppet 3 兼容:

#
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.现在,当使用额外的%{facts.context}-%{facts.hostgroup}.yaml文件为主机部署 apt_sources 时,源列表不会被合并,而只有更具体的 yaml 文件获胜,在这种情况下, %{facts.context}-%{facts.hostgroup}.yaml文件,因此未部署%{facts.context}.yaml中的主要存储库。 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:在 puppetserver 中,我可以在日志文件中看到 Puppet 如何使用全局hiera.yaml和本地hiera.yaml查找键,但仅用于第一个哈希,然后是这一行:

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.并且 Puppet 一直在寻找其他键,但这次仅使用全局hiera.yaml配置并跳过本地配置,因此 Puppet 找不到任何哈希并使用默认{}值。

Unfortunately I cannot replace hiear_hash with lookup function for the moment due Puppet 3 compatibility.不幸的是,由于 Puppet 3 兼容性,我暂时无法用lookup功能替换hiear_hash

EDIT编辑

Originally with only Ubuntu as OS I had all hiera data in the directory data/ and the init.pp looked like this:最初只有 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 <| |>
}

Maybe someone can explain this behavior.也许有人可以解释这种行为。

Thank you for your help.感谢您的帮助。

I fixed it by adding the following to the common.yaml :我通过将以下内容添加到common.yaml来修复它:

lookup_options:
  apt_sources::sources:
    merge:
      strategy: deep

further more I changed the create_resources statements as follows:此外,我更改了create_resources语句,如下所示:

create_resources('apt::source', $sources)
create_resources('apt::setting', $settings)
create_resources('apt::key', $gnupg_key)
create_resources('apt::pin', $pin)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM