Skip to main content

Getting Started with Puppet Modules

Hands-On Lab

 

Photo of Elle Krout

Elle Krout

Content Team Lead in Content

Length

00:45:00

Difficulty

Beginner

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.

What are Hands-On Labs?

Hands-On Labs are scenario-based learning environments where learners can practice without consequences. Don't compromise a system or waste money on expensive downloads. Practice real-world skills without the real-world risk, no assembly required.

Getting Started with Puppet Modules

Introduction

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.

Solution

  1. Begin by logging in to the lab server using the credentials provided on the hands-on lab page:

    ssh cloud_user@PUBLIC_IP_ADDRESS

Create an Installation Class

  1. Generate the mysql module:

    $ cd /etc/puppetlabs/code/environments/production/modules
    $ sudo pdk new module mysql
    • Puppet Forge username: clouduser
    • Who wrote this module?: Enter your name at the prompt
    • What license does this module code fall under?: Apache-2.0
    • What operating systems does this module support?: RedHat based Linux, Debian based Linux
    • Metadata will be generated based on this information: Yes
  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

    Exit the file.

  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:

    $ sudo puppet parser validate manifests/config.pp
    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

    > Note: It may not show it, but this command will prompt for a password.

  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:

    > Note: Add the following at the bottom of the file.

    node node1.ec2.internal {
     include mysql
    }

    Save and exit.

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

    $ sudo puppet agent -t

Conclusion

Congratulations — you've completed this hands-on lab!