You are on page 1of 25

Hands-on Lab

Building Your
First Puppet
Module
Contents Related Courses

Configure Puppet Environment 1


PPT-204 System
Configure /etc/hosts 1 Administration
Using Puppet
Configure SELinux 1

Install Puppet Enterprise 2


Related Videos
Set up the Puppet Agent Node 3

Create an NTP Module 3


Setting up a GitHub
Module Setup 3
Account
Create Manifests 5

Add to Git 10
Creating an NTP
View on Puppet Console 11 Class
Puppet Run 11

Add to Agent Node 12


Need Help?
Review 12

Linux Academy
Community

... and you can


always send in a
support ticket on
our website to talk
Lab Connection Information to an instructor!

• Labs may take up to five minutes to build


• The IP address of your server is located on the
Hands-on Lab page
• Username: linuxacademy
• Password: 123456
Building Your First Puppet Module Linux Academy

In this lab, we will build out an NTP module for our Puppet master and agent node. A params.pp file will
be used, as well as templates, and the service, file, and package resources. We will then validate our
code, push it to GitHub, create an NTP classification on the Puppet Console, and pin both our Master and
agent nodes before issuing a Puppet run.

Log in to both servers using the provided information on the Hands-on Lab page. Use sudo su - to switch
to the root user on both nodes.

Configure Puppet Environment


Configure /etc/hosts
For Puppet to run properly on our lab environment, we need to make some changes to our /etc/hosts
files by updating the loopback address to include our servers’ hostnames.

On the Puppet Master server, open /etc/hosts in your chosen editor, and add puppet.ec2.internal
to the loopback address:

127.0.0.1 puppet.ec2.internal localhost localhost.localdomain


localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.
localdomain6

Switch to the Puppet agent server. Open /etc/hosts, and add agent01.ec2.internal tot he loopback
address. We also want to associate our Puppet Master’s IP address with the internal DNS we added to its
own /etc/hosts file. Ensure you substitute <SERVER1IP> with the public IP address of your first server.

127.0.0.1 agent01.ec2.internal localhost localhost.localdomain


localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.
localdomain6
<SERVER1IP> puppet.ec2.internal

Configure SELinux
View the config file to see SELinux’s settings:

[root@puppet] cat /etc/selinux/config


# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:

-1-
Building Your First Puppet Module Linux Academy

# targeted - Targeted processes are protected,


# minimum - Modification of targeted policy. Only selected processes
are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted

Since SELinux is enabled, we need to set it to permissive before continuing:

[root@puppet] setenforce 0

Install Puppet Enterprise


cd into the puppet-enterprise-2016.2.1-el-7-x86_64/ directory. Using your preferred text
editor, create the pe.conf file:

{
“console_admin_password”: “password”,
“puppet_enterprise::puppet_master_host”: “puppet.ec2.internal”,
“pe_install::puppet_master_dnsaltnames”: [
“puppet”
“master”
]
}

Update the password with a secure password of your choosing.

Save and exit the file.

Install Puppet Enterprise. The installation file is located in the home directory of the server.

[root@puppet] ./puppet-enterprise-installer -c pe.conf

This process takes several minutes. Once finished, trigger a Puppet run:

[root@puppet] puppet agent -t

We can now use the server’s IP address to directly access the Puppet Enterprise Console. Copy the
Puppet Master’s IP address into your browser, ensuring to prepend https:// to the beginning:
https://<SERVER1PUBLICIP>

Log in using the username of admin and the password you set in the pe.conf file.

Click Nodes on the far-left menu. Go to Unsigned Certificates and copy the curl command provided
under Adding nodes to manage with Puppet Enterprise. This is the command we will use to set up our
Puppet agent.

-2-
Building Your First Puppet Module Linux Academy

Set up the Puppet Agent Node


From your terminal, ensure you are logged in as root on the second server.

Run the curl command from the Puppet Enterprise Console to install Puppet:

[root@agent01] curl -k https://puppet.ec2.internal:8140/packages/


current/ install.bash | sudo bash

This may take a few minutes to run.

Once the installation is complete, return to the Puppet Enterprise Console and refresh the Unsigned
Certificates page. Press Accept next to the agent01.ec2.internal node to sign the certificate.

Return to the agent server and execute a Puppet run:

[root@agent01] puppet agent -t

Once finished, from the Puppet Enterprise Console, click on Configuration in the far-left menu. Confirm
that the run was successful by checking that it appears under the Run status section of the overview page,
then clicking on the agent01.ec2.internal link under Node name. Select the Reports tab. Everything
should be running properly.

Create an NTP Module


Module Setup
We now want to create an NTP module. Modules are stored in /etc/puppetlabs/code/environments/
production/modules. Navigate to this directory:

[root@puppet] cd /etc/puppetlabs/puppet/code/environments/production/
modules

Use the puppet module generate command to create a new Puppet module for NTP, substituting your
own first initial and last name:

[root@puppet] puppet module generate flastname-ntp


We need to create a metadata.json file for this module. Please answer
the following questions; if the question is not applicable to this
module, feel free to leave it blank.
Puppet uses Semantic Versioning (semver.org) to version modules.
What version is this module? [0.1.0]
-->
Who wrote this module? [flastname]

-3-
Building Your First Puppet Module Linux Academy

-->
What license does this module code fall under? [Apache-2.0]
-->
How would you describe this module in a single sentence?
--> NTP Puppet module
Where is this module’s source code repository?

When you reach the Where is this module’s source code repository? prompt, do nothing.

Log in to your GitHub account and create a New repository. Set the name to puppet-ntp or another name
of your choosing. Create repository.

Copy the GitHub URL, under “Quick setup,” to your clipboard. Return to your Puppet Master and paste in
the URL to the source code prompt:

git@github.co m:<USERNAME>/puppet-ntp.git

When asked where [others can] go to learn more about this module copy and paste in
the plain URL to the GitHub repository:

Where can others go to learn more about this module?


--> https://github.com/<USERNAME>/puppet-ntp

Add /issues to the URL to state Where [others can] go to file issues about this
module:

Where can others go to file issues about this module?


--> https://github.com/<USERNAME>/puppet-ntp/issues

Continue by pressing y:

----------------------------------------
{
“name”: “flastname-ntp”,
“version”: “0.1.0”,
“author”: “flastname”,
“summary”: “NTP Puppet module”,
“license”: “Apache-2.0”,
“source”: “git@github.co m:<USERNAME>/puppet-ntp.git”,
“project_page”: “https://github.com/<USERNAME>/puppet-ntp”,
“issues_url”: “https://github.com/<USERNAME>/puppet-ntp/issues”,
“dependencies”: [
{“name”:”puppetlabs-stdlib”,”version_requirement”:”>= 1.0.0”}
],
“data_provider”: null
}
----------------------------------------
About to generate this metadata; continue? [n/Y]

-4-
Building Your First Puppet Module Linux Academy

--> y
Notice: Generating module at /etc/puppetlabs/code/environments/
production/modules/ntp...
Notice: Populating templates...
Finished; module generated in ntp.
ntp/Gemfile
ntp/Rakefile
ntp/examples
ntp/examples/init.pp
ntp/manifests
ntp/manifests/init.pp
ntp/spec
ntp/spec/classes
ntp/spec/classes/init_spec.rb
ntp/spec/spec_helper.rb
ntp/README.md
ntp/metadata.json

Create Manifests
Navigate to the manifests folder, under the ntp directory:

[root@puppet] cd ntp/manifests/

Create the params.pp, install.pp, config.pp, and service.pp files:

[root@puppet] touch params.pp install.pp config.pp service.pp

install.pp
Open the install.pp file in your chosen text editor. We want to now create our class, defining our
parameters:

class ntp::install(
String $package_name = $ntp::package_name,
String $package_ensure = $ntp::package_ensure,
) { }

Now, use the package resource to ensure that NTP is installed:

class ntp::install(
String $package_name = $ntp::package_name,
String $package_ensure = $ntp::package_ensure,
) {
package { $package_name:
ensure => $package_ensure,
}
}

-5-
Building Your First Puppet Module Linux Academy

Save and exit.

config.pp
Open the config.pp file. As before, we are first going to define our parameters:

class ntp::config(
String $config_name = $ntp::config_name,
String $config_file_mode = $ntp::config_file_mode,
Array[String] $servers = $ntp::servers,
) { }

Add the file resource to define the path of the configuration file:

class ntp::config(
String $config_name = $ntp::config_name,
String $config_file_mode = $ntp::config_file_mode,
Array[String] $servers = $ntp::servers,
) {
file { “/etc/${config_name}”:
ensure => file,
owner => 0,
group => 0,
mode => $config_file_mode,
content => template(“$module_name/ntp.conf.erb”)
}
}

Note that the $servers variable is not used in the file, because it will be used in the template.

Save and exit the file.

service.pp
Open the service.pp file, and add the class and parameters:

class ntp::service(
String $service_name = $ntp::service_name,
String $service_ensure = $ntp::service_ensure,
Boolean $service_enable = $ntp::service_enable,
Boolean $service_hasstatus = $ntp::service_hasstatus,
Boolean $service_hasrestart = $ntp::service_hasrestart,
) { }

Now, add the service resource:

class ntp::service(
String $service_name = $ntp::service_name,
String $service_ensure = $ntp::service_ensure,

-6-
Building Your First Puppet Module Linux Academy

Boolean $service_enable = $ntp::service_enable,


Boolean $service_hasstatus = $ntp::service_hasservice,
Boolean $service_hasrestart = $ntp::service_hasrestart,
) {
service { ‘ntp’:
ensure => $service_ensure,
enable => $service_enable,
name => $service_name,
hasstatus => $service_hasstatus,
hasrestart => $service_hasrestart,
}
}

Save and exit and file.

params.pp
Open the params.pp file, and add the class. We are then going to define our variables:

class ntp::params {
$package_name = ‘ntp’
$package_ensure = ‘present’
$config_name = ‘ntp.conf’
$config_file_mode = ‘0664’
$servers = [‘0.centos.pool.ntp.org’, ‘1.centos.pool.ntp.org’]
$service_ensure = ‘running’
$service_enable = true
$service_hasrestart = true
$service_hasstatus = true
$service_name = $facts[‘os’][‘family’] ? {
‘Debian’ => ‘ntp’,
default => ‘ntpd’,
}
}

Note that we use a selector for the $service_name variable.

Save and exit the file.

init.pp
Open the init.pp file and remove the commented lines, leaving only the class skeleton:

class ntp {

Add the parameters:

-7-
Building Your First Puppet Module Linux Academy

class ntp(
String $package_name = $ntp::params::package_name,
String $package_ensure = $ntp::params::package_ensure,
String $config_name = $ntp::params::config_name,
String $config_file_mode = $ntp::params::config_file_mode,
Array[String] $servers = $ntp::params::servers,
String $service_ensure = $ntp::params::service_ensure,
String $service_name = $ntp::params::service_name,
Boolean $service_enable = $ntp::params::service_enable,
Boolean $service_hasrestart = $ntp::params::service_hasrestart,
Boolean $service_hasstatus = $ntp::params::service_hasstatus,
) {
}

Now, add the class declarations:

class ntp(
String $package_name = $ntp::params::package_name,
String $package_ensure = $ntp::params::package_ensure,
String $config_name = $ntp::params::config_name,
String $config_file_mode = $ntp::params::config_file_mode,
Array[String] $servers = $ntp::params::servers,
String $service_ensure = $ntp::params::service_ensure,
String $service_name = $ntp::params::service_name,
Boolean $service_enable = $ntp::params::service_enable,
Boolean $service_hasrestart = $ntp::params::service_hasrestart,
Boolean $service_hasstatus = $ntp::params::service_hasstatus,
) inherits ::ntp::params {
class { ‘::ntp::install’: }
-> class { ‘::ntp::config’: }
~> class { ‘::ntp::service’: }
}

Save and exit.

Validate Module
Run the puppet parser validate command against each .pp file to ensure there are no errors. Make
any needed changes, should any issue arise:

[root@puppet] puppet parser validate init.pp


[root@puppet] puppet parser validate install.pp
[root@puppet] puppet parser validate config.pp
[root@puppet] puppet parser validate service.pp
[root@puppet] puppet parser validate params.pp

Create Template
Create the templates directory and change into it:

-8-
Building Your First Puppet Module Linux Academy

[root@puppet] mkdir ../templates

[root@puppet] cd ../templates

Create the ntp.conf.erb file:

# For more information about this file, see the man pages
# ntp.conf(5), ntp_acc(5), ntp_auth(5), ntp_clock(5), ntp_misc(5), ntp_
mon(5).

driftfile /var/lib/ntp/drift

# Permit time synchronization with our time source, but do not


# permit the source to query or modify the service on this system.
restrict default nomodify notrap nopeer noquery
# Permit all access over the loopback interface. This could
# be tightened as well, but to do so would effect some of
# the administrative functions.
restrict 127.0.0.1
restrict ::1

# Hosts on local network are less restricted.


#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.ht ml).
<% @servers.each do |server| -%>
<%= server %>
<% end -%>

#broadcast 192.168.1.255 autokey # broadcast server


#broadcastclient # broadcast client
#broadcast 224.0.1.1 autokey # multicast server
#multicastclient 224.0.1.1 # multicast client
#manycastserver 239.255.254.254 # manycast server
#manycastclient 239.255.254.254 autokey # manycast client

# Enable public key cryptography.


#crypto
includefile /etc/ntp/crypto/pw

# Key file containing the keys and key identifiers used when operating
# with symmetric key cryptography.
keys /etc/ntp/keys
# Specify the key identifiers which are trusted.
#trustedkey 4 8 42
# Specify the key identifier to use with the ntpdc utility.
#requestkey 8
# Specify the key identifier to use with the ntpq utility.
#controlkey 8

# Enable writing of statistics records.


#statistics clockstats cryptostats loopstats peerstats
# Disable the monitoring facility to prevent amplification attacks using

-9-
Building Your First Puppet Module Linux Academy

ntpdc
# monlist command when default restrict does not include the noquery
#flag. See
# CVE-2013-5211 for more details.
# Note: Monitoring will not be disabled with the limited restriction
#flag.
disable monitor

Notice that under the # Use public servers section we have added code to add the servers from the
array created earlier.

Save and exit the file.

Add to Git
Move back into the ntp directory:

[root@puppet] cd ..

Install Git:

[root@puppet] yum install git

Initialize the Git repository, then commit the module:

[root@puppet] git init


[root@puppet] git add .
[root@puppet] git commit -am “First commit”

Return to GitHub, and copy the provided git remote command (under “...or create a new repository on
the command line”). Use it to set the remote for the repository:

[root@puppet] git remote add origin git@github.co m:<USERNAME>/puppet-


ntp.git

Before we can push to GitHub, we have to set a deploy key associated with our repository on GitHub. First,
generate an SSH key:

[root@puppet] ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:

- 10 -
Building Your First Puppet Module Linux Academy

32:70:14:44:36:ac:90:a7:42:88:82:22:52:7f:fa:0d root@puppet.ec2.internal
The key’s randomart image is:
+--[ RSA 2048]----+
|+... B. |
|O. . . |
|* |
|. . .= |
| . E S |
| . = |
| . . |
| |
| |
+-----------------+

Copy the public key:

[root@puppet] cat ~/.ssh/id_rsa.pub


ssh-rsa <PUBLICKEY> root@puppet.ec2.internal

On GitHub, go to the Settings tab under your puppet-ntp repository. Click on Deploy keys, then Add
deploy key. Copy in the public key, give the key a title, and check off Allow write access.

Return to the server and run a git push:

[root@puppet] git push origin master

View on Puppet Console


Use the Puppet Console (found at https://<PUBLICIP>) to view the class. Go to Nodes, then
Classification. Click on Add group... and set the Group name to NTP. Add. Click on the newly-created
NTP group.

Under the Classes tab, search for ntp, then press Add class. You may need to refresh the page. At the
bottom of the page, lick Commit 1 Change.

Go to the Rules tab and, under Pin specific nodes to group, add the puppet.ec2.internal node. Commit 1
Change.

Puppet Run
Return to the Puppet Master server and preform a Puppet run:

[root@puppet] puppet agent -t

- 11 -
Building Your First Puppet Module Linux Academy

Add to Agent Node


To add to the agent node, return to the Puppet Console and return to Classification > NTP > Rules. Pin the
agent01.ec2.internal node as we did with the Puppet Master. Return to the agent node and issue a puppet
run:

[root@agent01] puppet agent -t

Review
We have now set up Puppet, created and validated an NTP module, and run it against both of our nodes.
With these skills, we can go on to experiment with more complex Puppet modules and otherwise further
practice with the Puppet DSL.

This lab is now complete!

- 12 -
Building Your First Puppet Module Linux Academy

- 13 -
Building Your First Puppet Module Linux Academy

- 14 -
Building Your First Puppet Module Linux Academy

- 15 -
Building Your First Puppet Module Linux Academy

- 16 -
Building Your First Puppet Module Linux Academy

- 17 -
Building Your First Puppet Module Linux Academy

- 18 -
Building Your First Puppet Module Linux Academy

- 19 -
Building Your First Puppet Module Linux Academy

- 20 -
Building Your First Puppet Module Linux Academy

- 21 -
Building Your First Puppet Module Linux Academy

- 22 -
Building Your First Puppet Module Linux Academy

- 23 -

You might also like