diff --git a/playbooks/bootstrap-infra-ops-user.yaml b/playbooks/bootstrap-infra-ops-user.yaml index d4b50dc..5174815 100644 --- a/playbooks/bootstrap-infra-ops-user.yaml +++ b/playbooks/bootstrap-infra-ops-user.yaml @@ -24,21 +24,35 @@ # ALL FOUR PVE HYPERVISORS (pfi-pve, nh3-pve, esh-pve, # esh-pve-nas) DO get infra-ops — done that day. # PVE ships without sudo: `apt-get install sudo` first. +# Also granted by operator request: esh-docker-vm, +# esh-vm-db (2026-08-24) and vm-esh-nas (2026-09-27). # - nh3-nas (Synology DSM) (no standard useradd / sudoers.d) # # Idempotent: re-running reconciles the key + sudoers without error. vars: ops_user: infra-ops + ops_uid: "850" ops_pubkey: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN+1HBwfXrkfTYWdcnWCjLJ6VLAGC87gxH5h5vKaaA3c infra-ops@pfi-fleet" # Optional authorized_keys from="..." source restriction. Empty = none. # Hardening follow-up once per-path source IPs (LAN vs WG tunnel) are pinned. ssh_from: "" steps: - - name: Create the infra-ops system user (home + bash shell) + # New accounts get the fleet-pinned UID/GID 850 (docs/pfi/fleet-conventions.md § 3) + # when both are free. Otherwise the OS allocates, as every pre-2026-09-27 host did. + - name: Create the infra-ops system user (home + bash shell; uid/gid 850 when free) sudo: true - shell: useradd -m -s /bin/bash {{ ops_user }} + shell: | + set -eu + if ! getent passwd {{ ops_uid }} >/dev/null && ! getent group {{ ops_uid }} >/dev/null; then + groupadd -g {{ ops_uid }} {{ ops_user }} + useradd -m -s /bin/bash -u {{ ops_uid }} -g {{ ops_uid }} {{ ops_user }} + else + echo "uid/gid {{ ops_uid }} taken; letting the OS allocate" + useradd -m -s /bin/bash {{ ops_user }} + fi + chmod 0700 /home/{{ ops_user }} when: "! id {{ ops_user }} >/dev/null 2>&1" - name: Add infra-ops to the docker group (only if docker is installed)