December 8, 2016 · linux dotfiles

Ansible for dotfiles management

I (as many do) have a tonne of configuration files finely tuned over time. They
are all stored safely in a git repository to track changes and sync with other
computers I have an account on.

This is all very well, but it presents two major problems:

  1. Programs need to find the config files where they expect them, and that isn't
    in a subdirectory of some git repo.
  2. Not all computers are the same. I work on computers with high dpi monitors,
    low dpi, headless servers, laptops, desktops, etc.

To overcome these problems, some sort of dotfiles management software is
required. There are many options available, ranging from diy bash scripts, to
large software projects.

Dotbot

I started off using Dotbot, an
excellent tool written in python. Configuration is done with a yaml config file,
and it works by symlinking specified files from the repo to their required
locations.

It's really easy to use - simply dump all your dotfiles in the repo wherever you
want, add the dotbot repo as a git module, and create a yaml file according to its docs:

{% highlight yaml %}

  • clean: ['~']

  • link:
    ~/.vim: .vim/
    ~/.vimrc: .vimrc
    ~/.bashrc: .bashrc
    ~/.tmux.conf: .tmux.conf
    ~/.config/awesome:
    create: true
    path: .config/awesome/

  • shell:

    • [git submodule update --init --recursive, Installing submodules]
      {% endhighlight %}

To actually install them, you can run dotbot -c <configfile.yaml>.

Pros

  • simple and quick
  • only deps are git and python
  • symlinked, so you can edit your dotfiles live and they're updated in the git
    repo too (obviously you have to git add, but that's it).

Cons

  • need a separate config file for each computer if the config isn't exactly the
    same.
  • no templating system - if two computers need different dpi's set, there needs
    to be duplicate files in the repo with the changes.

Ansible

With multiple systems with different dpi's and software installed as well as
wanting to sync dotfiles on servers, I found I was wanting more features than
Dotbot could offer. After some research, and inspiration from Greg Hurrell's
dotfiles repo
, I settled on Ansible.

So Ansible is an entire "automation
platform" that is capable of far more than manage dotfiles (like using a sledge
hammer to hit a tack).

Feel free to check out my dotfiles repo
for how I'm currently managing it with ansible. Not an ansible expert, so be
warned: it's probably quite messy. (suggestions welcome!)

The basic structure is:

  • main yaml config file that includes a bunch of roles (structured
    subdirectories containing config, files, templates, etc.)
  • the roles are roughly split into categories - eg. terminal-global for
    terminal config to be installed on everything, terminal-personal for
    computers I use for my stuff, vim for, well vim, and so on.
  • each role has a main yaml file with config including what software should be
    installed, directories that should be present, files to be copied from the
    repo (including templates), and other tasks.
  • relevant files and such are also included in subdirectories of the roles.

And the workflow for installing/updating them is:

  1. make sure git and ansible are installed
  2. clone/pull the dotfiles repo to wherever
  3. cd into the repo
  4. run ansible-playbook dotfiles-install-localhost.yaml -e '<vars>', where
    <vars> are any variables you want to override the defaults - for example
    'dpi=192'.

Note that you can set per-host variables, but when running on a fresh machine
with the default 'localhost' ansible host available, they obviously won't take effect.
I'm still trying to work out a way to avoid needing to specify the variables as
args every time.

Pros

  • manage installing software and any other extra configuration
  • vault for storing sensitive info in the repo if required
  • modular for using different config on headless servers to desktops for example
  • templating system combined with host variables for easily managing config
    across multiple different systems
  • possibility of updating dotfiles on all systems at once.

Cons

  • dangers with live editing config - don't forget to change it in the repo as
    well, or next time you run ansible it will overwrite changes!
  • steeper learning curve - not exactly "simple"

Recommendations

I've been really happy with both tools, and they are both excellent. Either way,
if you do plan on tracking dotfiles, you will need some method of getting them
from the repo to your home directory.
I'd definitely recommend Dotbot for most cases, but if you plan on tracking your
dotfiles on multiple different machine types, you might want to consider Ansible
or another configuration management tool.