Precedence is different, so why are values merged


#1

ntp has the following in attributes/default.rb:

default['ntp']['servers']  = %w{ 0.pool.ntp.org 1.pool.ntp.org

2.pool.ntp.org 3.pool.ntp.org }

i added the following to my development.rb:

default_attributes( "ntp" => { "servers" =>

[“0.north-america.pool.ntp.org”, “1.north-america.pool.ntp.org”] })

but i see all 6 of them in ntp.conf. on irc someone said that when
the precedence is the same, they get merged; but, according to the
docs [1] the precedence is not the same:

The precedence of the attributes - from low to high

default attributes applied in an attributes file
default attributes applied in an environment
default attributes applied in a role
default attributes applied on a node directly in a recipe
normal or set attributes applied in an attributes file
normal or set attributes applied on a node directly in a recipe
override attributes applied in an attributes file
override attributes applied in a role
override attributes applied in an environment
override attributes applied on a node directly in a recipe

[1] http://wiki.opscode.com/display/chef/Setting+Attributes+(Examples)


#2

I have encountered this exact problem before, when I was setting both
override and default attributes at the environment level.

Array merging is covered here for roles/environments:
http://wiki.opscode.com/display/chef/Deep+Merge

I ended up changing that setting to:
default[‘ntp’][‘servers’]=Array.new

Otherwise I ended up with an array list and setting of:
pool.ntp.org,pool2,ntp.org,myserver.whatever.com,mysecondserver.whaterver.com

Thanks,

On Mon, Sep 17, 2012 at 6:05 PM, bradford fingermark@gmail.com wrote:

ntp has the following in attributes/default.rb:

default['ntp']['servers']  = %w{ 0.pool.ntp.org 1.pool.ntp.org

2.pool.ntp.org 3.pool.ntp.org }

i added the following to my development.rb:

default_attributes( "ntp" => { "servers" =>

[“0.north-america.pool.ntp.org”, “1.north-america.pool.ntp.org”] })

but i see all 6 of them in ntp.conf. on irc someone said that when
the precedence is the same, they get merged; but, according to the
docs [1] the precedence is not the same:

The precedence of the attributes - from low to high

default attributes applied in an attributes file
default attributes applied in an environment
default attributes applied in a role
default attributes applied on a node directly in a recipe
normal or set attributes applied in an attributes file
normal or set attributes applied on a node directly in a recipe
override attributes applied in an attributes file
override attributes applied in a role
override attributes applied in an environment
override attributes applied on a node directly in a recipe

[1] http://wiki.opscode.com/display/chef/Setting+Attributes+(Examples)


#3

I am still a little confused. Perhaps someone could improve the docs
a bit? More clarification is needed on when merging takes place. Is
it always, unless you specify “!merge:”? How do the
default_attributes, normal_attributes, and override_attributes fit in
with the precedence? The person I was talking to on IRC said he was
bit by the same thing. Or maybe it’s just me and I am simply just
reading through the docs too fast.

On Tue, Sep 18, 2012 at 12:43 AM, Scott Kaminski
scott.kaminski@gmail.com wrote:

I have encountered this exact problem before, when I was setting both
override and default attributes at the environment level.

Array merging is covered here for roles/environments:
http://wiki.opscode.com/display/chef/Deep+Merge

I ended up changing that setting to:
default[‘ntp’][‘servers’]=Array.new

Otherwise I ended up with an array list and setting of:
pool.ntp.org,pool2,ntp.org,myserver.whatever.com,mysecondserver.whaterver.com

Thanks,

On Mon, Sep 17, 2012 at 6:05 PM, bradford fingermark@gmail.com wrote:

ntp has the following in attributes/default.rb:

default['ntp']['servers']  = %w{ 0.pool.ntp.org 1.pool.ntp.org

2.pool.ntp.org 3.pool.ntp.org }

i added the following to my development.rb:

default_attributes( "ntp" => { "servers" =>

[“0.north-america.pool.ntp.org”, “1.north-america.pool.ntp.org”] })

but i see all 6 of them in ntp.conf. on irc someone said that when
the precedence is the same, they get merged; but, according to the
docs [1] the precedence is not the same:

The precedence of the attributes - from low to high

default attributes applied in an attributes file
default attributes applied in an environment
default attributes applied in a role
default attributes applied on a node directly in a recipe
normal or set attributes applied in an attributes file
normal or set attributes applied on a node directly in a recipe
override attributes applied in an attributes file
override attributes applied in a role
override attributes applied in an environment
override attributes applied on a node directly in a recipe

[1] http://wiki.opscode.com/display/chef/Setting+Attributes+(Examples)


#4

Array and hash attributes of the same precedence level get merged.

On Tue, Sep 18, 2012 at 2:59 PM, bradford fingermark@gmail.com wrote:

I am still a little confused. Perhaps someone could improve the docs
a bit? More clarification is needed on when merging takes place The person I was talking to on IRC said he was
bit by the same thing. Or maybe it’s just me and I am simply just
reading through the docs too fast.

http://wiki.opscode.com/display/chef/Attributes#Attributes-SettingAttributesattheSamePrecedenceLevel

“A common use case is to set default attributes in a cookbook’s
attribute files, and also set the same default attributes, but with
different values, using a role. In this scenario, the attributes set
in the role will be deep merged on top of the attributes from the
attributes file. The attributes set by the role will win if there is a
conflict.”

If an attribute that is a string of the precedence level default is
set in a cookbook and a role, the value will be that set in a role.
If that attribute is an array, the value will be the two arrays merged together.
If that attribute is a hash, all the keys will be merged together and
the conflicting keys will be chosen from the object of a higher
precedence (the role).

How do the default_attributes, normal_attributes, and override_attributes fit in with the precedence?

http://wiki.opscode.com/display/chef/Attributes#Attributes-Precedence

Is it always, unless you specify “!merge:”?

BTW, subtractive merge is not supported in Chef 11+.

Bryan


#5

Specifically, if your goal is to replace a default attribute that is
an array or hash - set by cookbook attributes files or by another role

  • you will commonly either use node.set in a recipe (most typical) or
    use override_attributes in a role or environment, but be wary of the
    arms race you’ve entered. The now deprecated use !merge: may seem a
    bit duct tapey but allow(ed) granular control. There are other ways
    of manually replacing attributes, but they are less explicitly part of
    the attribute model.

However… and this is where everyone can take a big step back… if
this doesn’t fit your needs, that’s okay too. The way attribute
resolution works is meant to be convenient and useful for most cases.
It turns out that there are lots of ways one could conceive of
merging, precedence, overlays, and other such constructs working.

So it’s crucial to understand both how the model works and how to get
what you need. Especially if it changes from time to time. The
intent of the original design was, if I can read into it, to allow
"gathering" of data from a bunch of producers in the form of composed
roles and other sources. For instance, imagine I have a nagios
cookbook that installs application- and service-specific checks based
on the contents of certain hashes. With deep merging of attributes in
roles, As I build up an application stack with roles that provide
appropriate checks, the nagios recipe consumes the hash to produce all
of them in a single configuration, and I have a fully instrumented app
stack. Now I can add additional specifications, alerts, thresholds,
etc. to, say, prod environments, and the existing cookbook implements
them as well.

-a

On Tue, Sep 18, 2012 at 11:59 AM, bradford fingermark@gmail.com wrote:

I am still a little confused. Perhaps someone could improve the docs
a bit? More clarification is needed on when merging takes place. Is
it always, unless you specify “!merge:”? How do the
default_attributes, normal_attributes, and override_attributes fit in
with the precedence? The person I was talking to on IRC said he was
bit by the same thing. Or maybe it’s just me and I am simply just
reading through the docs too fast.

On Tue, Sep 18, 2012 at 12:43 AM, Scott Kaminski
scott.kaminski@gmail.com wrote:

I have encountered this exact problem before, when I was setting both
override and default attributes at the environment level.

Array merging is covered here for roles/environments:
http://wiki.opscode.com/display/chef/Deep+Merge

I ended up changing that setting to:
default[‘ntp’][‘servers’]=Array.new

Otherwise I ended up with an array list and setting of:
pool.ntp.org,pool2,ntp.org,myserver.whatever.com,mysecondserver.whaterver.com

Thanks,

On Mon, Sep 17, 2012 at 6:05 PM, bradford fingermark@gmail.com wrote:

ntp has the following in attributes/default.rb:

default['ntp']['servers']  = %w{ 0.pool.ntp.org 1.pool.ntp.org

2.pool.ntp.org 3.pool.ntp.org }

i added the following to my development.rb:

default_attributes( "ntp" => { "servers" =>

[“0.north-america.pool.ntp.org”, “1.north-america.pool.ntp.org”] })

but i see all 6 of them in ntp.conf. on irc someone said that when
the precedence is the same, they get merged; but, according to the
docs [1] the precedence is not the same:

The precedence of the attributes - from low to high

default attributes applied in an attributes file
default attributes applied in an environment
default attributes applied in a role
default attributes applied on a node directly in a recipe
normal or set attributes applied in an attributes file
normal or set attributes applied on a node directly in a recipe
override attributes applied in an attributes file
override attributes applied in a role
override attributes applied in an environment
override attributes applied on a node directly in a recipe

[1] http://wiki.opscode.com/display/chef/Setting+Attributes+(Examples)