Tuesday, May 31, 2016

Speaking History

Over the past couple years I've been lucky enough to present and give a few talks either at conferences or on webinars.  Here's a list along with links to the slides (if any).

Tuesday, May 10, 2016

Testing Puppet Code: Bundle, Rake and Gems. Oh My! Part 3

This is the third post in a series on testing Puppet code.  The first two posts explored why we should test code and how to use Puppet's 'puppet parser validate' and rodjek's 'puppet-lint' commands.  In this post we'll set up the Ruby framework needed to run 'puppet parser validate' and 'puppet-lint' via the Ruby gem.  The Ruby framework will also allow us to add unit tests with rspec.

A collection of Puppet code, tests, and associated templates and files is called a Puppet Module.  All of those files should be in a single directory named 'your_puppet_module'.  Your Puppet manifests should be in a directory named 'manifests'.  See the Puppet documentation for more information on Puppet module layout.  Although not required, if your Puppet code is not currently in a module format you should try to get it into a module format now.

- your_puppet_module
| - manifests
  | - init.pp
  | - another_manifest.pp

Before following the examples please install ruby and bundler on your system.

The Gemfile and Rakefile

We'll use Ruby's 'rake' command to run puppet-lint.  'rake' is a Ruby tool used to run repetitive tasks, such as tests.  'rake' uses a special file named 'Rakefile' where we configure the tasks we want to run.

The 'Rakefile' can require other Ruby gems to run the tasks we write.  We will use the Ruby dependency manager bundler to manage the Ruby gems our 'Rakefile' needs.  'bundle' uses a configuration file named a 'Gemfile'.  The 'Gemfile' lists the Ruby gems and version.

Our sample Puppet module has a 'Rakefile', 'Gemfile', and a manifests directory with a sample manifest.  The 'Gemfile' contains our two dependencies: 'puppet-lint' and 'rake'.  The 'Rakefile' requires the 'puppet-lint' gem.

Clone the sample repository and look at the 'Rakefile' and 'Gemfile'.
git clone https://github.com/mmarseglia/testing_puppet.git

Running puppet-lint

According to the 'puppet-lint' documentation all we have to do is run 'rake lint' after the module is installed.

Clone the sample repository.
git clone https://github.com/mmarseglia/testing_puppet.git
Enter the directory and checkout example1.
cd testing_puppet
git checkout example1 
Use bundler to install required Ruby gems in a directory local to our project,
bundle install --path vendor/bundle
Run the puppet-lint task on our Puppet code. We prefix the 'rake' command with 'bundle exec'.  This runs 'rake' in context of the gems we installed.
bundle exec rake lint

Congratulations!  We just ran puppet-lint as a rake task and it checked all the Puppet manifests in our project.  puppet-lint found some problems but those files aren't part of our project.  We'll need to configure puppet-lint to ignore that directory.

Checkout the tag named 'example2'.
git checkout example2
In example2 I've made two modifications to the Rakefile:
  1. Clear any previous definition of the rake task named 'lint'.
  2. Configure puppet-lint to ignore vendor directory

Run the rake task again and puppet-lint is no longer checking files in the vendor directory.

puppet-lint can be configured entirely in the 'Rakefile'.  You can still use puppet-lint's configuration file named .puppet-lint.rc when puppet-lint is called as a rake task. 

Running puppet syntax checks

Adding Puppet syntax checks to the 'Rakefile' is just as easy.  Let's look at example 3 to see the changes.

Checkout the tag named 'example3'.
git checkout example3
We need two new Ruby gems: puppet-syntax and puppet.  The puppet-syntax gem has a rake task named 'syntax' that will check our manifests and depends on the puppet gem.  The Ruby gems are added to our Gemfile.

We require the puppet-syntax gem in the 'Rakefile' to be able to run the 'syntax' task and, like puppet-lint, we'll configure it to ignore the 'vendor' directory.

Run the rake command to check our manifests for any syntax errors.  No errors!
bundle exec rake syntax 

What if we had errors in our code?  What would that look like?  I've inserted an error into example 4 so we can see what happens.

Checkout the tag named 'example4'.
git checkout example4
 Run the 'rake' command to check our manifests for any syntax errors.
bundle exec rake syntax

Puppet could not parse our manifest, init.pp, due to a missing curly brace at the end of the file.  The syntax check will tell you the line number, the file and error message.  The error message is the same if we run the 'puppet parser validate' command.

The puppet-syntax rake task will also check templates and hiera YAML files if present.  You can read the full documentation for puppet-syntax on GitHub.


In the previous blog posts I demonstrated running 'puppet-lint' and 'puppet parser validate' on the command line.  Many shell scripts take advantage of those command line utilities and I relied heavily on scripts when I started.  The command line utilities may have a place in your environment but advancing to the next level of testing with rspec and beaker requires laying a foundation.

We started with our Puppet code and gathering our manifests, templates and file into something more resembling a Puppet module.  Then we install ruby and bundler in our development environment.  After bundler is installed we add the 'Gemfile' to our project to manage our Ruby gem dependencies.  Lastly we create a 'Rakefile' that defines the rake tasks we will repeatedly run to lint and syntax check our Puppet code.  Now we have a project that can be easily added to a continuous integration system and can start building a software development pipeline for our Puppet code.

Tuesday, May 3, 2016

Improving Code Quality With SonarQube and Jenkins CI

I recently had the opportunity to install/configure SonarQube with Puppet and Jenkins.  Not knowing what I was getting into I found it a little daunting at first but I love the insight SonarQube provides into the Puppet code.

SonarQube is platform for measuring and reporting code quality.  SonarQube scans the codebase for quality standards violations, aka the Developer's Seven Deadly Sins, and produces a list of issues and reports.  Although SonarQube can find syntactical errors it is more like a linter and does not replace unit testing.  SonarQube is complementary to the array of utilities software developers have at their disposal.

If you're using Puppet you can easily stand up a SonarQube server with either this or that puppet module.  I chose to fork Maestrodev's puppet module because it was tied to their wget module and caused a conflict for me.

Getting started with SonarQube is easy when integrated with Jenkins.  First install the SonarQube plugin for Jenkins.  Second, navigate to the Jenkins "Configure System" section for SonarQube.  Enter your SonarQube server information and it will be made available to jobs.

I prefer to create a service account for Jenkins to log into SonarQube and have all Jenkins jobs use it.  You could also assign developers, or a group of developers, their own SonarQube credentials.

In your job's configuration, check the box and Jenkins will automatically inject the required environment variables for the SonarQube server.

Maven projects can add sonar options as properties to the pom.xml as in this example.  Add the sonar goal and environment variables for the SonarQube server for the Maven target.

​Freestyle projects use the Execute Shell block to run sonar-scanner and a sonar-project.properties file.  The properties file specifies where the source is located, the language type, project name, and project key.  This example shows a typical properties file.  The options passed on the command line are required for connecting to the SonarQube server.

In the following example I test for a sonar-project.properties file in my project.  If that file exists then I run sonar-scanner with environment variables from the Jenkins global settings for SonarQube.
After your Jenkins job runs links are available to the SonarQube reports for each run.  You can click on the "SonarQube" link in the main menu or on the blue wavy lines for the job.  You will be taken the project report on the SonarQube server.

SonarQube by default comes with the Java plugin to scan Java code.  If you want to scan Puppet code you'll need to install the Puppet plugin via SonarQube's Update Center.  When you scan your codebase you'll get a nifty dashboard with the ability to drill down and get specific errors.

The level of effort to get the server running and integrated with Jenkins was minimal.  Not knowing anything about the platform I was able to get the server up and running in a day, and that included working on my Puppet module.  It took another 4hrs of messing around until I figured out how to get it working from Jenkins.  It's so easy to get started I highly recommend setting this up.

Monday, May 2, 2016

Testing Puppet Code, Linting Part 2

In the first post I reviewed testing Puppet code syntax.  If you are just getting starting testing Puppet code I suggest you start there and read about why we test code and how to get started with Puppet parser.  If you've already read that then let's get started!

Linting is the act of tidying up your code.  Each programming language has a certain style or way about writing.  This is just a matter of formatting spaces, tabs and newlines so that your code looks a certain way.

Linting is not related to how a program functions, whether it will compile, or anything technical.  Linting is purely a matter of style.  So why include linting in a series on testing code?  Because adhering to the language's style makes your code more readable to other programmers.  Linting is the act of testing how well your code adheres to that style and cleaning it up.

There's a nifty program for Puppet code called puppet-lint.  puppet-lint will check your Puppet code and ensure it adheres to the Puppet Style Guide.  Run this to install:

     gem install puppet-lint

Once installed run it, passing a manifest as the argument and will tell you if your code is OK.

     puppet-lint init.pp

Lets see a real example on a manifest from https://github.com/mmarseglia/puppet-sonarqube.

In the above example we can see puppet-lint has thrown some warnings and one error.  puppet-lint has full documentation explaining each error and warning in detail.  In this case it's the autoload module layout is related to the directory name not matching the module name, see http://puppet-lint.com/checks/autoloader_layout/.

We can ignore bogus errors and warnings by telling puppet-lint to turn off specific checks.

puppet-lint can also fix your poorly indented code with its handy 'fix' feature.  Here I missed an indent.

I run puppet-lint with the --fix option to fix any indentation problems.

Look back at the code and we see puppet-lint has fixed the issue for me.

Practical experience has showed me sometimes it gets confused with multiple nested hashes.  Sometimes I've wondered if the resulting linted code is easier to read or more confusing.  puppet-lint also has a thing for 80 characters in a line.  There are times when I just can't (or won't) fit a line of code into 80 characters.  I typically ignore that check every time I run puppet-lint.

puppet-lint is a great tool by turning ugly code into easily readable code.  Add it to your arsenal of tests along with "puppet parser validate" to ensure your code is top notch.  Use your best judgement when running puppet-lint.  The goal is to make your code readable in a standard format.  The style guide is just that, a guide.