All Blog Posts

Upcoming Webinar

When to Migrate to the M1 Mac
Thursday, Feb 4, 2021
12 PM EDT / 9 PM PDT

Grab a seat

Check this out

A new virtualization layer for Mac build infrastructure.

Try Orka

Automating macOS Server Configuration with Ansible

Thumbnail for Automating macOS Server Configurations with Ansible

DevOps engineers in the Mac world can benefit immediately from adopting Ansible as a configuration tool. Ansible is a lightweight configuration solution that requires only two things of the target servers it configures. Python must be installed (macOS’ factory installation will work just fine), and SSH must be enabled (this is a simple switch on macOS). Easy peasy.

Today, we’ll walk through the setup and execution of geerlingguy/mac-dev-playbook (2.8k ⭐) against macOS VMs hosted at MacStadium.

Prep macOS Target Servers

As macOS comes with a factory install of Python, we only need to enable SSH. We can do so from the command line, like so:

$ sudo systemsetup -setremotelogin on

NOTE: This feature is enabled by default on MacStadium VMs.

Decision Time: to install Vagrant or not to install Vagrant

To install Vagrant by way of this playbook, we will need to enable “no password” access for our Ansible user. For users who would like to rely solely on sudo, we also include instructions for the removal of Vagrant from the playbook, so that it can execute without errors in the absence of “no password” permissions.

* Option 1: Allow sufficient permissions for the Vagrant installation

We will need to give “no password” permissions to Ansible to run this playbook successfully. To do so, we need to run the following:

sudo visudo

This will bring up a text editor. Scroll down to a section that looks like the following:

# root and users in group wheel can run anything on any machine as any user
root            ALL = (ALL) ALL
%admin          ALL = (ALL) ALL

For our purposes, Ansible will be acting as the admin user. To give “no password” access to the admin user,  type “A” to edit the file, and edit the file like so:

# root and users in group wheel can run anything on any machine as any user
root            ALL = (ALL) ALL
%admin          ALL=(ALL) NOPASSWD: ALL

NOTE: be careful here. A mistake will not be accepted. If you happen to try to save with errors, type “e” and press enter to try again.

Press escape, type “:wq”, and press enter to write our changes to the file and exit the editor.

* Option 2: Remove the Vagrant portion of the playbook

In order to forego the above, you may elect to remove Vagrant from the list of homebrew_cask_apps listed in the file 'default.config.yml'. To do so, simply delete it from the list, like so:

 - chromedriver
 - docker
 - transmit
 - vagranthomebrew_cask_apps:
 - chromedriver
 - docker
 - transmit

Prep Controlling Server

Once SSH is enabled on the target servers, it’s time to install Ansible on your controlling machine. There are many ways to do this, but pip, the Python package manager, is the standard means on Mac, and it works well on any machine with pip installed.

If working from a Mac controlling server, you will first need to install xcode-select to make an installation of Ansible possible:

xcode-select --install

Then, to install Ansible with pip, run the following:

pip install ansible

Next, because we are using password-based auth today for gaining SSH access to our target server(s), we will need to install sshpass.

  • On Mac, we can simply run:
brew install hudochenkov/sshpass/sshpass
  • Alternatively, on Debian-based Linux distributions, we can run:
sudo apt install sshpass

Finally, clone the mac-dev-playbook repo down to the controlling server, like so:

git clone

Edit the inventory file

Ansible looks to the inventory file we pass on the command line to find which servers to connect to and act upon. It is worth noting that SSH keys are the preferred means of securing your connection. To learn more about SSH keys and Ansible check out Automation 101: Introduction to Ansible. For the sake of brevity, we’ll be using password-based authentication here.

# inventory
ansible_ssh_pass=<ssh password>

Port_8823_VM-1 ansible_ssh_port=8823 ansible_ssh_host=
Port_8824_VM-2 ansible_ssh_port=8824 ansible_ssh_host=

Above, we have set our SSH credentials and created a group of servers, hosts. You can define your connection points in a number of different ways, but we have found the above pattern of host name, port, and host IP to work well, as it can sometimes be difficult to get Ansible to pick up the port in other patterns. This can cause problems when VMs are exposed by port on a single IP, such as in our example above.

Edit main.yml

By default, the mac-dev-playbook is pointing at the local machine. In order to change this behavior, we are going to need to remove line three entirely from this file, and save.

- hosts: all
 connection: local

   - default.config.yml
The resulting file should look like this:
- hosts: all

   - default.config.yml

Edit ansible.cfg

In order for Ansible to be able to act as a successful SSH user, we will either need to manually SSH into each of our target servers one time, so as to add the target servers to the list of trusted hosts on the controlling server, or we can update our ansible.cfg file to disable host key checking, like so:

host_key_checking = False

Install Ansible requirements

Homestretch. Run the following to give Ansible what it needs to run this specific playbook:

$ ansible-galaxy install -r requirements.yml

Run the Playbook

Finally, run the playbook against all servers in our inventory file. The --ask-become-pass flag will ask us for our admin user’s sudo password, so that it can have the required privileges to make changes to the target servers.

$ ansible-playbook main.yml -i inventory --ask-become-pass
BECOME password:

Next Steps

You May Also Like

Was this article helpful?

Vote Submitted
Oops! Something went wrong while submitting the form.
Vote Submitted
Oops! Something went wrong while submitting the form.
Return to Blog Home