Resources
Quest objectives
- Understand how resources on the system are modeled in Puppet's Domain Specific Language (DSL).
- Use Puppet to inspect resources on your system.
- Use the Puppet Apply tool to make changes to resources on your system.
- Learn about the Resource Abstraction Layer (RAL).
Getting Started
Before you go on to learn the more complex aspects of Puppet, you should start with a solid understanding of resources, the fundamental building blocks of Puppet's declarative modeling syntax.
In this quest, you will learn what resources are and how to inspect and modify them with Puppet command-line tools.
When you're ready to get started, type the following command:
quest begin resources
Resources
For me, abstraction is real, probably more real than nature. I'll go further and say that abstraction is nearer my heart. I prefer to see with closed eyes.
-Joseph Albers
There's a big emphasis on novelty in technology. We celebrate the trail-blazers who spark our imagination and guide us to places we hadn't imagined. Often, however, it's not these frontier fireworks themselves that truly drive innovation in a field. It's something more basic: abstraction. Taking common tasks and abstracting away the complexities and pitfalls doesn't just make those tasks themselves easier, it gives you the stable, repeatable, and testable foundation you need to build something new.
For Puppet, this foundation is a system called the resource abstraction layer. Puppet interprets any aspect of your system configuration you want to manage (users, files, services, and packages, to give some common examples) as a unit called a resource. Puppet knows how to translate back and forth between the resource syntax and the 'native' tools of the system it's running on. Ask Puppet about a user, for example, and it can represent all the information about that user as a resource of the user type. Of course, it's more useful to work in the opposite direction. Describe how you want a user resource to look, and Puppet can go out and make all the changes on the system to actually create or modify a user to match that description.
The block of code that describes a resource is called a resource declaration. These resource declarations are written in Puppet code, a Domain Specific Language (DSL) based on Ruby.
Puppet's Domain Specific Language
A good understanding of the Puppet DSL is a key first step in learning how to use Puppet effectively. While tools like the PE console give you quite a bit of power to make configuration changes at a level above the code implementation, it always helps to have a solid understanding of the Puppet code under the hood.
Puppet's DSL is a declarative language rather than an imperative one. This means that instead of defining a process or set of commands, Puppet code describes (or declares) only the desired end state. With this desired state described, Puppet relies on built-in providers to handle implementation.
One of the points where there is a nice carry over from Ruby is the hash syntax. It provides a clean way to format this kind of declarative model, and is the basis for the resource declarations you'll learn about in this quest.
As we mentioned above, a key feature of Puppet's declarative model is that it goes both ways; that is, you can inspect the current state of any existing resource in the same syntax you would use to declare a desired state.
Task 1:
Use the puppet resource
tool to take a look at your root user account. The
syntax of the command is: puppet resource \
puppet resource user root
You'll see something like the following:
user { 'root':
ensure => present,
comment => 'root',
gid => '0',
home => '/root',
password => '$1$jrm5tnjw$h8JJ9mCZLmJvIxvDLjw1M/',
password_max_age => '99999',
password_min_age => '0',
shell => '/bin/bash',
uid => '0',
}
This resource declaration syntax is composed of three main components:
- Type
- Title
- Attribute value pairs
We'll go over each of these below.
Resource Type
You'll get used to the resource syntax as you use it, but for this first look we'll go through the example point by point.
We'll start with the first line first:
user { 'root':
...
}
The word user
, right before the curly brace, is the resource type.
The type represents the kind of thing that the resource describes. It tells
Puppet how to interpret the rest of the resource declaration and what kind of
providers to use for managing the underlying system details.
Puppet includes a number of built-in resource types, which allow you to manage aspects of a system. Below are some of the core resource types you'll encounter most often:
user
A usergroup
A user groupfile
A specific filepackage
A software packageservice
A running servicecron
A scheduled cron jobexec
An external commandhost
A host entry
If you are curious to learn about all of the built-in resources types
available, see the Type Reference
Document
or try the command puppet describe --list
.
Resource Title
Take another look at the first line of the resource declaration.
user { 'root':
...
}
The single quoted word 'root'
just before the colon is the resource title.
Puppet uses the resource title as its own internal unique identifier for that
resource. This means that no two resources of the same type can have the same title.
In our example, the resource title, 'root'
, is also the name of the user we're inspecting
with the puppet resource
command. Generally, a resource title will match the name
of the thing on the system that the resource is managing. A package resource will
usually be titled with the name of the managed package, for example, and a file resource
will be titled with the full path of the file.
Keep in mind, however, that when you're creating your own resources, you can set
these values explicitly in the body of a resource declaration instead of letting them
default to the resource title. For example, as long as you explicitly tell Puppet
that a user resource's name
is 'root'
, you can actually give the resource any
title you like. ('superuser'
, maybe, or even 'spaghetti'
) Just because you can do
this, though, doesn't mean it's generally a good idea! Unless you have a good
reason to do otherwise, letting Puppet do its defaulting magic with titles
will save you typing and make your Puppet code more readable.
Attribute Value Pairs
Now that we've covered the type and title, take a look at the body of the resource declaration.
user { 'root':
ensure => present,
comment => 'root',
gid => '0',
home => '/root',
password => '$1$jrm5tnjw$h8JJ9mCZLmJvIxvDLjw1M/',
password_max_age => '99999',
password_min_age => '0',
shell => '/bin/bash',
uid => '0',
}
After the colon in that first line comes a hash of attributes and their
corresponding values. Each line consists of an attribute name, a =>
(pronounced 'hash rocket'), a value, and a final comma. For instance, the
attribute value pair home => '/root',
indicates that root's home is set to the
directory /root
.
So to bring this all together, a resource declaration will match the following pattern:
type {'title':
attribute => 'value',
}
Note that the comma at the end of the final attribute value pair isn't required by the parser, but it is best practice to include it for the sake of consistency. Leave it out, and you'll inevitably forget to insert it when you add another attribute value pair on the following line!
Task 2:
Of course, the real meat of a resource is in these attribute value pairs. You
can't do much with a resource without a good understanding of its attributes.
The puppet describe
command makes this kind of information easily available from
the command line.
Use the 'puppet describe' tool to get a description of the user type, including a list of its parameters.
puppet describe user | less
(You can use the jk
key mapping or the arrow keys to scroll, and q
to exit
less.)
No need to read all the way through, but take a minute to skim the describe page for the user type. Notice the documentation for some of the attributes you saw for the root user.
Puppet Apply
You can use the puppet apply
tool with the -e
(--execute
) flag to execute
a bit of Puppet code. Though puppet apply -e
is limited to one-off changes, it's
a great tool for tests and exploration.
Task 3:
In this task, you'll create a new user called galatea. Puppet uses reasonable
defaults for unspecified user attributes, so all you need to do to create a new
user is set the ensure
attribute to present
. This present
value tells
Puppet to check if the resource exists on the system, and to create the specified
resource if it does not.
puppet apply -e "user { 'galatea': ensure => present, }"
Use the puppet resource
tool to take a look at user galatea
. Type the
following command:
puppet resource user galatea
Notice that while the root user had a comment attribute, Puppet hasn't
created one for your new user. As you may have noticed looking over the puppet
describe
entry for the user type, this comment is generally the full name of
the account's owner.
Task 4:
Though you could add a comment with the puppet apply -e
, you'd have to cram
the whole resource declaration into one line, and you wouldn't be able to see
the current state of the resource before making your changes. Luckily, the
puppet resource
tool can also take a -e
flag. This will drop the current
state of a resource into a text editor where you can make any changes
you like.
Let's give it a try:
puppet resource -e user galatea
You should see the same output for this resource as before, but this time it will be
opened in a text editor (Vim, by default). To add a comment attribute, insert
a new line to the resource's list of attribute value pairs. (If you're not used
to Vim, note that you must use the i
command to enter insert mode before you
can insert text.)
comment => 'Galatea of Cyprus',
Save and exit (ESC
to return to command mode, and :wq
to save and exit Vim), and the
resource declaration will be applied with the added comment. If you like, use
the puppet resource
tool again to inspect the result.
Review
So let's rehash what you learned in this quest. First, we covered two very
important Puppet topics: the Resource Abstraction Layer (RAL) and the anatomy of a
resource. To dive deeper into these topics, we showed you how to use the puppet
describe
and puppet resource
tools, which also leads to a better
understanding of Puppet's language.
We also showed you how you can change the state of the system by declaring
resources with the puppet apply
and puppet resource
tools. These tools
will be useful as you progress through the following quests!