Book Image

LEARNING PUPPET

Book Image

LEARNING PUPPET

Overview of this book

Table of Contents (17 chapters)
Learning Puppet
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Puppet on command line


Now it is the right time to start the real Puppet work:

  1. Select the virtual machine from the list, and click on the Start button at the top of the window.

  2. Once the virtual machine has booted up, you should see a login prompt:

  3. At the login prompt, type in the user name root and hit Enter. Then, type in password puppet and hit Enter again.

  4. You have now entered the development environment, where we can start familiarizing with the Puppet commands and manage our system. You are free to play around and change the configuration as much as you like.

  5. If you happen to break the environment, you can easily restore the original configuration from the snapshot as we did in the earlier paragraph.

Puppet version

The Puppet executable can be run from the command line. Let's begin with confirming which version of Puppet we are running. We can check the version by running the following command:

puppet --version

At the time of writing, the command run on the Learning VM, it shows the Version as 3.7.3 (Puppet Enterprise 3.7.1.).

The first Version number 3.7.3 is for the open source version of Puppet that we are using. The second Version number 3.7.1 is for the Puppet Enterprise version number.

What is the difference between these two versions? The difference between them is how these products are packaged, distributed, and supported.

The open source Puppet

The open source Puppet is the community-driven version of Puppet that is developed by the open source community and maintained by Puppet Labs. It can be used and distributed freely.

The Puppet Enterprise edition

The Puppet Enterprise edition is a distribution that is developed, maintained, and supported by Puppet Labs, which is the commercial arm behind Puppet.

Companies can purchase the Puppet Enterprise license from Puppet Labs, and in return, Puppet Labs provides support services and software updates for the Puppet Enterprise software bundle that enables companies to get up and running with Puppet quickly.

The Puppet Enterprise edition is free to use in environments that consist of 10 or less Puppet managed hosts.

The environment that we will be building throughout the course of this book will consist of four hosts only, which makes Puppet Enterprise a perfect fit for our goal of learning Puppet.

Puppet resources

So now we know how to extract the version using the Puppet command-line utility. Let's shift our focus to the resources next.

Resources in Puppet are known as types. Types are operating system resources such as a file, a user, or a package. There are tens of built-in types in Puppet, and in addition to these, you can create your own custom types to manage resources.

We will learn more about custom types later in Chapter 5, Load Balancing the Cluster, but for now we will take a look at the built-in types and see how to use them.

A complete list of available built-in types is available on the Puppet Labs website at http://docs.puppetlabs.com/references/latest/type.html.

Run the puppet describe --list command in the Learning VM to list all the built-in types known to Puppet.

The output will contain about 60 resources and their descriptions. To paginate the output, you can extend the command by adding | less to the end of it.

Here is the command to view the output page by page:

puppet describe --list | less

You should now be able to scroll the output up and down using the arrow keys, and you can exit the view by pressing Q on the keyboard.

All the Puppet types have attributes that are used to describe the characteristics of the resources we want Puppet to manage.

For example, the type user has attributes such as a name for the user name and a password for the user account password.

To list the available attributes for a specific type of resource, you can use the puppet describe <type> command. For example, to list the available attributes of a type user, you can run the puppet describe user, or puppet describe user | less command to paginate the output.

If you scroll down the list of attributes, you can find a password attribute that is used to set a password for the user account. Another attribute that you can find on the list is called ensure, which defines the state of the user account. The attribute can have three values:

  • present: This ensures that an account is created unless it already exists

  • absent: This ensures that the account is removed if it exists

  • role: This is a specific user attribute of the Unix operating system, such as Oracle Solaris, and therefore it has has no meaning when running Puppet on Linux like we are doing

Managing resources from the command line

We can manage Puppet resources from the command line using the following syntax: puppet resource <type> <name> <attribute1>=<value> <attribute2>=<value>.

Let's create a user called Elisa on the system using Puppet. In the Learning VM terminal, type in the following command and and hit the Enter key:

puppet resource user Elisa ensure=present

When the command is executed successfully, it produces the following output:

The first line of the output displays a notice confirming that the user account Elisa was created by Puppet. Lines 2-4 show the syntax that we will be using when we declare resources in the Puppet manifest files. The manifest files will be explained more in detail later.

Let's take a look at the syntax line by line:

  • Line 1: Notice: /User[Elisa]/ensure: created

    This displays a confirmation of an action that Puppet has created a user called Elisa.

  • Line 2: user { 'Elisa':

    This declares a resource for a type user, which follows the opening curly brace ({), that indicates that the user resource name and optional attributes are to follow. The name 'Elisa': at the end of the line sets the Puppet resource name, which will become the name of the user account. The Puppet resource name must contain a colon at the end.

  • Line 3: ensure => 'present'

    This attribute means that a user account must be created unless it already exists.

  • Line 4: }

    The closing curly brace indicates the end of the resource statement.

The name Elisa on line 2 has two use cases. Firstly, it declares the name of the Puppet resource. Each Puppet resource must have a unique name, otherwise Puppet reports an error.

Secondly, the name Elisa is used as the name of the user account that was created. If the user statement contains a name attribute (alongside the ensure attribute), then the value of the name attribute would become the name of the user account and the name Elisa would only be used as the Puppet resource name.

As the name attribute is omitted, Puppet will use the name for the Puppet resource name as well as for the user account name.

Declaring the following statement in the Puppet manifest would result in the Jakob user account being created in the system, as the name attribute would take priority over the Puppet resource name Elisa:

user { 'Elisa':
  ensure => 'present',
  name   => 'Jakob',
}

This produces an output that is similar to the following, although the numeric information in the output may vary between the systems:

uid=501(Elisa) gid=501(Elisa) groups=501(Elisa)

Next, we can remove the account Elisa from the system by setting the ensure attribute value to absent.

puppet resource user Elisa ensure=absent

Assuming that the command executes successfully, you should see the following output:

This output is very similar to how we created the user account Elisa except that line 1 confirms that the user account Elisa was removed and line 3 has the ensure attribute value set to absent, which results in the account being removed when declaring a resource in the Puppet manifest file.

To confirm whether Puppet really removed the account, you can run the command id Elisa again, which will confirm that the account no longer exists in the system.

The command id Elisa should produce the following output:

id: Elisa: No such user

Congratulations! You just did two system configuration changes using Puppet. It wasn't hard, right?

Puppet dry run

Sometimes, you want to simulate configuration changes without applying the changes to the system. This can be done by adding the --noop parameter after the resource keyword in the Puppet command.

To simulate account creation without creating the account, we can extend the previous user account creation command with the --noop option:

puppet resource user Elisa ensure=present --noop

Line1 in the output tells us that the user account does not exist in the system, and if you run the following command without the --noop option, Puppet would create an account:

Notice: /User[Elisa]/ensure: current_value absent, should be present (noop)
user { 'Elisa':
  ensure => 'absent',
}

The --noop option comes in handy when testing Puppet commands for a syntax. To demonstrate this, we declare an invalid value removed for the attribute ensure:

puppet resource user Elisa ensure=removed --noop

Puppet will return an error that tells you that we have used an invalid value for the ensure attribute:

Use Puppet to examine the current state of resources

Puppet can also be used to query resources from the system. Information produced by the query can be helpful when we are uncertain about what syntax we should be using to create a resource.

Earlier, we created a user account called Elisa. This account was created without a password, which means that the account cannot be used for interactive logins. Let's recreate the user account and use the password attribute to set a password for the account.

As passwords on Linux are encrypted, we must provide them to the password attribute in the encrypted format.

We know that the user account root on the Learning VM uses the password puppet, but we yet don't know how the password would look like in the encrypted format.

No problem, as we can query the password with the command and then use the encrypted password when recreating the user account Elisa.

The following command shows all the attributes for the root user account:

Puppet resource user root

The preceding command produces the following output:

Now we can create the user account Elisa with the password attribute, which is the same as the value of the password attribute for the user root.

The following command will create the user account Elisa that uses the password puppet:

puppet resource user Elisa ensure=present \
managehome=true \
password='$1$jrm5tnjw$h8JJ9mCZLmJvIxvDLjw1M/'

I've split the command into three lines with the backslash character at the end of the first two lines.

Note

The $1$jrm5tnjw$h8JJ9mCZLmJvIxvDLjw1M/ string is a hash of the password puppet. Please note that we have to use single quotes around the password hash '$1$jrm5tnjw$h8JJ9mCZLmJvIxvDLjw1M/' because the string contains characters that the Linux command line otherwise interprets as a control character.

Now we can test whether we can log on to the system as the user Elisa.

Log out from the system using the logout command. Then, log in with the username Elisa and password puppet. You will see the following welcome screen, which confirms that the login of Elisa was successful:

Puppet is run as a user root

The root account in Linux is equivalent to an administrator account in the Windows operating system. This is the user account that is commonly used for system configuration changes.

The user account Elisa that we created does not have the same amount of privileges as the root account.

To change the system configuration in the protected areas of the operating system, we must run Puppet as a root user.

If you are still logged onto the system as user Elisa, you can try creating a user account and see what happens.

As the user Elisa is not configured to run Puppet, we will do our test using the Linux adduser command.

Let's see what response we get if we try to create a user called Jakob using the user Elisa:

useradd Jakob

The output of the preceding command shows you that the user Elisa did not have sufficient permissions to add a new user to the system:

/usr/sbin/useradd: Permission denied

To avoid possible permission issues on Puppet managed systems, Puppet runs as a user root that provides Puppet full control of the system to add and remove users, install and uninstall software packages, as well as manage system services.

In the end, Puppet is your new system administrator, which manages the system according to the instructions you have provided from the command line or in the form of the Puppet manifest.

Puppet DSL and manifests

I've mentioned Puppet manifests earlier, but I haven't yet explained what manifests are. Puppet manifests are text files that declare one or more Puppet resources. Instead of running Puppet resource commands on the command line, you can declare resources in the manifest file and apply the manifest to the system.

Puppet manifests uses the Puppet Domain Specific Language (DSL) and resource statements in the manifest file, which are described in a syntax that looks very similar to a Hash data type in the Ruby language.

We can use our user account Elisa as a simple example of the Puppet manifest syntax.

First, log out from the user account Elisa by running the logout command. Then, log on to the system as a root user and remove the user Elisa from the system with the following command:

puppet resource user Elisa ensure=absent

Then, inspect the state of the user account Elisa with the following commands:

puppet resource user Elisa
user { 'Elisa':
  ensure => 'absent',
}

In the Ruby language, if we try to declare a hash called User that contains a key Elisa with the value of the ensure attribute as absent, we will declare it using the following syntax:

User = { 'Elisa' =>
  { 'ensure' => 'absent' }
}

If you compare the preceding two code blocks, you can see that the Puppet DSL syntax looks similar to the Ruby language syntax, but it is slightly simpler and easier to read than the Ruby equivalent.

The output of the preceding Puppet resource command is spread across three lines only in order to make it easier for us to read. The Puppet parser that reads the manifest file doesn't care about the line feed characters.

The preceding user resource can be declared on a single line as follows:

user { 'Elisa': ensure => 'absent', }

We now have the Puppet DSL representation of the user resource Elisa.