# macOS Configuration Personal macOS setup. This README is a complete, ordered runbook for setting up a fresh machine — follow it top to bottom and you end up with a working environment. Two kinds of files live here: - **Symlinked** — the file in this repo *is* the live config (fish, starship, ssh, kube, npm, NuGet). Edit either side, they're the same file. - **Copied** — files that can't be symlinked (`/etc/hosts`, Claude/Serena settings, the AWS config, the brewfile). Refresh them from the machine with `./update.fish`. ## Fresh machine setup — the fast way Get this repo onto the machine (USB stick copy or a clone) and run: ```bash /bin/bash setup.sh ``` The script is idempotent and does steps 1–9 below automatically: it copies the repo to `~/Repositories/personal/macos-configuration` (so it works straight off a USB stick), installs Command Line Tools and Homebrew, runs the brew bundle, creates all symlinks, restores the copied configs, sets fish as the default shell, and installs the .NET SDK. At the end it prints the manual steps that remain (1Password/SSH keys, iTerm2 profile import, `gh auth login` + repo cloning, WireGuard, app sign-ins). The sections below document what the script does, for reference or manual runs. ## Fresh machine setup — step by step ### 1. Install Command Line Tools and clone this repo ```bash xcode-select --install mkdir -p ~/Repositories/personal git clone https://github.com/awatertrevi/macos-configuration.git ~/Repositories/personal/macos-configuration cd ~/Repositories/personal/macos-configuration ``` (First clone happens over HTTPS; once 1Password + SSH are set up below, remotes work over SSH.) ### 2. Install Homebrew ```bash /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" eval "$(/opt/homebrew/bin/brew shellenv)" ``` ### 3. Install all packages, casks, and VS Code extensions ```bash brew bundle --file=brewfile ``` This installs everything: CLI tools (fish, gh, node, pnpm, uv, opentofu, …), apps (1Password, iTerm2, Docker Desktop, Fork, VS Code, …), fonts, and VS Code extensions. ### 4. Sign in to 1Password and enable the SSH agent Open 1Password → Settings → Developer → enable **SSH Agent**. The ssh-config symlinked below routes all SSH auth through the 1Password agent (`~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock`), so the private keys never live on disk — only the `.pub` files referenced in `ssh-config` need to exist in `~/.ssh/` (1Password can export them, or copy them from the old machine). ### 5. Symlink configuration files Run from the repo root: ```bash mkdir -p ~/.config/fish ~/.kube ~/.nuget/NuGet ln -sf $(pwd)/fish-config.fish ~/.config/fish/config.fish ln -sf $(pwd)/starship.toml ~/.config/starship.toml ln -sf $(pwd)/ssh-config ~/.ssh/config ln -sf $(pwd)/kube-config ~/.kube/config ln -sf $(pwd)/.npmrc ~/.npmrc ln -sf $(pwd)/NuGet.Config ~/.nuget/NuGet/NuGet.Config ``` ### 6. Restore the copied configs ```bash mkdir -p ~/.claude ~/.serena ~/.aws cp claude-settings.json ~/.claude/settings.json cp serena_config.yml ~/.serena/serena_config.yml cp aws-config ~/.aws/config sudo cp hosts /etc/hosts ``` (`aws-config` only holds profile definitions — the actual AWS credentials are set up later, in the "AWS + OpenTofu state access" step.) ### 7. Set fish as the default shell ```bash echo /opt/homebrew/bin/fish | sudo tee -a /etc/shells chsh -s /opt/homebrew/bin/fish ``` ### 8. Configure iTerm2 iTerm2 → Settings → Profiles → Other Actions → **Import JSON Profiles** → select `iterm-profile.json`, then set it as the default profile. (Requires the Fira Code Nerd Font installed in step 3.) ### 9. Install the .NET 10 SDK ```bash fish install-dotnet10.fish ``` Installs into `~/.dotnet` via the official dotnet-install script and prints the `fish_add_path` line to persist it if needed. ### 10. Clone work repositories ```bash gh auth login # authenticate the GitHub CLI first fish clone-resoftware-repos.fish ``` Clones every repo in the `resoftware` GitHub org via SSH into `~/Repositories/{customer-number}/{repo-name}`, based on each repo's `customer-number` custom property. Safe to re-run — existing clones are skipped. ### 11. AWS + OpenTofu state access (resoftware-iac) All OpenTofu state for `resoftware-iac` lives in the S3 bucket `resoftware-iac-state` (eu-north-1); the backend blocks in that repo reference the `resoftware-iac` AWS profile, so `tofu init` fails with *"failed to get shared config profile resoftware-iac"* until that profile exists. The `aws-config` restored in step 6 already defines both profiles in `~/.aws/config`: - `resoftware-iac` — the `iac` IAM user; used for the S3 state backend and plans. - `default` — a root login session (account 693091788121); used for applies via `aws configure export-credentials`. What can't live in git and must be set up by hand: ```bash aws configure --profile resoftware-iac ``` Enter the `iac` user's access key (from 1Password or the old machine's `~/.aws/credentials`; or mint a fresh key in the AWS console — IAM is deliberately console-managed, not IaC) and region `eu-north-1`. Beware if editing the files manually instead: `~/.aws/config` section headers carry a `profile ` prefix (`[profile resoftware-iac]`) but `~/.aws/credentials` headers do **not** (`[resoftware-iac]`) — mismatching them causes exactly the "failed to get shared config profile" error. `aws configure` writes both correctly. For applies, also establish the root session once: ```bash aws login ``` Then restore each stack's gitignored `terraform.tfvars` (Infisical machine-identity creds — copy securely from the old machine or refill from Infisical; currently only `infra/cloudflare/terraform.tfvars`), and verify: ```bash aws sts get-caller-identity --profile resoftware-iac cd ~/Repositories/kl0000/resoftware-iac/infra/cloudflare && tofu init ``` ### 12. WireGuard tunnel to home network (optional) `meerkoet-proxy.conf` is a WireGuard client config for the home (Fritz!Box) network. Import it into the WireGuard app (installable from the App Store) via **Import Tunnel(s) from File**. ### 13. Manual leftovers Things not automated here: - Sign in: iCloud, Chrome/Zen, Slack, Spark, Google Drive, Docker Desktop, Todoist. - JetBrains Toolbox → sign in and install the IDEs you use. - Grant permissions as apps ask (Bartender, BetterTouchTool, CleanShot, Mos, Cursr). - Alfred / BetterTouchTool: restore licenses and sync/import preferences. ## Keeping this repo up to date The symlinked files are always current by construction. Refresh the copied ones with: ```bash ./update.fish ``` It re-dumps the brewfile (`brew bundle dump --force`) and re-copies `~/.claude/settings.json`, `~/.serena/serena_config.yml`, `~/.aws/config`, and `/etc/hosts` into the repo. Review `git diff` afterwards and commit. (`~/.aws/credentials` is never tracked.)