|
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:
- node[:fqdn]
- node[:platform]-node[:version]
- node[:platform]
- 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:
Would render:
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:
To override this template, create the same file under site-cookbooks.
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.
Comments (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.