Provision Your Local Machines

This is an old photo, but my home workspace looks somewhat akin to this:

Twitter Desks

As you can see, I have a lot of monitors… and three separate laptops, running Synergy to share my keyboard and mouse across all the machines.

Since I have the three machines, migrating settings and software that I had set up on one machine to another started becoming more and more painful.  To add insult to injury, Ubuntu releases a new version every six months, and when I upgrade I tend to wipe my entire partition and reinstall from scratch. Therefore I have to reinstall all my software, which is isn’t that much fun once, let alone three times over.  For a while I was keeping setting files (tmux, zsh etc) in a Dropbox folder, but that still required manual intervention when setting up a new machine, didn’t cover software installation, and there were many pieces of software that doesn’t work for.

I was already experimenting with Ansible, and it seemed like it’s simple, no nonsense approach to machine provisioning was going to be a perfect fit for automating the installation and configuration of the software on my local machines.  Since it’s SSH based, and also allows local connections, and has no need of any server or client install, it’s also exceedingly lightweight, which again, was a perfect fit for my needs.

My final result is a combination of a couple of small bash scripts, to bootstrap the process, combined with several Ansible Playbooks (which defines what to actually install and configure) to do the actual provisioning.  You can find it all up on github.

Some interesting highlights include:

  • I have an install.sh to install the base dependencies to get going when I’ve got a bare machine.
  • The up.sh is the script to run to actually provision a machine. This does a few things:
    • Updates my local forked Ansible Git repository (So I can hack on Ansible when I want)
    • Updates my local git repository with all my Ansible Playbooks, so when the provision runs, it self updates to the latest version of my configuration.
    • The actual Playbook to run comes from a .playbook file that is not stored in the git repository. This means I can easily have specific playbooks to each machine. For example, the primary.yml playbook is for my main machine, but I have a variation of the seconday.yml for my other two (at time of writing, one secondary is running Ubuntu 13.10, while the other is running 13.04)
    • Ansible has a feature called Roles that gives you the ability to group together a set of configuration for reuse, and I’ve used several roles:
      • core – The configuration to be used across all machines
      • primary – The configuration to be used on my main development machine
      • secondary – The configuration the be used on my secondary (left and right) machines
      • ubuntu_x – This is so that I can have slightly different configuration as necessary for different ubuntu versions. For example, PPA software repositories will change depending on what version of Ubuntu you are on.
      • xmonad – I wasn’t sure I wanted to use xmonad, so I did it as a separate role while I was trying it out. Maybe one day I’ll merge it into core, since I’m pretty hooked on it now.

I’ve really enjoyed having my local machine provisioning, because:

  • I can take a completely clean machine, and have it up and running and ready for me to write code on in around an hour (depending on download speeds).
  • Wiping a partition and reinstalling Ubuntu is a clean and easy process now.
  • I can set up software and/or configuration tweaks on a secondary machine, and transport it across all my machines with ease.
  • If I want to test out software installation and configurations without committing to them, it’s only a git branch away.
  • It’s really easy to clear out cruft on any machine. I’ve no need for Thunderbird, or Empathy, and when I was running Unity, I could instantly remove all those annoying Shopping Lenses.
  • I never have to go back to old blog posts to remember how I installed / fixed / configured various things. It’s a write once, fixed forever type deal.

Strangely enough, it’s many of the same benefits you get when you automate the provisioning of your servers, but applied locally. If you are new to machine provisioning, starting by provisioning your local machine is also a low risk way to get up to speed on provisioning, while giving you a lot of benefits.

Hope that has been enough to inspire you to automate more on your local machines!

 

Leave a Comment

Comments

  • Raymond Camden | November 11, 2013

    I have to ask – and I mean this politely (*grin*) – is it really worth while to wipe your machines every 6 months? I could perhaps understand that making since with older Windows machines as Windows tends to get pretty slow, but I can’t see doing that w/ OSX or Ubuntu. It just seems like a waste of time for minimal return. What am I missing?

  • Mark Mandel | November 11, 2013

    A valid question.

    It’s been many years since I used the Ubuntu upgrade path when updating versions. I probably should try it again, as way back in the day, I found it didn’t work well with the variety of hacks I had on a system to work around various bugs. Now I expect it’s become more of a habit, and is less necessary than 5 years ago.

    These days it’s kinda nice to clear out the cruft every six months, and make sure everything is just as I like it. Also I get all the new bells and whistles with new releases every six months, so that usually also gives me incentive.

    And it’s kinda fun too – “oooh, what new things will I get with this release”.

    I’ve got it down to a fine art these days too. Do a full copy of everything overnight (local and on a separate drive), then in the morning clear the partition, install Ubuntu (that can take a while, depending), and then run provisioning. I kinda enjoy it to be honest 🙂