http://feedly.com/e/DQCm59mW
One of our goals here at Chef (née Opscode) is to make installing Chef on a new node as easy as possible so that you can start enjoying the benefits of automation with minimal delay. But what happens to nodes that stick around for extended periods of time?
If you operate in an ecosystem where you cannot treat your infrastructure like garbage then you should have a plan for upgrading the copies of chef-client
that are already running in your environment. With omnibus Chef 11, automatic in-place upgrades can be handled using Heavy Water Operations' omnibus_updater
cookbook. Chef can update Chef!
Basic Usage
To get started, add the omnibus_updater
cookbook to your run_list. For our example, we will add the omnibus_updater
to the base
role's run_list.
{ "name": "base", "description": "All good Chefs have base roles!", "chef_type": "role", "json_class": "Chef::Role", "run_list": [ "recipe[chef-client::delete_validation]", "recipe[chef-client]", "recipe[omnibus_updater]" ] }
When chef-client
executes on your node, omnibus_updater
will collect the required metadata (platform
, platform_version
and machine['kernel']
) and use this information to download and install the correct package from Chef's omnitruck API.
Specifying The Version
The default behavior of omnibus_updater
is to download and install the latest version of the Chef. You can specify which version of Chef you would like to install by setting the node['omnibus_updater']['version']
attribute appropriately.
Because the version of Chef you wish to download is stored as an attribute, you can leverage merge-order precedence to control what version of chef-client
is installed in different scenarios. As an example, let's walk through an example where your team would like to promote versions of chef-client through your two Chef environments: staging
and production
.
In staging
, you hard-code the latest release of Chef so that your team can test its stability in your infrastructure.
{ "name": "staging", "description": "Test latest chef-client before moving to Prod.", "chef_type": "environment", "json_class": "Chef::Environment", "default_attributes": { "omnibus_updater": { "version": "11.8.2" } } }
In production
, you hard-code the version of Chef that has been approved for use in production by your team.
{ "name": "production", "description": "Use approved, well-tested version of chef in Prod.", "chef_type": "environment", "json_class": "Chef::Environment", "default_attributes": { "omnibus_updater": { "version": "11.6.2" } } }
Once the decision has been made that 11.8.2 is stable enough for use in production
, all that would be required is to update the attribute in the environment. That version of Chef would be installed the next time chef-client
is run.
{ "name": "production", "description": "Use approved, well-tested version of chef in Prod.", "chef_type": "environment", "json_class": "Chef::Environment", "default_attributes": { "omnibus_updater": { "version": "11.8.2" } } }
Downloading From Custom Location
If you are unable to access the public Internet to download the omnibus packages from Chef or wish to download your packages from a mirror (e.g. a mirror behind your company's firewall), you can set the node['omnibus_updater']['direct_url']
attribute to point to a specific omnibus package.
One solution could be to set the node['omnibus_updater']['direct_url']
attribute in your Chef environment.
{ "name": "production", "description": "Use approved, well-tested version of chef in Prod.", "chef_type": "environment", "json_class": "Chef::Environment", "default_attributes": { "omnibus_updater": { "direct_url": "http://example.com/chef-11.8.2-1.el6.x86_64.rpm" } } }
The downside of this implementation is that it will not work in a cross-platform ecosystem. To create a more robust solution, you could create a wrapper cookbook and build the node['omnibus_updater']['direct_url']
value based on your specific requirements.
To do this, you would specify the version of Chef you want in your production
environment like we did before.
{ "name": "production", "description": "Use approved, well-tested version of chef in Prod.", "chef_type": "environment", "json_class": "Chef::Environment", "default_attributes": { "omnibus_updater": { "version": "11.8.2" } } }
Then you would write a recipe, like the one in the example below, that uses cross-platform logic to set the node['omnibus_updater']['direct_url']
attribute to point to the appropriate chef-client
package before calling the omnibus_updater
cookbook via include_recipe
.
# If no version is specified, use a default value (latest) version = node['omnibus_updater']['version'] || '11.8.2' if platform_family?('rhel') node.default['omnibus_updater']['direct_url'] = "http://example.com/chef_#{version}-1.el#{node['platform_version'].to_i}.#{node['kernel']['machine']}.rpm" elsif platform_family('debian') node.default['omnibus_updater']['direct_url'] = "http://example.com/chef_#{version}-1.#{node['platform']}.#{node['platform_version']}_#{node['kernel']['machine']}.deb" else Chef::Log.warn "The platform #{node['platform']} has not been accounted for in the download logic. Please update this recipe accordingly." end include_recipe "omnibus_updater"
Summary
Using Heavy Water Operations' omnibus_updater
cookbook you can avoid the laborious and time consuming practice of manually upgrading your chef-client
. The omnibus_updater
cookbook has other useful features that might interest you so I encourage you to read its documentation.
No comments:
Post a Comment