How to override node attribute value within ruby block / using a value of variable in ruby block?


i have a custom attribute JSON like below;

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

and, I can use #{node[:custom_attributes][:custom_attribute_1]}" to print / use that value anywhere in my recipes. Then, I want to change that value and I can achieve it by mentioning it in default.rb file inside attributes directory of my cookbook, like below;

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

Now, if I print / use this attribute, new value will get reflected. This works well.

Lets consider I haven't overridden the value and trying to use a ruby block for this like below;

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

log 'message' do
    message "attribute value = #{node[:custom_attributes][:custom_attribute_1]}"
    level :info

Now, if we take a look at log, it will show default_value instead of overridden_value. Why this is happening and how to fix this?

below are couple of links I have came across, but I don't know how to make use of it because I am a beginner.


message lazy { "attribute value = #{node[:custom_attributes][:custom_attribute_1]}" }

When the log resource is compiled, your ruby block resource hasn't been run, just compiled, it's the usual compile vs converge problem people stumble on.

Wrapping the property value with lazy { } will tell chef to delay until converge phase to resolve the value instead of evaluating it at compile time.

More details: Chef's Two Pass Model – Noah Kantrowitz


Thanks @Tensibai , it helped :+1:

thanks for the awesome information.

Following this post , I am using lazy block to evaluate node attribute lazily in registry_key chef resource to set registry key , However lazy evaluation is not working as expected & I am getting
undefined method `to_a' for #<Chef::DelayedEvaluator:0x000000000a585c28> error . I would appreciate if some one can take a look on it & suggest a hint.


# Simple Recipe:: rectify-java-param-heapdump

node.default['options_value1'] = []
options_value = []

#Creating common heapdump directory path for given tomcat services on node (if it doesn't exist)
directory "#{node['birst_post_installation']['heapdump_path']}" do
	recursive true
	not_if { ::Dir.exist?("#{node['birst_post_installation']['heapdump_path']}") }

#Fetching existing registry value of birst service
ruby_block "heapdump - Proceeding for modifying registry" do
      block do
        existing_value = registry_get_values("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Apache Software Foundation\\Procrun 2.0\\ABC\\Parameters\\Java", :x86_64)"heapdump existing value is - service is  ")
        #Checking existing registry value & storing conditionally modified registry object in variable
           if e[:name] == "Options" 
            		node.override['options_value1'] = e[:data]
            		node.override['options_value1'].insert(-1, "-XX:+HeapDumpOnOutOfMemoryError")
        }"here heapdump options node value is ")['options_value1'])
	  action :run

#Setting updated 'Options' param's value for given birst tomcat service in registry
registry_key "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Apache Software Foundation\\Procrun 2.0\\ABC\\Parameters\\Java" do
	  values [{
        name: 'Options',
        type: :multi_string,
        data: lazy { node['options_value1'] }
      action :create


Installing Cookbook Gems:
Compiling Cookbooks...
Converging 3 resources
Recipe: mycookbook::rectify-java-param-heapdump
  * directory[D:/Heapdumps] action create (skipped due to not_if)
  * ruby_block[heapdump - Proceeding for modifying registry] action run
    - execute the ruby block heapdump - Proceeding for modifying registry
  * registry_key[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Apache Software Foundation\Procrun 2.0\ABC\Parameters\Java] action create

    Error executing action `create` on resource 'registry_key[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Apache Software Foundation\Procrun 2.0\ABC\Parameters\Java]'

    undefined method `to_a' for #<Chef::DelayedEvaluator:0x000000000a585c28>
    Did you mean?  to_s

    Resource Declaration:
    # In D:/chefRepo/cache/cookbooks/mycookbook/recipes/rectify-java-param-heapdump.rb

     77: registry_key "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Apache Software Foundation\\Procrun 2.0\\ABC\\Parameters\\Java" do
     78:          values [{
     79:         name: 'Options',
     80:         type: :multi_string,
     81:         data: lazy { node['options_value1'] }
     82:       }]
     83:       action :create
     84: end

    Compiled Resource:
    # Declared in D:/chefRepo/cache/cookbooks/mycookbook/recipes/rectify-java-param-heapdump.rb:77:in `from_file'

    registry_key("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Apache Software Foundation\Procrun 2.0\ABC\Parameters\Java") do
      action [:create]
      default_guard_interpreter :default
      values [{:name=>"Options", :type=>:multi_string, :data=>#<Chef::DelayedEvaluator:0x000000000a585c28@D:/chefRepo/cache/cookbooks/mycookbook/recipes/rectify-java-param-heapdump.rb:81>}]
      unscrubbed_values [{:name=>"Options", :type=>:multi_string, :data=>#<Chef::DelayedEvaluator:0x000000000a585c28@D:/chefRepo/cache/cookbooks/mycookbook/recipes/rectify-java-param-heapdump.rb:81>}]
      declared_type :registry_key
      cookbook_name "mycookbook"
      recipe_name "rectify-java-param-heapdump"
      key "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Apache Software Foundation\\Procrun 2.0\\ABC\\Parameters\\Java"

    System Info:
    ruby=ruby 2.6.5p114 (2019-10-01 revision 67812) [x64-mingw32]

Created 'registry_key' resource's values can't be set lazily. · Issue #11877 · chef/chef · GitHub for this