templates
Puppet
In Puppet, the combined configuration to be applied to a host is called a catalog, and the process of applying it is called a run.
The Puppet client software is called the agent. Puppet calls the definition of the
host itself a node. The Puppet server is called the master.
In the chapter, Puppet packages, services, and files II with nginx, we had Puppet deploy an nginx virtual host file for the 'bogo' application where we simply used a file resource with the bogo.conf file distributed from Puppet master to our EC2 agent node.
In this chapter, we'll learn how to template configuration files out with Puppet, filling in variables with the managed node's facts.
Often we may want to maintain configuration files for applications that are different between servers. If we have a couple of configurations, it's not touch to maintain multiple files, but what if we have a very large number of differing configurations? We can manage this situation by writing ERB templates and populating the templates with node-specific information. This can be done in Puppet with the template() function:
Puppet supports templates written in the ERB templating and it can be used to specify the contents of files.
Now we want to manage many different websites, it would quickly become tedious to supply an almost identical virtual host file for each site, altering only the name and domain of the site.
The best way of doing this is to give Puppet master a template file into which it could just insert these variables for each different site. The template() function serves just this purpose. Anywhere we have multiple files that differ only slightly, or files that need to contain dynamic information, we just use a template.
Templates are evaluated via a simple function as show in the following example:
$value = template("my_module/my_template.erb")
Template files should be stored in the templates directory of a Puppet module, which allows the template function to locate them with the simplified path format shown above. For example, the file referenced by template("my_module/my_template.erb") would be found on disk at /etc/puppet/modules/my_module/templates/my_template.erb.
Templates are always evaluated by the parser, not by the client. This means that if we're using a puppet master server, then the templates only need to be on the server, and we never need to download them to the client. The client sees no difference between using a template and specifying all of the text of the file as a string. - Docs: Using Puppet Templates
Suppose new we want to build three new sites: bogo1.com, bogo2.com, and bogo3.com. To prepare for this, we need to change the Puppet config for bogo.com to use a template so that we can later use the same template for the new sites.
-
Here is our new modules/nginx/manifests/init.pp file:
class nginx { package { 'nginx': ensure => installed, } service { 'nginx': ensure => running, enable => true, require => Package['nginx'], } file { '/etc/nginx/sites-enabled/default': ensure => 'absent', } }
Since we previously used the file /etc/nginx/sites-enabled/ default as the virtual host for bogo.com (Puppet packages, services, and files II with nginx), we need to remove that now:file { '/etc/nginx/sites-enabled/default': ensure => absent, }
-
We want to reate a new templates directory in the nginx module:
ubuntu@ip-172-31-45-62:/etc/puppet$ sudo mkdir -p modules/nginx/templates
- Create the file modules/nginx/templates/vhost.conf.erb with the following
contents. The template file is for the virtual host definition:
server { listen 80; root /var/www/<%= @site_name %>; server_name <%= @site_domain %>; }
The <%= %> signs mark where parameters will go; we will supply site_name and site_domain later, when we use the template. Puppet will replace <%= @site_name %> with the value of the site_name variable. - Then in the site.pp file, we include the nginx module on the node:
node 'puppet-agent' { include nginx $site_name = 'bogo' $site_domain = 'bogo.com' file { '/etc/nginx/sites-enabled/bogo.conf': content => template('nginx/vhost.conf.erb'), notify => Service['nginx'], } ... }
Note that before using the template, we need to set values for the variables site_name and site_domain:$site_name = 'bogo' $site_domain = 'bogo.com'
Also note that when we refer to these variables in Puppet code, we use a $ prefix ($site_name), but in the template it's an @ prefix (@site_name). This is because in templates we're actually writing Ruby, not Puppet!Now we can use the template to generate the nginx virtual host file:
file { '/etc/nginx/sites-enabled/bogo.conf': content => template('nginx/vhost.conf.erb'), notify => Service['nginx'], }
This looks just like any other file resource, with a content attribute. Though we can give the contents of the file as a literal string:content => "Hello, bogotobogo\n",
However, here we call the template function:content => template('nginx/vhost.conf.erb'),
The argument to template tells Puppet where to find the template file. The pathnginx/vhost.conf.erb
Translates tomodules/nginx/templates/vhost.conf.erb
- Run puppet:
ubuntu@ip-172-31-45-62:/etc/puppet$ sudo puppet apply modules/nginx/manifests/init.pp Notice: Compiled catalog for ip-172-31-45-62.ec2.internal in environment production in 0.02 seconds Notice: Finished catalog run in 0.02 seconds
- Check the resulting virtual host file on agent node:
ubuntu@puppet-agent:~$ cat /etc/nginx/sites-enabled/bogo.conf server { listen 80; root /var/www/bogo; server_name bogo.com; }
Puppet now evaluated the template, inserted the values of any variables referenced in <%= %> signs in modules/nginx/templates/vhost.conf.erb, and generated the final output as we can see in the bogo.conf.
Puppet
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization