Dynamic merging of attributes


Hey chefs,

I’m running into an issue with how to construct some recipes to play nicely with a cookbook I’m using. Namely, it’s the cookbook for the scout agent: https://github.com/scoutapp/scout_cookbooks

The cookbook uses an attribute to determine what roles to register the node as in the scout dashboard. In our case, the chef node roles don’t match up exactly with the scout roles. So, what I’d like to do is the following:

  1. have a base scout role name for certain chef roles (eg: ‘app-a resque’ or ‘app-b appserver’)
  2. prefix the scout role name with the node.chef_environment, so we could have ‘production app-a appserver’
  3. support for a node to belong to multiple scout roles

Currently I’m accomplishing #1, above, with the following code in the role ruby file:

default_attributes “scout” => {
“roles” => [ “app-a+resque” ]

For those unfamiliar, the scout agent uses the node.scout.roles array to report which roles to which the server belongs so they are properly grouped in the scoutapp.com dashboard. There is also a bug in the scout agent which causes issues for roles with spaces in the names, so I have a ‘+’ in there for now (I’ve got a pull request waiting in the queue for the scout agent on github that fixes this issue).

and then, for #2, in the scout recipe, I have:

if node[‘scout’][‘roles’] && node[‘scout’][‘roles’].count > 0
node.set[‘scout’][‘roles’] = node[‘scout’][‘roles’].map do |r|
if r.match(/^#{ node.chef_environment }/i)
[ node.chef_environment, r ].join(’+’)

Basically, if the node contains scout roles, iterate over them and prepend the node.chef_environment if it doesn’t contain that already.

Needless to say, this is probably completely incorrect. It’s super hacky, but accomplished what I needed last night.

I have no idea how to accomplish #3.

I’m sure that I’m just not thinking chefy enough for this, but it has to be possible, right? Ideally, I’d like to define the scout role in the role.rb file, per environment (we monitor production and sandbox with scout, but not staging), but if a node has multiple roles in chef, I’d like to merge those scout roles together.

Thanks in advance!