How to Automatically Setup Your MacBook for Development

How to Automatically Setup Your MacBook for Development

This guide will show you how to automatically set up your Macbook or Linux machine using Ansible and dotfiles.

Featured on daily.dev
Danny Steenman

Published on Dec 22, 2020

7 min read

Subscribe to my newsletter and never miss my upcoming articles

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

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

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).

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:

Setup your preferred 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 in 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: git@github.com: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 link 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.

Installation

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.

Installation complete!

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.


👋 Enjoyed this article? Reach out in the comments below or on Twitter to let me know what you think of it.

If you found some value in reading this, please consider showing your support by sponsoring me. Thanks to your support, I'm able to continue doing what I enjoy the most, which is sharing my learnings with the Cloud Community. Donate here 👇

Did you find this article valuable?

Support Danny Steenman by becoming a sponsor. Any amount is appreciated!

See recent sponsors Learn more about Hashnode Sponsors