Chef common recipe multiple roles....any suggestions?

i have created a mongodb chef recipe, and i am overriding the default attributes on the recipe from the role.

name 'mongo_datanode_jackey'
description 'this module is currently under testing...'

override_attributes(
susemongodb: {
node_type: 'datanode',
node_nickname: 'jackey',
port: '27018',
is_replicaset_node: true,
is_cluster_node: true,
replicaset_name: 'myreplica',
clusterRole: 'configsvr',
}

)

run_list(
"recipe[susemongodb::setupmachine]",
"recipe[susemongodb::datanode]"
)

now, I would like to spin up multiple datanodes within the same VM,
so i have created another role similar to above but with different
attribute values.

name 'mongo_datanode_meerkat'
description 'this module is currently under testing...'

override_attributes(
susemongodb: {
node_type: 'datanode',
node_nickname: 'meerkat',
port: '27019',
is_replicaset_node: true,
is_cluster_node: true,
replicaset_name: 'myreplica',
clusterRole: 'configsvr',
}

)

run_list(
"recipe[susemongodb::setupmachine]",
"recipe[susemongodb::datanode]"
)

If you notice they are using the same recipe, which gets passed the attributes,

I am calling the roles in the client,

{
"name": "mongo1",
"chef_environment": "development",
"normal": {
"tags": [

]

},
"run_list": [
"role[mongo_datanode_jackey]",
"role[mongo_datanode_meerkat]",
"role[mongo_datanode_zebra]"
]

}

however, when chef runs the it runs on the last role on the run_list....any idea why?

[2016-02-11T16:51:35+00:00] INFO: Forking chef instance to converge...
[2016-02-11T16:51:35+00:00] INFO: *** Chef 12.6.0 ***
[2016-02-11T16:51:35+00:00] INFO: Chef-client pid: 14010
[2016-02-11T16:51:40+00:00] INFO: Run List is [role[mongo_datanode_jackey], role[mongo_datanode_meerkat], role[mongo_datanode_zebra]]
[2016-02-11T16:51:40+00:00] INFO: Run List expands to [susemongodb::setupmachine, susemongodb::datanode]
[2016-02-11T16:51:40+00:00] INFO: Starting Chef Run for mongo1

I would like each role to be applied on the server and use the common recipe.....?

Because the attributes you set are aggregated across all possible attribute
sources for a Chef run. So the second one is used because it is at the same
priority and defined last.

Sorry I am quite new to chef, do you know how I can fix this or what
pattern should I use?

I can’t find anything about that cookbook, is it internal?

It looks like it uses a recipe to configure mongodb based on specifically
named attributes. If that’s the case you don’t have many options but to
either have one db per node or wrap the cookbook and write other recipes
which use different attribute names.

Yes it’s internally written, and configured node with named attributes,

Out of curiosity, what’s the procedure to write a cookbook which can.be
used with multiple roles and uses same attribute, I have been using puppet
and it supports this feature.

The run list defines which recipes run, but each recipe will only run once.

There are two ways to look at your problem. The first one is simply: what are you actually telling chef to do? Are you trying to tell Chef to install a node named “jackey” or a node named “meerkat”? Your code states both, and for practical purposes, in your scenario, it is random who “wins” (Yoshi already explained the rules for that).

The other way to look at your problem is that I think you may be approaching chef with a “functional” mindset. Attributes aren’t “passed” to recipes, and Recipes are not like functions in a programming language that you can call multiple times with different parameters. Attributes are more akin to global variables or entries in a configuration file.

In fact, recipes are not executed at all, at least not in the sense that you are familiar with in programming languages.

Rather, recipes are descriptive.

Your mongodb recipe describes what the system should look like eventually. The attributes you set tell the recipe details about the desired state. The only parts of the recipe that actually run are whatever is needed to make it happen.

Incidentally, the recipes may not even execute in the order you expect them to. In your example, it is entirely possible that “susemongodb::setupmachine” is executed last instead of first. If you need a particular sequence, use “notifies” or “subscribes” to enforce it.

The solution is to decide what the final outcome from your common recipe really should be. Then set the attributes according to that final outcome, don’t expect any particular intermediate state.

Kevin Keane
The NetTech
http://www.4nettech.com
Our values: Privacy, Liberty, Justice
See https://www.4nettech.com/corp/the-nettech-values.html