Getting Started with Puppet Modules

45 minutes
  • 4 Learning Objectives

About this Hands-on Lab

In this hands-on lab, we’ll be focusing on learning and using the basic components of a Puppet module. A module in Puppet is a collection of Puppet code that helps us configure an end state — specifically, we’re going to be creating a basic module that installs, configures, and starts the MySQL service.

As we create this module, we’ll learn about manifests, classes, class definitions, resource types and definitions, and the syntax used to create simple Puppet code. Once finished, the student will have an understanding of the core components of a Puppet class, and can start exploring more advanced features, such as templating, including Hiera, and creating parameters.

Learning Objectives

Successfully complete this lab by achieving the following learning objectives:

Create an installation class
  1. Generate the mysql module:

    $ cd /etc/puppetlabs/code/environments/production/modules
    $ sudo pdk new module mysql

    Name the module mysql and use your own information when prompted for a Puppet Forge account and module author. Note that if you do not have a Puppet Forge account, you can leave that option as-is. Leave the licensing with the default information, and set the operating system to RedHat- and Debian-based Linux. Generate the metadata.

  2. Generate the open the install.pp manifest:

    $ cd mysql
    $ sudo pdk new class install
    $ sudo vim manifests/install.pp
  3. Review the class declaration — this provides Puppet with a unique name reference for the class we’re creating:

    class mysql::install {
    }
  4. Set the resource type with a resource name:

    class mysql::install {
     package { 'mysql-server-5.7':
     }
    }

    We’re using the package resource because we are installing and otherwise managing a package. mysql-server-5.7 is the package name, which can also be supplied in the body of the resource declaration with the name attribute.

  5. Speaking of attributes, let’s ensure we’re actually downloading the package by supplying the ensure attribute. Attributes are ways of detailing the specifics of our resource. In this case, we just have to state that we want the package installed with the present value:

    class mysql::install {
     package { 'mysql-server-5.7':
       ensure => 'present',
     }
    }
  6. Save and exit. We can now check for syntax errors with:

    $ sudo puppet parser validate manifests/install.pp

    If no data is returned, then we’re structurally sound.

Create a configuration class
  1. Create a configuration class:

    $ sudo pdk new class config
    $ sudo vim manifests/config.pp
  2. Download the MySQL configuration file and add it to the files directory under the mysql module. This is where all static files are stored.

    $ sudo curl https://raw.githubusercontent.com/linuxacademy/content-ppt206-extra/master/mysql.cnf -o files/mysqld.cnf
  3. Update the file to note it is being managed by Puppet:

    $ sudo vim files/mysqld.cnf
    
    # This file is managed by Puppet
    #
  4. Open the config manifest and set the resource type. We’re going to use the file resource type:

    $ sudo vim manifests/config.pp
    
    class mysql::config {
     file { '/etc/mysql/mysql.conf.d/mysqld.cnf':
       ensure => 'file'
     }
    }
  5. Set the associated attributes. We specifically want to include the file mode, owner, group, and file source:

    class mysql::config {
     file { '/etc/mysql/mysql.conf.d/mysqld.cnf':
       ensure => 'file',
       source => "puppet:///modules/mysql/mysqld.cnf",
       mode   => '0644',
       owner  => 'root',
       group  => 'root',
     }
    }

    Notice how source lets us use a Puppet URI to reference the location of the file on our master in shorthand. puppet:/// references the environment we’re in. We can also leave out the files directory reference.

    Save and exit the file.

  6. Check the file’s syntax with the Puppet parser:

    $ sudo puppet parser validate manifests/config.pp
Create a service class
  1. Finally, we want to make sure the mysqld service is started, enabled to start at boot, and is set to restart whenever there are changes made to our config file. Let’s first create the manifest and define our resource type:

    $ sudo pdk new class service
    $ sudo vim manifests/service.pp
    
    class mysql::service {
     service { 'mysql':
     }
    }
  2. Next, we want to supply our attributes. The ensure and enable attributes are fairly self-explanatory:

    class mysql::service {
     service { 'mysql':
       ensure => 'running',
       enable => 'true',
     }
    }

    However, we also want to assign it the hasrestart parameter, which will allow for restarts under certain circumstances:

    class mysql::service {
     service { 'mysql':
       ensure     => 'running',
       enable     => true,
       hasrestart => true,
     }
    }

    Save and exit the file.

  3. Run the Puppet parser against the service.pp manifest:

    $ sudo puppet parser validate manifests/service.pp
  4. We’re not quite done, however. We want to reopen the config class to ensure it triggers the service class to restart. To do this, we use the notify metaparameter, assigning it to the resource in our service class:

    class mysql::config {
     file { '/etc/mysql/mysql.conf.d/mysqld.cnf':
       ensure => 'file',
       source => 'puppet:///modules/mysql/mysqld.cnf',
       mode   => '0644',
       owner  => 'root',
       group  => 'root',
       notify => Service['mysql']
     }
    }

    Save and exit.

  5. We now need to tie our module together with an init.pp class. Generate the class:

    $ sudo pdk new class mysql
  6. Then use the class as a wrapper to contain our other classes:

    $ sudo vim manifests/init.pp
    
    class mysql {
    
     include mysql::install
     include mysql::config
     include mysql::service
    
    }
Test the module
  1. Log in to the Ubuntu node and bootstrap it to use Puppet:

    $ curl -k https://puppet.ec2.internal:8140/packages/current/install.bash | sudo bash
  2. Approve the node on the master:

    $ sudo puppetserver ca sign --all
  3. We now need to map our mysql module to our node1 node. First, let’s open up the main manifest — or where we perform all these mappings:

    $ sudo vim /etc/puppetlabs/code/environments/production/manifests/site.pp
  4. Next, let’s add a node definition and assign our module:

    node node1.ec2.internal {
     include mysql
    }

    Save and exit.

  5. Return to the node1 node and test the module:

    $ sudo puppet agent -t

Additional Resources

Note: Please wait a few minutes before starting the lab to made sure pdk is available.

You are a member of the DevOps team, working to create reusable code that can generate desired environments quickly and easily. As part of this process, you work with Puppet for desired state configuration, and have been tasked with making sure there is a MySQL module ready to install and configure the MySQL package across all hosts.

All infrastructure is currently hosted on Ubuntu (barring the Puppet master itself), and the Dev team wants to begin writing code in these new and consistent environments. As such, you must create a basic Ubuntu-based MySQL module that installs the package, sets Puppet up to manage the configuration file, and triggers a restart when the configuration file is updated.

When finished, bootstrap the provided Ubuntu node with:

curl -k https://puppet.ec2.internal:8140/packages/current/install.bash | sudo bash

Approve the node on the master:

sudo puppetserver ca sign --all

Then test the module with a puppet agent -t on the Ubuntu node.

The configuration file used is located at:

https://raw.githubusercontent.com/linuxacademy/content-ppt206-extra/master/mysql.cnf

What are Hands-on Labs

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Sign In
Welcome Back!

Psst…this one if you’ve been moved to ACG!

Get Started
Who’s going to be learning?