My Profile Photo

Spencer Owen


The art of progress is to preserve order amid change and preserve change amid order - Alfred North Whitehead


CHEF breadcrumb design pattern

Sometimes when you are automating your infrastructure, you run into a situation where you need to manage a file once, and then ignore it later so that another program can modify it. (Looking at you redis).

Chef has a create_if_missing resource type which can accomplish this nicely.

file '/var/foo.sh' do
  action :create_if_missing
end

However what if you later have a need to modify that file? Your only option would be to destroy and recreate the VM, or ssh/rdp in and delete foo.sh.

Here is an alternative idea; Use a breadcrumb.

file '/var/foo.sh' do
  action :create
  not_if do File.exists?('/var/foo.breadcrumb') end
end

file '/var/foo.breadcrumb' do
  content 'foo.breadcrumb prevents foo.sh from being modified'
  action :create_if_missing
end

The foo.sh will be overwritten once, and as long as the breadcrumb file exists, it will not be modified again.

The main advantage over the bread crumb over just using create_if_missing directly on the resource, is that you can perform additional logic on that file.

For example, only restart a service if the file is created

file '/var/foo.sh' do
  action :create
  not_if do File.exists?('/var/foo.breadcrumb') end
  notifies :restart, 'service[bar]'
end

Or delete the breadcrumb if a package is updated. Chef will then modify foo.sh

package 'derp' do
  action :install
  notifies :delete, 'file[/var/foo.breadcrumb]'
end

In cookbooks where an application needs to create the initial config file, then surrender control of that file to another process, this pattern allows you to take control back of that file by deleting its breadcrumb file.

We use this breadcrumb pattern in one of our cookbooks at work to let chef create a config file once, and then let developers modify it as often as they want. It also lets a config file persist across updates of a build, and only get reset on major updates.

Related: The food taster pattern