Skip to end of metadata
Go to start of metadata


Overview

Templates get used all the time in Chef! We love templates.

A template is a file written in a markup language that allows one to dynamically generate the file's final content based on variables or more complex logic. Templates are commonly used to manage configuration files with Chef.

You utilize a template by adding a template resource to a recipe and creating a corresponding ERB template in the cookbook.


For example, the following template and template resource may be used to manage the /etc/sudoers configuration file on your nodes. This example depends on node attributes that would have to be set elsewhere. Within a "sudo" cookbook, we might place the following resource within recipes/default.rb and save the template as templates/default/sudoers.erb:

A template resource
A template (sudoers.erb)

Variables and ERB

Chef templates are ERB templates. ERB templates allow you to embed Ruby code inside a text file within specially formated tags:

An ERB Template

When rendered, the ruby code delimitated by <%= and %> is evaluated and its output is placed in the final text file. You will mostly be using Ruby Expressions, as this is how you reference any variables you sent to the template. You can also use Ruby Statements though, such as each, if or end statements. These are surrounded by <% and -%> instead.

When a template is rendered, Chef passes the variables listed in the resource's variables attribute and the node object to the template. The variables will be accessible as instance variables within the template while the node object can be accessed just as it can be in a recipe, using the name node.

For example:

Simple template resource
Simple ERB template

Would render:

Rendered template

As can be seen in the example present in the Overview, more complex Ruby features can be used to dynamically generate configuration files using the data passed to the template resource. For more information about how to use ERB, check out the Erubis Documentation.

Template Location Specificity

Cookbooks are often designed to work on a variety of hosts and platforms. Templates often need to differ depending on the platform, host, or function of the node. When the differences are minor, they can be handled with a small amount of logic within the template itself. When templates differ dramatically, you can define multiple templates for the same file. Chef will decide which template to render based on the following rules.

Within a Cookbook's template directory, you might find a directory structure like this:

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

For a node with FQDN of foo.example.com and the sudoers.erb 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.

Then, for example: sudoers.rb placed under the files/host-foo.example.com/ directory, means it will be only copied to the machine with the domain name foo.example.com. (Note the "host-" prefix to the directory name)

So, the rule distilled:

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

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


Host Notation
The host- is literal. If your host was foo.example.com than your folder needs to be named host-foo.example.com.
Hey, Cfengine people!
This is inspired by Single Copy Nirvana - if you think about it that way, this will click immediately.

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.

Use Case Scenario

We have an Apache cookbook writing out httpd.conf, then we have an application under site-cookbooks that needs its own very custom httpd.conf. How do we have the site cookbook override the httpd.conf template?

Review the `cookbook` attribute for the `template` resource. Use of this attribute allows you to specify an alternate cookbook in which to look for a template. You could therefore create application specific cookbooks that hold app-specific versions of the template in question. Usually the core `httpd.conf` file doesn't change between applications, but the vhost conf file may differ heavily.

For example, the `web_app` definition that is found within the Opscode apache2 cookbook is meant to simplify the process of creating an app specific vhost:

The web_app definition

The Opscode wordpress cookbook has a great example of using this definition:

Use of the web_app definition







Unix Environment Variables and Chef Recipes


Version Constraints



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

    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.

  2. yesterday at 8:24 PM

    Thanks so much for Chef.

    The sudoer example would be a bit more helpful if it was shown how to, for example, set the

    attribute. I cannot find in the Chef wiki how to set an attribute to include multiple values. In the sudoer groups example, I need to set that attribute to include the following list:

    ServerAdmins
    ServerAdmins2
    ServerAdmins3

    How do I set the attribute?

    1. yesterday at 8:30 PM

      Looking at the README.md in the source code of the sudo cookbook explained it.

      http://community.opscode.com/cookbooks/sudo/source