如何从Puppet代码或puppet lookup命令访问多层嵌套Hiera值
在Puppet模块中通过Hiera获取匹配通配符的键值列表
嘿,这个问题确实有点棘手,网上资料零散很正常——我来给你捋捋两种靠谱的实现方式,都是Puppet生态里常用的方案,完全满足你用foo::bar::*::baz这类通配符获取值列表的需求。
方法一:直接用lookup()的Glob匹配(最简洁)
从Puppet 4.9+(对应Hiera 5)开始,lookup()原生支持Glob模式匹配键路径,刚好能实现你要的foo::bar::*::baz匹配逻辑。
步骤说明:
假设你的Hiera数据文件(比如common.yaml)里有这些条目:
foo::bar::server1::baz: 'web01' foo::bar::server2::baz: 'web02' foo::bar::server3::baz: 'web03'
在Puppet模块里,你可以直接用Glob匹配所有符合foo::bar::*::baz的键,然后提取它们的值生成列表:
# 用Glob匹配所有目标键,返回哈希后提取值转为数组 $baz_values = lookup('foo::bar::*::baz', Hash, 'unique').values
- 这里的
'unique'是合并策略,用来自动去重复值;如果不需要去重,换成'first'或者'hash'都可以 - 如果需要匹配任意深度的子键(比如
foo::bar::group1::server1::baz),把通配符换成**就行:lookup('foo::bar::**::baz', Hash, 'unique').values
方法二:先获取父节点哈希,再遍历提取(更灵活)
如果你的Hiera数据是嵌套结构(比如foo::bar下是一个哈希,每个子节点包含baz字段),这种方式更适合做后续的过滤或自定义处理。
步骤说明:
假设你的Hiera数据是这样的嵌套结构:
foo::bar: server1: baz: 'web01' role: 'frontend' server2: baz: 'web02' role: 'backend' server3: baz: 'web03' role: 'database'
在Puppet模块里,先获取整个foo::bar的哈希,再用map遍历提取每个子节点的baz值:
# 获取foo::bar的完整嵌套哈希 $foo_bar_data = lookup('foo::bar', Hash, 'deep') # 遍历哈希,提取每个子节点的baz值,生成一维数组 $baz_values = $foo_bar_data.map |$key, $node_data| { $node_data['baz'] }.flatten
这种方式的好处是,你可以额外添加过滤逻辑,比如只提取role为frontend的节点的baz值:
$frontend_baz_values = $foo_bar_data.filter |$key, $node_data| { $node_data['role'] == 'frontend' }.map |$key, $node_data| { $node_data['baz'] }.flatten
注意事项
- 确保你的Puppet版本在4.9以上,Hiera 5及更高版本才支持Glob匹配
- 检查Hiera配置文件(
hiera.yaml)的层级设置,确保数据文件能被正确加载 - 如果
lookup()返回空数组,先核对键路径的拼写,确认Hiera数据里确实存在匹配的条目
内容的提问来源于stack exchange,提问作者patok
相关产品推荐
相关产品推荐

