Chris Bednarski

Software Engineering: Make it work. Make it right. Make it fast.

Creating a CentOS 6.2 Base Box for Vagrant 1.1

In order to use vagrant you need something called a base box. When you run vagrant up, vagrant makes a copy of your base box to use with your project.

Mitchell Hashimoto (vagrant’s author) provides an example base box based on Ubuntu, but I use CentOS at my workplace, so I’ve rolled my own base boxes. This walkthrough explains how to create a base box for Vagrant 1.1 using CentOS 6.2.

There are some automated tools you can use to do this, but I wanted to understand how all of the pieces fit together, because I feel less nervous about putting ssh keys and passwords into boxes that way, and I’m also better situated to troubleshoot when things go wrong (and they will).

However, once you’ve digested this article you might want to check out veewee and bento. At the very least, I’m sure you can improve on my process.

Installing Ruby the Correct Way

Ruby is an extremely flexible, concise language which boasts a rampant proliferation of libraries and popular frameworks like rails. However, using your system’s default ruby to install gems is a quick path into dependency nightmares, as different gems fight to use different versions of the same library.

I’ll walk you through how to avoid this using rbenv, ruby-build, and bundler. At the conclusion, you’ll have a better understanding of where ruby lives on your system and you’ll also have a stable, flexible ruby installation that can grow with new development while simultaneously providing a bulletproof runtime environment for existing applications and tools.

Understanding Environment Variables and the Unix Path

When I was new to Mac and Linux, environment variables and the Unix PATH were mysterious and confusing. Documentation for various tools would frequently make references to “add this to your path” or “set this environment variable” and I had no idea what they meant.

Fortunately, this seemingly-magic behavior is relatively transparent once you know where to look and understand some of the basic assumptions in Unix. By the time you’re done reading you’ll be on your way to mastering environment variables.

PATH and ENV In 5 Minutes or Less

When you type the name of a program cat or grep, your shell looks in all the directories specified in your PATH to try to find a matching program. PATH itself is an environment variable (other common ones include EDITOR and JAVA_HOME). Environment variables are global variables that live in your shell session, and help your shell fill in shortcuts or specify preferences.

You can dynamically set (or change) environment variables using export, or persistently set the values in your ~/.bash_profile or ~/.bashrc file. For example, we set EDITOR to vim, then use $EDITOR to invoke vim on our .bash_profile so we can persist some other environment variables:

$ export EDITOR=vim
$ $EDITOR ~/.bash_profile
export PATH=$PATH:/something/i/need/to/add
export NEW_ENVIRONMENT_VARIABLE=value

Environment variables are read from .bash_profile at the start of the shell session, so after you save the file you’ll need open a new terminal window before the changes will take effect.

If the extremely terse example above doesn’t satisfy you, keep reading. (Also, if you got stuck in vim, press ESC type :quit! and press ENTER to exit.)

Make It Work. Make It Right. Make It Fast.

I strive to follow a simple, disciplined and pragmatic approach to software engineering, which I’ve borrowed from Kent Beck and learned through blood and sweat: Make it work. Make it right. Make it fast.

People commonly mistake this for the adage “Good, cheap, or fast. Pick any two.”, which represents the three axes of control that a product owner has to tweak delivery timelines. These two ideas are only vaguely related (in the sense that if you don’t Make it Right, Work, and Fast, you’ll choose none from the preceeding selection). But the relation stops there.

Make it Work > Right > Fast is not a choice. It’s the order in which you do things.

Linux Login Using SSH Keys

Using SSH keys to login to a server provides a convenient alternative to typing your password each time. SSH key-based authentication also allows scripts to run unattended without leaving your password in plain text. And it does your laundry. Well, alright, maybe not that last one.

Once you have ssh auth setup, you can use commands like ssh, scp, sftp, and rsync without having to enter a password. Handy!

SSH Keys in 5 Minutes or Less

If you’re lazy or adventurous and prefer to skip the details, you can follow these instructions:

Generate a key if you don’t have one already, pressing enter at all the prompts:

$ ssh-keygen

Set permissions on your private key and upload your public key to the server:

$ chmod 400 ~/.ssh/id_rsa*
$ scp ~/.ssh/id_rsa.pub username@example.com:~/id_rsa.pub

Login to the remote server to create the .ssh folder, create the authorized keys file and set permissions:

$ ssh username@example.com
username@example.com's password: <enter password>
$ mkdir ~/.ssh/
$ cat id_rsa.pub >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
$ rm id_rsa.pub
$ exit

Now when you login via ssh, it should use your ssh key instead of prompting you for a password.

SSH Keys in Slightly More than 5 Minutes

If you got stuck in the <5 minutes version, would like to know a bit more about what just happened (or what you’re about to do), or want to learn about some advanced use cases, read on.