首页 > 解决方案 > 如何覆盖红宝石块中的节点属性值/使用红宝石块中的变量值?

问题描述

我正在使用 AWS OpsWorks 的厨师。我有一个自定义属性 JSON,如下所示;

{
    "custom_attributes": {
        "custom_attribute_1": "default_value"
    }
}

而且,我可以#{node[:custom_attributes][:custom_attribute_1]}"在我的食谱中的任何地方打印/使用该值。然后,我想更改该值,我可以通过在我的食谱目录default.rb内的文件中提及它来实现它,如下所示;attributes

override['custom_attributes']['custom_attribute_1'] = "overridden_value"

现在,如果我打印/使用此属性,新值将得到反映。这很好用。

让我们考虑一下我没有覆盖该值并尝试为此使用红宝石块,如下所示;

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. 如果我的理解很清楚,它的发生是因为compileconvergence阶段。有人可以告诉我如何解决这个问题吗?

谢谢。

编辑

根据我的研究,我了解属性分配发生在编译阶段,而 ruby​​ 块评估发生在收敛阶段。在这种情况下,有人可以告诉我如何使用 Chef Lazy 覆盖/创建新属性吗?以下是我遇到的一个博客;

https://blog.alanthatcher.io/lazy-is-good/

标签: rubychef-infradevopsaws-opsworks

解决方案


有人可以告诉我如何使用 Chef Lazy 覆盖/创建新属性吗?

你可以使用惰性评估

在某些情况下,直到 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

推荐阅读