Puppet Agent执行模板循环时报错:undefined method `[]' for nil:NilClass
问题:Puppet模板循环执行时出现
undefined method [] for nil:NilClass错误 相关代码片段
清单参数定义
Array $secretsproperties_diffusion_siteweb_ftp_keys = ['eliasseAN','eliasseAN.server2'], Hash $eloi_eliasse = {'eliasseAN' => ['ftpeliasse','Eliasse0000'], 'eliasseAN.server2' => ['ftpeliasse','Eliasse0000']},
清单资源配置
file { "generate-secrets-properties-file": ensure => 'file', path => "${app_working_directory}/cfg/secrets.properties", owner => "${appuser[0]}", group => "${appuser[0]}", content => template("${name}/secrets.properties.erb"), notify => "secretsproperties_diffusion_siteweb_ftp_keys : $content1", notify => "eloi_eliasse : $content2", require => [ User["${appuser[0]}"], File['create-dir-cfg'] ] }
ERB模板内容(secrets.properties.erb)
<%- @secretsproperties_diffusion_siteweb_ftp_keys.each do |key| -%> <%= key %>.ftp.login=<%= @eloi_eliasse[key][0] %> # That's line 7 <%= key %>.ftp.pwd=<%= @eloi_eliasse[key][1] %> <% end -%>
执行错误信息
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Function Call, Failed to parse template appeloi/secrets.properties.erb: Filepath: /etc/puppetlabs/code/environments/development/modules/appeloi/templates/secrets.properties.erb Line: 7 Detail: undefined method `[]' for nil:NilClass (file: /etc/puppetlabs/code/environments/development/modules/appeloi/manifests/init.pp, line: 322, column: 16) on node eloi-pre-tst-mgt.assemblee-nationale.fr Warning: Not using cache on failed catalog Error: Could not retrieve catalog; skipping run Debug: HTTP POST https://frm-dev-app.assemblee-nationale.fr:8140/puppet/v3/catalog/eloi-pre-tst-mgt.assemblee-nationale.fr returned 500 Server Error
排查分析
错误核心是模板第7行中@eloi_eliasse[key]返回nil,说明循环遍历的key在@eloi_eliasse哈希中找不到对应的键值对。结合场景,可能的原因包括:
- 参数传递异常:尽管声明未被外部覆盖,但Foreman注入参数时可能存在隐式转换,比如数组元素与哈希键的大小写不一致、存在不可见字符或空格差异。
- 变量作用域问题:模板未正确接收
$eloi_eliasse变量,需确认类参数是否暴露给同模块模板(Puppet类参数默认可访问,但局部变量需显式传递)。 - 哈希键类型不匹配:数组元素为字符串,若哈希键是符号(如
:eliasseAN),会导致匹配失败。 - 清单资源配置错误:
file资源重复定义notify属性,后面的配置会覆盖前面的,虽不是当前错误直接原因,但会导致第一个notify失效。
解决方案
验证变量实际值:在清单中添加调试输出,确认两个变量的实际内容:
notify { 'debug-puppet-vars': message => "Keys: ${secretsproperties_diffusion_siteweb_ftp_keys}, Hash: ${eloi_eliasse}" }执行
puppet agent -t --debug查看输出,确认数组中每个key都存在于哈希内。修复模板空值问题:添加存在性检查,避免nil报错:
<%- @secretsproperties_diffusion_siteweb_ftp_keys.each do |key| -%> <% if @eloi_eliasse.key?(key) %> <%= key %>.ftp.login=<%= @eloi_eliasse[key][0] %> <%= key %>.ftp.pwd=<%= @eloi_eliasse[key][1] %> <% else %> # Warning: Key <%= key %> not found in eloi_eliasse configuration <% end %> <%- end -%>修复重复
notify属性:将多个notify合并为数组形式(注意:若为资源引用需确保对应资源存在,调试用建议改用notify资源):notify => [ "secretsproperties_diffusion_siteweb_ftp_keys : $content1", "eloi_eliasse : $content2" ],
内容的提问来源于stack exchange,提问作者Alexis Dufrenoy
相关产品推荐
相关产品推荐

