Ansible roles and playbooks that set up a work laptop on macOS. The playbook
runs against localhost with a local connection. No SSH is necessary.
| Role | Effect |
|---|---|
homebrew |
Adds taps, installs formulae and casks, cleans up old files. |
git |
Sets the global git config, aliases, gitignore, and GPG agent. |
shell |
Checks the login shell and reports how to change it. |
dotfiles |
Installs Oh My Zsh and writes ~/.zshrc, or a sn-zsh fragment. |
macos |
Applies macOS defaults and restarts the affected apps. |
git clone <this-repo> ~/Code/sonniesedge/laptop
cd ~/Code/sonniesedge/laptop
./bootstrap.shThe script installs the Xcode command line tools, Homebrew, Ansible, and the required collections. Then it runs the playbook.
make check # dry run, shows the changes
make run # apply everything
make upgrade # apply everything and upgrade all Homebrew packagesEach role has a tag.
make homebrew
make git
make macos
make shell
make dotfilesOr use ansible-playbook directly.
ansible-playbook playbook.yaml --tags homebrew,git --diffAll tunable data is in group_vars/all.yaml. The roles are generic. To add a
package, a git alias, or a macOS setting, edit that file and run make run.
Find the domain and key first.
defaults read com.apple.dockThen add an entry to macos_defaults.
- { domain: com.apple.dock, key: tilesize, type: float, value: "48" }Valid types are array, bool, int, float, and string.
Add host: currentHost for keys that are stored per-host.
Change the entry to state: absent. That deletes the key, so macOS falls back
to its own default.
- { domain: com.apple.LaunchServices, key: LSQuarantine, state: absent }See AGENTS.md for why removal works this way rather than by deleting the line.
~/.zshrc is generated by the dotfiles role from
roles/dotfiles/templates/zshrc.j2. Do not edit ~/.zshrc by hand. The next
run overwrites it. A backup of the old file is kept each time.
On a laptop that uses sn-zsh, set sn_zsh_mode: true. Read "Work laptops that
use sn-zsh" below.
Change the content through group_vars/all.yaml.
| Variable | Holds |
|---|---|
zsh_env |
Plain environment variables. Committed. |
zsh_secrets |
1Password item UUIDs. Only the UUID is committed. |
zsh_path_prepend |
Directories to put on the front of PATH. |
zsh_plugins |
Oh My Zsh plugins. |
zsh_extra_lines |
Raw lines appended near the end. |
For anything machine-specific that should not be committed, use
~/.zshrc.local. The generated file sources it and Ansible never overwrites it.
Secrets are read from 1Password when the template renders, so no secret value is
ever committed to this repo. The op CLI must be signed in before you run.
op signin
make dotfilesTo add a secret, find the item UUID and add it to zsh_secrets.
op item listzsh_secrets:
MY_TOKEN:
uuid: abcdef1234567890
field: notesPlainBecause ~/.zshrc holds real secrets once rendered, the role writes it with
mode 0600.
sn-zsh is the standard Springer
Nature shell environment. It makes ~/.zshrc a symlink into ~/.sn-zsh, and
it loads Oh My Zsh, Homebrew, the prompt, and the Zscaler setup for you. Both
projects want to own ~/.zshrc, so the last one to run wins.
Set sn_zsh_mode: true in group_vars/all.yaml to stop the fight. The
dotfiles role then leaves ~/.zshrc alone. It writes
~/.sn-zsh-custom/50-personal.zsh instead, and sn-zsh sources that file at the
end of startup.
| Part | Owner |
|---|---|
~/.zshrc, Oh My Zsh, prompt |
sn-zsh |
Homebrew on PATH, plugins, Zscaler |
sn-zsh |
| Environment variables and secrets | this repo |
PATH prepends, GPG agent, nvm |
this repo |
Install sn-zsh first. The role fails if ~/.sn-zsh/zshrc is missing.
git clone git@github.com:springernature/sn-zsh.git "$HOME/.sn-zsh"
cd "$HOME/.sn-zsh" && make installThen set the flag and apply the role.
sn_zsh_mode: truemake dotfilesHomebrew, git, and macOS roles are not affected. They run as before.
Note: sn-zsh reports a problem at session start when the ~/.sn-zsh repo has
uncommitted changes. This is why the role writes to ~/.sn-zsh-custom/ and
never into ~/.sn-zsh/.
Note: sn-zsh sets no_unset after it loads. A command in zsh_extra_lines
that reads an unset variable stops the shell with an error.
This repo replaced an earlier chezmoi setup. To clear the leftovers once:
make remove-chezmoiThat deletes ~/.local/share/chezmoi, ~/.config/chezmoi, ~/.cache/chezmoi,
and uninstalls the formula. It refuses to run if the chezmoi source repo has
uncommitted changes.
- Some macOS settings need a logout or a restart before they take effect.
- The login shell is not changed automatically.
chshneeds a password.