Search code examples
rubychef-infrachef-solo

Chef Looping Recipes and Passing Data?


In Chef Solo I am creating several virtual-hosts in a recipe called projects. I have three recipes which are used to compile 1 project:

  • Recipes
    • gunicorn::addsite
    • nginx::addsite
    • supervisor::addsite

They only generate the needed templates. I am wondering:

  • How can I run all three recipes in a loop to create several projects?
  • Is including a recipe the right way like below?

projects/default.rb

django.each do |params|
    include_recipe "gunicorn::addsite"
    include_recipe "nginx::addsite"
    include_recipe "supervisor::addsite"
end

Then in the recipes within that loop, can I pass global variables like below?

gunicorn/addsite.rb

template "/var/server/gunicorn/#{params['vhost']}.sh" do
   ..
   ..
end

I am not using databags because I am using Vagrant and OpsWorks and it is a l bit tricky in OpsWorks. Thanks for any help.


Solution

  • You can dynamically populate node attributes, which are basically global variables, for each iteration (each app). Just set it in main recipe and read it in other recipes.

    For example:

    projects/default.rb

    django.each do |params|
        node.default["my_app"]["virtual_host"] = params
    
        include_recipe "gunicorn::addsite"
        include_recipe "nginx::addsite"
        include_recipe "supervisor::addsite"
    end
    

    gunicorn/addsite.rb

    template "/var/server/gunicorn/#{node['my_app']['virtual_host']}.sh" do
       ..
       ..
    end
    

    __

    Alternative to this approach is to make nested recipes to receive array. And create array into main recipe. With this approach, your recipes can create one or many templates depending on number of elements in passed array.

    projects/default.rb

    node.default["my_app"]["virtual_hosts"] = django
    
    include_recipe "gunicorn::addsite"
    include_recipe "nginx::addsite"
    include_recipe "supervisor::addsite"
    

    gunicorn/addsite.rb

    node['my_app']['virtual_hosts'].each do |host|
      template "/var/server/gunicorn/#{host}.sh" do
        ..
        ..
      end
    end