Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions ansible/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,24 @@ the one operator list, `baseline_sudo_users`. Add other admins there — list yo
name) to override the auto-detected head with explicit keys. Set
`baseline_sudo_autodetect_runner: false` to skip the runner and provision only the explicit
list (e.g. from CI). baseline **asserts a non-root account with a key resolves** before
`ssh_hardening` disables root + password login, so you can't lock yourself out. After the
first deploy, switch each host's `ansible_user` to that admin account (your local username
unless you listed one).
`ssh_hardening` disables root + password login, so you can't lock yourself out.

The inventory template sets **no `ansible_user`**, so Ansible connects as your local `$USER`
— the same account baseline creates. That account doesn't exist yet on a fresh box, so
bootstrap each new host once as a sudo-capable user (root, or the image's default user such
as `ubuntu`):

```bash
make deploy LIMIT=decdn-node-1 ANSIBLE_ARGS='-u root' # first converge only; swap root for your image's bootstrap user
make deploy LIMIT=decdn-node-1 # every run after that first converge succeeds
```

Set a per-host `ansible_user` only when the admin account's name differs from your `$USER`
(you listed a different name in `baseline_sudo_users`) or you set
`baseline_sudo_autodetect_runner: false`. Never set it to the bootstrap user: an inventory
`ansible_user` beats `-u`, and root login is gone after the first converge. For the same
reason, add a per-host `ansible_user` only after that host's bootstrap run, or `-u` is
ignored on the first converge.

---

Expand Down Expand Up @@ -141,11 +156,11 @@ make deploy LIMIT='!decdn-node-2' # any ansible host pattern
Quote the pattern at your own prompt — your shell runs before make does, and eats a bare
`!decdn-node-2` (history expansion) or `decdn-node-*` (globbing).

Use `LIMIT` when **bringing up a new node**: that host's first converge creates the
operator account and then lets `ssh_hardening` disable root + password login — after which
you switch its `ansible_user` by hand (see [Setup](#setup) above; the converge does not
edit your inventory). You do not want that play re-converging nodes already serving
paid traffic. Same when re-running a single node after a config change, a failed play, or a
Use `LIMIT` when **bringing up a new node**: that host's first converge connects as the
bootstrap user (`ANSIBLE_ARGS='-u root'`, see [Setup](#setup) above), creates the operator
account and then lets `ssh_hardening` disable root + password login. Every later run
connects as your `$USER` with no flag. You do not want that bootstrap play — or its `-u root`
— reaching nodes already serving paid traffic. Same when re-running a single node after a config change, a failed play, or a
binary bump.

`make check`/`make deploy` refuse to run if `LIMIT` or `ANSIBLE_ARGS` reaches them from an
Expand Down
17 changes: 12 additions & 5 deletions ansible/inventory/hosts.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,17 @@
# template; your real hosts.yml is yours — commit it in your fork if you like, or keep
# it local. (Just never push real host IPs to the upstream template.)
#
# First run: connect as a user that can sudo (often root) to bootstrap the box.
# After the baseline role creates your admin account (the auto-detected runner, or an
# entry in baseline_sudo_users) and ssh_hardening disables root login, switch
# ansible_user to that admin account.
# No ansible_user by default: Ansible connects as your local $USER, which is the admin
# account the baseline role creates (the auto-detected runner). A fresh box doesn't have
# it yet, so bootstrap each new host ONCE as a user that can sudo (root, or the image's
# default user such as ubuntu):
# make deploy LIMIT=<host> ANSIBLE_ARGS='-u root' # swap root for your image's bootstrap user
# After that first converge ssh_hardening disables root login, and plain `make deploy`
# connects as $USER. Set a per-host ansible_user only if the admin account's name differs
# from your $USER (you listed another name in baseline_sudo_users) or you set
# baseline_sudo_autodetect_runner: false. Never set it to the bootstrap user: an
# inventory ansible_user overrides -u, and root login is gone after the first converge.
# For the same reason, add a per-host ansible_user only AFTER that host's bootstrap run.
#
# Ubuntu sudo-rs workaround: 25.10 (Questing) and 26.04 ship sudo-rs as the default
# /usr/bin/sudo. Ansible's sudo become plugin passes a custom `-p` prompt sentinel and
Expand All @@ -29,5 +36,5 @@ decdn_nodes:
hosts:
decdn-node-1:
ansible_host: REPLACE_WITH_NODE_VPS_IP_OR_DNS
ansible_user: root
# ansible_user: alice # post-bootstrap, only if the admin account's name ≠ your $USER — see note above
# ansible_become_exe: /usr/bin/sudo.ws # Ubuntu sudo-rs workaround — see note above
Loading