Data bag item object

Topics: Chef

A class for a specific data bag item can encapsulate all the code that’s necessary to access and/or process the item’s attributes in a straightforward and simple way. It makes for Clean Chef code.

The following example demonstrates this with a Website object that gets initialized with a data bag item hash. We can simply pass the object to a template and within this template, access its attributes via website.main_domain or website.url. The ssh_keys method makes sure that we’re always dealing with an array, even if the data bag item is missing the ssh_keys attribute.

module MyDataBags
  # Provide information about website data bag item
  class Website
    ATTR_NAMES = %i[
      id main_domain ssh_keys
    ].freeze

    attr_reader(*ATTR_NAMES)

    def initialize(data_bag_item)
      @item = data_bag_item
      fix_missing_fields

      ATTR_NAMES.each do |key|
        instance_variable_set("@#{key}", item.fetch(key, nil))
      end
    end

    def url
      "https://#{main_domain}"
    end

    def ssh_keys
      @ssh_keys || []
    end    
  end
end

website_item = data_bag_item(:websites, "mysite")
website = MyDataBags::Website.new(website_item)

template "myconf" do
  ...
  variables(
    website: website
  )
end