Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 2 down vote accepted

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.

share|improve this answer
    
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 1 '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 1 '12 at 20:27
    
Hah, real solution: use redis. –  cjc Feb 1 '12 at 20:28

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.