使用多个hiera.yaml文件与Puppet

3
在我们的基础设施中引入Debian作为硬件及虚拟机操作系统之后,在Ganeti环境中,我现在试图使用模块内部的本地文件为Debian hosts部署apt源列表。
我们使用专门的模块作为puppetlabs/apt模块的包装器,为Ubuntu以及我们的本地repo部署apt源列表。Puppet服务器上的全局如下所示:
---
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和我们仓库的源列表,在大多数情况下已足够,因此对于一些主机组,我们需要一些外部仓库,例如mysqlperconaceph等。这些源被包含在相应的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文件,因此%{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无法找到任何哈希并使用默认的{}值。不幸的是,由于兼容性问题,我目前不能用lookup函数替换hiear_hash。
编辑
最初只有Ubuntu作为操作系统,我将所有的hiera数据放在data/目录中,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 <| |>
}

也许有人可以解释这个行为。
谢谢你的帮助。
1个回答

2
我把它修好了,方法是在 common.yaml 中加入以下内容:
lookup_options:
  apt_sources::sources:
    merge:
      strategy: deep

进一步地,我将create_resources语句更改如下:

最初的回答

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

1
@John Bollinger您好,希望您能解释一下这种行为。我从未不得不将合并查找选项添加到yaml文件中。这可能是因为模块的第二个hiera.yaml和hiera数据的嵌套目录吗? - Max

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接