如何将参数传递给厨师的模板?

how to pass parameters to template in chef?

刚开始学厨师。这些天,我正在测试模板示例 -- https://docs.chef.io/resources/template/

但我总是失败...这是我的代码 --

  1. 我创建了一个名为 sample 的食谱,并创建了一个名为 default.rb
  2. 的食谱
file '/srv/www/htdocs/index.html' do
  content 'Hello World!'
end

include_recipe '::e'
  1. 然后我创建了另一个食谱e.rb --
default['authorization']['sudo']['groups'] = %w(sysadmin wheel admin)

default['authorization']['sudo']['users'] = %w(jerry greg)

template '/tmp/test.txt' do
  source 'test.txt.erb'
  mode '0440'
  owner 'root'
  group 'root'
  variables(
    sudoers_groups: node['authorization']['sudo']['groups'],
    sudoers_users: node['authorization']['sudo']['users']
  )
end
  1. 在这本食谱的模板文件夹中,我创建了一个 erb 文件 -- test.txt.erb
Defaults        !lecture,tty_tickets,!fqdn
root          ALL=(ALL) ALL
<% @sudoers_users.each  do |user| -%>
<%= user %>   ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL
<% end -%>

%sysadmin     ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL

<% @sudoers_groups.each do |group| -%>

<%= group %> ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL
<% end -%>

  1. 然后启动 "chef-client" 后,错误信息显示 --
[2022-05-06T18:01:07+08:00] FATAL: NameError: undefined local variable or method `default' for cookbook: sample, recipe: e :Chef::Recipe
  1. 由于错误显示无法找到名为 'default' 的变量,并且在该示例中——它使用 node['authorization']['sudo']['groups'] 将参数传递给 sudoers_groups,我认为 e.rb 也许应该是这个 --
node['authorization']['sudo']['groups'] = %w(sysadmin wheel admin)
node['authorization']['sudo']['users'] = %w(jerry greg)

template '/tmp/test.txt' do
  source 'test.txt.erb'
  mode '0440'
  owner 'root'
  group 'root'
  variables(
    sudoers_groups: node['authorization']['sudo']['groups'],
    sudoers_users: node['authorization']['sudo']['users']
  )
end
  1. 但还是失败了--
[2022-05-06T17:39:38+08:00] FATAL: NoMethodError: undefined method `[]' for nil:NilClass

我真的被这个官方样本搞砸了。请帮助我,在此先感谢您的任何想法。

问候 艾森

有很多地方可以定义属性。出于此答案的目的,我们将其限制在配方和属性文件中。属性有不同precedence rules

在 cookbook 的属性文件中定义,例如 sample/attributes/default.rb 具有 default 优先级:

default['authorization']['sudo']['groups'] = %w(sysadmin wheel admin)
default['authorization']['sudo']['users'] = %w(jerry greg)

那么配方 sample/recipes/e.rb 和模板 test.txt.erb 就可以按照您在问题中描述的那样使用了。

但是我们在recipe中定义属性的时候,需要使用语法node.<precedence>,比如node.default:

sample/recipes/e.rb中定义:

node.default['authorization']['sudo']['groups'] = %w(sysadmin wheel admin)
node.default['authorization']['sudo']['users'] = %w(jerry greg)

template '/tmp/test.txt' do
# and so on