Clock synchronization across a network of computers is important for a number of reasons. The NTP is protocol designed to synchronize the clocks of computers over a network. In this guide, we will write our own NTP cookbook.
This tutorial assumes you have completed the QuickStart Guide, and already have a working
To get started, we need to create a new cookbook called "ntp". We can use the
knife command to generate some basic files and folders for us:
$ knife cookbook create ntp
This will generate an
ntp directory in the
cookbooks directory of your chef-repo (
chef-repo/cookbooks/ntp) with several subdirectories in it, such as
attributes, the initial framework for our cookbook.
Recipe names directly correspond to the structure within a cookbook's directory:
There is also a special recipe in every cookbook called
default.rb. It is executed by default when the cookbook is added to a
run_list without explicitely listing a recipe within that cookbook:
# These are functionally equivalent: recipe[ntp] => cookbooks/ntp/recipes/default.rb # implicit recipe[ntp::default] => cookbooks/ntp/recipes/default.rb # explicit
For simplicity in this guide, we will just use the
default recipe, but it is common practice to use multiple recipes to separate functionality that may be needed within a single cookbook, such as a piece of software that can be configured as both a client or a server.
First we need to ensure that a package containing the ntp software is installed on our node. Open the default recipe (
chef-repo/cookbooks/ntp/recipes/default.rb) in a text editor and add the following:
package resource is built into Chef, making Chef smart enough to determine which package manager to use (yum, apt, etc) based on the node's operating system. You can read more about the resources in the Chef's documentation.
Next we need to write out an NTP configuration file template using Chef's
template '/etc/ntp.conf' do source 'ntp.conf.erb' notifies :restart, 'service[ntp]' end
The line beginning with "template" tells Chef to use the
template resource to create the file residing at
/etc/ntp.conf on the node. The next line (beginning with "source") describes the file we will be using as a template for the final
ntp.conf. And the final line (beginning with "notifies") tells Chef to restart the NTP service, which we tell Chef about next, once the final
ntp.conf file is created.
Finally, alert Chef of the service and start it:
service 'ntp' do action [:enable, :start] end
Your final recipe should look like this:
package 'ntp' template '/etc/ntp.conf' do source 'ntp.conf.erb' notifies :restart, 'service[ntp]' end service 'ntp' do action [:enable, :start] end
Create a new file in
chef-repo/cookbooks/ntp/templates/default/ntp.conf.erb (since that's what we provided to the template resource in the previous step) and add the following:
# This file was generated by Chef for '<%= node['fqdn'] %>'. # Do NOT edit this file by hand! restrict default kod nomodify notrap nopeer noquery restrict -6 default kod nomodify notrap nopeer noquery restrict 127.0.0.1 restrict -6 ::1 server '0.pool.ntp.org' server 127.127.1.0 # local clock driftfile /var/lib/ntp/drift keys /etc/ntp/keys
erubis(.erb file extension) templates so that Ruby can be inserted into these file templates, as with "node['fqdn']" above. This gives the creation of configuration files from templates the ability to be dynamic based on Ruby code or Chef information.
In this tutorial we:
packageresource and its
To apply the functionality within our "ntp" cookbook to a node, we would need to upload this cookbook to a Chef server, add it to the
run_list of that node, and run
chef-client on that node.
The community cookbook is much more feature-complete than the one we've written and is designed to fit more use cases. While this cookbook serves as a great learning process, checking the community site before developing your own cookbooks can save you from re-inventing the wheel. You can always contribute to the community cookbooks if you create something useful.