jsonchef-infraruby-hash

How to iterate json array from role.json is role to chef recipe


I have a role_multi_module.json which is a chef role which contains a array in JSON format.

Role name: role_multi_module.json

{
    "name": "role_multi_module",
    "default_attributes": {
            "cloud": {
                    "global": false
            }
    },
    "override_attributes": {},
    "json_class": "Chef::Role",
    "description": "This is just a test role, no big deal.",
    "employees": [{
                    "name": "Ram",
                    "email": "ram@gmail.com",
                    "age": 23
            },
            {
                    "name": "Shyam",
                    "email": "shyam23@gmail.com",
                    "age": 28
            }
    ],
    "chef_type": "role",
    "run_list": ["recipe[hello-chef]"]
}

Using the below recipe I'm able to get only one employee details i.e. the second one.

Recipe name: multi.rb

execute 'test-multi-module' do  
  node['role_multi_module']['employees'].each do |employee|
    command "echo #{employees['name']} #{employees['email']}}"
  end
end

How to iterate the JSON array of 2 employees from the above recipe?


Solution

  • As per documentation on roles, there are some fixed allowed fields such as name, description, etc. User defined variables should be defined under default_attributes or override_attributes.

    A role structure like this:

      "default_attributes": {
        "employees": [
          {
            "name": "Ram",
            "email": "ram@gmail.com",
            "age": 23
          },
          {
            "name": "Shyam",
            "email": "shyam23@gmail.com",
            "age": 28
          }
        ],
        "cloud": {
          "global": false
        }
      },
    

    How to iterate the JSON array of 2 employees from the above recipe?

    We need to iterate the entire execute resource (not just command) for each item of employee array. Considering the above JSON declaration:

    node['employees'].each do |employee|
      execute "test-multi-#{employee['name']}" do
        command "echo #{employee['name']} #{employee['email']}"
      end
    end