http://wiki.opscode.com/display/chef/Resources
When you start composing your configuration, you will declare resources, which are essentially Ruby objects with the code behind them to configure your system. Behind each resource are one or more providers that tell Chef how to execute the actions you require against a certain type of system. For instance, the package resource has providers for yum, apt, gems, and more.
Log
The Log resource is the simplest resource there is. All it does is print a logging message at the level you provide (defaulting to INFO).
log “This is a message from chef”
This will generate the following message amidst the rest of the output when chef-client runs.
INFO: This is a message from chef
You can specify the level you want the message to be logged at with the level parameter.
log “Bad stuff happened” do
level :error
end
Packages
Chef includes providers for most major package management systems. These multiple providers allow the single package resource to be used on most major UNIX-based operating systems. Since the default action for a package is “install”, the simplest use is as follows:
package “autoconf”
This is equivalent to:
package “autoconf” do
action :install
end
You can even specify the version you want and the provider that should be used (such as YUruby gemsems, etc.):
package “cucumber” do
version “0.9.4”
provider Chef::Provider::Package::Rubygems
action :install
end
There are also shortcut resources that force a particular package provider to be used. For instance, the Ruby gem example above is the same as saying:
gem_package “cucumber” do
version “0.9.4”
action :install
end
As always, you have the full power of Ruby to handle edge cases, such as the package name to use when installing Apachttpstpd.
package “apache2” do
case node[‘platform’]
whecentstosred hathat”,”fedorasussuse”
package_namhttpstpd”
when “debian”,”ubuntu”
package_name “apache2”
end
action :install
end
In the example above, we use a Ruby case statement to look at the node object, which represents the system we are currently configuring. The node object includes all the data discovered by the Ohai application. Ohai sets the platform element to the name of the distribution.
Files, Directories, and Templates
Configuration on Linux and *NIX systems often starts with managing files and directories. Chef provides the file, remote_file, and cookbook_file resources to manage static files and a directory resource for managing directories.
Directory
The directory resource lets us create, remove, and manage the permissions on directories. If you need a temporary directory, you can create one as follows:
directory “/tmp/mydirectory” do
action :create
end
The owner and group of the directory will be the defaults for the user running the Chef client, usually root. The create action is the default, so that could be rewritten as:
directory “/tmp/mydirectory”
Using the defaults can make your cookbooks more concise, but make sure they aren’t more confusing for your future self and your team.
In defining your resources, you have the full power of Ruby available to you. For instance, this allows you to loop through entries in an array to build a set of directories.
[“site1”, “site2”, “site3”].each do |dir|
directory “/srv/vhosts/#{dir}” do
mode 0775
owner “root”
group “root”
action :create
recursive true
end
end
In the example above, three directories will be created under /srv/vhosts. In this case we used the recursive true property of the directories to ensure that the base directories (/srv and /srv/vhosts) are created if they do not exist.
File
The file resource allows you to manage the permissions and ownership of files on the node, with the option to pass content from inside your recipe. To retrieve a file from a URL or the cookbook, use the remote_file or cookbook_file resources respectively.
The parameters for a file are the same as a directory with a couple of exceptions. Files have a touch action that updates the modified time and last accessed time of the file, they don’t have a recursive attribute so the target directory must exist, and they have a backup attribute that defines how many backup versions of the file should be kept if the contents change.
NOTE: Backups are saved to the directory specified by file_backup_path in your client.rb file. This defaults to /var/chef/backup.
file “/etc/nologin” do
backups false
owner “root”
group “root”
mode “0755”
action :create
end
The resource above creates a file called /etc/banner with the content set to the string provided. It will not back up the file if it changes.
Remote File
The remote_file resource is identical to the file resource, except instead of having a content parameter, remote_file has a source parameter that is the URL of the file to transfer. It also has an optional checksum parameter that, if the managed file’s checksum matches, will prevent Chef from downloading the file an extra time. Chef uses SHA-256 for its checksums, but only the first 5-10 characters of the hash are usually needed to ensure consistency.
Also, the actions on a remote_file are limited to create and create_if_ missing. To delete a file created by remote_file, change it to a standard file resource.
Cookbook File
A cookbook_file resource is largely the same as a remote_file resource, with the exception that files will be retrieved from the files/ directory structure (respecting File Specificity) of the cookbook. An additional cookbook attribute is available to fetch files from cookbooks other than the one you are currently running.
As a rule, do not store large binaries in Chef. It can handle it, but the side effects (larger database size, slower repository checkouts) make it less desirable than many alternatives such as a package repository,
Templates
http://wiki.opscode.com/display/chef/Templates
Chef suppotemptingting text based configuration files using ERB. In its simplest form, Ruby code is wrapped in special brackets.
<% x = “This is Ruby code” %>
Things that are not wrapped in the tags are not parsed as Ruby code. A similar tag is used to put a value into the resulting file.
The value of x is: <%= x %>
Notice the equals sign after the opening tag. ERB will parse the statement included in that tag and replace the tag with the return value.
By combining these elements with regular Ruby conditionals and flow control, we can create templates for even complex configuration. Let us stick with the simple case for now, a resolv.conf file used by *NIX systems to define their DNS servers.
domain <%= node[‘domain’] %>
search <%= node[‘domain’] %>
<% @nameservers.each do |server_ip| -%>
nameserver <%= server_ip %>
<% end -%>
You can see that the domain and search lines are adding the value returned by node[‘domain’] to the end of their lines. This shows the first way Chef maketemptingng a little easier. The node object with its extensivhash mapap of attributes and Ohai values is injected into your template’s namespace.
The second piece is a loop over each item in an array called @nameservers. The template resource has a variables attribute that you can pass other data to for use in your templates without inserting it into the node object itself.
You may have noticed that the each do and end statements have an extra hyphen attached to the end tag. This prevents the newline character outside the tag from being printed, keeping you from having extra blank lines in your template.
Lets take a quick look at how to declare the template resource for the file above. Remember that templates respect File Specificity, so we will need to put it in template/default/resolv.conf.erb.
template “/etc/resolv.conf” do
source “resolv.conf.erb”
mode “0644”
variables( :nameservers => [‘8.8.8.8’, ‘8.8.4.4’] )
end
We set the source and mode, just like a cookbook_file resource. Then we add a variables attribute that assigns an array to the symbol name servers. This array will be made available, as you saw in our template, as the variable @ nameservers.
For more on ERB, see the documentation at http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/.
Services
Once the package is installed and you have put your configurations (either as files or templates) in place, it is time to manage the services you intend to provide. Again, Chef providers are available for most of the major service management schemes.
service “ntpd” do
action [:start, :enable]
end
This will start the service (if it is not running) and make sure it will restart when the node is rebooted.
If it appears that Chef is attempting to start your service every time it runs, check the resources wiki page for the `supports`, `pattern`, and `status_ command` attributes.
Execute
So far we can manage files, install packages, and restart services. But sometimes you just need to run a real command. Perhaps it is an installer for your monitoring system or to add records to an LDAP server.
execute “bundle install --deployment” do
cwd “/srv/app”
environment ({‘HOME’ => ‘/home/myhome’})
user “app user”
group “app group”
end
In the example above, the Chef client will switch to the user and group provided, add HOME to the environment variables, and change directories to “/srv/app” before running the command provided as the name of the resource.
Script (Bash, csh, Perl, Python, Ruby)
The script resource is an extension of the execute resource, supporting all of parameters of the latter, while allowing you to pass a block of commands inside the resource. This works well for running a custom compile of an application that you do not have a package for or for running a set of tasks every time the Chef client runs.
script “git update and garbage collection” do
interpreter “bash”
user “root”
cwd “/srv/app”
code <<:-EOH
git pull stage
git gc
EOH
end
You can see the added code block with the Ruby specific <<- annotation to create a string out of everything it sees until the pattern provided (EOH in this case) is reached.
{{ parent.title || parent.header.title}}
{{ parent.tldr }}
{{ parent.linkDescription }}
{{ parent.urlSource.name }}