HeavyObjectLifter HeavyObjectLifter - 3 months ago 18
Ruby Question

Chef Data_bag usage via Ruby Recipe error?

I have a Chef DataBag that I'm trying to read and use inside of a chef recipe, and its kicking my ass. Please note: I'm not a programmer, and the use of Chef is my first entry into Ruby.

Based off of the examples I've found online, here is the contents of the databag "AWSProd" that lives in a folder called WEB under the data_bags folder on my Chef server:

{
"id" : "AWSProd",
"hosted_sites" : {
"siteA" : [
{
"site_name" : "siteA",
"site_doc_root_folder" : "siteA",
"site_simlink" : ""
}
],
"siteB" : [
{
"site_name" : "siteB",
"site_doc_root_folder" : "siteB",
"site_simlink" : ""
}
]
}
}


In my recipe, I'm using the following to grab the Databag for use:

WEB = data_bag("WEB")
WEB_env_globals = data_bag_item("WEB", node.chef_environment)


Then I basically want to iterate each site (siteA, siteB, etc) and grab those individual values for site_name, site_doc_root_folder, etc...

I'm trying to just echo the values so I know they work. I tried this:

WEB_env_globals["hosted_sites"].each do |site|
each_sitename = site["site_name"] ## can't convert String into Integer
each_site_doc_root_folder = site["site_doc_root_folder"]
each_site_simlink = site["site_simlink"]

execute "echo each site" do
command "echo #{each_sitename} #{each_site_doc_root_folder} #{each_site_simlink}"
action :run
end

end


But I received a "can't convert String into Integer" error on the line where I have the double ##.

Then I tried replacing that line with something like this:

each_sitename = WEB_env_globals["hosted_sites"][site]["site_name"]


But then I get an "undefined method `[]' for nil:NilClass" error on that line.

I know I'm missing something completely basic with Ruby here, and I've been looking for about an hour for a clear explanation and cant find one. Help me Ruby-Won-Kenobi...

Answer

Ok, so I got it! Took a little education on Hash Vs Arrays...

Below is the correct ruby block:

WEB_env_globals["hosted_sites"].each do |site,data|

  data.each do |hash|
    each_sitename = hash["site_name"]
    each_site_doc_root_folder = hash["site_doc_root_folder"]
    each_site_simlink = hash["site_simlink"]

      execute "echo each site #{site}" do
        command "echo #{each_sitename} #{each_site_doc_root_folder} #{each_site_simlink}"
        action :run
      end
    end
  end