Role data in cookbooks

We’re currently putting location specific attributes into roles. We have
one role per location (multiple Amazon regions, us1, us2 etc). Examples of
this location specific data might include things like the redis server, the
apt-cache server address, amazon bucket names to use for various things and
so on.

With our current approach, for any given node, the run list typically
contains 1) the location role, 2) the base role added by our provisioning
script, and 3) a role that defines what the node does, like this:

{
“name”: “dl01-us1.foo.net”,

“run_list”: [
“role[role_base]”,
“role[role_downloader_app]”,
“role[location_us1_prod]”
]
}

And, the functional role, role_downloader_app, would contain the actual
recipe that does the work, e.g.:

// role_downloader_app.
// A role for a download server.
{
“name”: “role_downloader_app”,

“run_list”: [
“recipe[bc-foo-downloader::dl]”
],
}

By not adding the base role until the node is provisioned on ec2, it allows
for quicker testing with vagrant.

So, getting to the point…

If I take the location specific attributes and put it into a cookbook
instead of a role, it’s going to become very messy. With a role, only the
specific data for that role is added to the name space. If I use a
cookbook, I have to put everything into the default/attributes file and
qualify it for the location. Eg:

default[‘us1’] = { … }
default[‘eu2’] = { … }

and so on. Then, to actually use the attribute in a cookbook I have to
qualify it again. Instead of saying node['some_sever], I have to say
node[‘us1’][‘some_server’]. This is cumbersome. I could create one recipe
per location, only include that recipe and then set the attributes in the
recipe, but it seems like this may not be the best approach either.

There’s plenty of blogs out there on putting roles into cookbooks but they
all seem to gloss over the details and not go beyond generally saying don’t
put role data in roles.

Thanks,
Doug.

I suppose, assuming that this entire approach is not folly, would be to use
one cookbook per location, rather than one recipe (in a single cookbook)
per location. Seems like a lot since we have a lot of locations, but I
guess the number is still relatively small and manageable... half a dozen new
cookbooks or so maybe.

Doug.

On Thu, Mar 13, 2014 at 11:31 PM, Douglas Garstang
doug.garstang@gmail.comwrote:

We're currently putting location specific attributes into roles. We have
one role per location (multiple Amazon regions, us1, us2 etc). Examples of
this location specific data might include things like the redis server, the
apt-cache server address, amazon bucket names to use for various things and
so on.

With our current approach, for any given node, the run list typically
contains 1) the location role, 2) the base role added by our provisioning
script, and 3) a role that defines what the node does, like this:

{
"name": "dl01-us1.foo.net",
...
"run_list": [
"role[role_base]",
"role[role_downloader_app]",
"role[location_us1_prod]"
]
}

And, the functional role, role_downloader_app, would contain the actual
recipe that does the work, e.g.:

// role_downloader_app.
// A role for a download server.
{
"name": "role_downloader_app",
...
"run_list": [
"recipe[bc-foo-downloader::dl]"
],
}

By not adding the base role until the node is provisioned on ec2, it
allows for quicker testing with vagrant.

So, getting to the point...

If I take the location specific attributes and put it into a cookbook
instead of a role, it's going to become very messy. With a role, only the
specific data for that role is added to the name space. If I use a
cookbook, I have to put everything into the default/attributes file and
qualify it for the location. Eg:

default['us1'] = { ... }
default['eu2'] = { ... }

and so on. Then, to actually use the attribute in a cookbook I have to
qualify it again. Instead of saying node['some_sever], I have to say
node['us1']['some_server']. This is cumbersome. I could create one recipe
per location, only include that recipe and then set the attributes in the
recipe, but it seems like this may not be the best approach either.

There's plenty of blogs out there on putting roles into cookbooks but they
all seem to gloss over the details and not go beyond generally saying don't
put role data in roles.

Thanks,
Doug.

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

Any reason you're not using environments for location-specific attributes?

On Thu, Mar 13, 2014 at 11:50 PM, Douglas Garstang
doug.garstang@gmail.comwrote:

I suppose, assuming that this entire approach is not folly, would be to
use one cookbook per location, rather than one recipe (in a single
cookbook) per location. Seems like a lot since we have a lot of locations,
but I guess the number is still relatively small and manageable... half a
dozen new cookbooks or so maybe.

Doug.

On Thu, Mar 13, 2014 at 11:31 PM, Douglas Garstang <
doug.garstang@gmail.com> wrote:

We're currently putting location specific attributes into roles. We have
one role per location (multiple Amazon regions, us1, us2 etc). Examples of
this location specific data might include things like the redis server, the
apt-cache server address, amazon bucket names to use for various things and
so on.

With our current approach, for any given node, the run list typically
contains 1) the location role, 2) the base role added by our provisioning
script, and 3) a role that defines what the node does, like this:

{
"name": "dl01-us1.foo.net",
...
"run_list": [
"role[role_base]",
"role[role_downloader_app]",
"role[location_us1_prod]"
]
}

And, the functional role, role_downloader_app, would contain the actual
recipe that does the work, e.g.:

// role_downloader_app.
// A role for a download server.
{
"name": "role_downloader_app",
...
"run_list": [
"recipe[bc-foo-downloader::dl]"
],
}

By not adding the base role until the node is provisioned on ec2, it
allows for quicker testing with vagrant.

So, getting to the point...

If I take the location specific attributes and put it into a cookbook
instead of a role, it's going to become very messy. With a role, only the
specific data for that role is added to the name space. If I use a
cookbook, I have to put everything into the default/attributes file and
qualify it for the location. Eg:

default['us1'] = { ... }
default['eu2'] = { ... }

and so on. Then, to actually use the attribute in a cookbook I have to
qualify it again. Instead of saying node['some_sever], I have to say
node['us1']['some_server']. This is cumbersome. I could create one recipe
per location, only include that recipe and then set the attributes in the
recipe, but it seems like this may not be the best approach either.

There's plenty of blogs out there on putting roles into cookbooks but
they all seem to gloss over the details and not go beyond generally saying
don't put role data in roles.

Thanks,
Doug.

--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.garstang@gmail.com
Cell: +1-805-340-5627

On 3/15/14 3:06 AM, Christopher Armstrong wrote:

Any reason you're not using environments for location-specific attributes?

Hosts can only be in one environment. You can wind up with the cross
product of all your locations with all your prod/int/test/dev
application environments if you go down that road (us-west-1-prod,
us-east-1-test, etc). If you've got a large company with multiple
business units you might also want to mixin per-business-unit accounts
as another dimension and this gets unwieldy to do as environments where
you have to enumerate every cell and adding a new dimension is
difficult. Its easier to have 'role[us-west-1],role[ecomm]' with
environment = 'production'.

OTOH, if you're using pinned environments to do deployments you may want
exceedingly fine grained environments, that are the cross product of
(application-role)x(app-environment)x(datacenter)x(deployment-cell).
You're going to need to carefully plan your automation around managing
that right now since that will create a ton of environments and if
you're doing that by hand it'll create a mess.