The first awesome tool I want to dig into is Vagrant. It’s a great tool for spinning up ephemeral environments on demand. Sure we have VM’s we can spin up in our favorite hypervisor, and we may be lucky enough to have a quality lab. You may be asking yourself “why do we need another tool in our tool belt?” Well, to answer that, we need to delve into having the ability to iterate quickly and fail safely. Being able to reset the environment quickly is a key to this. Let’s delve into our current testing methodologies to see why we need Vagrant.
Most of our testing involves grabbing an older box we life cycled out, or a smaller box we snuck on to a large order. We drop the box into a lab environment and throw a config on it. Hopefully the lab resembles production in design and complexity, though scale is not necessary. While testing out some new idea or harebrained requirement you get handed it’s great! It’s easy to mockup what you need, then roll it forward or back. What about six months from now? Will you remember that wacky, and more importantly, very dysfunctional, 0/0 you had as a weighted static hiding beneath BGP originating a much more sane 0/0? Perhaps you and a coworker need to test opposing configurations. Don’t get me wrong, Labs are great, and everyone should have one. I just want to get you thinking about gaps.
In our journey to put things into a “X as code”, what if we had “Testing Environment as code.” This isn’t trying to shoe horn a trend into testing, X as code isn’t a fashion trend, Its a better way to do things. It makes thing s reproducible, document, an audible. By having a testing environment available as code, you can tear it down, stand it back up as known good, and try something out again. If the last iteration went horribly wrong, like “trashed the environment and caused you to raise Frankenstein’s Monster” horribly wrong, no harm. Just blow it away and rebuild with our testing as code tools. The village is still safe.
Enter Vagrant. Vagrant fills our Test Environment as Code requirements. You define what your environment looks like, and more importantly how to build it. This is accomplished by using Ruby in a plain text file that you can keep in Git, or pass it around like a Stargate SG-1 dvd boxed set.
As we do our demo, I like to pair up Vagrant with Virtual Box. Virtual box is a virtualization tool that is a free and open source virtualization tool, the can be managed all via the CLI.
Installing the pair is simple. On linux, we can use our native package manager to
dnf/yum/apt install vagrant Virtualbox. On MacOS, I would recommend using the package manager Homebrew to install them. You could go the Windows path and download the installers and roll that way. On windows… I’m clueless to the state of package managers, but the old school download and install works. So lets get started.
First lets make a directory and initialize our environment with following commands
mkdir vagrant-test cd vagrant-test vagrant init geerlingguy/centos8 ls
You should notice a new file, Vagrantfile. If we were to look at it, we’ll see a lot of commented out lines, but when we distill it down, this is the guts.
Vagrant.configure("2") do |config| config.vm.box = "geerlingguy/centos8" end
To bring it up, all we need to do is run
vagrant up and get a tasty cup of coffee™… Because coffee is life…. And vagrant will need some time to download image, copy into the .vagrant directory in
vagrant-test/, boot it up , and even set up ssh keys for you. The first time you pull down a box, there’sa few minutes required To get it from the internet. To connect to our new vm, just give it a
vagrant ssh and try things, like . When its time to blow it away,
vagrant destroy then
vagrant up at your leisure. ssh back in, and note you’re back to step one. I’m lazy, and like to one liner it with
vagrant destroy -f && vagrant up. If you’re thinking ok neat, but where the value in this since I’ll have to set this up the same way every time.
Have no fear, vagrant has a concept of provisioning. it lets you add steps to configure it when its done. Lets add a line to install sensible and git in our vm. Provisioning can be simple shell lines, or as complex as an ansible play or powershell script.
Vagrant.configure("2") do |config| config.vm.box = "geerlingguy/centos8" config.vm.provision "shell", inline: "sudo yum -y install ansible git" end
We can do one of two things, we can either
vagrant destroy -f && vagrant up, or we can
vagrant provision. Calling vagrant with the provision option, will just run the provisioning steps in your vagrant file. if you are testing a play, this is a great way to re-run your play.
Lets talk about boxes and where they come from. Boxes are vm templates. built by any number of people and organizations. Hashicorp, the company behind Vagrant, maintains a directory of Boxes here. How trust worthy are they? The answer is our favorite engineering answer… “it depends.” The various Linux distributions tend to publish boxes, as well as companies line Chef. If you’re doing stuff thats not sensitive, then maybe you might want to stick to the official publishers. If its pretty sensitive, such as you have to test with real data or important secretes, maybe you want to go through the process of rolling your own box from a trusted ISO and importing it.
In a future blog post, I’ll work with a sample network topology.