Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use normal attributes (attribute.set[..]) in chef?

I'm working on a chef implementation where sometimes in the past attribute.set has been used where attribute.default would have done. In order to untangle this I've become pretty comfortable with the Chef attribute precedence paradigm. I understand that "Normal" attributes (assigned using attribute.set[]) persist between chef client runs.

This has led me to wonder what are the common and best ways to use attribute.set? I don't understand the value of having attribute assignments persist on a node between chef client runs?

like image 363
eatCitrus Avatar asked Sep 30 '22 10:09

eatCitrus


2 Answers

The places to use node.set are when you need some state but can't (easily) store it in the system. This is common with self-generating database passwords. You need to store it somewhere, usually because other nodes need the password but the database itself only stores it hashed so you can't retrieve it from there. Using the node object as stateful storage gives you a place to put the data in the interim.

Also because I have to say it, storing passwords like this is highly insecure, please don't.

like image 150
coderanger Avatar answered Oct 03 '22 00:10

coderanger


Historically node.set and "normal" attributes were first introduced. They just were attributes and were how attributes worked.

They are useful for tags, the run_list, the chef_environment and other bits of 'desired' state -- things that you set with knife on the command line and expect the node to pick up and for the recipes to consume, but not set themselves. Since chef clients need a run_list to do anything this problem had to get solved first, and normal attributes are how it got implemented.

As Chef evolved, default and override precedence levels were created and those were cleared on the start of the chef run, which means that recipes can use them much more declaratively. This is how people generally want attributes in recipes to behave, which is why it was introduced that way.

The use of 'node.set' is now highly confusing since it seems like if you want to set a node that you'd use 'node.set' but in nearly all cases for users 'node.default' or 'node.override' are preferred. The use of 'node.set/normal' leads to hard to debug behavior when code that sets attributes is removed from cookbooks, but the attributes persist leading to fun times debugging until its recognized that the state is persisting in the node object.

While it can be used to store password information, as @coderanger points out this is completely insecure. Every node on the chef server can read the node information of every other node, so your password is essentially broadcast out globally.

Unless you're doing something akin to 'tagging' the server (in which case why not use the node.tags feature we already built over the top of normal attributes?) then you really don't want to be using the normal precedence level.

The Chef attributes system unfortunately grew organically and now we're left with the rule "do not use node.set to set node attributes".

For that reason, we're doing to start deprecating the use of node.set in favor of node.normal in order to whittle away at a bit of the confusion (https://github.com/chef/chef/pull/5029).

like image 21
lamont Avatar answered Oct 03 '22 00:10

lamont