92 lines
4.0 KiB
Markdown
92 lines
4.0 KiB
Markdown
# 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.:
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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.
|