1. Introduction to the course
Welcome to using Puppet configuration and programming. Puppet is an open source configuration management tool.
Puppet is closely coupled with the DevOps methodology and it's implemented with its own declarative language or Ruby.
Mostly used by system administrators. Puppet automates a configuration provisioning and management of physical and virtual servers.
With automation, Puppet eliminates the errors that occur with manual tasks. In this course, you will learn how to configure puppet and manage its resources.
Puppet programming, implementation, and troubleshooting techniques will be discussed and demonstrated.
1. Coding and management of packages
Puppet uses a custom DSL language to specify the desired host configuration. The custom DSL used by Puppet is highly optimized to solve problems in a declarative way inside Puppet. This special language is human readable and easy to understand. But it's not designed like a general-purpose language, thus has little use outside Puppet. Puppet manages node configuration through a code. You will use DSL in managing packages, modules, and just about anything else Puppet related. A resource declaration is an expression that describes the desired state for the resource. This tells Puppet to add it to the catalog. Resource declarations are specified using an attribute-value structure. The resource declarations expression syntax has advanced and additional declaration features such as declaring multiple resources at the same time and changing or overriding resources after they have been declared. Let's cover some syntax. To manage a package resource, we must first declare it using the following syntax. Start by declaring the resource type. In this case, we declare a package resource. The next step is to give the package resource a title between single quotes. Then continue by specifying attributes and their values. Notice how simple the syntax is – well, at least when you know what the syntax actually should be.
Heading: Package Coding and Management.
The syntax to manage a package resource is as follows:
Package { 'openssh': //openssh is the resource title
ensure => present,
}
Learning syntax is boring. And, through trial and error, you'll get it. For example, ensure that each line ends with a comma. That's a best practice. When declaring resources, the declarative nature of Puppet abstracts the platform for you. The administrator does not have to worry about the node OS. Using facts, Puppet will determine the node OS and will apply the package using yum, apt, or other package managers. The resource declaration simply says, "I want this resource," but does not specify how to get it or for which platform. To view packages and resources, type puppet describe package. This will list the attributes, providers, and more info. Resources can also be combined. Classes define a collection of resources that are managed together as a single unit.
Heading: Package Coding and Management (Continued).
It is also possible to declare multiple packages in a class. And there will be times when you will want to install multiple packages in a Puppet module or manifest. You are allowed to install multiple packages containing more than one package resource. There are a few things worth noting when writing packages and resources. A namevar is a special attribute – typically the name for a package or a resource. If namevar is not specified, it defaults to the resource title value. In this example, the resource title is openssh and manages the package named openssh. Here the namevar is not specified. And we leave it to Puppet to determine which openssh to install based on the facts of the agent. Omitting the namevar is perfectly appropriate. It's done all the time. Let's cover another scenario. Let's say we want to specify which version of an application to be installed. What happens when you manage a multiplatform environment? Here we are doing just that. Below, the ssh package name for Solaris is different than the ssh package that we're using for CentOS. Why? Because we said so. The name attribute here can also be assigned to a variable.
Heading: Package Coding and Management (Continued).
The example used by the presenter in the illustration is as follows:
Package { 'openssh':
ensure => installed,
}
1. Concept of Puppet service management
One of the core resources in Puppet is services. Puppet is good at handing services as long as they are supported by your operating system. If the service that you are concerned with is already configured on the machine or has existing scripts, you can write Puppet service resources with only a couple of attributes. Of course, service resource management accepts different attributes depending on how you want the service to run. Use Puppet describe service to view the attributes, providers, and more. A service declaration is done using a similar syntax. Also, it is possible to declare multiple service resources in a class. Below is an example of using a service resource. For service resource declaration, the type will be service. Services of course vary. And, in the below example, Apache is specified as a service resource. So the title of the service would usually be its name. If no name attribute is specified, the namevar will default to the title. The software specified, as a service type, needs to be installed for any of this to work. Use one or more of the attributes to describe the resource. Here we are specifying two attributes – ensure and enable. Also, it is common to use a variable as a value to handle multiplatform environments.
Heading: Service Management.
The illustration includes an example of service resource. The example is as follows:
service { 'apache2':
ensure => running,
enable => true,
}
As you have seen, it's relatively simple to use services within Puppet. All possible attributes could be found using the Puppet describe service. Some of the common attributes are as follows. First we have the name attribute. The name attribute is the service name or the namevar. The next attribute is ensure. Ensure is the control of the service state – running, stopped, et cetera. The last attribute shown here is enable. This attribute specifies whether a service is enabled or disabled at startup. It's important to keep a good coding style. Indenting and blocking are part of the Puppet coding convention. Make sure the code is readable and easy to understand. And keep the code simple. Actually, it's worth going over Puppet coding conventions, as you will use them when using types. First start each declaration by specifying the resource type – service in this example. All attributes and title should be in curly braces and the braces should be blocked off just like in other languages. The assignment operator in Puppet is "=>". This will set the attribute to a certain value. Also, each attribute line should end with a comma – attribute, assignment, value, comma. Make sure the code is clean and arranged. And keep it indented. All Puppet code is handled this way.
Heading: Service Management (Continued).
There are many plugins to help keep good coding style for Puppet for VIM and for VI. Both VIM and VI can be difficult to use. The good news is you can pick your own editor. Puppet labs have developed an IDE called Geppetto. Geppetto offers a toolset for coding, developing, and integrating Puppet modules and manifests. And, since Puppet code is held in text files, any text editor will do. At the lowest possible denominator, Notepad could even be used in Windows environments. Puppet also has a command line tool that checks for syntax errors. The syntax is Puppet parser validate. And then put in the path to the module.
Heading: Service Management (Continued).
Handling Puppet Resource Dependencies
Learning Objective
After completing this topic, you should be able to
•identify Puppet resources and handling their dependencies
1. Puppet resource dependencies
A resource will often have dependencies, which it requires to run. This is a very common occurrence in Puppet. A service resource cannot be started unless that service is first installed on the box. The SSH service, for example, will require the ssh package to be installed and, perhaps, a predefined configuration file. The same goes for other popular services such as Apache. To resolve dependencies, we will often need to declare multiple resources. This can be done individually or as a collection. Classes define a collection of resources that are managed together as a single unit. Puppet does not enforce resources top down based on their position in the manifest. Resource dependencies are evaluated all at once. Remember, the manifest is applied, it's not run. So the order is not important. Puppet checks for the applicable dependencies between the resources in the manifest code. Puppet then reorders resource enforcement to meet the determined relationship requirements. This process orders the operations into the steps in which they need to happen. This process is declarative, thus hidden from you. For example, the Apache service could not be started before the conf file is configured. Puppet ensures that the proper steps are taken. Resource enforcement order is driven by the dependency graph.
Heading: Handling Puppet Resource Dependencies.
There are, of course, some guidelines to follow when handling multiple resource dependencies. First it is recommended to explicitly define ordering relationships. Ordering relationships is easy to spot in the code, thus explicitly communicating the intent of what is to be done. Next the ordering relationships are defined using metaparameters. These four metaparameters are used to explicitly define what dependencies exist and how to handle them. There are four metaparameters – require, before, subscribe, and notify. A best practice is to always define the dependency relationship you need. Never define the relationships that you don't need. This may sound strange, but it is possible to define a relationship just to be safe such as installing a service on a server even when you are sure that the service will always be there. Let's go over the metaparameter syntax when dealing with dependencies. The syntax says subscribe>. And then you assign the type to a title. The type should start with an uppercase letter. The first metaparameter is require. When using require, it means that a referenced resource is required to be applied first. Example syntax: "require => Package['openssh'],". The next metaparameter is before. When using before, it means that a request needs to be applied before a referenced resource. Example syntax: before=> Service['sshd']. The part in braces indexes to the title of a resource.
Heading: Handling Puppet Resources Dependencies (Continued).
Next we have subscribe. Subscribe implies required. It enforces order as well as watching for changes. And lastly we have notify. Notify implies before. It enforces order as well as sending change notifications. Another way to control ordering is by using the ordering arrows. In the first example, it causes the resources above it to be applied before the one below. In the next example, it causes the resource above it to be applied first, then sends a refresh event to the resource below if the resource above changes.
Heading: Handling Puppet Resources Dependencies (Continued).
================
Managing Puppet Configuration Files
Learning Objective
After completing this topic, you should be able to
•identify the contents of a Puppet configuration file and how to manage it
1. Contents of Puppet configuration file
Hello everybody. Welcome to my demonstration. In this demonstration, we are going to talk about how Puppet handles configuration files. We are going to start with some basics of configuration files. Now, before we can go on and you could go on and learn more complex aspects or learn more complicated Puppet techniques, you need to have a solid understanding of how resources work. Now we have alluded to resources a little bit, but resources are really the fundamental or the principle building blocks of Puppet code or of the Puppet declarative modeling syntax. Now there is a big emphasis on how Puppet is declarative, meaning that when we put something in Puppet code, we are not specifically saying exactly how to do something, just do something. Now this is important because when we talk about this, we talk about the Puppet Resource Abstraction Layer. Now in Puppet, just about anything that you do in system configuration or anything that you might want to manage insofar as files, users, services, and packages – just to give you a few of the most common resources – is handled in the unit condor resource. So understanding resources is really the first thing that you need to know about how Puppet actually handles configuration files.
The vm [Running] - Oracle VM VirtualBox window is open.
Now Puppet can translate back and forth between the syntax or the syntax that we specify in a resource and specifically the native tools or the platform-specific tools of the operating system it's running on. For example, if we create a Puppet user, it can be a user on any specific operating system. Now obviously, if we are using Windows, creating a user on Windows is different than if we create a user on a Linux box. So the abstraction layer takes care of that. So what we need to do is, when we work with resources, we want to describe basically how we want a resource to look. And then Puppet takes care of all that abstraction behind the scene that we don't actually have to do that. Now, when we put something and a resource in Puppet code, we call it a resource declaration. Now resource declarations are written in Puppet. Or they are written in the DSL based on Ruby. So, if you understand Ruby, you have a good understanding about how you would actually start coding in Puppet. So, if you have a good understanding of the Puppet and the Puppet DSL, you are well on your way of learning how to use Puppet as a tool.
Now, as far as the DSL goes, the first step in learning how to use Puppet like you should is you should learn how declarative languages work. Now I am assuming that you know a little bit about declarative languages. So I am just going to kind of skip those as we go. So we are going to talk a little bit more about resources and resource types. Now there are a different number of Puppet built-in resource types. And they allow us to manage really all aspects of a Puppet system or a Puppet infrastructure. So, just off the top of my head, a couple or few of the resource types that are important are user resources, package resources, file resources, service resources, cron resources, executable resources, and host resources. So our first step in learning how Puppet stores and uses these configuration files is learning how to build a resource. So what we are going to do is we are going to go over an example of building a simple resource.
Let's start with the puppet describe command. I am going to type in puppet describe and nothing afterwards. Now I am going to get a list of the correct parameters and syntax for describe. So, if I want to see a list of all of my resources, I can type in puppet describe --list. Now, among other things, this should show me my complete list of resources. Now there is just a ton of them. There is more than you'll probably use in the first year or so that you actually are a Puppet developer or a Puppet administrator. But it is important to point out that this is how configuration is really stored in a Puppet system. It's stored in Puppet resources. Now there are some resources that are going to be used more than others.
To get the correct syntax for describing the Puppet, the presenter executes the "puppet describe" command. The output returns the correct syntax, which is as follows:
$ puppet describe -- list
$ puppet describe -- providers
$ puppet describe - s - m
Let's go over a few of them right here. I am going to type in puppet describe user. This will show all of the parameters and attributes for a user resource. Now again, there is going to be more to this that comes back than we can really cover, but that's okay. I just want you to be aware of how you can actually get this stuff. So that was a user resource. Now I am going to type puppet describe execute. And we can look at everything for our execute resource. There is more than can be described from what you see here. Again, I'll leave it to you to actually kind of look at this stuff. I just want you to be aware of where you could find that. And let me show you another one. Let's do puppet describe cron. And we can look at everything for our cron resource.
Now, as you go through Puppet, you are going to be learning how to work with these resource types. It's something that you are going to learn a little bit as you go. No one sits down – at least that I know of – and says, "You know what? Today, I'm going to learn five resource types. Or today, I am going to learn twelve resource types." It just kind of happens as you go. As a matter of fact – like I mentioned – you'll probably wind up using a half dozen to start with and you will add more as you go. And every once in a while, you'll use a resource type or you will be going over a manifest and you'll see one in there that looks new. And you are like, "Wow, I don't know what that is." And you'll look that up and you'll know a different resource type. So anyway, to understand how configuration is stored within Puppet or how configuration is used within Puppet, you need to first understand resources – at least start to understand resources – and how resources work within Puppet. Let me show you one more thing before I'm finished with my demo. If you want to look at a specific resource, you can type in something like this – puppet resource. And, if you want to look up a user resource like the current user I am, we can say root.
Now the syntax of this is more important than what we are looking up. I have here puppet resource user root. The two most important things of this syntax are the two last parameters – user, root. user specifies the type of resource in which I want to look up. And the last parameter – root – is the specific one. So knowing that combination – Puppet resource and then the type of the resource and the name of the resource – will allow you to look up that specific resource. Now, in this case, we will look up the resource of type – user. It is named root. And here are all the attributes. This concludes my demo. Thank you so much for watching.
The "puppet resource user root" command returns the information about the root user, such as gid name, home location, password, shell name, and so on.
=========================
The Package-File-Service Pattern
Learning Objective
After completing this topic, you should be able to
•identify the Package-File-Service pattern and how it is used in Puppet development
1. Identify Package-File-Service pattern
The Package-File-Service is a design pattern. This pattern isolates and encapsulates different Puppet operations. The pattern allows flexibility and a degree of interoperability between the three different pieces. It is the most common and the most useful design pattern used in production environments. When new to Puppet, this is the first design pattern to learn. We commonly specify several resources together to describe a desired configuration. A proper workflow when installing a service is as follows – install a package, change the configuration file or files, then start to service. Puppet workflows follow this pattern. The Package-File-Service pattern can further be broken down into the following detail. Below, we have a few things going on. In the first code example here, we have the first portion of the design pattern – the package portion. Here the package is slated for installation. In the code example, iptables is the package to be installed. It could be any package such as SSH or Apache. It really does not matter. Notice the metaparameter will ensure that this package is installed. In the second code example below, we have the second element of the design pattern – the file portion. Here the configuration is specified in the configuration file. This defines the iptable rules.
Heading: The Package-File-Service Pattern. For package installation for the design pattern, the following code block is used:
Package { 'iptables':
ensure => installed
}
For changing configuration file and defining iptable rules for the design pattern, the following code block is used:
File { 'etc/sysconfig/iptables':
mode => 60, owner => root, group => root,
ensure => present,
path => '/etc/sysconfig/iptables',
source => 'puppet:///modules/firewall/ iptables',
require => Package ['iptables'],
}
Here we illustrate the third portion of the design pattern – the service portion. This is where services are enabled – the same service that is defined in the package portion and configured in the file portion. Here the service is enabled. ensure is set to running. And enable is set to true. The iptables service resource is subscribing to the iptables file resource. It will restart a service when Puppet modifies the configuration file. Using this pattern, we address all dependencies in one class. Everything takes place in one spot – nice and easy. The following diagram illustrates the design pattern using iptables – the same example we have been using thus far. Remember that this design pattern is divided into compartments. This can be illustrated by looking in more detail in each of the three portions of the design pattern. The package portion specifies the package to be installed. It does not specify where the package is or even what platform in which to install it. All of this is determined by the Puppet master based on the facts provided by the agent. In the last portion, the service is started. Noteworthy is that the declarative nature of Puppet takes care of the details on how it is started. Note we don't have to do anything platform specific. Puppet does most of the thinking for us.
Heading: The Package-File-Service Pattern (Continued).
For enabling the service for the design pattern, the following code block is used:
service { 'iptables':
ensure => running,
enable => true,
subscribe => File [''/etc/sysconfig/iptables'],
}
Now the presenter explains the package, file, and service attributes by using a flow chart.
In some cases, the package will schedule its associated services to stop and restart before upgrade. This depends on the service and the operating system that is installed. In that case, we should not use schedule since it will restart a service. Your mileage will vary depending on your current installation. It is also recommended to keep in mind the package and service names vary between operating systems. In some instances, services will not even be supported. Also, the configuration file location will vary between operating systems. These challenges have various solutions. In this situation, we should use conditions and variables.
Heading: The Package-File-Service Pattern (Continued).
============================== ==
A Comprehensive Example
Learning Objective
After completing this topic, you should be able to
•work with an end-to-end example of a Puppet task
1. End-to-end example of a Puppet task
In this demonstration, we're going to perform a Puppet task kind of end to end. Now there are lot of different things obviously that we could do on Puppet. So, when we talk about doing something from end to end, what I did is I just picked something that was fairly simple that we can start. From the beginning, we can talk about some concepts about what we are doing and kind of – you know – go all the way to the end. Let's talk about the concept of a module. Now, in Puppet, we have resources and we have manifest that describe what we want our configuration to do. Now eventually, we are going to group a lot of this stuff into classes and then into modules. Modules are just groups of different things that we need to do our configuration. It has our manifests in it and our manifests have our resources in themselves. When we finally start working with some real...I hate to say real because we are doing real Puppet right now. But, when we start doing some more enterprise Puppet development, we start working with modules. Now, when we start working with modules, we can write our own or we can also use what is called Puppet Forge. Basically, it works like this. We could spend a lot of time building a module to do something. For example, we can say let's build a module that does this. It connects to a database. It installs Apache. It runs something. So basically, it just does a whole bunch of different stuff. Now what we can do is we can write that from scratch. And indeed, there's nothing wrong with writing down from scratch.
The vm [Running] - Oracle VM VirtualBox window is open.
Or what we could do is we could go to what is called Puppet Forge. What Puppet Forge is, is it is a service or a community of developers – just like you and just like me – that we can actually exchange modules. You could upload modules to Puppet Forge and you could download modules to Puppet Forge. And we can do it via a web site. We could just go to the URL and we could log in and do the stuff. Or we can do it from Puppet itself. Now basically, again what Puppet Forge is, is it serves as a central repository for these modules – these things that I am talking about. Now again, these are things that you can create and upload or you can download someone's modules that's already been uploaded to it. Now module again, basically, is everything really nicely packaged into one executable piece of code as far as Puppet is concerned. So what we can use is we can use the Puppet module tool, which is a command line tool that lets us search for modules directly from Puppet. What that will do is it will allow us to go into Puppet Forge to look, to see if there is a module that fits that specific description. Also, while we're doing this, it's important to play now that there are different sorts of modules that are out there. I mean, we have the modules and Puppet Forge that you and I create and we upload and we download.
We also have the Puppet approved modules, which are the modules that have been approved by Puppet labs. A lot of these are more professional, not that you and I are unprofessional. But they are more professionally written. Modules may be from different vendors – from the Apaches of the world, from the Oracles of the world, and from the Microsoft of the world where they may be Puppet approved. And we also have what are called Puppet supported modules. Now Puppet supported modules have been tested and they are fully supported by Puppet labs. In a lot of instances, they are created by Puppet labs themselves. So what we are going to do end to end here is we are going to issue some command line commands, if you will, to look at Puppet Forge to actually look at specific modules that may be there. And, once we find one, what we are going to do is we are going to actually install that module. So we are going to do that end to end in just actually a couple commands.
Now let's go over our first example. I am going to type in a command that's going to go to Puppet Forge and look for specific modules. I am going to type in puppet module search oracle. I had returned. Now Puppet is going out to Puppet Forge. And it's finding me all of the modules that have to deal with oracle. Now, in reality here, I'm going to have to probably narrow this down and determine exactly which module I am looking for. And, as you get better at this and as you are able to navigate your way around not just Puppet but Puppet Forge in general, you get more comfortable using it and finding out exactly what you're looking for.
Let me do another search here. I am going to look for a module called graphite, which is a graphing module used for Puppet and Puppet enterprise. So I can search for it by typing in puppet module search graphite. So let's go out to Puppet labs. And we see a couple of them out there. And let's see which one I want to actually download and install. So let me narrow this down. I am looking for a specific graphite module. So let me type in puppet module search dwerder. This is a specific developer that wrote that graphic module that I am looking for...the graphite module I am looking for. And there we go. We got dwerder-graphite.
So, to install this module, I simply would type puppet module install dwerder-graphite. And I'll leave that alone on my desktop a little bit – puppet module install dwerder-graphite. I am going to hit Return. And this module should be downloaded from Puppet Forge and installed on my node. And you could see messages indicating the success of installing my module.
So there we go. What we just did is we installed a module and we did it from end to end. We talked about the concept of modules. We discussed Puppet Forge and how Puppet Forge allows us to share modules. Either we can upload them once we are ready or we could download and install them once we are ready. Again, there are different kind of modules that are out there. There are modules that you and I put out there. And there are also some modules that are approved by Puppet labs and some that are actually supported by Puppet labs. You are going to be spending quite a bit of time, I am thinking, in Puppet Forge because it gives us a place to actually download modules that may already be working. Who has the time to develop these things from scratch, right? Well, a lot of the stuff is already developed for us or much of it develop for us. We could go in there and tweak it and maybe change it to customize it to fulfill whatever our current needs may be.
============================= =
Creating User Accounts
Learning Objective
After completing this topic, you should be able to
•create and set up a user account
1. Set up a user account
In this demonstration, I am going to create a Puppet user and I am going to do a couple of more things. I am going to create a password for the user and I am going to create a working directory for the Puppet user. Now users in Puppet are resources just like anything or almost anything else that we do in Puppet where we've packages and their resources, we've files, their resources. We have just a myriad of different things in Puppet that are resources, and users are one of them. Let us type in the command to look at the specific resource of user or the user resource. I am going to type in puppet describe user. I hit Return. And a whole bunch of stuff is going to be returned to me. Now this is going to be everything that describes user as far as the resource as Puppet is concerned. Now obviously, I can't go through all of this. But at least, you know where you could go to see the stuff. Now, if I want to see a specific user, I can type in puppet resource user – in this case – root, which is me. But it could be any user. And, since I am root, I get to do this – puppet resource user root.
The vm [Running] - Oracle VM VirtualBox window is open.
Now puppet returns to me the resource for this specific user. Now look at the syntax – "user { 'root':". Again this is a user resource. And everything here are attributes for the user resource where we have the home directory, we have the password, shell, uid, and some password information. Now, if I want to add a user, I can type in the following – useradd tammyh. And then hit Return. Now, if nothing happens, this is actually a good thing. It means that this user was created successfully. Now, to look at this user, I am just going to use the up arrow here because I can – puppet resource user and we've changed this user to tammyh – puppet resource user tammyh.
To add "tammyh" as a user in the system, the presenter executes the "useradd tammyh" command. Next to view the information about the "tammyh" user, he executes the "puppet resource user tammyh" command.
Now puppet returns to me information about the user resource – tammyh. And again, it looks very similar to how root did accept. There are couple of things that are slightly different. For example, here if you look at the password, password is just two exclamation points, which means that there is really no password at all. So let's assign tammyh a password. And her password will be...and I am not going to tell you. There we go. So what did we do? We added a user named tammyh and we assigned her a password. Now let's look to see what her working directory is. And type in puppet resource file /home/tammyh/tools. And, when we hit Return, we look at the file resource. And, if you look at the attribute, it says ensure – absent. That means that this folder does not exist. So let's create it,
To set the password for the "tammyh" user, the presenter executes the "password tammyh" command. He sets the password for the user and the vm returns a message, "all authentication tokens updated successfully." Next to see the working directory, he executes the "puppet resource file/home/tammyh/tools" command. The vm window returns a message that states searched file is absent.
mkdir /home/tammyh/tools. Now, using the up arrow, let's see if we could find this resource. And we can. So we see this resource does exist as a file resource. All right, let's review what we did. We logged in. We looked to see everything that was available for user resource. I showed you how you could look up a user resource. We used root. I showed you how you can create a user resource, which is tammyh. We assigned tammyh a password. And we assigned her a working directory. Congratulations! You've just been able to set up you first Puppet user.
To create the "tools" folder, the presenter executes the "mkdir/home/tammyh/tools" command.
==========================
Configuring SSH
Learning Objective
After completing this topic, you should be able to
•identify how Puppet uses SSH
1. How Puppet uses SSH
In this demonstration, what I am going to do is I am going to configure Puppet to be accessed via SSH. I am going to configure Puppet to be able to be accessed via SSH. Let me talk about what you see here on your screen in my desktop and I will talk us through the steps in which to do this. What you see here is you see Oracle virtual box. Now, inside of virtual box, what I am doing is I am running Linux syntax, to be specific. And on it, I have Puppet Enterprise. I am running Puppet Enterprise. And I am accessing it via virtual box. Now what I am going to do is I am going to set this up so I can access this via SSH. The first thing that we need to know – really the most important thing that we need to know – is we need to know the IP address that we're currently running Puppet Enterprise on. Now how did you do that? Now remember that there is a program within Puppet that gives us facts about the current node and that program is called facter. So let me type in facter and then hit return.
The vm [Running] - Oracle VM VirtualBox window is open.
Now, just as a review, facter gives us everything, almost everything. If we want a specific fact or something that describes us about the current node, chances are we'll use facter to do that. Now, what I want to do is, I want to get the current IP address of the node. And I could do that by typing facter ipaddress. And facter indeed gives me the IP address. Now, if you are following along with me, you may want to write this down because probably, hopefully your IP address is different than mine. But my IP address is 192.168.1.232. Now the next thing to do is you need to get SSH running in some sort of SSH program. Now there are a ton of them out there that you could use to actually configure SSH and to connect applications securely. Now I am going to use PuTTY. PuTTY is a very common tool used to do just this.
So let me move virtual box over a little bit. And I have PuTTY set up on my desktop. So let me click on PuTTY and PuTTY opens up. Now, quite simply, to connect via PuTTY, you just put in for the host name, put in your user – in this case, root for your root user – put in an @ sign, and the IP address in which you want to connect – 192.168.1.232. And let me click on open. But, before I do that, I'll let you take a mental picture of this. And again, if you are familiar with PuTTY, you can do other things such as save this configuration, you could load from an existing one, but since I am just setting one up here, this is how we do this.
The presenter opens the PuTTY Configuration dialog box. The dialog box is split into two sections. The left section shows a tree-like structure, which includes different categories, such as Session, Terminal, Window, and Connection. Each category has subcategories. The Session category has the Logging subcategory. The Terminal category has the Keyboard, Bell, and Features subcategories. The Window category has the Appearance, Behavior, Translation, Selection, and Colors subcategories. The Connection category has the Data, Proxy, Telnet, Rlogin, SSH, and Serial subcategories. The right section displays the basic options for the PuTTY session, such as Host name, Port number, Connection Type, close window on exit or not, and so on. By default, the connection type is set to SSH and close window only on clean exit. At the bottom of the dialog box, the About, Help, Open, and Cancel buttons are located.
So let me click on Open. And you should notice that we made the connection and it's asking me for my password. And again, in this case, it's Puppet. And now I have connected to Puppet Enterprise on my local machine via SSH. Now this has some additional advantages to...lot of them "look-and-feel". For example, I can actually close now my virtual machine and let me make my PuTTY command window a little bit larger. And now that I am connected via PuTTY, via my SSH tool, I have a bunch of stuff I can do. For example, I can click on Change Settings. And, for example, if I wanted to make my font a little larger in PuTTY, I can Change my font size. And just a whole bunch of other settings to make my look and feel and my behavior much more predictable and user friendly, much more so than virtual box. There we go. So I could do things such as make my font larger. And again other look and feel and behavior settings to make this act a little more user friendly than virtual box. But other than that, it's connected to Puppet Enterprise just like I was in virtual box. Now I am connected via SSH and I used PuTTY, which is a very common tool to do so.
The presenter clicks the OK button to close the dialog box. A command prompt window with the name, "192.168.1.232 - PuTTY" appears on the screen. The window shows the name of the user for the established connection and prompts for the password. He enters the password to start the session.
============================== ==
Distributing SSH keys
Learning Objective
After completing this topic, you should be able to
•describe how SSH keys are distributed in a Puppet installation
1. Distribution of SSH keys
One useful resource type is SSH authorized keys. Puppet can manage user accounts and also include their SSH public key. It allows distributing SSH keys to all nodes. Each agent contains a copy of the key. This way an administrator can access nodes over SSH without supplying a password. This makes administrative tasks easier and faster. It also helps automate the authentication process. An administrator doesn't need to distribute them manually. The public key will be installed on each node that has that specific user account. If that key ever changes, the change needs only to be reflected on the Puppet server. The next Puppet agent run will allow each host to update themselves. SSH – Secure Shell – enables encrypted connection and access to remote hosts. Puppet supports using SSH keys to provide a very secure connection mechanism for agents to communicate with the Puppet master. This is more secure than using passwords alone. This connection is based on SSH public/private keys. Passwords can be hacked by brute force. SSH keys are almost impossible to crack. When generating SSH keys, a public key and a private key are generated. A public key can be used for authorizing remote access. To do that, we must add the public key to the authorized key directory.
Heading: Distributing SSH Keys.
If a user has its SSH key in this file, it will not be required to supply a user ID or password for SSH access – a real-time saver. A user that doesn't have this key in this file will be required to authenticate using a valid user password. Before starting to manage the authorized keys, one should generate a public key using SSH. There are many different ways to do this. One way is to create the key value pair on the Puppet node. The next step is to obtain all public keys for which you would like to authorize access. Note that SSH can be enabled on Windows by third-party tools. In this example, we're going to create a new SSH module under our module directory. With the module set up and both agent and master configured to send and listen to SSL connections, our job is almost complete. The last step is do ensure that all agents as well as the master will accept the SSL options. This can be set up with some attributes. Some common attributes are listed below. Target – this is the path to the file which stores the SSH keys. And purge SSH keys – this removes any existing keys from the file, add only what is specified.
Heading: Distributing SSH Keys (Continued).
And lastly, we have name. It's the key comment with the namevar, and it defaults to the title if not specified. It might be a good idea to handle the service in the package resources. Handling the resources adds an additional step. By doing so, we avoid potential problems. There are multiple ways to install SSH. And they vary by operating system. For example, SSH can be installed on Windows using Cygwin. Cygwin emulates a Linux/UNIX environment. Open SSH is another popular free open source set of tools used to provide encrypted and secure communication using SSH. Open SSH is available for most Linux distributions. Open SSH is not available for Windows.
Heading: Distributing SSH Keys (Continued).
============================== ========
User Account Management
Learning Objective
After completing this topic, you should be able to
•distinguish between and manage user account
1. Managing user accounts
Hello everybody. Welcome to my demonstration. What I am going to demonstrate for you today over the next few minutes or so is I am going to show you some simple things that we can do for user administration, account management, and some basic puppet user management sort of stuff. Now I have created a puppet user called tammyh. So what we are going to be doing is we are going to be working with that user. If you want to see their resource, you can type in puppet resource user tammyh. And puppet should return you everything about that resource. And remember, everything in puppet is a resource, even users.
The vm [Running] - Oracle VM VirtualBox window is open.
So let's change ownership of her working directory or of the working directory to her. Let me type in chown – change ownership. And let me take a look at that. Let me change the ownership of the tools directory to tammyh. And that looks okay. And, if nothing comes up, we are good. So we changed ownership of the tools directory to tammyh. And we can also see that. So let me type in puppet resources or resource – singular. We are inquiring about a file resource. And remember, the file resource can be a folder as well. And let's take a look at that puppet resource file /home/tammyh/tools.
So we give this a second. And we could look at the owner of this directory of this folder is 502. Now we could look at tammyh again. Actually, we see it on the screen here, but let me use the up arrow to cheat a little bit just to retype that command. But we can type in puppet resource user tammyh. And it shows us that tammyh is uid 502, which is – indeed – the owner of that working directory – okay, so a little user management there. But we had a user that was existing and we made her the owner of her tools folder. Now let's do a couple more things with this. Let's just say, for example, I may want to delete a user. So let me make sure I am at my home folder. And what I am going to do is I am going to write a script or a manifest that is going to delete this puppet user. It seems often mean. No. Doesn't it? We just created the user. We just gave her a working directory. Now we're actually going to write a manifest to delete the user. But hey, this is account management, right. I am going to use the nano editor. Now you can use vi if you like or really any text editor that you are familiar with. But I am going to use nano here. And I am going to write a manifest that is going to delete this user.
So let me type in the following. User – okay, "user {'tammyh':". And we will do ensure => 'absent' – user tammyh, ensure absent. And that looks okay. Now let me save this and write it out by doing a Ctrl+O. It's asking me the name of the file to write. I will name it as tammyh.pp since it's a manifest. And Ctrl+X to exit there. So I wrote a manifest that will actually delete this user. Now, before I actually run this manifest, I can do a couple of things to make sure my syntax was correct. I am going to type in puppet parser validate tammyh.pp. So what the parser is doing now is it's looking over the manifest called tammyh.pp. It's validating it and it's looking for any errors – syntax errors not logic errors. And, if it comes backs with nothing – like it came back with nothing now – we are good to go. Meaning that there is no errors – at least syntax errors – in this manifest.
Now we can apply this manifest by typing puppet apply. And let me do a noop, which means that we're just pretending like we are going to apply it – puppet apply --noop tammyh.pp. And it tells us what would have happened. And you can read this. And, if you take a look, it says ensure the current value present and it should be absent, okay. So basically, it would actually run this manifest and make this user absent or nonexistent basically getting rid of our user. Now, to apply this manifest, we can type in puppet apply tammyh.pp. And you could look at the feedback. And we have here ensure is equal to removed now. So that attribute ensure is equal to removed. Now we can verify that all of this happened by looking at our user resource. So let me type in. I can use the up arrow too. But I am in a typing mood right now. Let's do puppet resource user tammyh. And we can ensure now that this user has been deleted. Ensure is absent as far as the attribute goes for this resource. You have just changed some account management information for a puppet user and then deleted the user. This concludes my demonstration. Thank you so much for watching.
============================
Using exec Resources to Run Commands
Learning Objective
After completing this topic, you should be able to
•work with exec resources to run commands
1. Working with exec resources
In the demo I am going to do for you right now is I am going to show you how you can use execute resources in Puppet. First let's start by opening up a manifest. I am going to use nano. And I created a manifest called mysql.pp. Now let me explain you what is in this manifest. And then we're going to get back into the execute resources. In this manifest, I have two resources. I have a package resource, and I have an execute resource. Now, in the package resource, what I am specifying here is I am specifying I want mysql and the server version – so mysql-server as a post of sql server. Mysql – as in the database management system – server version installed. Now, going down here to my execute resource, this is the important part. What I have here is I have an execute resource. What an execute resource, in Puppet, is it will execute either a program or a script. It's as simple as that. It will execute either a program or a script just like if you are in Windows, it would be command line and whatever platform you might be using. It's called something else. But it will actually execute again a program or some sort of script.
The vm [Running] - Oracle VM VirtualBox window is open. By using the nano command, the presenter shows the code of the "mysql.pp" file. The lines of code included in the file are as follows:
package {"mysql-server":
ensure => installed,
}
exec {"start_mysql":
command => "./start_mysql",
path => ".",
}
So what I am specifying here is I have an execute resource called mysql. And here is the command. And it is a program called start_mysql. It's found, as it turns out, here in the root folder. It requires the mysql-server package to be there. And I have another attribute set – path – with the ".", which just means the current path from which this manifest is actually run. It's quite a simple manifest that we have here. Again, we just have two resources – a package resource and an execute resource. Now let me exit. And I don't need to modify any changes. And now I am back at the command prompt. Now let's do two things just for fun. Let's do a couple of things here. Let's do puppet parser validate mysql.pp. Now remember what validate does. What the validate parser does is it will look at my manifest and determine if I have any errors in it. And, if nothing happens, that's good. I don't know what we expected – maybe balloons kind of fly out of the screen if everything is okay. But, if nothing happens, we are ok.
So now what we can do is we can do a puppet apply. And we can simulate if we want and why not noop mysql.pp. So this is a dry run. Let's run this manifest to see what would happen. And it's telling us that the package is installed. We have two notices – Would have triggered 'refresh' from 1 events and our catalog run ended in 67 one hundredth of a second, okay. So we look all right so far. So now let's change our command to puppet apply, and we'll type in mysql.pp. So what this will do before I hit the magical Enter or Return key is it will look to see if the mysql package is installed. If not, it will install it. And then it will start that command to actually start mysql. So let me hit Return. It's telling me that the catalog is already there. And then it's telling me that the command actually completed successfully. And I am in good shape. If you see the second to the last line, this is [start_mysql]/returns: executed successfully. So my execute resource looks good to go here. What I just demonstrated for you is the execute resource type where it executes a script or a program.
===========================
Using cron Resources to Run Scheduled Jobs
Learning Objective
After completing this topic, you should be able to
•work with cron resources to run scheduled jobs
1. Working with cron resources
In this demonstration, I am going to show you how you can define a cron resource or a cron job within Puppet. I'm going to keep this demo fairly brief. I am not going to go into the theory of cron. I am not going to go into, you know, using the specific Unix/Linux sort of methodology with scheduling cron jobs. I am just going to limit this conversation in this demonstration into how we do this within Puppet and how cron is a resource just like a lot of the other resources that we have been using. cron is a resource as well. So I have a test manifest here or a manifest that I've prewritten for us that has a cron resource in it. So I am going to log in via nano. So I am going to bring it up in my nano text editor. And I call this one bobcron. Since we are using just such incredibly polite naming conventions – nano bobcron.pp. And this is a very simple cron job that I built. Now cron again is a resource. So you're looking at a manifest. Now with one resource in it, the resource in this manifest is a cron resource. It's named bobcron. And you have the command. Now I have a script in my root folder called ./start_mysql. Now what this script does is completely up to me. I could really put anything I like within some limitations within the ./start_mysql script. I run it as user root. And this job will fire off every two hours.
The vm [Running] - Oracle VM VirtualBox window is open. By using the nano command, the presenter shows the code of the "bobcron.pp" file. The lines of code included in the file are as follows:
cron{ bobcron:
command => "./start_mysql",
user =>root,
hour => 2,
minute => 0,
}
So I have a cron job named bobcron that will fire off a script called ./start_mysql every two hours. Now I am not going to go into the internals of what isn't ./start_mysql. It could really be anything that's not the point here. The point here is I have a job that will fire that script off every two hours. So let me exit. Now I could run the parser against my manifest. We could say puppet parser validate bobcron.pp. This syntax looks correct. Now I could run this against a noop if I wanted to and sure why not. So we could say puppet apply --noop bobcron.pp. And we look good there. And it looks like I am replacing a previous bobcron that might have been there, which is fine. So now let's actually run this. And we do so by issuing puppet apply bobcron.pp.
And we ran our manifest. So now we have that cron job that will be launched every two hours. And it looks like here that we actually replaced an existing cron job that may have already been out there, which is very possible because I may have had one out there that I used for a prior example. And it looks like, in this case, that this cron job wrote over the definition for the prior one. So it looks like we're good to go here. Our cron job is waiting and will be fired every two hours.
=======================
Deploying Directory Trees
Learning Objective
After completing this topic, you should be able to
•recognize and deploy file tree structures
1. Deployment of directory trees
In the demo, I am going to do for you right now is I am going to show you some different ways that we can list directory structures and create directory structures within Puppet. Now why would you want to be able to do this? Well, there is a couple of reasons. Number one, when you create a module or you create any kind of code that may need to actually be deployed or to be placed in kind of a tree structure, you probably might want to do something like this where if you create a module that needs to be in a directory. And then maybe have some pieces of code in subdirectories, you probably would want, maybe perhaps, to have some code to actually do this. Now I do want to point out that what I am showing you here is really a technique more than anything. It's not really a practice. It's not really a standard. It's not really anything else than a technique in which to automate something and maybe do something a little bit better and a little bit more efficiently. There is certainly nothing wrong with manually building your directory structure. For example, if you have a folder you are going to deploy or you are going to develop something, and that's piece of code – I am being vague on purpose – needs to access from a relative path pieces of code further down the directory structure. There is nothing wrong with actually manually doing that. If you want to manually create your directory structure, you certainly can do that.
The File: tree.pp is open in the vm [Running] - Oracle VM VirtualBox window. The file includes the following code snippet:
# create a directory tree, list the dirs. In order, Puppet will create file
{["usr/local/bobtext/", "usr/local/bobtext/2.0/log"]:
"usr/local/bobtext/2.0/bin", "/ usr/local/bobtext/2.0/log"]:
Ensure => "directory",
}
# or assign them to a var, and use the dirs as a resource
$bobtext_dirs = {["usr/local/bobtext/", "usr/local/bobtext/2.0",
"usr/local/bobtext/2.0/bin", "/ usr/local/bobtext/2.0/log",
]
File {$bobtest_dirs"
Ensure => "directory",
Owner => "root",
Group => "wheel",
Mode => 750,
}
Now you may though want some way to automate this, like for example, if you have kind of the same way that you develop something that's going to constantly need you to build certain subdirectories under the directory in which you are developing, you may want to have some techniques to actually do that. On my desktop right now, I have a file called tree.pp and this is kind of code but it's more like a pseudo code. It's not really executable because there is a couple of things I want to talk about in here. Now first of all, what this does in a nutshell is it creates a directory tree structure by listing what directory tree is. First thing I want you to notice is when we build things like this we are building basically some resources like here we have some file resources. Now, when you're building directory trees or you're building out a directory structure in Puppet, it tends to be a little bit edgy or little bit not as forward as you might think that it should be. For example, if you create a directory structure or you want to create a directory structure in Puppet, it's a little bit harder than if you were doing this in Windows or in Linux or any native operating system.
Now, if we were working in native operating systems, for example, if we were just going to issue a Linux command or a UNIX or a Windows command, we can create a directory by the mkdir command – make directory – where we can make as many directories as we want. And, you know, from there we can change directories, we can do ownership and things of that nature. Now, in Puppet, it works a little bit differently because Puppet doesn't have the ability to natively make directories like we can in Windows and in Linux. Instead, what we can do in Puppet is we can actually read on array of directories each one of them kind of going down recursively, going down the tree structure, and kind of reading them into an array. And what we can do is we could read them and then we could have Puppet, create them as it actually reads them. Also, while we are doing this, while we are recursively reading a directory structure and actually specifying the directories as a part of a string array that we want to actually create, it's important to have that each directory, well actually, require its nearest ancestor directory to be on top of it. So we kind of have, like a recursive binary tree, data structure where we are actually reading these directories and having, you know, the actual ancestor directory populated first.
Now, while we are doing this, we can do a few things. We can use variables if you know how to use variables. We could use parameters if you know how to use parameters. You can do a lot of these things that you can regularly do on Puppet code. And again I want to point out that what I am showing you is more of a technique than a standard or a...you must do this as a part of your learning curve in Puppet, but this is certainly useful and it certainly wants an explanation here. So what you see here, as far as my code goes, is I have a couple of things here. The first thing I have is I have a file resource. And, in my file resource, I have here an array where I have user local and then I have my name in there. And I have the folders that I want to create. I want to create again like a 2.0 on a bin. And I am showing here that is part of my resource at the user directories. Now further down, I have a comment that these can be assigned to a variable if I want to use the variables part of the resource. And here I am declaring a variable. And, we know, it's a variable because it's got a dollar sign in front of it,
and that variable is actually in array of strings, where we have the directory structure here kind of denoted by the comma. And these are the directory structures that I wish to create. And below that I have another file resource where in my file resource is I have my variable again, which is an array of strings that contains an array of strings of the directories I want to create. Or variations of these techniques and perhaps put them in a looping structure, where we can actually maybe passing parameters and actually loop through, you know, an array of strings actually build these folders. Now again this is useful for if you want to automate the whole process of building directory structures and you don't want to create them manually. Again, if you want to create them manually, there is nothing wrong with that, but this is a technique that you're probably wind up learning as you go. So hopefully, I gave you some pseudo code example here of different ways that you can do this which should put you well on your way to developing your own different methods of building dynamic tree structures.
==========================
Using Puppet Templates
Learning Objective
After completing this topic, you should be able to
•use different kinds of Puppet templates to create configuration files
1. Types of Puppet templates
In this demonstration, I am going to do for you over the next couple of minutes is I am going to demonstrate Puppet templates and the concept of templates and how templates are implemented within Puppet and Puppet coding. Now this was an interesting example for me to kind of put together and put together a code example for you because the implementation of templates is much more complex than the basics of learning what they do and the fundamentals of how they are constructed and how they are used. So I tried to get an example and put together an example that is of the lowest common denominator, if you will, where we have just a more simple example possible of how a template is constructed because I truly feel that once you find out and learn how templates are constructed, the implementation part will come. It's something that comes with practice like anything in Puppet or like anything in any other language or indeed any sort of programming or operation's tasks that you might do is once you practice it and know the fundamentals, it comes a little bit more easy than if you don't. So I tried to keep this example very, very simple and easy to understand. Now let me open up a file with a template in it. And I will use nano template.pp.
The vm [Running] - Oracle VM VirtualBox window is open. By using the nano command, the presenter opens the template.pp file in the window. The file includes the following content:
bobfile /var/lib/ntp/bobfile
<% [1,2].each do |n| -%>
server <%=n%> <%=@ntp_server_suffix%>
<% end -%>
#Results of above template
bobfile /var/lib/ntp/bobfile
server 1.ubuntu.pool.ntp.org
server 2.ubuntu.pool.ntp.org
And this is a prewritten template, obviously, because you are not watching me code it that I put together for you. Now, on the top portion, you see four lines – you see bob file, and then you see some stuff here, you have server, and then end. More on this in just a moment. And, on the bottom here, you have the results of the template. Now what a template is, is a template is a piece of Puppet code that is evaluated dynamically at runtime. Picture a regular piece of Puppet code and then imagine somethings that could be derived at runtime. Now, if you have a Java background or if you have an ASP background, you are familiar with how Java uses JSP pages or how ASP pages work or you have some areas there that could be evaluated at runtime and that's exactly what a Puppet template is. Now, if you don't have a Java background or an ASP background, you are good as well. That's just, you are going to have to learn a couple of more concepts than any other person that's used to using maybe Java or ASP. Let's look at this template. First of all, we have everything here within my less than and my percent sign. That's evaluated as a command. Now what I have here in this template is I have two things.
I have flow of control statements. In this case, I have an 'each do | n |' statement and then I have regular Ruby code. So here what I have is I have a command which is going to iterate twice – each do and then | n | and here is the end of my command. Also, in this last line of code, what I am doing here is I just have an end statement. And this end statement kind of ends my looping structure that I have in my first line of code here. So basically, what I have here is I have a template that invokes a looping structure. Again this is an each do end looping structure. Now, in my looping structure which is going to occur twice, it's going to output server and here I got some Ruby interpreted code, where it's going to prone out the value of n and again some more Ruby code, where it's going to prone out the value of NTP server and a suffix. So this is the template. Now the template is evaluated at runtime and I am going to keep a lot of details of this out for you. Because like I mentioned, templates is really a runtime implementation issue once you know the syntax. So I am showing you the syntax here. Now after this template is evaluated, you are going to get something that looks like the following. You are going to have bobfile /var/lib/ntp/bobfile because in the template, that's not part of any sort of iteration. Now you also going to get these two lines of code – server 1.ubuntu.pool.ntp.org.
Server is printed out verbatim because in our template it is verbatim. And then we have some Ruby interpreted code here, where n is equal to 1. And then we have the server suffix here, which again is interpreted at runtime. And the server suffix is .ubuntu.pool.ntp.org. And these templates can iterate twice. So the second line of code or the second line that's going to be evaluated in output or replaced from this template is 2.ubuntu.pool.ntp.org. So this is the basics of templates. Once you understand how templates are evaluated, it's going to make it a lot easier to understand how they are implemented because they are implemented just about anywhere. So it doesn't make a lot of sense to go through the implementation of a template. And so you at least understand the syntax of how templates work within Puppet.
============================= =
Flow of Control Statements
Learning Objective
After completing this topic, you should be able to
•describe the syntax of flow of control statements
1. Syntax of flow of control statements
Hello everybody, welcome to my demonstration. What I am going to show you right now is I am going to show you how you can use conditional statements within your Puppet code. Now, in Puppet programming, you can use operators. As a matter of fact, if you're used to using a different language – a third-generation language – operators work almost the same way in Puppet. There is very little new stuff to learn. Puppet supports branching operations such as if else statements. And Puppet also supports iteration by looping. What I am going to do here is I am going to open up a file – nano accounts.pp. And let's take a look at this Puppet class.
The vm [Running] - Oracle VM VirtualBox window is open. By using the nano command, the presenter opens the accounts.pp file in the window. The file includes the following code snippet:
class accounts ($name){
if $: :operatingsystem == 'centos' {
$groups = 'Centos Folks'
elseif $: :operatingsystem == 'debian' {
$groups = 'Debian Folks'
}
else{
fail("This module does not support ${: :operatingsystem}."}
}
Notice ("Groups for user ${name} set to ${groups}
}
Now here I have a class with some if statements in it. So we're just going to go over it briefly. I have a class called accounts. Now accounts takes a parameter which I call name. Now, in the class, I have an if else statement. And let's go over it and talk about what it does. In the if statement, I am looking at the operating system. Now it's a variable...sort of a variable. Operating system is a system variable. It's denoted by the dollar sign and the two colons and then operating system. What that means is operating system is a fact of this node, which means I could get it via facter. So here what I'm saying is I'm looking at the operating system. If it is equal to centos, I set a variable named $groups = 'Centos Folks'. Then I have an else if looking at the operating system. And, if it is equal to debian, I set a variable named $groups = 'Debian Folks' and then I have the final else. So, if it is not equal to centos or debian, I fail and I pass in the string "This module does not support" and then I put in the operating system.
And then finally, at the very end, I just put notice for user name is set to groups. So I am doing a couple of new things here. First of all, I am using branching. I'm using an if statement to branch. I am also passing a parameter into my class. And I have a couple of new functions here such as fail and notice. But the important part is the branching. Now, if you're familiar with any other language such as Java or C#, this looks fairly standard. There's nothing really new here. Now, in addition to flow of control statements, Puppet also supports looping, choose case, and switch statements. All of them look fairly standard and fall into line with other third-generation languages that you may be used to. This concludes my demonstration. Thank you so much for watching.
=====================
Operators
Learning Objective
After completing this topic, you should be able to
•use program operators in Puppet
1. Program operators in Puppet
Over the next couple of minutes or so what I am going to do is I am going to cover some operators that you can use in Puppet programming. Now this should go fairly quickly because this stuff really reads more – like a grocery list. Let's put an example of each one of these up on the overhead and on my desktop and go through them. I am assuming that all of you have some sort of procedural language, maybe not background, but at least some sort of the exposure to some procedural languages – either peer or third-generation languages, such as Java. Or maybe even a scripting language – such as Java Script that will work just fine. But anyway, we are going to go over the different operators that we can use in Puppet programming kind of quick. Here up on the overhead, I have an example of a Puppet program that has some flow of control statements and some computers and operators. So we leave that as a visual as I talk about some other operator that we can use. Now here on the desktop, I have a program with some flow of control statements – an if statement. And also I have an equality operator. Now for comparisons – we have equality, non equality, less than, greater than, we have less than or equal to, greater than or equal to. We have regex, if you are looking for data type matches, we also have Boolean operators such as an AND, an OR, or a NOT. And we can also take these and put them in algebraic order of operations, which works just fine.
The accounts.pp file is open in the vm [Running] - Oracle VM VirtualBox window. The file includes the following code snippet:
class accounts ($name){
if $: :operatingsystem == 'centos' {
$groups = 'Centos Folks'
elseif $: :operatingsystem == 'debian' {
$groups = 'Debian Folks'
}
else{
fail("This module does not support ${: :operatingsystem}."}
}
Notice ("Groups for user ${name} set to ${groups}
}
Now, insofar is arithmetic operators, we have the addition, subtraction, division, multiplication. We have modulus, we have left shift, we have right shift. If you are going to be doing array operations, we also have splat, concatenation, removal. If you are working with hashing, we can also do merge and remove from hash. Now as far as operations go, all of the operations that I have mentioned are very analogist to other languages and work very much in the same fashion. So, if you are familiar with how operators work, they work the same way here in Puppet. As a matter of fact, the best way is trial and error, if you know the expression to use and the operator in which to use. Give it a try. It probably will work just fine, you'll probably get it at the first or the second try.
=======================
Expressions
Learning Objective
After completing this topic, you should be able to
•identify the different expressions used in Puppet
1. How to use expressions
When managing nodes using Puppet, sometimes challenges related to the OS type are encountered. These challenges include the different operating systems that might have different facts about them. Also those challenges could be caused due to differences in package names, service names, file paths, and the likes. This is common in a Puppet environment. How will Puppet know how to distinguish the different platforms? Each platform has different characteristics that make it up. You could find these differences with expressions. Puppet supports expressions. Expressions are used the same way across all operating systems. Expressions are the combination of values, variable operators, and functions. They are interpreted according to rules and produce a value. Rules are the same, and the functionality is abstracted from the user as the underlying functionality is different on different platforms. Using expressions, we can tell Puppet how to treat resources that are handled differently on each operating system even without knowing what the differences are. There is usually more than one way to solve differences using expressions. Usage is defined by you. Expressions ease the process of managing multiplatform environments. There are a few types of expressions supported by Puppet.
Heading: Expressions.
Conditional expressions – divided into two types. Conditionals, which return a value and selectors. A selector is a series of enumerated values. A single value is then taken from that list. There are also standard facts. This is a fact about the current node that Puppet agent is running on. The program facter is used to obtain standard facts. A standard fact is used as an expression in this code example below. Operating system is a standard fact. The name attribute will be selected depending on the operating system. Other facts can be obtained by facter and used as an expression anywhere within Puppet. There are other ways to get values to use as expressions. To see a list of standard facts about the current node, use the facter program. The value returned by a selector can be assigned into a variable. Selectors are a series of correct values to pick from. One is selected and placed into a variable. The second type of conditional expressions alters logic flow. There are flow of control coding structures or looping coding statements. There are many of these that make up the Puppet coding syntax. Case statements are often used when you have many variables to set. Case statements work the same in Ruby as they do in other languages. They can be used conditionally to include a resource or resources. A case statement doesn't need to match any cases and can be used to set a default value to catch those values that may fall through for each of the tested cases.
Heading: Expressions (Continued).
If, else if, and else. These conditionals act on Boolean expressions – either true or false. These flow of control statements are pretty standard. The only thing noteworthy here is that Puppet supports them. Boolean expressions – such as AND, OR, and NOT – are also supported by Puppet and work as advertised. Puppet also supports comparison expressions and arithmetic expressions. These are also supported expressions and work predictably here as well. Expressions can be put in parenthesis to enforce an algebraic order of operations.
Heading: Expressions (Continued).
=======================
Variables
Learning Objective
After completing this topic, you should be able to
•use variables in Puppet
1. How to use variables
In this demonstration, I am going to show you how you can use variables in your Puppet code. So I have some stuff that's prewritten for us just so we could go a little bit quicker and so you don't have to watch me actually code this stuff line by line. What I have here is a built of manifest called init.pp. And what this manifest does is the following. Let me open this up in nano. And I wrote this while you were not looking. So you don't have to watch me actually code this. So I'll kind of explain this. What this is, is this is a class that I wrote that's going to build two HTML files. Basically, it's going to build an HTML file that has the English language. And it's going to build an HTML file that is in the French language. And this is how it works. I have here a variable called doc_root. Now we denote variables in Puppet by the dollar sign. So we have $doc_root. We have three variables that we're defining here in this web class. We have doc_root, we have English, and we have French. Now doc_root is assigned to a string /var/www/html/questguide/, which just so happens to be the home HTML folder. Now, for English, I have Hello World with an exclamation point. And, for French – and I'm not quite sure how this is pronounced – but Bonjour le monde. Actually I think that is hello world again in French.
The vm [Running] - Oracle VM VirtualBox window is open. By using the nano command, the presenter opens the init.pp file in the window. The file includes the following code snippet:
Class web {
$doc_root = ' /var/www/html/questquide'
$english = 'Hello world!'
$french ='Benjour le mode!'
file { "${doc_root}hello.html"}
ensure => 'present',
content => "&{english}",
}
file {"${doc_root}bonjour.html":
ensure => 'present',
content => "${french}",
}
}
Now, underneath this, I have two file resources. The first file resource builds an HTML page called hello.html. And before it, I have doc_root prefixing it. So we have var/www/html/questguide, hello.html. I have "ensure => 'present'." And then the content is English. So we are going to have Hello World in English in HTML. It's also building a second file called bonjour.html. And prefixing bonjour.html, I am putting in doc_root. So basically, it's going to create this HTML file in the same place it's creating the Hello World HTML file. So this class is using variables – doc_root, English, and French – in the file declaration where we are actually building a file – hello.html and bonjour.html. If you look at the content for their French page, it's indeed in French. So this is what this class does. So let me exit. And I will not say when it changes. We can run the parser to see if this syntax is okay. So here we go – puppet parser validate web/manifests/init.pp.
The presenter presses the carrot key and X key to exit from the file. Then he executes the "puppet parser validate web/manifest/init.pp" command to validate the code.
And I get nothing coming back to me, which means that it's correct as far as the syntax goes. Now let's run it through a dry run. So we'll run it through a dry run and it looks okay. Now let's do a puppet apply. And it looks like we are okay. Alright, so we applied that class. Now let's see if this works. I am going to open up a web browser and see what our homepages look like. So let me open up Firefox and I pasted in our URL for our machine and the HTML page – bonjour. So there we go. I know it's a little small but it's only two pages we are going to look at. So there is our French page. And here is our English page. So what we did is we used variables in our class to pass three variables to our resources to build two HTML pages. And all looks like it's running fine.
Now the presenter executes the "puppet apply --noop web/manifests/init.pp" command to run the init.pp file. The file compiled successfully. Then he opens the Firefox and pastes the "192.168.1.232/bonjour.html" path in the address bar. The path pasted in the address bar displays a message, "Bonjour le monde!" Next he opens the "192.168.1.232/hello.html" page in the browser. This page returns a message, "Hello World!"
========================
Expression Substitution
Learning Objective
After completing this topic, you should be able to
•recognize how to substitute expressions
1. How to substitute expressions
Expression substitution has many powerful features to handle text. Substitution is common in other languages and indeed is used in Puppet.
Text and string manipulation is the most common type in Puppet, meaning text manipulation, search and replace within strings, or extracting
patterns from strings. The parse strings and expression substitution method is needed. Puppet has a built-in function, which can do just that.
This function will substitute one string for another. The operation is carried out using regular expressions. regex is a pattern that can match
some sets of strings and optionally capture parts of those strings for further use. Regsub string performs regexp replacement on a string or on
an array of strings and accepts some arguments. Target – the string or array of strings to operate on. This target is usually the source string
to perform action on. The regular expression – this is the regular expression matching the target string. This is usually the string to be searched
for and replaced. Next we have the replacement – this is the string that will be used for the replacement. Next there is encoding. This is optional
and this handles multibyte characters. Encoding is important when using languages other than English. These languages are often stored in Unicode format.
Heading: Expression Substitution.
The last parameter is Flag. The Flag, which is optional, is a string of letter value flags for how our regular expression is interpreted. The expression can be interpreted in many different ways. The flags can come in handy in some cases, which are as follows. First it ignores case sensitivity in regular expressions. Also, the replacement of all matches of the regular expression in each target string are handled different depending on the flag setting. In multiline regular expressions, characters are matched across multiple lines. There are other expressions that can be substituted. Once you get the recipe on how one works, you can apply those rules for other substitutions as well. Puppet's regular substitution is used to manipulate text and search and replace expressions within strings. Said another way, the function replaces a string within a string. Useful implementation can be used to augment system string used in Puppet. It can also be used to extract patterns from strings. Extracted strings can be passed to other Puppet objects. Puppet's regular substitution is basically one of many Puppet string functions. The function takes three arguments. Source – the string to be parsed. Pattern – the pattern to be searched. Replacement – the replacement string for the source. Again a simple recipe, but a good example, on how strings can be substituted.
Heading: Expression Substitution (Continued).
The pattern function can be any regular expression using the same Ruby syntax as in regular expressions. Ruby expressions are evaluated the same way as expressions are read and substituted in procedural languages. Expression substitution is common when – data that must be cleaned for logging purposes, custom notifications may require data to be in a specific format, certain output from Puppet needs to be obscured. Most of the time, when substituting expressions using string functions, the output is usually programmatic and usually system related. Substituting expressions is a common practice when extending the functionality of Puppet programming.
Heading: Expression Substitution (Continued).
===============
Collections
Learning Objective
After completing this topic, you should be able to
•describe the different kinds of collections
1. Types of collections
Collections are used by Puppet. If you are familiar with other languages, you may have already used collections. They are code constructs in Puppet code and used in Ruby in general. They are also used to hold data structures. Data structures can be simple such as a string array, or they can be infinitely more complex. They are limited implementation only by the knowledge of the developer. Data structures are standard and custom. Custom data structures can be defined by the Puppet developer. Custom structures can hold other data structures. These complex structures are held in collections. Collections can be on physical or virtual servers. Since they are held in the code, there is no platform or architectural issues on how they are used. Arrays can hold hundreds or even thousands of configuration rules. Arrays and other data types are commonly used to hold Puppet node facts and pass them as parameters. Arrays are only one form of collections that hold configuration management rules. Since all this configuration is in code, it can be saved. Custom collections are stored as code in a code repository. The repository can be used to reconstruct collection configuration for the entire business. This is a great example of why we consider infrastructure as code.
Heading: Collections.
Binary Trees encapsulate server provisioning and configuration tasks. They can be assigned to hold server startup data as well as messages written by the code. Information can also be stored as value pairs. Value pairs greatly reduce the complexity. Pairs can be ordered and grouped easily. Value pair collections are easy to work with and to pass off to other applications for storing or reporting. Value hashes are also collections. Hash tables reduce the complexity as the configuration process is standardized and repeatable. Collections containing node facts can be boxed. Boxing collections reduces the complexity of provisioning servers. All of this data can then be placed in arrays. Arrays of files can then be stored in version control. Puppet uses collections to generate configurations on nodes. Collections can contain many subtypes such as multidimensional arrays. In Puppet, multidimensional arrays are collections of resources. These resources are declared in manifests, which in turn can be stored as different collections. All Puppet code can be organized into collections. Variables or arrays of them can contain resources, files, templates, and other Puppet objects. Structures can be used in a reference language. Structures are collections that can hold a single variable as well as more complex types. Collections exist on other popular languages such as Java and are in Ruby in Puppet systems. Ruby arrays and collections are also used in procedural and reference languages.
Heading: Collections (Continued).
Collections can be standard or custom. Standard collections are out of the box. And custom collections can be implemented by the developer or even obtained in third-party Puppet modules. How they are used is really an implementation issue rather than a design one. Collection configuration is traditionally performed by operations, although developers traditionally have had more experience working with collections and data structures. Configuring new collections may be a slow process for those that have not used them. Arrays allow developers to perform traditional collection tasks. Developers can now use tools like Puppet to configure their own variables and custom collections.
Heading: Collections (Continued).
==============================
Types of Puppet Reports and Summaries
Learning Objective
After completing this topic, you should be able to
•work with different kinds of Puppet Reports
1. Puppet Reports
Puppet reports give you visibility into your infrastructure and collect node reports. All data is logged to PuppetDB where it is stored for Puppet or other third-party tools. Puppet Enterprise provides node hardware and software inventory. This provides an at-a-glance view of your Puppet infrastructure. Puppet Enterprise displays node configuration graphs via the console or third-party APIs. Except for graphing, third-party tools offer the most robust way to collect and report Puppet activity. Puppet Enterprise allows the ability to view runtime reports from each agent. These runtime reports show resource changes across all nodes. One of the Puppet agent's responsibilities is to send reports to the master. These reports are in the form of data and are sent to the Puppet master on a regular polled basis. The master aggregates all node reports and provides an overview of the infrastructure. The master makes this information available to third-party tools as well. Reports include log messages generated during the Puppet run and metrics related to what happened on that run. There are three types of metrics in each report – time, resource, and changes. Time presents how long it took to retrieve a catalog and apply it.
Heading: Types of Puppet Reports and Summaries.
Resources – how many resources are applied, skipped, failed, and so on? This is important as you may want to reapply skipped resources. Changes are also logged and changes are the total number of changes during the run. By default, the agent is configured to send reports to the master. This is done at a configurable time interval. This can also take place during every Puppet agent run. The master dumps reports as yet another markup file to the repo directory. This markup file has all the information passed from Puppet agent. Each node has a subdirectory under the repo directory where its reports are stored. Puppet allows writing custom report processors. You can write your own, or of course they are available to purchase. The most robust Puppet custom reporting systems are third party. You can use the default store report and write an external report processor that reads in and analyzes the saved Yet Another Markup Language files. This is ideal for analyzing large amounts of data. And, in most cases, there will be a ton of data to read through. The report processor can be written in any common scripting language. The formats will be different depending on the scripting language used. Follow the report formatting references for different versions.
Heading: Types of Puppet Reports and Summaries (Continued).
A large number of processors can be downloaded from Puppet Forge. There are some pretty cool reporting and graphing modules. All of course are free to use. There are processors that notify a wide variety of services often when a Puppet run fails. Most of these tools from Puppet Forge are worth investigating as it saves you the time in writing them yourself. Many have cool DevOps communication technique. They can notify through legacy tools and DevOps tools and the likes. Other processors can send notifications to cloud services or other mobile application. Another tool that lets you view Puppet reports is called theforeman.
Heading: Types of Puppet Reports and Summaries (Continued).
============================
Puppet Modes
Learning Objective
After completing this topic, you should be able to
•describe the different Puppet modes
1. Types of Puppet modes
Puppet provides many ways for debugging and logging. Since your Ruby code is never really compiled. It is important to make sure that the code is syntactically okay and runs as intended. Code can be added to your Puppet programs to assist in debugging. For example, messages can be displayed at execution time. There are simple lines of code that can print messages to the command line. Messages are used for instrumentation within the code as they can tell us what is happening. Messages can be used for logging as well. Log files are kept on the master and on the agent. Logging and log files can be used as a data source for the health of our Puppet infrastructure. Running puppetd -test will display all Puppet steps and actions. You will want to get used to running your code in test and debug mode. The puppet command is used to test the syntax of a manifest – puppet --debug --verbose test.pp. test.pp is your manifest. It is common and a good practice to run your code in test/debug mode before it is applied. The above will execute the code in test.pp without actually running it for real. Debug mode is just simulated for what would happen if the code was actually run. This technique is useful for testing small segments of code without breaking the system with misbehaving code. With –debug, you can perform any action that Puppet code can do.
Heading: Puppet Modes.
In any language, there are ways to add debugging and to print messages. Puppet is no different. Creating debug messages is common. The above code will log the following message and the value to the syslog of your master. Notify and notice are the two most common ways to display and log messages respectively. The above code will add this message and value to the syslog and the client. If you like, perform a puppetd – test on the client to view debug messages. Puppet allows the usage of arrays. Imbedding notice and notify messages within arrays is a common technique. Puppet loops using resources. The above code will log the following messages and values to the syslog of your master. The value is 7. The value is 8. The value is 9. Adding code like this adds visibility to what it might be doing. This is vital if running in debug or noop mode. Messages can be displayed at the agent console and can be logged in the Puppet master.
Heading: Puppet Modes (Continued).
You may consider replacing Shell scripts with Puppet manifest code. In this way, information can be more easily displayed at the agent command line and saved in Puppet log files. When using notice and notify, you are allowed to use variables or anything else gleaned from facter in order to make your messages more clear and concise. Here I'm getting a fact from the current node, then creating a message from my Puppet manifest code. Notice the host name is...and then I have a variable. This would generate – "The host name is bob.hendry.com," if this indeed was the host name. Facts and just about anything else can be accessed from the Puppet script.
Heading: Puppet Modes (Continued).
===========================
Printing Messages
Learning Objective
After completing this topic, you should be able to
•identify how to print messages
1. How to print messages
What I am going to show you now is I am going to show you how you can put in some simple debug messages in your Puppet code – specifically in your Puppet manifest. And this demonstration should not take too long. It's really straightforward. We should be able to get through this just in a couple of minutes. Let me open up a manifest that I already have created. So let me open up tammyh.pp. Now this is a manifest that deletes a user. Or I have user tammyh again. That is a user resource and I am removing her from Puppet. So let's put in some messages. Let's just say, I have this manifest and let's just say that this manifest is much more complex than the one you are looking at now. Or I may want to put in specific messages either to write to a log file to write a Puppet master or maybe quite simply just to echo back out to the Puppet agent and what is going on with the code. There are various ways of doing that. The simplest way is to add a notify. So let me type in the following. Let me type in notify and I will put {'Starting to delete user tammyh': or put something in that you might consider little bit more relevant. It really doesn't matter.
The vm [Running] - Oracle VM VirtualBox window is open. By using the nano command, the presenter opens the tammyh.pp file in the window. The file includes the following code snippet:
user {'tammyh':
ensure => 'absent',
}
The presenter adds the following piece of code above the user code block:
notify {'Starting to delete user tammyh':
Okay. Now, if you want to put in the path of where this specific manifest is, is you can specify withpath => true and put a comma and then a brace. notify {'Starting to delete user tammyh':. Now you can use variables in here too if you like and any other sort of programming context for concatenation or functions, whatever you might want to put in there. What notify will do is it will quite simply just echo out to the Puppet agent and what exactly is happening. So let me save this program. And let me exit. And I can run the parser if I want to take a look at if it is valid or I can do noop. But here let me just do puppet apply tammyh.pp. And there we go. We have our system instrumentation, our system messages. And then you see ours starting to delete user tammyh. Now again what notify does is notify writes out that string to the agent. Now, if we wanted to write a string to the Puppet master and actually do some logging in the Puppet master, we would use the notice function. So notice is used if we want to write to the Puppet master. And notify is used when we want to write to the Puppet agent.
The presenter adds the following line of code below the aforementioned line of code:
withpath => true,
He saves the file and exit from it. He compiles the program to show that program run successfully
============================== ==
Puppet Monitoring
Learning Objective
After completing this topic, you should be able to
•work with different methods of monitoring Puppet
1. Methods of monitoring Puppet
Puppet has a few internal ways to monitor internal functionality and execution. Puppet is engineered to be able to be accessed and monitored by third-party tools. Puppet can be monitored with Nagios. Nagios is a well-known tool established in 1996. Much of the basic functionality needed for Nagios to monitor Puppet is already built into Puppet. Nagios monitoring of Puppet is considered highly stable. Nagios configurations can be set up on Puppet master. Nagios plugins are generally simple to write – for example to create and use a database to store all of your Puppet collected resources and facts. Nagios setups are more or less easy to troubleshoot. Nagios has some significant drawbacks. Its architecture is not a direct match for Puppet. So there will be some configuration hoops. It's also a mature tool. There is stagnation in its development now. Some of its features are in need for a modern refresh. Under certain circumstances, it can be considered difficult to get set up. The default database is SQLite and has issues with concurrency. Nagios also has to be coded in a custom module within Puppet and must be configured in the Puppet master D section of the Puppet configuration file. Also, Nagios has a dated "look and feel" and uses dated methodologies such as text files. Development can be slow depending on your level of integration.
Heading: Puppet.
Icinga is an open-source networking monitoring application and is engineered from the ground up as such. It was created as a fork of Nagios in 2009. Many say Icinga is what Nagios should have been all along. Icinga was created due to the dissatisfaction built up for Nagios. Icinga has a more solid architecture than Nagios and can use the Nagios Remote Plugin Executor or the NRPE. Icinga supports additional database connectors such as Oracle, MySQL, and PostgreSQL. And Icinga servers can be configured using standard Puppet types. Icinga is known among other things for fast releases every couple of months. And Icinga can also use Puppet Nagios types. Nagios and Icinga have compatible configurations. Both can use Puppet Nagios types. Icinga can use Puppet to autoconfigure. Both monitor your Puppet infrastructure in similar ways. Icinga may have a few bells and whistles such as Icinga was created by fixing the perceived shortcomings with the Nagios. Icinga has a rich GUI and a really nice mobile GUI. Icinga can use the Nagios Remote Plugin Executor, NRPE and also more importantly, the interface in building the plugins. There may be issues however with the perceived compatibility of Icinga using the Nagios infrastructure. Nagios considers Icinga as a rogue branch and cautions users about compatibility claims.
Heading: Puppet (Continued).
The Nagios Remote Plugin Executor, the NRPE, can also be used for Puppet monitoring. This plugin allows for the remote execution of the Nagios plugin on other UNIX/Linux boxes. The NRPE runs on the client. This allows you to remotely monitor public infrastructure metrics. The plugin is secured via SSL. The NRPE can also be used to communicate with Windows using Windows agent add-ons such as NSClient++. In this way, Puppet metrics can be monitored on remote Windows systems. The plugin runs as user nobody, meaning it is not really a user on the system but it can execute commands.
Heading: Puppet (Continued).
============================== ============
Common Puppet Runtime Failures
Learning Objective
After completing this topic, you should be able to
•describe common runtime failures
1. Common runtime failures
While working with Puppet, it is likely that you will encounter runtime failures. Some runtime failures are tough to track down, most though are pretty avoidable. Since Puppet modules are constructed from many blocks of code and dependencies, many things can fail. Sometimes it's the dependency between the code that causes the failure. Sometimes bad coding techniques can lead to real-time bugs. There are a few good practices that help avoid failures, such as knowing and adhering to the package, file, service design pattern. When sticking to design and coding standards and by keeping a good coding style, many bugs can be avoided. It helps to work with an IDE for developing Puppet content. That way, syntax can be enforced. When writing your Puppet module, make sure you close all brackets. Remember that Puppet code is Ruby, and it's not compiled as it's being written. Puppet code is not really compiled at all but applied at runtime. Good coding practices are essential to the health of a runtime Puppet environment. A few tips. Finish each attribute line with a comma. Most attributes are separated by a comma, then a line feed. Also, make sure to use single quotes when needed. It's a best practice to test your code as you are coding it. Do this by creating a smoke test and creating a corresponding test manifest. A test for a class is just a manifest that declares the class and runs it.
Heading: Common Puppet Runtime Failures.
Use Puppet parser validate to check for any syntax errors. This is one of the few ways you can test your code without really running it. The Puppet parser will evaluate your code and inform you of any syntax errors. This can be considered a rudimentary compile step. Remember that your Puppet code is really just Ruby text files. And Puppet will allow you to save anything. That does not mean it is syntactically okay though. Also you can apply a smoke test – puppet apply --noop. And then put in the path to your manifest. When performing this, the syntax is exactly the same as when applying the manifest with the exception of noop, which stands for no operation. This parameter will prevent the apply from really happening – kind of a dry run. It will allow you to go back to the class to fix any issues. It's always a good idea to apply your module on a staging area first. After making sure that there are no errors, then you can apply changes and deploy the rest.
Heading: Common Puppet Runtime Failures (Continued).
Some other common issues could be related to the time/date differences between the Puppet agent and the Puppet master. To determine this, you can view the logs and reports to identify the issue. The following error is also common – failed to retrieve the current state of resource, could not retrieve information from the source. This means the file cannot be found on the Puppet master. Certificate errors also occur, such as could not request certificate, undefined method "closed?". puppetd is not run as root and doesn't have permissions to read the certificate. The following issues are common server issues. Change failed – could not find server. This means that the server name was not set to its real name. Certificate verify failed – the server certificate that states that Puppet is different from the actual one. No certificate found and waitforcert is disabled. The ssl certificate was not signed by the master. Run of Puppet configuration client already in progress. If Puppet isn't already running, delete the lock file. And also, cannot override local resource on node. This means that you have a duplicate resource definition.
Heading: Common Puppet Runtime Failures (Continued).
______________________________ ___
Exercise: Plan a Puppet Implementation
Learning Objective
After completing this topic, you should be able to
•establish a configuration management solution using Puppet
Puppet implementation configuration
Now that you've had a chance to learn more about Puppet, let's see if you can answer the following questions. In this exercise, you will describe the functionality of the Puppet master and the Puppet agent. You will identify the types of machines that can run Puppet master and Puppet agent. You will describe what is meant by the desired configuration. You will identify a few of the Puppet resources. And you will describe how resources work within manifests. Now, if you like, you can pause the video as you come up with your answers. When you are done, you can resume the video and see how they compare with what I came up with.
Welcome back. Do you have your answers? Let's see how your answers compare to mine. Now remember, there is more than one correct answer. So as long as you're basically in the ball part, you are probably doing just fine. Describe the functionality of the Puppet master and the Puppet agent. The Puppet master is a centralized server that manages a Puppet installation. The Puppet agent is each of the nodes that communicate with the Puppet master. Both terms are also used to describe the software run that provides the communications between the master and the agent. Identify the types of machines that can run Puppet master and Puppet agent. The Puppet master will only run on a Linux server. The Puppet agent runs on a variety of machines including Windows, Mac, Linux, and Unix. Describe what is meant by the desired configuration.
The desired configuration is the term that describes the rules on how a Puppet node should be configured. This is enforced by the Puppet master, which sends down manifests that contain the desired configuration for an agent and has the agent enforce the manifest. Thus enforcing the desired configuration. Identify a few Puppet resources. Three commonly used resources are the package resource, the service resource, and the file resource. Of course there are others. Describe how resources work with manifests? Resources are added to a manifest to enforce the desired configuration state for a Puppet agent. For example, a package resource may define a piece of software to install, and a service resource may specify a service to start. Each resource may specify a single piece of the configuration rules for a Puppet agent. So how did you do if your answers were close to the solutions? You did just fine. You are well on your way to learning more about Puppet.
========================== 222222222222222222222222222222 2222222==================
############################# ############################## ########################
Grouping Resources Together in a Manifesto
Learning Objective
After completing this topic, you should be able to
•identify the different methods in grouping resources within a manifest
1. Methods to group resources in a manifest
Hello everybody. Welcome to my demonstration. What I'm going to cover in this demonstration is I'm going to go into a little bit more depth about manifests and resources and how resources may be grouped within a manifest. What you see here on my desktop is you see a simple manifest. And within this manifest, I have two resources. I have a package resource, which is the first one. And I have a file resource. Now the manifest that you've been working with so far or if you've been working with actually making configuration changes on a Puppet agent, you've been working with perhaps a variety of different manifests with each of them with their own different resources within them. And what I'm going to talk about over the next couple of minutes is how those resources are evaluated, and how they're actually applied. Now one thing I want to point out about what you see here in the manifest is manifests are considered code. Now, if you're a third-generation language programmer, if you're used to writing stuff in C#, Visual Basic, .NET, PowerBuilder, Java, you look at something like this. And it does not look like it's executable to you. It looks like it's more, you know, non-executable sort of code. And in some ways you're right. Because Puppet is declarative, we don't have the situation where the stuff executes from the top and works its way down.
The Untitled file in the Notepad is open. The file contains the following commands:
package { 'openssh-server':
ensure => present,
before => File['/etc/ssh/sshd_config'],
}
file { '/etc/ssh/sshd_config' :
ensure => file,
mode => '0600',
source => 'puppet:///modules/sshd/sshd_ config',
require => Package['openssh-server'],
}
So we say in Puppet that this Puppet code or this manifest is not run. It's applied. Now with that in mind, there's some caveats with that. Generally, even though that we say that this manifest is applied, generally Puppet will apply these resources in the order that it gets them. Now again generally, it's kind of a white lie because I'm only applying the 80/20 rule where only most of the time it is true. But generally, we have an issue with resources not being applied in the correct order that maybe we would expect them to be. Now, when that is the case, we can use what are called metaparameters. A metaparameter. We have four metaparameters that we could use in Puppet. We have – before, require, notify, and subscribe. So what you see here is you see two resources. You see a package resource, and you'll also see a file resource.
Now the metaparameters are put in there to determine or to tell Puppet when the order is important when these resources are applied. Like for example, the before metaparameter means apply this resource before the target. So you see here before and then the target resource, which we have for file. So this metaparameter – before – means apply this package resource before this file resource. And here we have require. Now require means that you want to apply this resource after the target resource. And again, the target resource is right here – package. So here we have the correct order anyway. But we have metaparameters that tell Puppet explicitly which resources are going to be applied first. Now you don't see notify and you don't see subscribe here, which are the two other metaparameters. But you do see before and you do see require. Now again, we use metaparameters to tell Puppet the order in which we want our resources to be applied within our manifest. This concludes my demo. Thank you so much for watching.
============================= ============
Classes
Learning Objective
After completing this topic, you should be able to
•describe what a Puppet class is, and how it is used
1. Puppet class overview
Hello, everybody. In this demonstration, I’m gonna show you how you can use Puppet classes. And while I’m at it, I’m gonna talk a little bit more about what a Puppet class is and how it’s beneficial to us being the Puppet developers. Now, in Puppet classes are really code blocks that could be called anywhere else in our code by using class this will allows us-- the Puppet developers, to reuse Puppet code which is always a good thing and it certainly can make reading manifest a lot easier. What I have here in this example is I have a class definition and this is how I have a class formatted. Now, we have the curly braces and we have the class definition here. I call this guy Bob Class, and then for the code we have our Puppet code which really can be anything within our class. So, down here we have 2 examples of a class declaration. Now, for the class declaration, basically we have it occurring when a class is called from within a manifest.
The Untitled file in the Notepad is open. The file contains the following commands:
Here is how a class definition is formatted:
class bob_class {
...
code
...
}
include bob_class
class{'bob_class'}
node 'host2' {
class{ 'bob_class':} # use apache module
apache::vhost { 'example.com': # define vhost resource
port => '80',
docroot => '/var/www/html'
}
}
When we have a class declaration, it basically tells Puppet to evaluate code in the class and the class declaration really comes in 2 different kinds of formats. We have normal and we have resource. A normal class declaration will occur when we have the include keyword being used as a piece of the Puppet code like we have here like we have here in include Bob Class.
This will cause Puppet to look and evaluate the code in class. Here we have Bob Class. I also have a resource like declaration which occurs when the class is declared just like a resource. And here I have an example of that right below. Now, using a resource light class declaration will allow us to specify if needed some class parameters if we have some parameters that are going into the class which we could really use for anything but for the most part we could use them to overwrite any kind of default values that many class attributes might have.
Now, here below I have an example of a class that’s actually being used when we have node host 2 and here we have class Bob Class. And I supposed I could have named it something a little bit more useful. But let me change my comment while I’m talking about being useful to be somewhat useful. Notice we’re using the ruby comments here-- which is completely valid. Okay, so anyway, basically-- here what we’re doing is we’re saying import or execute the code that we have in Bob Class. It’s also important to point out though that when we have something like this with the class declaration, it’s not really an executable piece of code until we specify it down there or down here and then it becomes an executable piece of Puppet code.
So, really, classes make our life a lot easier. They make our code more reusable. We can reuse code and use it anywhere else within our Puppet program which makes it a lot more modular, a lot more shareable, a lot more scalable, a lot more easy to debug and to kind of implement within our whole Puppet programming paradigm. So, this concludes my demo. Thank you so much for watching, have a great rest of the day.
============================== ==
Modules
Learning Objective
After completing this topic, you should be able to
•recognize how Puppet uses modules
1. Puppet using modules
Hello everybody and welcome to my demo. And the demo I'm going to do for you right now is we're going to talk a little bit about what is called a Puppet module. You've used manifest probably by now and you've used resources within manifests probably by now as well. So I'm going to show you what a Puppet module is. Now basically, a definition of a Puppet module is basically a collection of manifests and data, such as files, fax, templates, and other goodies that have a specific directory structure. Now modules are pretty useful for basically organizing all your Puppet code and all of the stuff that you're going to need to actually perform a configuration on a node. Also modules allow you to split your code into multiple manifests. If you need to, what you can do is you can split your code into multiple manifests, and it's also important to point out that it's considered a Puppet best practice if you would organize your code into modules and use modules for all of your Puppet development or your Puppet, you know, when you're actually running something to enforce a configuration to actually run actual module.
So let's take a look at an example module. Now I'm going to Puppet Forge right now to actually look at an existing module that might be out there. We could kind of discuss what is in there. So let me look to see if there's any decent Oracle modules out here and let me click on Find. And we have a few. And let's see if we could find a decent one, here we go. How about Puppet module to Install Oracle Java on Linux systems? Sounds like a good module to me. Let's look at the module structure. I'm going to click on this link, look at the module. And, while we're here, you can take a look at this. It has the actual command to do the install – puppet module install and it's got the name of the module. And let's look at the zip version of this module. So I'm going to click on the download link and I'm not going to actually run this. I want us to see the file structure because the file structure is important. And I'm going to open this up in my favorite zip utility. And from here, we can look at the file structure. Let me see if I can make these icons slightly bigger. Actually, it was probably better the way it was, there we go.
So let's look at this file structure. I'm going to click on the root folder, and it has a folder indicating the name of the module. And below that, we have the manifests folder. Now, in our manifests folder, we have all of our manifests that are part of that module. Now remember, when we worked with manifest previously, we would work with the manifest and it would only have resources within it. Now, with modules, we could have multiple manifests within the module. And also we have the install folder where we have our specific manifests that are specific to the installation of this module. And let me Close this up. Now that you know the file structure, and as you can see the command to install is very straightforward – puppet module install and then the module name. Now remember, modules are considered a best practice to organize almost all of our Puppet code and our Puppet manifests. This concludes my demo. Thank you so much for watching.
============================= =
Puppet Forge
Learning Objective
After completing this topic, you should be able to
•recognize how to use Puppet Forge to create and share Puppet modules
1. Create Puppet modules using Puppet Forge
Hello everybody. Welcome to my demonstration. What I am going to demo for you over the next few minutes is I'm going to show you a pretty cool place where you can go to share Puppet modules, where the Puppet community goes to upload modules; to download modules, and to leave feedback about modules. So this is where you should be at in your Puppet career. You should be familiar with the basics of Puppet. You should be familiar with how Puppet works, where you have a master server called the Puppet master and you have nodes in which the Puppet master manages called agents. You should also know that you can build manifests and classes and resources and all that other good stuff and modules to actually perform configuration on Puppet agents to enforce the desired configuration or to get the nodes in the state of configuration that they need to be. Now, if you're already there, you're probably starting to think about writing your own Puppet modules. Indeed most of you probably are already there where you're already writing your own manifests and your own modules. So this will be a nice extension of that. The web site I'm going to show you is Puppet Forge. And you could get to it by the URL – forge.puppetlabs.com. And to repeat that – forge.puppetlabs.com. I'm sure you don't need to remember that because at this point in time, you could go to your favorite search engine and type in Puppet Forge and get this web site.
Now, if you're not a member of Puppet Forge, the first time you go to this web site, there's going to be a link that's going to ask you to set up your user ID and password. And it only takes a minute. They're not trying to sell you anything. You're not going to be put on some kind of mailing list, at least that I know of. It only takes a minute. You put in your user ID and your password and you're all set. No credit cards, no anything. Just put in your user ID and your password and you're set to go and then you log in and then you could start using all of the things that Puppet Forge has for you. Now I'm already logged in. If you could see in the upper right-hand side, there's my name and I'm already logged in. So I can show you Puppet Forge from kind of the ground up. Now there's not a lot to really go over because most of the exploration you're going to do yourself. But for example, what I'm going to do is I'm going to go into Search and I'm going to type in "oracle" and then Find. Now what Puppet Forge did is it did a search on Oracle and came up with all of the modules that have Oracle in them or are Oracle related. And here we have 35. Now let me change my Search and put in mysql. Something a little bit more open source. And I'm thinking we're going to get more search results than we do and we got 54.
So what you can do is you can actually search on different modules and look to see what modules fit that search criteria. Also, in the left-hand side here, you can see how many times it's been downloaded and you also have here a rating. Now there are a couple of different things you need to know. For example here, you see supported. This means that this is a Puppet supported or a Puppet labs supported module. Also down here, you'll see Puppet approved and you'll see the banner for Puppet labs approved as well if one is approved. Now, if it doesn't have either of them, it's probably from a user like you and I, which does not mean it's a bad thing. It just means that it's someone like you or I actually uploaded a module to actually share. Now there are some cool filters on the left-hand side. Like for example, you can filter by Operating System and by Puppet Version and Supported or Approved. Like for example, if I'm looking for Windows, Apply Filters. Let me change my Operating System to Any and change my Search to "sql server". Click on Find and there we go.
So here, we have all of the modules that match SQL server. Now we can also look by Latest release or most downloaded. And also, once you're ready to start uploading modules, you can click on Publish, which will allow you to publish your own modules and you can also click on Your Modules, which shows you all the modules that are owned and updated by you. So anyway, Puppet Forge gives you a good place where you can share modules, you can upload modules, you can download modules, and you could also search modules by functionality, by version, by operating system, and by specific technology. This concludes my demo. Thank you so much for watching.
=================
Catalog(s)
Learning Objective
After completing this topic, you should be able to
•describe how Puppet uses catalogs
1. Puppet using catalogs
The catalog is an object that represents the desired end state of a node. The catalog is defined and kept by the Puppet master. In Agent/Master communication, the agent sends its facts to the Puppet master. The master checks what modules should be applied to the agent. First the master makes sure the request is genuine. The Puppet master compiles those modules together with the facts. In the last step, the master sends the agent a document called the catalog – specifying how it should be configured. The agent node then reads and caches the catalogs enforcing its policy. Agents never see the manifests and modules that comprise a configuration. This information is only known to the Puppet master. The Puppet master is the ultimate authority as far as agent configuration is concerned. A catalog can contain many things. A catalog contains resources and relationships. You can also test catalogs with no detriment on the agent.
Puppet can simulate applying a catalog and reports what will be changed known as NOOP. Each node's most recent catalog is stored in PuppetDB. A history of catalogs is also stored here. PuppetDB can be queried for information about managed resources. Since the master compiles the catalog, each node has no knowledge about the other nodes. This is an important point, as all agents don't even know about each other's existence. This also reduces resource utilization on the node, CPU, memory, and so on since agents have no communication with each other, or whatsoever. There are ways though for the agents to know the contents of its catalog. The "puppet apply" command makes the agent compile its own catalog. When this occurs, it makes the node act as both the Puppet master and the agent since it also applies the policy of the catalog after it compiles it.
So then how was a catalog created? We have covered that a catalog is used to enforce the desired configuration on an agent. But how was it made? The master compiles a catalog using three sources of information. First the agent communicates to the master agent-provided data – node name, certificates, facts, and environment. The next step is to include external data – classes to apply, node environment, ENC data, PuppetDB data, et cetera. The last things to be included are Puppet manifests and templates – main manifests, puppet forge modules, modules written for your site, and so on. All of these are compiled into a catalog. So now what? We have our catalog. This brings us to the last steps. What happens when a catalog request is received? First the agent retrieves the node object. The agent reads the node object, then sets the variables from the node object from the facts and from the certificate. Next agent evaluates the main manifest and then loads and evaluates classes from the modules. Finally, after Puppet has finished evaluating the main manifest, Puppet will then evaluate and load any classes from the node object. Any resources from these classes will be added to the catalog. There are other things that happen here, of course, but we've covered the main points.
Table of Contents
===========================
Exercise: Define a Puppet Implementation Strategy
Learning Objective
After completing this topic, you should be able to
•define prerequirements for a Puppet installation on a local machine
Puppet installation on a local machine
Now that you have had a chance to learn about Puppet, let's see if you can answer some questions about configuring Puppet on a local machine. In this exercise, you will describe what types of operating systems support Puppet, identify what is a Puppet agent, describe how nodes communicate with the Puppet master, identify the role of Puppet forge in node configuration, describe how a Puppet master knows about an individual node's configuration. If you would like you can pause the video while you are coming up with your answers. When you are done, you could resume the video and see the answers that I came up with.
Welcome back. Do you have your answers? Let's compare your answers to what I came up with. Now remember, there is more than one answer. So, if your answer is slightly different than mine, you are probably okay. Describe what types of operating systems support Puppet? Puppet Enterprise can run on almost every major operating system or distribution. The Puppet master, though, can only be run on a Linux server. Identify what is a Puppet agent? A Puppet agent is a piece of client software that runs on each node managed by the Puppet master. Nodes can be of various operating systems. Describe how nodes communicate with a Puppet master?
Puppet nodes communicate with a Puppet master through scheduled communication intervals. These intervals are configurable by you. Identify the role of Puppet forge in node configuration. Puppet forge has many different modules that you can use to configure your nodes. Many of the modules are approved and even supported by Puppet Labs. Describe how a Puppet master knows about an individual node's configuration? The Puppet agent that runs on a node sends facts about itself to the Puppet master. These facts tell the Puppet master everything it needs to know about the node that it is managing. So how did you do? Were your answers close to mine? Now remember, there is more than one correct answer to any of these questions. So as long as you have the general idea of how Puppet works, you are well on your way to learning Puppet.
============================= ====
No comments:
Post a Comment