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

Posted

技术标签:

【中文标题】Chef:如何覆盖角色中的默认属性?【英文标题】:Chef: How do I override default attributes in roles? 【发布时间】:2012-08-22 02:17:07 【问题描述】:

我正在使用操作码 nginx cookbook 在我的节点上配置 nginx 服务器。 nginx 食谱有一些我想在我的角色中覆盖的默认属性(“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 配方会忽略我的覆盖并使用默认值。

我在这里做错了什么?

谢谢!

【问题讨论】:

你是不是忘了上传角色到 chef-server(如果你正在使用它)? 您是否在使用自定义运行列表 (-o) 的情况下运行 chef-client?今天我了解到(经过 2-3 小时的调试),在覆盖运行列表时不使用角色/节点中设置的属性。 我遇到了同样的问题:/ 我很确定我在角色中设置了 override_attributes,并且我只在我的属性文件中使用默认值。我敢打赌这是一种厨师错误或什么。 这个问题你解决了吗? @AndréRoaldseth 感谢您的评论。我花了几个小时试图弄清楚为什么在通过 -o 运行我的配方时我的角色属性没有被拾取。您是否在任何地方找到了有关此行为的文档? 【参考方案1】:

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

确保没有直接在您的配方中覆盖节点上的属性。

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

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

# your roles/web_server.rb file

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

【讨论】:

【参考方案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

【讨论】:

【参考方案5】:

您还可以在角色编辑器中使用覆盖属性(在 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】:

根据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 级别的属性的优先级规则实际上是相同的:

    如果有,则使用来自角色的属性,例如,require_two_factor_authrole[single_sign_on] 中强制为真,default_overrides,即使在 QA 中也是如此 如果有,则使用来自环境的属性,例如,require_two_factor_authproduction 中被强制为真 如果有,则使用配方中的属性,例如,require_two_factor_authauth::two_factor 中设置为 true 最后,使用默认属性文件中的健全默认属性,例如,require_two_factor_auth = false

但是,在所有这四个地方都设置相同的属性是非常不寻常的。如果属性的正确值确实取决于配方、角色和环境,那么通常生成的值会结合所有三者的特征,并在每个级别设置不同的属性并在配方中组合。


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

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

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

【讨论】:

【参考方案7】:

这个问题来自 2012 年,非常非常古老。我的第一个建议是更明确地创建哈希参数,优先级应该设置为默认值,永远不要覆盖:

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 中,覆盖角色属性也应该已经被解析,并且应该超过此处第一行中的默认设置。我不知道为什么 override 属性在 2012 年对该用户不起作用。这可能与 Chef 11.x 版本中围绕生成所有优先级的合并视图的简单错误有关(错误早已修复,但我想不起来细节了)。

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

【讨论】:

以上是关于Chef:如何覆盖角色中的默认属性?的主要内容,如果未能解决你的问题,请参考以下文章

Typo3:如何通过属性验证覆盖默认错误消息?

如何覆盖红宝石块中的节点属性值/使用红宝石块中的变量值?

快速覆盖 UIView 中的默认图层类型

在 Chef 食谱中使用变量

如何在 application.properties 文件中覆盖 Spring Boot Starter 的默认属性?

C# protobuf-net - 默认值覆盖 protobuf 数据中的值