如何覆盖红宝石块中的节点属性值/使用红宝石块中的变量值?
Posted
技术标签:
【中文标题】如何覆盖红宝石块中的节点属性值/使用红宝石块中的变量值?【英文标题】:How to override node attribute value within ruby block / using a value of variable in ruby block? 【发布时间】:2021-08-31 08:53:35 【问题描述】:我正在使用 AWS OpsWorks 的 Chef。我有一个自定义属性 JSON,如下所示;
"custom_attributes":
"custom_attribute_1": "default_value"
而且,我可以使用#node[:custom_attributes][:custom_attribute_1]"
在我的食谱中的任何位置打印/使用该值。然后,我想更改该值,我可以通过在我的食谱的attributes
目录中的default.rb
文件中提及它来实现它,如下所示;
override['custom_attributes']['custom_attribute_1'] = "overridden_value"
现在,如果我打印/使用此属性,新值将得到反映。这很好用。
让我们考虑一下我没有覆盖该值并尝试为此使用 ruby 块,如下所示;
ruby_block 'test_block' do
block do
node.override['custom_attributes']['custom_attribute_1'] = "overridden_value"
end
action :run
end
log 'message' do
message "attribute value = #node[:custom_attributes][:custom_attribute_1]"
level :info
end
现在,如果我们查看日志,它将显示 default_value
而不是 overridden_value
。如果我的理解很清楚,它的发生是因为 compile
和 convergence
阶段。谁能告诉我如何解决这个问题?
谢谢。
编辑
根据我的研究,我知道属性分配发生在编译阶段,而 ruby 块评估发生在收敛阶段。在这种情况下,有人可以告诉我如何使用 Chef Lazy 覆盖/创建新属性吗?下面是我偶然发现的一个博客;
https://blog.alanthatcher.io/lazy-is-good/
【问题讨论】:
您有什么理由要从ruby_block
中设置节点属性吗?它看起来更像是一个(变量的)范围问题,而不是编译/收敛阶段。
@seshadri_c 我明白你的意思。但问题是,假设我有一个跨不同接收者使用的属性值,并且该值是动态的。因此,即使我没有覆盖该值并假设我正在使用 ruby 块创建一个新属性并在我的食谱中提及它,它也会看起来是空白的。我同意编译/收敛阶段,我明白这就是正在发生的事情。
您在ruby_block
中分配给变量(或属性)的值将仅在其中应用。如果你编写一个简单的 Ruby 代码将属性的值写入ruby_block
中的一个文件,你会看到overridden_value
。
【参考方案1】:
有人可以告诉我如何使用 Chef Lazy 覆盖/创建新属性吗?
你可以使用lazy evaluation
在某些情况下,直到 Chef Infra Client 运行的执行阶段才能知道属性的值。在这种情况下,使用属性值的惰性求值可能会有所帮助。不是为属性分配一个值,而是为它分配一个代码块。使用惰性求值的语法如下:
property_name lazy code_block
lazy 用于告诉 Chef Infra Client 稍后在资源评估过程中评估代码块的内容(而不是立即),而 code_block 是提供该值的任意 Ruby 代码。
所以你可能想使用lazy
,如下所示
log 'message' do
message lazy "attribute value = #node[:custom_attributes][:custom_attribute_1]"
level :info
end
【讨论】:
以上是关于如何覆盖红宝石块中的节点属性值/使用红宝石块中的变量值?的主要内容,如果未能解决你的问题,请参考以下文章