This week I have been working on writing an Ansible playbook that will help new employees on my team configure their MacBooks. I have been configuring my own MacBook for years this way, so most of the work is already done. I also have a repository for storing my dotfiles where I store my various dotfile configurations.

As I was thinking through the layout of my playbook and dotfiles, I noticed how many of my configuration files are a combination of personal and work entries. One of the things that I am trying to achieve with this project is to create the source of truth for our various work related configuration files. But I don’t want to clobber personal settings either. One example would be my .ssh/config file. Some of the entries in the file are for my personal systems and some are for my work systems. In addition to making the file rather large, it doesn’t lend itself to being under configuration management and sharing with coworkers.

I decided to check and see if there was a way to use some type of includes directive, and I was really excited to learn not only was this possible, it was really easy to do as well.

I started by creating a directory called config.d in my ~/.ssh directory. To make things more logical, I decided to limit the directives in the primary config file to the Include statement and anything that I would want to apply to all hosts.

My ~/.ssh/config file:

Include config.d/*

Host *
  ServerAliveInterval 300
  ServerAliveCountMax 2

Then in the config.d directory, I added files for each environment. An example config of my ~/.ssh/config.d/acg-aws file looks like this:

# Development
Host 10.10.16.* 10.10.17.* 10.10.18.* 10.10.19.* 10.10.20.* 10.10.21.*
  User ec2-user
  IdentityFile ~/.ssh/other/key-master
  ProxyCommand ssh -q -W %h:%p bastion.example.com

# Production
Host 10.10.1.* 10.10.2.* 10.10.3.* 10.10.4.* 10.10.5.* 10.10.6.*
  User ec2-user
  IdentityFile ~/.ssh/other/key-master
  ProxyCommand ssh -q -W %h:%p bastion.example.com

Now I can put my work configuration into the Ansible playbook that I am writing for my co-workers, while still maintaining my own ssh configs. Next is figuring out what other configuration files will lend themselves to this type of separation.