I would like the Chef cookbook network_interfaces to have dynamic values for ip addresses, netmasks and alike for each of my nodes. What works for me is the following:
db_role.rb (block1):
override_attributes(
"network_interfaces" => {
:device => 'eth0',
:address => '123.123.123.123',
}
)
But that is not very dynamic. My idea was to submit the ip address(, netmask, etc.) to each node on knife bootstrap.
The node would then look like so (block2):
{
"normal": {
"network_interfaces" => {
"device" : "eth0",
"address" : "123.123.123.123"
}
},
"name": "foobar",
"run_list": [
"recipe[zsh]",
"role[networking_interfaces]"
]
}
Unfortunately the network_interfaces cookbook does not pick up those values by default. My idea was to reference the node specific attributes shown in block2 in the roles definition like so:
override_attributes(
"network_interfaces" => {
:device => node['network_interfaces']['device'],
:address => node['network_interfaces']['address'],
}
)
This does not work because it is not json obviously and Chef can not handle dynamically allocated values in roles files.
How can I achieve to run the network_interfaces recipe and pass my node specific values to it?
If you add normal attributes via
knife bootstrap -j …, and leave override attributes in the role, the override will take over (see http://docs.opscode.com/essentials_node_object_attributes_precedence.html for a complete list of attribute precedence). If you have deletedoverride_attributesfromdb_role.rbbefore runningknife bootstrap, or changed it todefault_attributes, then setting IP in node attributes should have worked.The last snippet won’t work: roles are static JSON documents on the Chef server, and Ruby is only interpreted once by
knifewhen uploading role to the server (http://docs.opscode.com/essentials_roles_formats.html). You can’t refer to node’s attributes from role’s Ruby code, as it’s compiled to JSON before it even touches any node. If you want to try a similar approach, you need to use a custom cookbook (say,my_network_interfaces) with a recipe that would look somewhat like this:This way, you’d use
network_interfacesas a “library” cookbook, called by your “application” cookbookmy_network_interfaceswhich implements whatever logic you need. From your question, I can’t suggest how would you compute device and address, as your example just tries to copy same attributes, which is a no-op. As far as I understand what you want to achieve, you want to havedefault_attributesin the role, and pass specific JSON with normal attributes toknife bootstrapto override the defaults.