0

i would call my self beginner with Chef and currently would like to ask what is the best practice for storing information for chefs use(not sensitive).

I will give example:

1) In order for one recipe to run correctly i had to have information about environments and which machines are in the environment. So i did created json and put it to cookbook/files.

#cookbook/files
        {
          "UAT1" : [
           "hostname1",
           "hostname2",
           ],
          "DEV2" : [
           "hostname3",
           "hostname4", 
           "hostname5"
           ]
       }

Then in the recipe i create this json on the node , and read from it when chef runs to see if i can find this hostname in the json and if yes, set attribute that i use in template later.

cookbook_file 'hostnames.json' do
  path '/hostnames.json'
  source 'hostnames.json'
  owner USER
  group GROUP
end.run_action(:create)

json = File.read('/hostnames.json')
hostname_list = JSON.parse(json)

hostname_list.each do |env, hostnames|
  hostnames.each do |host|
    node.default['environment'] = env if hostname == host
  end
end

Questions:

a) Can i read from files in cookbook without creating it actually? Because the way i am doing it right now doesnt feel right.

b) Is there any other/preferred way to store information?I have used data bags but i think its not the case, or it is?

I know question is wide, so tldr would be, what is your way of storing information that you need to use in chef run?

1 Answers1

0

file or template resources are for managing files on the target machine, and not storing some meta information for the chef-client run.

This kind of information can be taken from 3 places: search, attributes and data bags. (Chef attributes versus data bags)

In your case actually, you need to specify the node's environment at the bootstrap. So when you bootstrap hostname1 add another parameter to knife command:

knife bootstrap [...] --environment UAT1

This will set node['chef_environment'] value on the node.

If some node actually requires a list of nodes, that belong to some environment, this can be found using search

# recipe
uat1_nodes = search(:node, 'chef_environment:UAT1')

This would be the preferred way. If it does not suite you, then the place to store this information is a data bag. This way you can get your data, without this dancing with a tambourine:

# data bag item
{
  "id": "myhosts",
  "UAT1" : [
    "hostname1",
    "hostname2",
  ],
  "DEV2" : [
    "hostname3",
    "hostname4", 
    "hostname5"
  ]
}
# recipe
hostname_list = data_bag_item('<data_bag_name>', 'myhosts')
hostname_list.each do |env, hostnames|
  hostnames.each do |host|
    node.default['environment'] = env if hostname == host
  end
end
Draco Ater
  • 20,820
  • 8
  • 62
  • 86