Chef-solo’s lack of environment support seems to be pretty controversial. On one hand, one of the features of environments is the ability to pin cookbooks to specific environments, and this makes absolutely no sense with chef-solo. On the other hand, lots of us would like to be able to merge in environment-level attributes and use environment-specific run lists when testing with Vagrant. And I think I may have found a simple way to hack around the problem. Assuming I use the JSON syntax in all my environments and roles, and I stick to the following convention for setting attributes (from lowest to highest precedence):
- default in cookbook attributes files
- default in role files
- override in environment files
It looks like I can just parse these files myself and inject the attributes into chef-solo using the -j option. So for example, I could do something like this in my Vagrantfile:
chef_env_conf = parse_json("./environments/#{ENV['CHEF_ENVIRONMENT']}.json")
chef.json = chef_env_conf["override_attributes"]
Since attributes set via the -j option are applied at the normal priority level, this can be another way to override role defaults, and this might be all you need in a context where the environment isn’t pulled in automatically.
You could do something similar to get per-environment run lists (by parsing the role files):
chef_role_conf = parse_json("./roles/#{role}.json")
chef.run_list = chef_role_conf["env_run_lists"][ENV['CHEF_ENVIRONMENT']]
I realize this isn’t the most elegant hack, but it seems like it could be a workable solution for some people. Does anyone think it’s a really bad idea?
Chef 11.6.0 finally added support for environments in chef-solo.