Setup for CI/CD with Ansible

This guide will explain how to install the build tools needed to set up a CI Build Node.

The minimum set of required tools is the following:

Depending on your project you may also need Node.js.

Java 8 is also a requirement if you are looking to set up a Jenkins agent.

Finally, it is a good practice to have a bot user whose only responsibility is to build your OSX/iOS projects. This means such a user with the correct permissions should be created, so the user can build OSX/iOS projects.

Since this can be cumbersome and error-prone if done manually, the recommended way to set up a CI Build Node is to use Ansible.

Ansible is a configuration management tool that is used to automate the setup of a specific system. It allows you to defined your system as code. This makes changes to a specific system easier and most importantly, it lets you track who changed what and how.
If you are not familiar with Ansible, we recommend this quickstart video. It gives a good idea of what Ansible is and how it can be used.

MacStadium provides an Ansible playbook that takes care of the installation and setup of the tools need for a CI Build Node. The playbook is open-source and can be found here.

Note: The playbook works for OSX High Sierra and Mojave. It is capable of installing Xcode 8 and above. If you are using an older OSX version or require an older Xcode version, refer to our manual installation guide.

The playbook is intended to be executed on the machine that you want to set up as a CI Build Node. If you want to execute the playbook remotely, you will need to configure another Ansible inventory.

The Xcode installation requires a UI session. This means the user that executes Ansible must be logged in. For example, if you execute Ansible with admin user make sure that this user is logged in. You can achieve this via VNC or via the Web Console.

Ansible Playbook

Initial setup

The first step is to connect to the target machine. You can either do this via VNC or via the Web Console, or if you enable Remote Login in the macOS settings, you can SSH in.

Now you need to download and run the setup script contained in the repository. To do that run the following commands:

curl -o ~/  
chmod +x ~/
sudo ~/  

This will install:

Now you need to clone the repository containing the Ansible playbook.
This can be done by running:

git clone

This playbook consists of two roles:

  • OSX-CI - Installs all common tooling and creates a user capable of running build jobs
  • Xcode - Installs and configures Xcode

In order to install these two roles execute:

cd ansible-playbook-osx-ci-setup
ansible-galaxy install -r requirements.yml

OSX-CI Role Requirements

The OSX-CI requires a path to a public public ssh key on the target machine. The role will add the key to the authorized_keys file of the created user in order to enable remote login via ssh with a private key.

Note: If you are going to use the target machine as a Jenkins agent you will need a key pair generated using the RSA algorithm.

If you do not have a ssh key pair you can create one by executing on the target machine:

ssh-keygen -m PEM -t rsa -C "build machine key" -f "buildMachine_rsa"

Note: For an increased security, it is recommended to associate a passphrase to the private key.

The command will create two files:

  • buildMachine_rsa - This is your private key. Keep it safe and do not share it with anyone.
  • - This is your public key.

To copy the private key to a secure machine that you own, you can use scp. This command executes copy over ssh.
You can run:

scp /path-to-buildMachine_rsa/ username@host:/path-to-location-on-secure-machine

Xcode Role Requirements

The Xcode needs a Xcode xip file to be present on the target machine. You can get the version you want from the Apple Downloads Page.

Password Encryption

The playbook requires a privilege escalation password:


You will also need to specify a password which will be used to create a default keychain for the build user:


It is highly recommended not to pass the passwords in plain text.
To encrypt them we will use Ansible Vault.
You can add the variable to group_vars/all.yml and execute the following command:

ansible-vault encrypt group_vars/all.yml

You will be asked for a vault password. It will be later used to decrypt the file. Once the operation is executed the file will be encrypted.

Running the Ansible Playbook

To execute the Ansible playbook you can use the following command by replacing the {placehoders} with the correct values:

ansible-playbook site.yml -i inventory -e ansible_user={AdminUser} -e xcode_xip_location={XcodeLocation} -e xcode_major_version={XcodeMajorVersion} -e ci_user_public_key_location={PublicSshKeyLocation} --ask-vault-pass

You will be prompted for the vault password that you used to encrypt the group_vars/all.yml file in the previous step.

Once the executing is completed, you will have a fully-setup machine that you can use for OSX/iOS builds and for a Jenkins agent.