Skip to content

About

Install all your applications and configure everything the way you like it with one command

Topics

Resources

Stars

226 stars

Watchers

9 watching

Forks

Repository files navigation

macbook-playbook

Install all your applications and configure everything the way you like it with one command.

TODO:

  • add brew to path when installing. (/opt/homebrew/bin)
  • add GitHub to known hosts: ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
  • unencrypt and add SSH key to ssh session
  • figure out Emacs symbolic link internal directory
  • make caps lock -> ESC remapping work
  • fix glances webserver “msg: Destination directory /Users/mpereira/Library/LaunchAgents does not exist”
  • install insta360 link ap
  • wait 1s after install spotify and steam
  • GraalVM on apple silicon?
  • kubectl-krew isn’t available right after installing
  • launch BTT on startup, load configuration and license
  • symlink id_rsa to mpereira@pluto SSH key
  • turn on dictation

Table of Contents

Tested on

I’ve been using macbook-playbook since 2013. I’ve used it on at least eight MacBook Pros with different macOS versions. As of May 2023 I use it on my personal 16” 2023 Macbook Pro with Ventura installed and on my work 16” 2019 Macbook Pro with Monterey installed.

Please open an issue if you’re trying this out and bump into anything.

Bootstrap machine (make bootstrap)

These are one-time steps that need to be done on machines that are running macbook-playbook for the first time.

Install Developer Tools (xcode-select)

Open the “Terminal” application, type git into the shell and follow the instructions to install the Apple Developer Tools.

Clone repository

Now your machine should have git and python3 installed.

git clone https://github.com/mpereira/macbook-playbook.git

Give Terminal/iTerm2/Emacs/etc. assistive access

Depending on your macOS version you will be queried or not for assistive access while make converge runs. This is required for example to remap caps lock to control.

In case that task fails, or if you want to do it beforehand just in case, go to “System Preferences > Security & Privacy > Privacy > Accessibility” and add the application running macbook-playbook (Terminal/iTerm2/Emacs/etc.) to the list.

Secrets

I keep secrets encrypted in a file outside of this repository. I have a project (also outside of this repository) that will write all secrets required by this project’s roles to group_vars/localhost/vars.yml. This file is git-ignored in this project.

These are the roles that use secrets:

DescriptionSecret nameRole
AWS CLI credentialsaws_credentials_file_base64awscli
BetterTouchTool licensebetter_touch_tool_license_file_base64better-touch-tool
DaisyDisk licensedaisydisk_registration_key_file_base64daisydisk
Enviroment variables for dotfilesdotfiles_environment_yml_file_base64dotfiles
iStat Menus settingsistat_menus_settings_file_base64istat-menus
Prey API keyprey_api_key_yaml_file_base64prey
Private SSH keympereira_at_pluto_ssh_private_key_base64ssh-keys
s3cmd configurations3cmd_cfg_file_base64s3cmd

If a group_vars/localhost/vars.yml file with those secrets is absent running these roles will fail.

You have two choices: skip these roles, or write your group_vars/localhost/vars.yml.

To skip them, when you reach the provision machine step, make Ansible skip roles tagged with uses-secrets. You don’t need to run this now, the command below is just an example.

make converge ARGS='--skip-tags uses-secrets'

Prepare machine to run the Ansible playbooks

This will:

  1. Set up Touch ID sudo with password fallback (macOS 14 or later)
  2. Install a user Python3
  3. Install Ansible
make bootstrap

Your machine should now be ready to be provisioned! You won’t need to run the above steps again.

Configure machine (make converge)

Now that the machine is bootstrapped, we can provision it.

Provision machine

This runs all non-disabled roles in =main.yml=.
make converge ARGS='--skip-tags disabled'

ansible-playbook arguments can be passed via the ARGS environment variable. For example, --tags can be passed so that only matching roles are run.

make converge ARGS='--tags google-chrome'

--skip-tags can also be passed to avoid running certain roles.

make converge ARGS='--skip-tags disabled,unity'

All role tags can be seen in =main.yml=.

Tasks may fail due to intermittent reasons like temporary server unavailability. When a task fails you can either disable its role via --skip-tags or use --start-at-task with the name value of some task to cause Ansible to start the playbook exactly there.

For example, if the “Install Emacs” task from the “build-emacs” role fails for what seems to be an intermittent issue, you can pick up provisioning from there so that previous tasks don’t have to re-run.

make converge ARGS='--skip-tags disabled --start-at-task "Install Emacs"'

Check the official Ansible documentation for more details.

Manual steps post make converge

These are steps that are currently not automated because:

  • it would be difficult
  • it would be impossible
  • or I just didn’t have the time

Change keyboard layout to U.S. international

  1. System Preferences -> Keyboard -> Input Sources
  2. Click +
  3. Select “English” on left column
  4. Select “U.S. International - PC” on right column
  5. Click “Add”
  6. Remove other keyboard layouts from the left column

iStat Menus

  1. Import license from roles/istat-menus/files/iStat Menus Settings.ismp

PDF Expert

  1. Register license

BetterTouchTool

  1. Register license

Terminal

Preferences > Profiles > Pro > Font

Set to Hack Regular 18 pt.

System Preferences > Security & Privacy > Privacy > Accessibility

  • BetterTouchTool.app
  • Emacs-*.app
  • MacGPT
  • RescueTime
  • Terminal
  • VLC
  • WhatsApp

System Preferences > Keyboard > Shortcuts > Mission Control

Uncheck:

  • Mission Control
  • Move left a space
  • Move right a space
  • Switch to desktop 1

I use these keybindings on Emacs.

Roles

Installs

Desktop Applications

Agent skills

Managed by the skills role. The canonical copy of every skill lives under ~/.agents/skills (which Codex reads natively) and is symlinked into ~/.claude/skills for Claude Code. No ~/.codex/skills symlinks are created, since that would double-list each skill in Codex. Codex’s own .system and codex-primary-runtime directories are left untouched.

make converge updates git-backed skills; add a version: to an entry in the defaults to pin it. Locally-maintained skills are copied from roles/skills/files and updated with the playbook. Sources (configured in roles/skills/defaults/main.yml):

The clickup skill is the exception: it is generated by the cup CLI itself (cup skill --print) and provisioned by the clickup-cli role, so it always matches the installed CLI version.

Invoke these skills in Codex with $asd-ste100 or $show-me, and in Claude Code with /asd-ste100 or /show-me. Our ASD-STE100 skill defaults to an “80% STE” style for readable technical explanations, with stricter wording when requested. It does not certify compliance with the official dictionary. Both skills allow automatic selection when relevant. Show-me’s auto_invoke: true setting creates a configured copy with automatic selection enabled for Codex and Claude Code, keeping the upstream Git checkout clean.

Local skills are supported in the ChatGPT desktop app. This role provisions the local Codex discovery path; it does not publish a plugin for ChatGPT web or mobile. See OpenAI’s skill documentation.

Claude chat and Cowork require a separate upload. Enable code execution in Settings > Capabilities, then upload each skill folder as a ZIP in Customize > Skills and enable it. Use the resolved skill folder, including supporting scripts and references, rather than archiving only its symlink. See Claude’s skill setup instructions.

Text Editors

Configuration

Biome’s user-level config is provisioned directly by this playbook at ~/Library/Application Support/biome/biome.json.

Claude local settings are ignored through .gitignore.

Programming Languages

Multimedia

Fonts

Browser Plugins

Virtualization, Provisioning, Containers and System Tools

Package Managers and Build Tools

Shell

Programming Utilities

Data Systems

  • Apache Hadoop (disabled by default, it conflicts with the yarn JavaScript package manager)

Configuration, Monitoring and Debugging

Document Processors and Plotting

Markup Tools

Command line tools

Security

GNU Command Line Tools

  • binutils
  • coreutils
  • diffutils
  • ed
  • findutils
  • gawk
  • gnu-indent
  • gnu-sed
  • gnu-tar
  • gnu-which
  • gnutls
  • grep
  • gzip
  • screen
  • watch
  • wdiff
  • wget

Miscellaneous

Configures

Routes links with Finicky

The finicky role sets Finicky as the HTTP/HTTPS handler, routes app.clickup.com task and Doc links to the ClickUp desktop app, and uses Google Chrome for other links. It manages ~/.finicky.js and preserves the URL path, query, and anchor. Run it with make converge ARGS“–tags finicky”=. Accept macOS’s browser-change prompt if one appears. ClickUp’s desktop app must already be installed and signed in.

Links clicked inside Chrome normally stay in Chrome. With ClickUp running, open a ClickUp page in Chrome and select the notification checkbox to automatically open future links in the desktop app. This is ClickUp’s Detect Desktop App setting. Tracked notification URLs and public Doc URLs are left to Chrome to resolve.

Passwordless sudo

The passwordless-sudo role enables Touch ID authentication through /etc/pam.d/sudo_local on macOS Sonoma 14 or later. This local PAM file survives macOS updates. Enroll a fingerprint in System Settings under Touch ID & Password before using it.

The role replaces its previous NOPASSWD: ALL rule with PASSWD: ALL, so sudo authenticates with Touch ID and falls back to your login password when Touch ID is unavailable. Existing local PAM customizations are preserved, and the system /etc/pam.d/sudo file is left intact.

Reapply this configuration with:

make converge ARGS='--tags touch-id-sudo --ask-become-pass'

For other roles that need administrator access, add --ask-become-pass to ARGS if Ansible cannot authenticate with Touch ID in its session. To check the fingerprint prompt from a local terminal, run:

sudo -k
sudo whoami

A successful authentication prints root. Canceling Touch ID allows password fallback. SSH and some terminal multiplexer sessions may need the password instead. See Apple’s macOS Sonoma enterprise release notes.

Puts SSH keys in place

Remaps Caps-Lock to Control

Uses an AppleScript helper for the current System Settings flow.

Author

Murilo Pereira

License

MIT

About

Install all your applications and configure everything the way you like it with one command

Topics

Resources

Stars

226 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages