You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ruby块中覆盖Chef节点属性值,解决编译收敛阶段差问题

问题根因

Chef执行分为两个核心阶段:

  • 编译阶段:读取所有食谱代码,解析所有资源的属性值,生成资源执行队列,此时不会执行任何资源的实际操作
  • 收敛阶段:按照队列顺序依次执行资源的action

你定义的ruby_block的block内部代码仅在收敛阶段才会执行,但log资源的message属性在编译阶段就完成了字符串插值求值,此时属性还未被修改,因此输出的仍然是初始的default_value。

修复方案(使用Chef Lazy)

Chef的lazy关键字可以将资源属性的求值时间,从编译阶段推迟到对应资源执行前的收敛阶段,刚好匹配ruby_block修改属性的执行时机。

修改后的代码如下:

ruby_block 'test_block' do
    block do
        node.override['custom_attributes']['custom_attribute_1'] = "overridden_value"
    end
    action :run
end

log 'message' do
    # 用lazy包裹求值逻辑,延迟到收敛阶段执行log资源前再读取属性值
    message lazy { "attribute value = #{node[:custom_attributes][:custom_attribute_1]}" }
    level :info
end

修改后log输出的就是修改后的overridden_value。

扩展说明

  • 新增属性的操作逻辑和覆盖完全一致,只要在ruby_block内给node属性赋值,后续引用该属性的资源属性都用lazy包裹即可
  • 如果有多个依赖这个动态修改属性的资源,每个资源的对应属性都需要单独加lazy修饰

内容的提问来源于stack exchange,提问作者Alfred

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 23:54:03