user1106405
user1106405

Reputation: 161

Best Practice for setting unique Chef Node Attributes

I am attempting to use Chef to manage new virtual machines. I'm using a dedicated Chef server and doing all this work from a separate workstation vm.

The way I am currently doing it is cloning a base vm image then using knife bootstrap to install Chef and bring the vm to a consistent state.

I can specify an environment or run list for the vm; I can override certain settings in my environment, e.g. I have the chef-client interval in the "overrides" block of the test environment set to run the client every 60 while I'm testing so I don't have to manually run chef-client every time.

For instance, my workflow is this:

The problem I am having is setting per-node attributes. I would like to use the hostname cookbook to set the node's hostname, if I set this in a role then each server would have to have a new role created. But when I attempt to bootstrap and include this role I get an error:

chef-test1   * log[Please set the set_fqdn attribute to desired hostname] action write[2013-12-09T16:26:56-07:00] WARN: Please set the set_fqdn attribute to desired hostname

When I bootstrap without that recipe and attempt to edit the node and set the "set_fqdn" attribute, I am unable to save the attribute, e.g. this json:

{
  "name": "chef-test1",
  "set_fqdn": "chef-test1.local.fqdn",
  "chef_environment": "test-dev1",
  "normal": {
    "tags": [

    ]
  },
  "run_list": [
    "recipe[ntp]",
    "recipe[chef-client]",
    "recipe[hostname]"
  ]
}

when I exit out of my editor, knife tells me:

Node not updated, skipping node save

I attempted to edit this attribute in the chef gui and the attribute won't save.

I found this guy who is creating the json in /etc/chef/chef.json, doing basically what I would expect, but I'm not sure how /etc/chef/chef.json comes into play (update it for each new node? I'm not using chef-solo so maybe that's where my confusion is).

According to this email thread it's not possible to override default attributes with knife node edit, but "set_fqdn" isn't a default. I would like to avoid creating a role for each node, and I think I can use the hostname cookbook to alleviate the need to manually set the hostname, something like:

knife bootstrap saucy64 -r 'recipe[ntp],recipe[chef-client],recipe[hostname]' --json '"{ set_fqdn": "chef-test1.local.tld", "chef_client": { "interval": "600" }'

knife bootstrap fedora19 -r 'recipe[ntp],recipe[chef-client],recipe[hostname]' --json '"{ set_fqdn": "chef-test2.local.tld", "chef_client": { "interval": "60" }'

I appreciate the assistance.

Upvotes: 11

Views: 22565

Answers (3)

user1106405
user1106405

Reputation: 161

how about a recipe that sets the hostname based on the defined node.name when you bootstrap the node, I wrote one which is a fork of the original chef-hostname cookbook.

Upvotes: 2

user1106405
user1106405

Reputation: 161

This works:

knife bootstrap 192.168.15.43 -r 'recipe[hostname],recipe[ntp],recipe[chef-client]' -j '{"set_fqdn": "chef-test2"}'

(also found reading knife help bootstrap help)

This stackoverflow answer uses similar syntax.

Edit: Well, almost, this creates two node entries. need to specify the node name with the -N parameter:

knife bootstrap 192.168.15.43 -r 'recipe[hostname],recipe[ntp],recipe[chef-client]' -j '{"set_fqdn": "chef-test2"}' -N chef-test2

knife bootstrap 192.168.15.43 --run-list 'recipe[hostname],recipe[ntp],recipe[chef-client]' --json-attributes '{"set_fqdn": "chef-test2"}' --node-name chef-test2

Upvotes: 0

StephenKing
StephenKing

Reputation: 37580

I see some problems:

  • during knife node edit, you can't set the attribute as a top-level attribute next to fqdn etc. You have to place it below normal. This is the hierarchy between default and override. See Attribute Precedence
  • using knife node edit smells. I'd rather not do this (might be okay for the host name, but for everything else it's impossible to track such changes in version control). Try to get the hostname cookbook running instead.
  • writing attributes out to a chef.json file should be IMHO also avoided. Your logic should be inside your cookbooks
  • you should have a base role / cookbook or similar that includes the trivial things that every node has (like ntp, chef-client and also the hostname).
  • you can set the environment also directly during bootstrapping: -E myenv (but yes, I'm wondering why this isn't documented)
  • you can set the node name during bootstrapping, too: -N NAME or --node-name NAME.

Upvotes: 6

Related Questions