Shell

macbook-playbook

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

M

mpereira

Dernière activité 21 juin 2026
mpereira/macbook-playbook

226

étoiles

33

forks

2

issues ouvertes

ansibleansible-playbooksautomationmacbookmacosplaybook

Ce README est souvent en anglais.

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 passwordless sudo
  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

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

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

Projets similaires

Mac setup and configuration via Ansible.

Shellansibleautomationdeveloper
Ggeerlingguy
7,1 k étoiles1,9 k

Collection of macOS automation tools for Ansible.

Shellansiblecollectionconfiguration
Ggeerlingguy
392 étoiles109

Ansible-powered MacBook configuration

Shell
Aadamchainz
219 étoiles79