Puppet, Mercurial and Syntax-Checking

July 15th, 2011 § 0 comments

I am a frequent user of Puppet for system administration, and have given a couple of presentations on how to use Puppet in a security-focused shop. One of the things I’ve found is that revision-control of the puppet configuration via an SCM is a huge win and helps enormously in troubleshooting issues and rolling back errors. Since a large part of Puppet’s configuration is essentially an interpreted language with a real syntax, it makes sense to enforce valid syntax, either at commit-time or push-time, particularly since Puppet’s syntax is quite irritating and prone to error. Searching around, I couldn’t find anyone who had done this with Mercurial, since apparently Git or SVN are the weapons of choice in the Puppet community. Since I work at a Mercurial shop, I adapted this script. Here’s how to make it work:

  1. Put this shell script somewhere world-executable:
    #!/bin/bash
    
    echo "Starting puppet syntax check"
    
    # Create a tempfile
    tempfile=`mktemp -t puppet_syntax`
    
    # Get a list of all modified files
    hg log -r tip --template "{files}\n" | sort | uniq > $tempfile
    
    # Walk through our list
    for line in $(< $tempfile); do
            # Check that it's actually a puppet file
            if [ `echo $line | grep -E "\.pp$"` ]
    		then
    		echo "Found puppet file $line"
    		hg cat -r tip $line | puppet --parseonly
                    if [ $? -ne 0 ]
    			then
                            rm -f $tempfile
                            echo "Puppet parse error found"
                            exit -1
                    fi
    		echo "Puppet file valid: $line"
            fi
    done
    rm -f $tempfile
    exit 0

     

  2. If you use a central repository that you keep your code in, you’ll probably want to use Mercurial’s ‘pretxnchangegroup’ hook. Put this section in the hgrc file for the repo in question; you may need to add the file in /path/to/repo/.hg if it doesn’t exist:
    [hooks]
    pretxnchangegroup = /usr/local/bin/puppet-syntax-check.sh
  3. That should be about it. Next time you push a changeset to your central repository, the script will be invoked. Note that only files that end in .pp will be syntax-checked. Your repository probably contains multiple sorts of configuration files which obviously won’t conform to the Puppet syntax. If the check fails, the central repository will roll back the transaction, and you’ll have to push a changeset which results in the ‘tip’ revision containing valid syntax.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>