Environment includes? role includes? run list in the environment?

I want to have a “base” role and automatically include a
datacenter-specific role depending on the environment.

essentially i have:

datacenter 1 (primary production):
10 environments

datacenter 2 (international):
6 environments

datacenter 3 (development):
6 environments

i have a “base” role that includes all of the recipes and roles and
attributes that are common to all of the above as well as specific to DC1

then i have attribute overrides in the other 12 environments to fix things
that are specific to DC2 or DC3.

i could use environment run lists, but then i’d have to list the 15 recipes
that are in the default run list 22 times. yuck.

is there any way to specify a run list in the environment file instead? any
other ideas?

thanks!

Hi,

IMHO you are doing it wrong. :slight_smile: (See [1])

We have the exact same problem. Different data centers require
different runlists and/or configuration. When presented with the
prospect of doing logic that may require evolution/versioning I tend
to see that the best place to do that in chef atm is in a cookbook.

So we typically will do the logic in such a big switch or decision
tree of some type. Our nameservers are not chef managed so they are a
bunch of static configurations and we have something like the
following in a recipe in our base cookbook.

if '8ND' == node['datacenter']
node.override['resolver']['nameservers'] = ["X.X.X.X"]
elsif 'BWD' == node['datacenter']
node.override['resolver']['nameservers'] = ["X.X.X.X", "X.X.X.X"]
....
elsif 'VAGRANT' == node['datacenter']
node.override['resolver']['nameservers'] = ["10.61.69.22", "10.61.69.23"]
else
raise "Unknown datacenter #{node['datacenter']}"
end

We also use this approach to decide whether or not to include certain recipes.

At other times we use search to derive the configuration and then
limit the criteria by environment/datacenter.

HTH

[1] http://realityforge.org/code/2012/11/19/role-cookbooks-and-wrapper-cookbooks.html

On Thu, Feb 28, 2013 at 11:50 AM, Jesse Campbell hikeit@gmail.com wrote:

I want to have a "base" role and automatically include a datacenter-specific
role depending on the environment.

essentially i have:

datacenter 1 (primary production):
10 environments

datacenter 2 (international):
6 environments

datacenter 3 (development):
6 environments

i have a "base" role that includes all of the recipes and roles and
attributes that are common to all of the above as well as specific to DC1

then i have attribute overrides in the other 12 environments to fix things
that are specific to DC2 or DC3.

i could use environment run lists, but then i'd have to list the 15 recipes
that are in the default run list 22 times. yuck.

is there any way to specify a run list in the environment file instead? any
other ideas?

thanks!

--
Cheers,

Peter Donald

Well what i think i want, is a role (or recipe) that is dc1 specific, dc2
specific, and dc3 specific.
Then something to automagically add it to the list... (which sounds an
awful lot like a recipe)

i guess I could talk to my team about moving all our config out of roles
and into recipes, but that means essentially abandoning roles (and
environments) for config.

On Wed, Feb 27, 2013 at 8:03 PM, Peter Donald peter@realityforge.orgwrote:

Hi,

IMHO you are doing it wrong. :slight_smile: (See [1])

We have the exact same problem. Different data centers require
different runlists and/or configuration. When presented with the
prospect of doing logic that may require evolution/versioning I tend
to see that the best place to do that in chef atm is in a cookbook.

So we typically will do the logic in such a big switch or decision
tree of some type. Our nameservers are not chef managed so they are a
bunch of static configurations and we have something like the
following in a recipe in our base cookbook.

if '8ND' == node['datacenter']
node.override['resolver']['nameservers'] = ["X.X.X.X"]
elsif 'BWD' == node['datacenter']
node.override['resolver']['nameservers'] = ["X.X.X.X", "X.X.X.X"]
....
elsif 'VAGRANT' == node['datacenter']
node.override['resolver']['nameservers'] = ["10.61.69.22", "10.61.69.23"]
else
raise "Unknown datacenter #{node['datacenter']}"
end

We also use this approach to decide whether or not to include certain
recipes.

At other times we use search to derive the configuration and then
limit the criteria by environment/datacenter.

HTH

[1]
http://realityforge.org/code/2012/11/19/role-cookbooks-and-wrapper-cookbooks.html

On Thu, Feb 28, 2013 at 11:50 AM, Jesse Campbell hikeit@gmail.com wrote:

I want to have a "base" role and automatically include a
datacenter-specific
role depending on the environment.

essentially i have:

datacenter 1 (primary production):
10 environments

datacenter 2 (international):
6 environments

datacenter 3 (development):
6 environments

i have a "base" role that includes all of the recipes and roles and
attributes that are common to all of the above as well as specific to DC1

then i have attribute overrides in the other 12 environments to fix
things
that are specific to DC2 or DC3.

i could use environment run lists, but then i'd have to list the 15
recipes
that are in the default run list 22 times. yuck.

is there any way to specify a run list in the environment file instead?
any
other ideas?

thanks!

--
Cheers,

Peter Donald

Hi,

We use a concept of Infrastructure environments that provide the services
you would expect; deployment servers, ntp, dns, local repos etc, these
exist in each datacentre. Each "application" environment then defines its
infrastructure environment and includes it in the relevant searches.

But that doesn't really address your problem of modifying the run_list.

Rgds,

mgh

On Thu, Feb 28, 2013 at 11:50 AM, Jesse Campbell hikeit@gmail.com wrote:

I want to have a "base" role and automatically include a
datacenter-specific role depending on the environment.

essentially i have:

datacenter 1 (primary production):
10 environments

datacenter 2 (international):
6 environments

datacenter 3 (development):
6 environments

i have a "base" role that includes all of the recipes and roles and
attributes that are common to all of the above as well as specific to DC1

then i have attribute overrides in the other 12 environments to fix things
that are specific to DC2 or DC3.

i could use environment run lists, but then i'd have to list the 15
recipes that are in the default run list 22 times. yuck.

is there any way to specify a run list in the environment file instead?
any other ideas?

thanks!

Hi,

On Thu, Feb 28, 2013 at 1:11 PM, Jesse Campbell hikeit@gmail.com wrote:

Well what i think i want, is a role (or recipe) that is dc1 specific, dc2
specific, and dc3 specific.
Then something to automagically add it to the list... (which sounds an awful
lot like a recipe)

i guess I could talk to my team about moving all our config out of roles and
into recipes, but that means essentially abandoning roles (and environments)
for config.

We still use roles to a degree. They are the top level recipes that
make sense to apply to a node. So we still do something like


roles/iris_appserver.rb

name 'iris_appserver'
description 'IRIS Server'
run_list('recipe[fisg-iris]')

That way the role appears in our management application. Our
environments are also used to some degree but they tend to just
populate a couple of fields that are used by the base recipe to switch
on behaviour. They also tend to lock the version of the top level role
recipes. So they would look something like


environments/training.rb

name 'training'
description 'The Training environment'

cookbook_versions('fisg-iris' => '0.0.24')

override_attributes(
'datacenter' => 'BWD',
'cookbook_environment' => 'stable'
)

This approach has allowed us to safely migrate cookbook versions
across environments with out many adverse impacts. However we
experienced many adverse impacts to get to this state :wink:

--
Cheers,

Peter Donald