Opscode
Home     Introduction to Chef     Cookbooks     Blog     GitHub     Tickets 

Templates

Templates get used all the time in Chef! We love templates. For those of you not in the know, a template is simply a file that has been marked up to include variables (or more complex logic).

Chef utilizes Erubis for our templates - for those of you coming from the Rails, Merb, or Puppet communities, this means it's just ERB (only faster!).

You utilize a template by adding a template resource to a recipe, and putting the template in the cookbook.

A template resource

Template Location Specificity

Often, Cookbooks will work on multiple platforms, or distribute templates that are only subtly different depending on the platform. Chef Cookbooks allow you to only specify those templates one time, but make sure that the right template ends up on each system. Within a Cookbook's template directory, you might find a directory structure like this:

  • templates
    • host-foo.example.com
    • ubuntu-8.04
    • ubuntu
    • default

Given the resource above, we would match:

  • host-foo.example.com/sudoers.erb
  • ubuntu-8.04/sudoers.erb
  • ubuntu/sudoers.erb
  • default/sudoers.erb

In that order (given a Node named foo.example.com running Ubuntu 8.04). Then for example, if we put sudoers.rb under files/host-foo.example.com/ directory it will be only copied to the machine with the domain name foo.example.com.

So, the rule distilled:

  1. node[:fqdn]
  2. node[:platform]-node[:version]
  3. node[:platform]
  4. default

NOTE: 'default' here does not refer to the recipe in default.rb. Templates are not split up into different directories by recipe.

Hey, Cfengine people!

This is inspired by Single Copy Nirvana - if you think about it that way, this will click immediately.

Variables and ERB

When a template is rendered, we pass all the variables listed in the resources variables attribute to template, along with the contents of the node|Nodes. The variables will be accessible as instance variables within the template.

For example:

Simple template resource
Simple ERB template

Would render:

Rendered template

For more information about how to use ERB, check out the Erubis Documentation.

When does a template get transferred?

Chef caches a template when it is first requested. On all subsequent requests for that template, we compare that to the template on the server - if they are the same, we won't transfer the entire template again.

Overriding Templates

If you're following along with the Chef Server Installation and Repository defaults, you have a cookbook search path that looks in site-cookbooks before cookbooks. If you're using Opscode's cookbooks as 'upstream' in cookbooks, and your own in site-cookbooks, you can easily override an upstream template with local modifications.

Let's do an example. The Opscode Chef cookbook has a template for the Chef client configuration, client.rb.erb. In your local clone of the opscode/cookbooks repository, you would have:

client.rb.erb

To override this template, create the same file under site-cookbooks.

client.rb.erb

Customize the file as you need for your site, then install the cookbooks to the chef-server (usually rake install). When clients run, they'll grab the site-cookbooks version of chef.rb.erb instead of the cookbooks one. This can be done for any template or remote-file resource, following the 'single copy nirvana' pathing described above.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. May 02

    Michael Johnston says:

    Is there a clean way to define a library method so that it is in scope in a reso...

    Is there a clean way to define a library method so that it is in scope in a resource, for example to pass as a variable to a template? The only way I've come up with is to assign the library method to a local variable, which is annoying.


Copyright © 2009 Opscode, Inc. All Rights Reserved.