Cross-platform Ansible playbooks that bootstrap a dev machine on Linux, macOS, and Windows in minutes.
Setting up a fresh dev machine should not take a weekend of copy-pasting install commands. This playbook treats workstation provisioning as infrastructure: declarative, idempotent, version-controlled. One command produces the same environment on Ubuntu, Fedora, Arch, macOS, and Windows.
The trick is a small dispatch layer. group_vars/all.yaml declares intent
(install_chrome: true); per-OS dictionaries under vars/ map that intent to the correct
package manager.
- Idempotent. Run it ten times, get the same machine.
- One toggle file in group_vars/all.yaml drives the installation across every supported OS.
- Per-OS translation dictionaries under vars/ map a generic app name to
apt,dnf,pacman,brew,choco,winget,flatpak,snap, or AUR. - Profile overrides for live USB, minimal, or full installs without touching the base playbook.
- PowerShell entrypoint on Windows that hands off to Ansible inside WSL.
- Docker Compose stack for local-dev databases and Keycloak.
- OpenSpec workflow for spec-driven changes.
Ansible, Bash, PowerShell, Docker Compose, WSL, Keycloak, KDE Plasma, GNOME, systemd, OpenSpec.
flowchart TD
A[setup.sh / setup.ps1] --> B[Interactive TUI<br/>software selection]
B --> C{Detect OS}
C -->|Windows| D[WSL bridge]
C -->|Linux/macOS| E[Ansible playbook<br/>site.yaml]
D --> E
E --> F[Load group_vars + vars/{OS}.yaml<br/>os_dict translation]
F --> G[OS core roles<br/>system_core, windows_core, macos_core, arch_core, fedora_core]
G --> R[Repo provisioning<br/>debian_repos.yaml, fedora_repos.yaml]
R --> H[Cross-platform roles<br/>shell_zsh, env_variables, sdk_manager, ai_tools]
H --> I[software_installer<br/>dynamic_install.yaml]
I --> J1[apt, dnf, pacman, AUR]
I --> J2[brew, brew_cask, mas]
I --> J3[choco, winget]
I --> J4[flatpak, snap]
I --> CI[custom_installs.yaml<br/>macos_install.yaml<br/>windows_install.yaml]
H --> K[Linux advanced<br/>systemd_boot, virtualization_config, linux_security]
The phase order matches setup/ansible/site.yaml. OS core bootstrap first, then APT and DNF
repo provisioning (keyrings, .list and .repo files for Chrome, Brave, VS Code, Sublime, kubectl, Docker), then
SDK and runtime managers, then snapd and flatpak setup, then a single batched install per package manager, then
custom installs for AppImages, DMGs, and .exe artefacts.
| Category | Examples |
|---|---|
| Language toolchains | Python (Pyenv), Node.js (NVM), Java (SDKMAN), Dart and Flutter (FVM), Android SDK, Go, Rust |
| IDEs and editors | IntelliJ IDEA, VS Code, Android Studio, Cursor, Zed |
| CLI tools | git, zsh, oh-my-zsh, Docker, kubectl, k3d, Helm, Terraform, Ansible, gh, jq, fzf, ripgrep |
| AI tools | Claude Code, Claude Desktop, OpenCode, OpenSpec |
| Apps | Chrome, Firefox, Slack, Discord, Spotify, OBS, VLC, Postman |
| Fonts | Nerd Fonts (FiraCode, JetBrainsMono, Hack, Meslo) |
| Desktop | KDE Plasma and GNOME setup, dotfiles, shell config |
The full per-OS list is in setup/SOFTWARE.md. The authoritative per-OS package mappings live under setup/ansible/vars/.
The interactive wizard installs Ansible if missing, pulls the required collections, and presents a
filter-as-you-type checklist for what to install. The TUI uses gum on Linux and macOS and
Microsoft.PowerShell.ConsoleGuiTools on Windows. Both are auto-installed on first run.
Linux / macOS (run as your regular user, not root):
bash setup/setup.shWindows (PowerShell 7+, not as Administrator; the script runs Ansible inside WSL):
pwsh setup/setup.ps1The script prompts for sudo or admin only when needed.
Both entrypoints accept CLI flags to skip the wizard. Useful for CI, Packer images, or live USB bootstrap.
Show usage (Linux / macOS):
bash setup/setup.sh --helpApply a preset profile and skip the wizard (Linux / macOS):
bash setup/setup.sh --profile linux_live --non-interactivePowerShell equivalent on Windows:
pwsh setup/setup.ps1 -Profile linux_live -NonInteractiveAvailable flags:
--profile <name>/-Profile <name>: apply setup/ansible/profiles/.yaml and skip selection.--non-interactive/-NonInteractive: use group_vars defaults, never prompt.--no-color/-NoColor: disable themed output (also honoured viaNO_COLOR=1).--help/Get-Help .\setup.ps1: show usage.
For manual instructions, logging notes, and per-OS caveats, see setup/README_SETUP.md.
Ubuntu, Debian, Fedora, Arch, Manjaro, macOS, Windows (via WSL).
InstallationHelper/
├── setup/
│ ├── setup.sh # Linux/macOS entrypoint
│ ├── setup.ps1 # Windows entrypoint (WSL bridge)
│ └── ansible/
│ ├── site.yaml # Main playbook
│ ├── group_vars/ # Cross-platform + OS-specific toggles
│ ├── vars/ # OS translation dictionaries
│ ├── profiles/ # Override profiles (linux_live, etc.)
│ ├── roles/ # OS core, software_installer, sdk_manager, ai_tools, ...
│ └── SOFTWARE.md # Per-OS software catalog
├── local-dev/ # Docker Compose stack (MySQL, PG, Mongo, Keycloak)
├── openspec/ # Spec-driven change proposals & specs
├── docs/ # Per-OS guides + agent tooling docs
└── utils/ # Helper scripts
The Compose file under local-dev/ runs MySQL, PostgreSQL, MongoDB, and Keycloak (HTTPS) without polluting the host.
docker-compose -f ./local-dev/local-dev-docker-compose.yaml up -dPorts, credentials, and TLS notes live in local-dev/README_LOCAL_DEV.md.
The repo ships agent-standard imports for Claude Code, Kilo Code, OpenCode, and Codex, plus OpenSpec for spec-driven changes. The setup, integration points, and per-agent quirks are in docs/AGENT_TOOLING.md.
To propose a change:
-
Fork the repo and create a feature branch.
-
For non-trivial changes, draft an OpenSpec proposal under openspec/changes/. The workflow is documented in docs/AGENT_TOOLING.md.
-
Run the syntax check before opening a PR:
wsl -d Ubuntu bash -c "ansible-playbook --syntax-check setup/ansible/site.yaml" -
Open a PR with a clear description of the change and the OS(es) it affects.
Bug reports and feature requests are tracked via GitHub Issues.
Released under the MIT License.
| Doc | What's in it |
|---|---|
| setup/README_SETUP.md | Manual setup walk-through, script flags, logging, troubleshooting |
| setup/CONFIGURATION.md | Toggle reference per OS |
| setup/SOFTWARE.md | Full per-OS software catalogue with install methods |
| setup/VERSION_SOURCES.md | Where to look up the latest version for every pinned package |
| setup/ansible/TAGS.md | Ansible --tags taxonomy for surgical partial runs |
| local-dev/README_LOCAL_DEV.md | Docker Compose stack: ports, credentials, image tags |
| local-dev/auth/README.md | Local auth: hosts file entries, self-signed certs, Let's Encrypt |
| local-dev/auth/Keycloak/README.md | Keycloak container build, token curl, OS trust store import |
| local-dev/auth/Keycloak/CONFIG.md | Realm export, client setup, export-import flow |
| local-dev/postgresql/README.md | Standalone Postgres build and run |
| docs/AGENT_TOOLING.md | Agent-standards, OpenSpec, per-agent integration notes |
| docs/MCP_SETUP.md | MCP server setup (Context7 only in this project) |
| docs/AI_TOOLS_ADDING.md | How to add a new npm-based AI / CLI tool to the playbook |
| docs/linux/Virt-Manager_setup.md | virt-manager setup notes for Linux hosts |
| docs/macos/UTM_setup.md | UTM (Apple Virtualization) notes for macOS |
| docs/windows/VirtualBox_setup.md | VirtualBox notes for Windows hosts |
| utils/mouseMove/README.md | Tiny Windows script that nudges the mouse to keep sessions awake |