Using tags
Sometimes one Puppet class needs to know about another or at least to know whether or not it's present. For example, a class that manages the firewall may need to know whether or not the node is a web server.
Puppet's tagged
function will tell you whether a named class or resource is present in the catalog for this node. You can also apply arbitrary tags to a node or class and check for the presence of these tags. Tags are another metaparameter, similar to require
and notify
we introduced in Chapter 1, Puppet Language and Style. Metaparameters are used in the compilation of the Puppet catalog but are not an attribute of the resource to which they are attached.
How to do it...
To help you find out if you're running on a particular node or class of nodes all nodes are automatically tagged with the node name and the names of any classes they include. Here's an example that shows you how to use tagged
to get this information:
- Add the following code to your
site.pp
file (replacingcookbook
with your machine'shostname
):node 'cookbook' { if tagged('cookbook') { notify { 'tagged cookbook': } } }
- Run Puppet:
root@cookbook:~# puppet agent -vt Info: Caching catalog for cookbook Info: Applying configuration version '1410848350' Notice: tagged cookbook Notice: Finished catalog run in 1.00 seconds
Nodes are also automatically tagged with the names of all the classes they include in addition to several other automatic tags. You can use
tagged
to find out what classes are included on the node.You're not just limited to checking the tags automatically applied by Puppet. You can also add your own. To set an arbitrary tag on a node, use the
tag
function, as in the following example: - Modify your
site.pp
file as follows:node 'cookbook' { tag('tagging') class {'tag_test': } }
- Add a
tag_test
module with the followinginit.pp
(or be lazy and add the following definition to yoursite.pp
):class tag_test { if tagged('tagging') { notify { 'containing node/class was tagged.': } } }
- Run Puppet:
root@cookbook:~# puppet agent -vt Info: Caching catalog for cookbook Info: Applying configuration version '1410851300' Notice: containing node/class was tagged. Notice: Finished catalog run in 0.22 seconds
- You can also use tags to determine which parts of the manifest to apply. If you use the
--tags
option on the Puppet command line, Puppet will apply only those classes or resources tagged with the specific tags you include. For example, we can define ourcookbook
class with two classes:node cookbook { class {'first_class': } class {'second_class': } } class first_class { notify { 'First Class': } } class second_class { notify {'Second Class': } }
- Now when we run
puppet agent
on thecookbook
node, we see both notifies:root@cookbook:~# puppet agent -t Notice: Second Class Notice: First Class Notice: Finished catalog run in 0.22 seconds
- Now apply the
first_class
andadd --tags
function to the command line:root@cookbook:~# puppet agent -t --tags first_class Notice: First Class Notice: Finished catalog run in 0.07 seconds
There's more…
You can use tags to create a collection of resources, and then make the collection a dependency for some other resource. For example, say some service depends on a config file that is built from a number of file snippets, as in the following example:
class firewall::service { service { 'firewall': ... } File <| tag == 'firewall-snippet' |> ~> Service['firewall'] } class myapp { file { '/etc/firewall.d/myapp.conf': tag => 'firewall-snippet', ... } }
Here, we've specified that the firewall
service should be notified if any file resource tagged firewall-snippet
is updated. All we need to do to add a firewall
config snippet for any particular application or service is to tag it firewall-snippet
, and Puppet will do the rest.
Although we could add a notify => Service["firewall"]
function to each snippet resource if our definition of the firewall
service were ever to change, we would have to hunt down and update all the snippets accordingly. The tag lets us encapsulate the logic in one place, making future maintenance and refactoring much easier.
Note
What's <| tag == 'firewall-snippet' |> syntax
? This is called a resource collector, and it's a way of specifying a group of resources by searching for some piece of data about them; in this case, the value of a tag. You can find out more about resource collectors and the <| |>
operator (sometimes known as the spaceship operator) on the Puppet Labs website: http://docs.puppetlabs.com/puppet/3/reference/lang_collectors.html.