Chef:如何覆盖角色中的默认属性?

时间:2012-08-27 15:04:13

标签: chef

我正在使用opscode nginx cookbook在我的节点上配置nginx服务器。 nginx cookbook有一些我想在我的角色中覆盖的默认属性(“web_server”)。

这些是我要覆盖的属性:

default['nginx']['version'] = "1.2.2" # in cookbooks/nginx/attributes/default.rb
default['nginx']['source']['prefix'] = "/opt/nginx-#{node['nginx']['version']}" # in cookbooks/nginx/attributes/source.rb

在我的角色/ web_server.rb文件中,我有类似的内容:

name "web_server"
description "Setup a web server"
run_list "role[base]", "recipe[nginx]"
override_attributes 'nginx' => {
  'install_method' => "source",
  'version' => "1.2.3",
  'source' => { "prefix" => "/opt/nginx", "checksum" => nil }
}

但是,在运行chef-client时,nginx配方会忽略我的覆盖并使用默认值。

我在这里做错了什么?

谢谢!

7 个答案:

答案 0 :(得分:4)

属性优先级图表[1]显示这四个选项排在您的角色之上:

12. An override attribute located in an environment
13. A force_override attribute located in a cookbook attribute file
14. A force_override attribute located in a recipe
15. An automatic attribute identified by Ohai at the start of the chef-client run

如果这些似乎不是原因,那么改变格式可能会有所帮助。我会这样写:

override_attributes(
  nginx: {
    install_method: 'source',
    version: '1.2.3',
    source: {
      prefix: '/opt/nginx',
      checksum: [ ],
    },
  }
)

[1] https://docs.chef.io/attributes.html#attribute-precedence

答案 1 :(得分:3)

根据Chef Attribute Preference文件,这应该有效:

name "web_server"
description "Setup a web server"
run_list "role[base]", "recipe[nginx]"
default_attributes 'nginx' => {
  'install_method' => "source",
  'version' => "1.2.3",
  'source' => { "prefix" => "/opt/nginx", "checksum" => nil }
}

您不应在角色中使用override_attributes 。一旦你开始使用覆盖而不是默认值,你很快就会发现你已经使用了最强大的覆盖并没有其他方法来覆盖它。请改用default_overrides

仅使用default级别的属性优先级规则实际上非常相似:

  1. 如果有,则使用该角色的属性,例如require_two_factor_authdefault_overrides中被强制为role[single_sign_on],即使在QA中也是如此
  2. 如果有,则使用环境中的属性,例如require_two_factor_auth
  3. 中强制production为真
  4. 如果有,则使用配方中的属性,例如require_two_factor_auth
  5. auth::two_factor设置为true
  6. 最后,使用默认属性文件中的合理默认属性,例如require_two_factor_auth = false
  7. 但是,在所有这四个地方设置相同的属性是非常不寻常的。如果属性的正确值实际上取决于配方和角色以及环境,那么结果值通常会结合所有三个的特征,并且在每个级别设置不同的属性并在配方中组合。

    如果这不起作用,有两种可能性:

    • 已编辑的角色未上传到服务器
    • 使用chef-client -o "recipe[nginx]"代替chef-client -o role[web_server]或普通chef-client
    • 覆盖运行列表

    如果情况并非如此,请提供更多详细信息。我一直都在使用它,而且它总是有效的,而且我会担心是否存在不符合记录的边缘情况。

答案 2 :(得分:2)

这个问题来自2012年,非常老。我的第一个建议是在创建hash参数时更加明确,并且优先级应设置为默认值,切勿覆盖:

name "web_server"
description "Setup a web server"
run_list "role[base]", "recipe[nginx]"
default_attributes({
  'nginx' => {
    'install_method' => "source",
    'version' => "1.2.3",
    'source' => { "prefix" => "/opt/nginx", "checksum" => nil }
  }
})

问题可能与nginx食谱中使用的Derived Attributes有关:

default['nginx']['version'] = "1.2.2" # in cookbooks/nginx/attributes/default.rb
default['nginx']['source']['prefix'] = "/opt/nginx-#{node['nginx']['version']}" # in cookbooks/nginx/attributes/source.rb

如果在解析第二行时先前解析的配置未设置更高级别的替代,它将立即使用第一行。由于至少Chef 11角色属性始终会胜过属性文件中的默认属性。即使在Chef 10中,重写角色属性也应该已经解析,并且应该超过此处第一行中的默认设置。我不知道为什么覆盖属性在2012年对该用户不起作用。这可能与Chef 11.x版本中的简单错误有关,该错误围绕生成所有优先级的合并视图(错误,早已修复,但我再也无法回忆起细节了。

我鼓励当前正在阅读此问题的任何人使用PolicyFiles,该文件将替换角色,环境和Berkshelf文件。后者仍然受所有支持,但是没有进一步的开发。

答案 3 :(得分:1)

您是否在此处检查了属性优先顺序? https://docs.chef.io/attributes.html#attribute-precedence

确保您的食谱中的节点上没有覆盖任何属性。

答案 4 :(得分:1)

我能想到的唯一问题是这些属性必须被过度使用 force_overridden属性。 还要确保您已经覆盖的属性可用于运行列表(因为我对您安排角色文件的方式持怀疑态度)

答案 5 :(得分:1)

您还可以在角色编辑器中使用覆盖属性(在Web或刀角色编辑中)

{
  "name": "web_server",
  "description": "nginx version",
  "json_class": "Chef::Role",
  "default_attributes": {

  },
  "override_attributes": {
    "nginx": {
      "version": "1.2.2"
    }
  },
  "chef_type": "role",
  "run_list": [
  "recipe[]",
  "recipe[]"
  ],
  "env_run_lists": {

  }
}

答案 6 :(得分:0)

你试过括号吗?我用括号尝试了你的例子并得到了覆盖的默认属性。

# your roles/web_server.rb file

override_attributes(
  'nginx' => {
    'install_method' => "source",
    'version' => "1.2.3",
    'source' => { "prefix" => "/opt/nginx", "checksum" => nil }
  }
)