Tested on Monterey/Intel. Requires python3.
Install XCode. (The command line tools are insufficient. python3 seems to be unable to verify ssl certificates without the full app).
- Run
init.sh
. You'll be prompted for your password. - Grant yourself passwordless sudo permission:
sudoers.sh -K -e nopasswd=yes
. You'll be prompted for your password. - Run the bootstrap script:
bootstrap.sh
. - Run the playbook:
setup.sh
.
- Run
init.sh
, which does the following:- Accepts the Xcode license (may prompt for admin password)
- Installs ansible (
pip3 install --user ansible
) - Installs task dependencies in
requirements.txt
(again, withpip3 install --user
). - Installs dependencies in
requirements.yml
usingansible-galaxy
.
- Optionally grant users the ability to use sudo with
sudoers.sh -K
. Seesudoers-playbook.yml
for options. - Run
bootstrap.sh -K
(omit-K
if you're set up with passwordlesssudo
). This runsbootstrap-playbook.yml
, which runs the Xcode first launch tasks (if necessary) and installs MacPorts, along with several ports needed to make setup tasks work properly. You only need to do this once. The playbook is imported insetup-playbook.yml
, so the tasks will run again if necessary. - Sign in to the app store app.
mas
cannot install apps unless you do so, and sign in via the command line no longer works. See mas known issues. - (Currently optional) update everything to the latest python version (see python versions below).
- Run
setup.sh -K
(omit-K
if you're set up with passwordlesssudo
). The script passes all arguments on toansible-playbook
. - The following
tags
are defined (which you can pass to the script, e.g.,setup.sh --tags ports
):-
apps: Install applications from the app store using
mas
and from non-app-store disk images (seevars/mas.yml
andvars/dmgs.yml
). You must be signed in to the app store formas
to function properly. -
customize: Customize app and OS settings. You need to log out and log back in to apply many of the changes.
-
dotfiles: Clone my dotfiles and emacs config.
-
emacs: Clone emacs from GitHub, build, and install. Clones my emacs config.
-
fonts: Install fonts (see
vars/fonts.yml
). -
launchd: Load launchd jobs (see
vars/launchd.yml
). -
pip: Install pip packages (see
vars/pip.yml
). -
ports: Install/update a configurable list of ports/variants (see
vars/ports.yml
). -
tex: Install MacTeX.
-
...and more.
The system python version is 3.9
, which is now quite outdated. It seems unlikely that Apple will be keeping it up to
date. Because ansible
requires a python installation to work, and we want to use ansible to automate installing
things (including newer python versions), we're in a bit of a bind.
In particular, ansible-lint
is no longer actively maintained for 3.9
(new versions require newer pythons). Other
dependencies are likely to move on as well. Eventually, perhaps, even ansible
itself (at which point we'll need to
come up with some other solution for init and bootstrapping).
The easy solution is to init, then bootstrap, which sets everything up with the system python and installs macports. Adding the latest python to the bootstrap ports means that it will be installed on bootstrap. So, the sequence of steps to get properly set up is
- Run
init.sh
to install ansible for the default (3.9
) python. - Run
bootstrap.sh
to bootstrap using this installation. This installs a newer python version. - Run
init.sh
again to install ansible for the new python. - (Optional) install the development dependencies by running
dev-init.sh
. - Run
setup.sh
as needed. This will run the ansible installed for the newer python version.
To upgrade python:
- First, change the version installed in the bootstrap ports.
- Run
bootstrap.sh
to install this version. - Run
init.sh
to install ansible, etc., for the new python version. - After verifying that things work with the new python version, optionally remove the old version.
Passing boolean values in -e/--extra-vars
. If you pass -e something=false
to ansible, something
will have the
string value "false"
. This string evaluates to False
in most contexts when you type it in a playbook or in a vars
file, but it does not do so as an extra var. No, passing -e something=False
doesn't work, either. something
will
have the string value "False"
.
Because many roles have boolean defaults that you may wish to override on the command line, this is a problem. There are several ways to deal with it:
- Use JSON. This syntax is cumbersome on the command line, but it works:
-e '{"something": false}'
.False
also works here. - Pass an empty value, which will evaluate to false in conditionals:
-e 'something='
.
See ansible 17193 and this blog.