As a Cloud Engineer, automation has become a part of my daily life. Automatically deploying Infrastructure using Code has become a safe and fast way to provision servers in the Cloud.
Initially, it takes more time to configure the infrastructure as code, but it’s reusable and minimizes configuration errors by human mistakes.
What if we could apply the same principle to our local development environment?
This guide will show you how to automatically set up your Macbook or Linux machine using Ansible and dotfiles.
Table of Contents
Prerequisite
Ensure Apple’s command-line tools are installed:
xcode-select --install
Install Homebrew
The first step is to download Homebrew for your Mac:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Homebrew allows you to easily install packages and applications on your machine without having to go to the download page of the vendor to install it from there. An added benefit is that you can easily update the packages using a simple command like:
brew update && brew upgrade
Install Ansible
Ansible is a tool that automates provisioning, does configuration management, and is being used widely in the Cloud.
It uses no agents and no additional custom security infrastructure, so it’s easy to deploy – and most importantly, it uses a very simple language (YAML, in the form of Ansible Playbooks) that allow you to describe your automation jobs in a way that approaches plain English.
So the next step is to install Ansible using Homebrew:
brew install python ansible
An important note when installing Python with Homebrew is that we need to change the PATH on our system for Python, otherwise MacOS will use the system default Python.
export PATH="/usr/local/opt/python/libexec/bin:$PATH"
We want to avoid using the system default for many reasons, but the most important one is that it still comes with Python2.7 (which is deprecated).
Download the mac-dev-playbook
Ansible is the orchestration tool and uses Playbooks to record and execute Ansible’s configuration and deployment on the system.
Playbooks can be seen as an instruction manual at which the system is guided to execute the instructions that you have written. The benefit of using this is that you can apply the same set of instructions to different machines and expect the same outcome every time.
These Playbooks can be shared. So before we proceed with the installation, you need to clone or fork the mac-dev-playbook repository.
Configure your Homebrew packages
Every development environment is unique, so you can create a config.yml
that contains a list of packages and configuration settings that you want to apply to your environment.
As an example you can have a look at the default.config.yml
at the root of the folder which contains a list of packages and configurations, as shown below:
---
downloads: ~/.ansible-downloads/
configure_dotfiles: true
configure_terminal: true
configure_osx: true
configure_sudoers: false
sudoers_custom_config: ''
# Example:
# sudoers_custom_config: |
# # Allow users in admin group to use sudo with no password.
# %admin ALL=(ALL) NOPASSWD: ALL
dotfiles_repo: https://github.com/geerlingguy/dotfiles.git
dotfiles_repo_accept_hostkey: true
dotfiles_repo_local_destination: ~/Development/GitHub/dotfiles
dotfiles_files:
- .zshrc
- .gitignore
- .inputrc
- .osx
- .vimrc
homebrew_installed_packages:
# - ansible # Installed via Pip.
- autoconf
- bash-completion
- doxygen
- gettext
- gifsicle
- git
- github/gh/gh
- go
- gpg
- httpie
- iperf
- libevent
- sqlite
- mcrypt
- nmap
- node
- nvm
- php
- ssh-copy-id
- cowsay
- readline
- openssl
- pv
- wget
- wrk
homebrew_taps:
- homebrew/core
- homebrew/cask
homebrew_cask_appdir: /Applications
homebrew_cask_apps:
- chromedriver
- docker
- dropbox
- firefox
- google-chrome
- handbrake
- licecap
- sequel-pro
- slack
- sublime-text
- transmit
- vagrant
# See `geerlingguy.mas` role documentation for usage instructions.
mas_installed_apps: []
mas_email: ''
mas_password: ''
osx_script: '~/.osx --no-restart'
# Install packages from other package managers.
# Note: You are responsible for making sure the required package managers are
# installed, eg. through homebrew.
composer_packages: []
# - name: drush
# state: present # present/absent, default: present
# version: "^8.1" # default: N/A
gem_packages: []
# - name: bundler
# state: present # present/absent/latest, default: present
# version: "~> 1.15.1" # default: N/A
npm_packages: []
# - name: webpack
# state: present # present/absent/latest, default: present
# version: "^2.6" # default: N/A
pip_packages: []
# - name: mkdocs
# state: present # present/absent/latest, default: present
# version: "0.16.3" # default: N/A
# Glob pattern to ansible task files to run after all other tasks are finished.
post_provision_tasks: []
This playbook is pretty versatile and allows you to install Homebrew, Mac Application Store (mas) packages, composer, gem, npm, and pip packages.
Configure dotfiles
Once you’ve created your own config file with your preferred packages, it’s time to add your own Dotfiles repository to set up custom configurations for your software.
So what are dotfiles? Dotfiles are text-based configuration files that store settings of almost every application, or tool that runs in your environment.
In communities like Github, people share their application preferences so others can use them to set up their systems faster by restoring these “dotfile” configuration files.
The biggest advantage is that you can backup your application preferences and make sure you’re always using the same preferences, irrespective of the machine that you’re using.
If you’re new to dotfiles you can read more about it in this helpful guide on dotfiles. I’ll also share a few links below which contain pre-configured dotfiles for your favorite tools:
Note: dotfiles contain personal preferences, so it’s good to review these files and apply changes where necessary before you copy them to your own repository
Once you have your own repository filled with dotfiles, you can update the dotfiles_repo
variable in the config.yml
with your own dotfiles repository. Below I’ve shown an example of what it looks like when I set up my own dotfiles:
configure_dotfiles: true
dotfiles_repo_accept_hostkey: false
dotfiles_repo_local_destination: ~/Github/dotfiles
dotfiles_repo_version: master
dotfiles_repo: [email protected]:dsteenman/dotfiles.git
dotfiles_files:
- .aliases.zsh
- .aws
- .eslintignore
- .eslintrc
- .fzf.zsh
- .gitconfig
- .gitconfig.user
- .gitignore
- .iterm2
- .macos
- .starship
- .zprofile
- .zsh_plugins.txt
- .zshenv
- .zshrc
The parameter dotfiles_repo_local_destination
is the location where ansible downloads your dotfiles repository. Remember that location, because that’s where you’ll manage changes in your dotfiles.
Ansible automatically creates symlinks of the dotfiles that you enabled in the parameter dotfiles_files and links them to your home folder on your Mac or Ubuntu machine.
The advantage of this construction is that when you make adjustments in your dotfiles over time, it will automatically update the repository. You only have to commit and push the changes to update it remotely.
Run Ansible to install all the Homebrew packages that you’ve configured
Once the requirements have been fulfilled, we can proceed with the actual installation and let Ansible perform its magic!
In the root of the folder mac-dev-playbook
repository that you forked or cloned run the command ansible-galaxy install -r requirements.yml
to install the required ansible roles.
Now you can run the playbook and install your packages and dotfiles with the command ansible-playbook main.yml -u [username] --ask-become-pass
(substitute [username]
for your username). Enter your account password when prompted.
Conclusion
Your Macbook should be fully customized and ready for development! Having automated provisioning of your development machine is very useful if you use lots of different development tools, each with its own unique settings.
If you need to manage these tools then it’s a must to keep track of any changes in preferences.
By using this playbook solution we save our configurations in Github.
That way we have a backup and we’re able to reuse these settings irrespective of any machine we use.
Once you’ve set up your playbook, it takes approximately 30 minutes to install all the development packages and preferred configuration settings.