rubychef-infradatabags

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...


Solution

  • 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