Puppet 5.3.3环境中$facts['ec2_metadata']['instance-id']未定义问题问询
解决Puppet 5.3.3中EC2元数据Fact不存在的问题
我明白你在本地测试Puppet时遇到的麻烦——本地环境没有EC2元数据,直接访问$facts['ec2_metadata']['instance-id']会触发错误,你试的几种写法都没解决问题,我来帮你理清原因并给出靠谱的方案。
先说说你之前写法的问题:
- pick函数直接用的问题:如果
$facts['ec2_metadata']本身就不存在,访问$facts['ec2_metadata']['instance-id']会直接抛出哈希键不存在的错误,pick根本没机会执行。 - defined()函数用错场景:
defined()是用来检查Puppet资源(比如class、file)是否被定义的,不是用来判断变量或哈希键是否存在的,这个写法从根上就不对,而且同样会先触发键不存在的错误。 - getvar参数格式错误:getvar需要传入字符串形式的变量路径,比如
getvar('facts.ec2_metadata.instance-id'),你直接传$facts['ec2_metadata']['instance-id']还是会先尝试访问不存在的键,导致报错。
正确的解决方法
因为Puppet 5中访问哈希不存在的键会抛出错误,所以必须用安全的方式获取嵌套哈希的值,这里有几种可靠的写法:
方法1:用dig函数(推荐)
dig函数可以安全地遍历嵌套哈希,任何一级不存在都会返回undef,完美适配pick函数:
$instance_id = pick($facts.dig('ec2_metadata', 'instance-id'), $facts['ipaddress'])
方法2:嵌套检查哈希键是否存在
先确认父级哈希ec2_metadata存在,再检查子键instance-id:
if $facts.key?('ec2_metadata') and $facts['ec2_metadata'].key?('instance-id') { $instance_id = $facts['ec2_metadata']['instance-id'] } else { $instance_id = $facts['ipaddress'] }
方法3:正确使用getvar函数
把变量路径写成字符串形式,getvar会安全地解析这个路径,不存在时返回undef:
$instance_id = pick(getvar('facts.ec2_metadata.instance-id'), $facts['ipaddress'])
这三种方法都能在本地环境(无EC2元数据)和EC2环境中正常工作,不会触发错误。
内容的提问来源于stack exchange,提问作者icalvete
相关产品推荐
相关产品推荐

