Introducing generate-puppetfile, or Creating a ruby program to update your Puppetfile and .fixtures.yml

About a month ago, I whipped up simple shell script that would download some puppet modules and then generate a valid snippet of code you could insert into your Puppetfile. This was helpful when you wanted to add a single module but it had dependencies, and then those dependencies had dependencies, and then 30 minutes go by and you have no idea what it was you set out to do in the beginning. As I started using it, I realized this was only half the battle – I might already have some of those dependencies in my Puppetfile and adding the same modules again doesn’t work.

So I started adding to the script and quickly realized a shell script was not sufficient. About three weeks ago, I decided to convert it to a ruby program and add cli arguments to support all the new features I wanted and that some users were requesting. I had a few problems I knew I needed to solve, namely how to parse an existing Puppetfile and pull out the existing forge modules, how to combine that and any non-forge module data with the new module list and generate a new file, and how to generate a .fixtures.yml file. I also ended up with a boatload of problems that I didn’t know I needed to solve.

The first problem I had was how to get started writing a ruby program. I never did find a good guide for this. Instead, I looked at some programs that I used and how they structured things, like the program entry points and such. The two programs I drew the most from where puppet-lint and r10k. I’m still internalizing a lot of what I learned so I don’t feel confident in explaining it to others, but you might start with the lib/ directory where the module’s namespace is defined, then look at bin/ where the CLI entry point is (i.e. when you call r10k on the CLI versus require ‘r10k’ in another ruby program). I stumbled a lot here, but after a day or two had something that worked, even if it wasn’t idiomatic ruby.

The next step was learning how to create and publish a ruby gem. Rubygem’s own Make Your Own Gem tutorial was pretty helpful. It does often tell you what to do, and expect you to just do it, rather than explaining why. Regardless, there’s enough information there to create a .gemspec file, perform a gem build, and create an actual gem that you can upload with gem push.

This was a bit of a trial and I can’t say it was all that enjoyable (maybe ask me in a month or so!), but once I made it over those two humps, actually programming in ruby was pretty fun. If you’re interested in ruby, I hope this helps, and feel free to ask any questions in the comments or on twitter.

Today, I released v0.9.6 of generate-puppetfile. You can find the source on github and gem at Install it with gem install generate-puppetfile and call it with a list of modules. You can add the -f option to generate a .fixtures.yml file for use with rspec, or -p <filename> to read an existing Puppetfile (not shown):

[rnelson0@build02 ~]$ generate-puppetfile puppetlabs/apache rnelson0/certs -f

Installing modules. This may take a few minutes.

Your Puppetfile has been generated. Copy and paste between the markers:

forge ''

# Modules discovered by generate-puppetfile
mod 'puppetlabs/apache', '1.6.0'
mod 'puppetlabs/concat', '1.2.4'
mod 'puppetlabs/stdlib', '4.9.0'
mod 'rnelson0/certs', '0.6.2'

Generating .fixtures.yml using module name profile
[rnelson0@build02 ~]$ cat .fixtures.yml
    profile: "#{source_dir}"

If you’re using puppet and either librarian-puppet or r10k, you may find this useful. Report any bugs at the issue tracker, and PRs are gladly accepted!

One thought on “Introducing generate-puppetfile, or Creating a ruby program to update your Puppetfile and .fixtures.yml

  1. Pingback: 2015 Recap: How did I do? | rnelson0

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s