Resources

Prerequisites

  • Welcome Quest
  • Power of Puppet Quest

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

In this quest, you will be introduced to resources, the fundamental building blocks of Puppet's declarative modeling syntax. You will learn how to inspect and modify resources on the Learning VM using Puppet command-line tools. A thorough understanding of how the Puppet resource syntax reflects the state of a system will be an important foundation as you continue to learn the more complex aspects of Puppet and its DSL.

When you're ready to get started, type the following command:

quest --start 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

Resources are the fundamental units for modeling system configurations. Each resource describes some aspect of a system and its state, like a service that should be running or a package you want installed. 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) built on Ruby.

Puppet's Domain Specific Language

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, and relies of built-in providers to deal with implementation.

When Luke Kanies was initially designing Puppet, he experimented with several languages before settling on Ruby as the best match for his vision of a transparent and readable way to model system states. While the Puppet DSL has inherited many of these appealing aspects of Ruby, you're better off thinking of it as a distinct language. While a bit of Ruby knowledge certainly won't hurt in your quest to master Puppet, you don't need to know any Ruby to use Puppet, and you may even end up in trouble if you blindly assume that things will carry over.

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 be learning about in this quest.

A nice 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 :

Using the puppet resource tool, take a look at your root user account. Note the pattern of the command will be: puppet resource <type> <name>.

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',
}

It's a little abstract, but a nice portrait, don't you think?

Resource Type

To be sure that you have a solid understanding of how resources are represented, we'll go through this example point by point.

Take a look at your first line in the above resource declaration.

user { 'root':

The word user, right before the curly brace, is the resource type.

Puppet includes a variety of built-in resource types, which allow you to manage various aspects of a system. Below are some of the core resource types you'll likely encounter most often:

  • user A user
  • group A user group
  • file A specific file
  • package A software package
  • service A running service
  • cron A scheduled cron job
  • exec An external command
  • host A host entry

If you are curious to learn about all of the different built-in resources types available for you to manage, see the Type Reference Document

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 a resource's title as a unique identifer for that resource. This means that no two resources of the same type can share a title. In the case of the user resource, the title is also the name of the user account being managed.

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 your 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',
}

The Trailing Comma

Though the comma at the end of the final attribute value pair isn't strictly necessary, 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!

So in the world of Puppet, you and everything around you can be respresented as a resource, and resources follow this tidy declarative syntax. As pretty as they are, presumably you don't want to just look at resources all day, you want to change them!

You can, and easily. But before making any changes, take a moment to learn a bit more about the user type. You'll want a way of knowing what you're changing before you start changing attributes.

Task 2 :

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 resource declaration syntax with the puppet apply tool to make quick changes to resources on the system. (Note, though, that while puppet apply is great for tests and exploration, it's limited to this kind of one-off change. We'll get to the more robust ways to manage resources in later quests.)

Task 3 :

You can use the puppet apply tool with the -e (--execute) flag to execute a bit of Puppet code. In this example, you'll create a new user called galatea. Puppet uses some defaults for unspecified user attributes, so all you'll 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 :

While puppet apply with the -e flag can be handy for quick one-liners, you can pass an --execute (incidentally, also shortened to -e) flag to the puppet resource tool to edit and apply changes to a resource.

puppet resource -e user galatea

You'll 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 in 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.

Quest Progress

Have you noticed that when you successfully finish a task, the 'completed tasks' in the lower right corner of your terminal increases? Remember, you can also check your progress by entering the following command:

quest --progress

The Resource Abstraction Layer

As we mentioned at the beginning of this quest, Puppet takes the descriptions expressed by resource declarations and uses providers specific to the operating system to realize them. These providers abstract away the complexity of managing diverse implementations of resource types on different systems. As a whole, we call this system of resource types and providers the Resource Abstraction Layer or RAL.

In the case of users, Puppet can use providers to manage users with LDAP, Windows ADSI, AIX, and several other providers depending on a node's system. Similarly, when you wish to install a package, you can stand back and watch Puppet figure out whether to use 'yum', 'apt', 'rpm', or one of several other providers for package management. This lets you set aside the implementation-related details of managing the resources, such as the names of commands (is it adduser or useradd?), arguments for the commands, and file formats, and lets you focus on the end result.

Review

So let's rehash what you learned in this quest. First, we covered two very important Puppet topics: the Resource Abstraction Layer 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 actually 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.