Thoughtbot has an excellent and much desired article on getting Docker + Rspec + Serverspec wired up but I couldn’t find anything about images generated from Packer. Packer generates its own images and so we can’t just build_from_dir(.)
. Our images are already built at that point. We’re using Packer to run Chef and other things beyond what vanilla Docker can do.
The fix is really simple after I was poking around in pry looking at the serverspec API.
First of all, what am I even talking about? Serverspec is like rspec for your server. It has matchers and objects like
So although we have application tests of varying styles and application monitors, serverspec allows us to test our server just like an integration test before we deploy. I had previously tried to go down this route with test kitchen to test our chef recipes but it was sort of picky about paths. Additionally, going with serverspec and docker doesn’t even require Chef. Chef has already been run at this point! What this means is fast tests. Just booting a docker image and running a command is fast.
Nice!
So how does this work? Well, like I said the thoughtbot article is really good but I wanted to add to the
‘net about packer specifcally. The critical piece to make Serverspec work with a Docker image
created from Packer is in your spec itself (spec/yer_image_name/yer_image_name_spec.rb
).
See that image = Docker::Image.get("yer_package_image")
bit in the before block? This
is the difference between build my image (what the thoughtbot article uses)
and run an existing image. Since packer builds the image, we can just reuse
the one we have from our local store. Then later :docker_image, image.id
sets
the image to use during the test. It knows about docker because of require "docker"
from
serverspec. I’ll mention what versions of these gems I’m using at the time of this post
since this might bit-rot.
An idea that didn’t work
Ok this is cool! How about we have packer run our tests after the
packer build
. Unfortunately this is mostly useless. :( The tests will run but
they won’t do anything if the tests fail.
Here’s the post-processor bit of our packer config. It just tells Packer to do things after it’s done building. The first bit is tag our image so we can push it out to our registry.
The path structure is arbitrary above. We have a project we’re currently
working on that I’ll explain in another blog post or talk. The only specifics
about this file structure is that typically you’d want to do something like
require 'spec_helper'
but if you are building an image from a subdirectory
and then running tests from another nested subdirectory then you’ll need to
require_relative 'spec_helper'
. I actually don’t know why this isn’t the
default anyway.
But like I said, running tests with Packer as a post processor doesn’t do anything. You could run it with PACKER_DEBUG or something but I don’t like any of that. I’ll be following up with a more complete workflow as we figure this out. So you don’t need to do this last bit with the post-processors. I just wanted to leave a breadcrumb for myself later.