2026-07-01 11:13:43 -04:00
2026-06-30 13:51:06 -04:00
2026-07-01 11:13:43 -04:00
2026-06-30 13:51:06 -04:00
2026-06-30 13:51:06 -04:00
2026-06-30 13:51:06 -04:00

container_isolation Ansible role

Creates per-app service accounts (UID/GID 2000+) on every host, so each Docker container can run as its own dedicated UID instead of root or a shared user. jerick is added as a secondary member of every app group (and the shared mediapipeline group), so jerick retains access everywhere regardless of whatever folder permissions you set up separately on the NFS server.

Scope: this role only manages accounts (groups + users). NFS folder creation, ownership, and permission bits are handled outside Ansible, by you, on the NFS server.

Layout

ansible/
├── site.yml                          # top-level playbook, hosts: all
└── roles/container_isolation/
    ├── tasks/
    │   ├── main.yml                  # entry point, includes the others
    │   ├── sync_users.yml            # creates groups + users on every host
    │   └── jerick_access.yml         # adds jerick to every group, every host
    ├── vars/main.yml                 # source of truth: app list, uids, shared groups
    └── files/
        ├── passwd.containers         # reference copy, human-readable
        └── group.containers          # reference copy, human-readable

vars/main.yml is what Ansible actually reads. The files/*.containers files are a human-readable reference / diff-friendly changelog — not consumed directly by any task, since the built-in group/user modules create accounts idempotently rather than appending raw lines to /etc/passwd.

Before running

  1. Point this at your dynamic inventory however you normally do, e.g.:
    ansible-playbook -i your_dynamic_inventory.py site.yml
    
    No inventory group targeting is needed — site.yml runs against hosts: all, and the role applies the same logic everywhere.
  2. Confirm jerick already exists as a real user on every host. The role does not create jerick's account (treated as a pre-existing human user) — it only adds jerick to the app groups. If jerick is missing on a host, the role prints a warning and skips the group-membership tasks for that host rather than failing the whole run.

Running

ansible-playbook -i your_dynamic_inventory.py site.yml --check --diff   # dry run first
ansible-playbook -i your_dynamic_inventory.py site.yml

Safe to re-run any time — every task uses Ansible's built-in idempotent modules (group, user), so a second run produces no changes.

Adding a new app later

  1. Add a line to roles/container_isolation/vars/main.yml under container_apps, with the next free UID (currently up to 2026 — use 2027 next). Never reuse or renumber an existing UID once real folders have been chowned to it on the NFS server.
  2. If it needs shared access to another app's data, add it to the relevant shared_groups[].members list (or create a new shared group, GID 3001+).
  3. Update files/passwd.containers and files/group.containers to match, for the human-readable record.
  4. Re-run the playbook.

What you still need to do yourself

  • NFS folder creation/ownership/permissions on the NFS server — chown <uid>:<gid> and chmod each app's folder using the UIDs/GIDs from vars/main.yml. With jerick in every app's group, 770 (owner+group rw, others none) gives jerick read-write access everywhere while keeping apps isolated from each other; 750 would make jerick read-only.
  • /etc/exports on the NFS server — not touched by this role.
  • docker-compose.yml edits — add user: "UID:GID" (and group_add: for apps in mediapipeline) to each service, using the UIDs from vars/main.yml. Happy to generate these once you share your compose files.
  • NFS protocol version / idmapping verification — confirm with nfsstat -m on a client before relying on numeric UID/GID matching across hosts; NFSv4 idmapping misconfiguration is the most common cause of permissions silently not working as expected.
Description
No description provided
Readme 35 KiB