I've been running Chef version 0.9 for some months, and I've been looking forward to trying out 0.10; in particular the "environments" feature described in OpsCode's preview blog post, and Chef's documentation.
The Old Environments
In Chef 0.9 I had implemented different environments as follows:
- have separate machines running chef-server for each environment
- have separate chef role definitions for each role × environment
- use attributes overrides in the roles to have per-environment behaviour
- selectively load roles into servers (e.g.
webserver_demois not needed on
- assign roles at boot time from a custom client.rb (in the AMI) using JSON from instance data
- the same mechanism also names the nodes to include the role and
- use git to share a chef repository between environments
This has worked well, but the role × environment matrix size explosion was a headache to manage, and keeping the right roles (and only the right roles) in the right servers was error-prone.
The New Environments
In Chef 0.10 environments are a first-class concept.
Upgrading some of the servers involved a little trial and error, fresh gem installs worked fine, and upgrading the existing clients was trivial.
Because I restrict port 22 on internal machines with EC2
security groups I did immediately run into a "ssh hang" bug
KNIFE_EC2-2 but the
linked patch works fine.
To then migrate the configuration for existing machines:
- create environment
.rbfiles, applying the attributes from the old role files
- create the environments with knife
- move all nodes to the new enviroments using nodes.tranform
- create new role files, which have the roles/recipes but not the attributes from the old roles
- load the new roles, and apply to the relevant machines
- remove the old roles
- re-run chef-client and verify all roles succeed
- verify normal system operation
And that was basically that.
The next step, was to review how I create machines.