November 2024
M T W T F S S
 123
45678910
11121314151617
18192021222324
252627282930  

Categories

November 2024
M T W T F S S
 123
45678910
11121314151617
18192021222324
252627282930  

for loops in Chef

for config in [ "contacts.cfg", "contactgroups.cfg" ] do
  remote_file "/etc/nagios3/#{config}" do
    source "#{config}"
    owner "root"
    group "root"
    mode 0644
    notifies :restart, resources(:service => "nagios"), :delayed
  end
end

Write it in the order you want it to run

Chef executes resources in the order they appear in a recipe. Coming to Chef from Puppet, I found this to be a welcome surprise. Need to install the NTP daemon and then make sure the service is started? No problem. Just put your service resource after your package resource.

package 'ntp' do
  action :install
end

service 'ntp' do
  action :start
end

This is the most common way to sequence events. You can tell what the control flow is just by reading a cookbook from top to bottom.

Notify resources about changes

Chef provides a notification mechanism for signaling when things change. This lets you do things like restart a service when a configuration file changes. Want to lay down your own NTP configuration file and bounce the service when it’s updated? Easy. Have your template resource notify your service resource of the change.

template '/etc/ntp.conf' do
  notifies :restart, 'service[ntp]'
end

service 'ntp' do
  action :start
end

Something that surprised me when I first started working with Chef, was that notifications on resources queue, then trigger at the end of the run. So the recipe above takes the following actions:

  1. Updates the template.
  2. Queues a restart of the service.
  3. Starts the service.
  4. Restarts the service.

Sometimes you want a notification to trigger right after something changes, instead of waiting until the end of the run. In that case, you can use the :immediately flag.

template '/etc/ntp.conf' do
  notifies :restart, 'service[ntp]', :immediately
end

service 'ntp' do
  action :start
end

Check if resources have changed

Chef resources are first class objects, which means you can ask them about their state during the run. Every resource has an updated_by_last_action? method which returns true if the resource changed. Combining this with sequential execution lets you build robust cookbooks.

Suppose you want to download and unpack a tarball. If the folder you’re unpacking into exists, you’ll want to remove it first. But if the tarball hasn’t changed, you’ll want to skip that step. Download the package with a remote file resource resource, cache the result, and use the only_ifmodifier on a directory resource to skip the removal if the tarball’s unchanged.

tarball = remote_file '~/node-v0.8.20.tar.gz' do
  source 'http://nodejs.org/dist/v0.8.20/node-v0.8.20.tar.gz'
end

folder = directory '~/node-v0.8.20' do
  action :remove
  only_if { tarball.updated_by_last_action? }
end

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>