1

One of chef node's attributes is an array of hashes:

"array_of_hashes": [
      {
        "hash_key_1": "value1",
        "hash_key2": "value2",
      },
      {
        "hash_key_2": "value4",
        "hash_key_1": "value3",
      }
    ]

I need to cycle through every array element and generate a configuration file with template parameters defined by values in hashes:

# cat my_config.conf
key1=value1; key2=value2
key1=value3; key2=value4

I can't achieve this result using template resource because it owerwrites the config file (doesn't append it) on every cycle iteration and I get only the last string as a result.

What's the best way to generate such a config file mentioned above?

HUB
  • 6,630
  • 3
  • 23
  • 22

2 Answers2

2

Can you use a bash block?

http://wiki.opscode.com/display/chef/Resources#Resources-Script

So, something like:

bash "append_to_config" do
  user "root"
  cwd "/path/to/config/directory"
  code <<-EOH
  echo "#{node[:array_of_hashes][:hash_key]}=#{node[:array_of_hashes][:hash_value]}" > my_config.conf
  EOH
end

Plus whatever loops, conditions, etc., you would need to make that work.

cjc
  • 24,916
  • 3
  • 51
  • 70
  • This is just what I've done. The only difference is that I used the `execute` resource but the idea is the same. Though this is still a workaround. – HUB Feb 01 '12 at 17:31
  • I wonder if it would be cleaner to use the template, but use a subsequent bash block to append the new contents of the file to your real config file? – cjc Feb 01 '12 at 20:27
  • Hah, real solution: use redis. – cjc Feb 01 '12 at 20:28
1

This isn't strictly built into Chef as a feature of the library or any of the resources because when managing system state it is better and more reliable to manage the whole contents of a file. If the content of the template is modified elsewhere in another cookbook, consider why that is and if it may be sensible to consolidate the recipes.

You can also use a nifty feature to "reopen" a defined resource - the resources method can be used to select particular resource. Very basic example:

That said, the Chef::Util::FileEdit class has a number of helper methods for managing content. The ticket that originally implemented the feature is CHEF-78. It isn't documented (sorry) for reasons I mentioned above. There is a patch to further extend this library to append a line if it doesn't exist, which is under ticket CHEF-2740. You may be able to achieve the results you want with the existing library's methods.

jtimberman
  • 7,587
  • 2
  • 34
  • 42