In the demonstration that Jamie Windsor did for berkflow at Chefcon he used
a role/environment cookbook with multiple roles rather than single role
cookbooks.
I think in your case if you have a cookbook per role then the only way you
can make it work that way is if cookbooks common to your role cookbooks all
have the same version requirement (or no specific version requirement).
I.e. if your lb cookbook needs nginx 1.2.3 but your web cookbook needs
1.2.4, and those versions are locked, then there's not much you can do as
you'll have conflicting version locks in your environment.
If you don't have one role cookbook per role or you don't have these
specific version requirements then it's pretty easy. You'd make a top level
cookbook to wrap your role cookbooks which would be your environment
cookbook (or if you have one role cookbook with multiple roles then this
could be your environment cookbook) then just add the Berksfile.lock from
the cookbook to source control, make sure it's not in chefignore and that's
your one source of version locks which you can apply to all environments.
You then add the recipes from the environment cookbooks to your nodes/roles.
As there's no actual logic in the environment cookbook whenever you want to
update your environments you bump the metadata on the environment cookbook,
run berks update and then upload it to your chef server. You can then use
berkflow to apply the cookbook from your chef server to an environment,
which will apply the locks only.
You can now use your environments for whatever attributes you want.
On Mon, Jun 22, 2015 at 10:43 PM, Torben Knerr mail@tknerr.de wrote:
Hi Yoshi,
ah, interesting, was not aware of the fact that it would apply the
cookbook locks to an existing environment while keeping the env attributes.
That gets me some new thoughts.
However, that would still mean I have one environment per node (or "role"
at least), e.g.: "prod_lb", "prod_web", "prod_db" etc.., right?
If so, that would also mean I have to duplicate the prod-specific
attributes here (3x times in the example above), right?
I realize I may could get around this using the YAML include approach
Ranjib shared, which would keep it single-sourced, but still I'd need to
update each of the "prod_*" environments from that single source.
Last but not Ieast might have an impact on searches or environment checks
as well, but that could be dealt with easily I guess, at least if it's
happening in your own recipes where you are in control of it.
If there's a better way to work with berksflow / berks apply while keeping
the intuitive environment semantics, I'd be happy to learn more about it.
Cheers,
Torben
On Mon, Jun 22, 2015 at 5:33 PM, Yoshi Spendiff <
yoshi.spendiff@indochino.com> wrote:
Hi Torben,
Not sure if you know, but the A/B choice you stated above aren't actually
mutually exclusive. If you want to use berkflow/berks apply to apply
cookbook version locks to an environment that doesn't stop you supplying
normal environment variables to the environment. Berkflow/berks apply
doesn't change any attributes other than the version locks.
Cheers,
Yoshi
On Sun, Jun 21, 2015 at 6:39 AM, Torben Knerr mail@tknerr.de wrote:
Hey Doug,
I believe you first have to decide for what purpose you actually want to
use Chef environments, and this decision then limits the options for
technically implementing this.
For me the key decision is:
a) if you are going to use the berkflow / the environment cookbook
pattern with berks apply environment
, then this means you will end up
with one environment per node
b) if you are going to use environments for dev / test / staging / prod
stages, you probably want to share environmental attributes across many
nodes
Personally, I prefer b) and try to stick to the following principles:
- use environments only for supplying environment specific data
- don't use environment for composing a node's run list or other node
specific internals
- instead I use a single "top-level" wrapper cookbook per node, which
- glues together the run list
- sets attributes for configuring the wrapped cookbooks
- sometimes adds addional glue code
- locks the whole cookbook dependency graph via metadata.rb (so I can
do it per node here and not need to use an environment for that)
- defines the interface for the user (i.e. README, attributes, etc..)
- the environments should contain only environment specific attribute
overrides + the versions of the "top-level" cookbooks
Since I'm wrapping other cookbooks and setting their attributes in (the
"top-level" cookbook's) recipe, I'm sometimes faced with the "computed
attributes problem". I tackle that by reloading the wrapped attributes file
between setting the attributes and including the recipe, e.g. here:
https://docs.chef.io/chef/essentials_cookbook_recipes.html#reload-attributes
Also, my environments often share the same data, i.e. common attributes
that are environmental data but still the same for many or even all of my
environments. Ranjib recently posted a nice way on how to deal with that:
Consuming common datra across environments using Chef's ruby environment DSL · GitHub
Hope that helps or at least gives you some more ideas. There are many
ways and even more opinions
Cheers,
Torben
On Fri, Jun 19, 2015 at 4:22 PM, Douglas Garstang <
doug.garstang@gmail.com> wrote:
If I was going to put move my environmental attributes into cookbooks...
When deployed to an instance, the top level run list would need to
include the environmental run list. That's ok.
However, when testing, this would mean that each cookbook would need to
either include the environment cookbook (ie #include_recipe "env-dev") and
refer to it in the metadata.rb and Berksfile files, OR I'd have to
specifically put each attribute into the Vagrantfile's json data.
This might work for simple cookbooks, but it would mean the cookbook is
not being effectively tested. The attributes I'm testing against aren't
what really gets deployed to an instance. I also have to maintain two
copies of the attributes and the worst case scenario is where the attribute
is set in both places but the value in the Vagranrfile is incorrect and
therefore leads to the incorrect assumption that the cookbook is working
correctly.
For my base cookbook it gets even worse. It would need to have every
single attribute from every cookbook it includes put into the Vagrantfile's
json data. This just does not scale.
It doesn't seem like the benefits of gaining some revision control
outweigh the maintenance disadvantages here. For all those that espouse the
use of putting environment attributes into a cookbook how do you get around
this?
Doug
--
Yoshi Spendiff
Ops Engineer
Indochino
Mobile: +1 778 952 2025
Email: yoshi.spendiff@indochino.com
--
Yoshi Spendiff
Ops Engineer
Indochino
Mobile: +1 778 952 2025
Email: yoshi.spendiff@indochino.com