I’m a big fan of Vagrant. It allows me to work on on just about any platform in any language without making a mess of my host operating system and my actual development environment.
At Spry Group, I’ve been building out our continuous integration infrastructure for both our internal work and client work. I desparately wanted to be able to use Vagrant. I wanted to have one build agent for all projects without any dependency or version issues.
I had three concerns going into the setup.
- How well would the jenkins build agent handle ‘vagrant’ and virtual box?
- Would I get the right exit codes if jenkins used vagrant ssh to run the build scripts.
- Would I be able to get the package assets I needed from the shared folders.
Fortunately all of those concerns we’re unfounded.
Here is a quick overview of how we use Vagrant in our Jenkins Continuous Integration.
It is important that your vagrants themselves be completely self contained testing environments. Our vagrants come fully loaded with unit testing frameworks, selenium server, phantomjs, linting tools, and more. All of our build and testing is wrapped in shell scripts that can be easily called with no arguments for a given project.
Our vagrants are configured so that
vagrant provision will produce a white gloves fresh install of an environment pre-loaded with testing data. It is important to ensure that your vagrant provision runs quickly. We accomplish this by having base boxes which have all of our packages pre-installed and only having the provision scripts responsible for configuration.
Our build jobs run the following tasks.
- vagrant up
- vagrant provision.
- vagrant ssh scripts/tests-infrastructure.sh
- vagrant ssh scripts/tests-unit.sh
- vagrant ssh scripts/tests-integration.sh
- vagrant ssh scripts/tests-e2e.sh
For jobs that run frequently such as pull request builders for active projects we do not shutdown the vagrant on the agents so they’re always warm. For jobs that run infrequently we’ll go ahead and run vagrant halt.
Occasionally we will have a is misbehaving vagrant. To assist we’ve setup a custom build jobs in Jenkins per project with a custom workspace that matches the project workspace which accepts a vagrant command. This allows us to us to easily vagrant destroy or provision from the Jenkins interface and control access with project level permissions.
If you have any cool CI setups using vagrant we’d love to hear about it. Expect some more posts about how we’ve constructed our Development, Continuous Integration, and Continuous Deployment pipelines using Virtual Box, VeeWee, Vagrant, Ansible, and Jenkins.