initial commit
This commit is contained in:
70
Jenkinsfile
vendored
Normal file
70
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
|
||||||
|
parameters {
|
||||||
|
string(
|
||||||
|
name: 'LIMIT',
|
||||||
|
defaultValue: '',
|
||||||
|
description: 'Target host(s)/group(s), e.g. "vms", "lxcs", "docker_hosts", "kubernetes", "update_targets", or a hostname (no .lan required). Leave blank to run against all machines.'
|
||||||
|
)
|
||||||
|
booleanParam(
|
||||||
|
name: 'DRY_RUN',
|
||||||
|
defaultValue: false,
|
||||||
|
description: 'Run in check mode (no changes made)'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
environment {
|
||||||
|
PROXMOX_URL = 'https://192.168.0.166:8006'
|
||||||
|
PROXMOX_USER = 'dynamic-inventory@pve'
|
||||||
|
PROXMOX_TOKEN_ID = 'dynamic-inventory'
|
||||||
|
PROXMOX_TOKEN_SECRET = credentials('PROXMOX_TOKEN_SECRET')
|
||||||
|
ANSIBLE_HOST_KEY_CHECKING = 'False'
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Checkout') {
|
||||||
|
steps {
|
||||||
|
checkout scm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Verify Inventory') {
|
||||||
|
steps {
|
||||||
|
sh '''
|
||||||
|
echo "Testing dynamic inventory connection..."
|
||||||
|
ansible-inventory -i inventories/inventory.proxmox.yml --list | head -10
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Run Playbook') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def limitFlag = params.LIMIT ? "--limit '${params.LIMIT}'" : ''
|
||||||
|
def checkFlag = params.DRY_RUN ? '--check --diff' : ''
|
||||||
|
|
||||||
|
echo "Limit: '${params.LIMIT ?: 'all'}'"
|
||||||
|
echo "Dry run: ${params.DRY_RUN}"
|
||||||
|
|
||||||
|
sh """
|
||||||
|
ansible-playbook \
|
||||||
|
-i inventories/inventory.proxmox.yml \
|
||||||
|
site.yml \
|
||||||
|
${limitFlag} \
|
||||||
|
${checkFlag}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
success {
|
||||||
|
echo "site.yml completed successfully (limit: ${params.LIMIT ?: 'all'})"
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
echo "site.yml failed (limit: ${params.LIMIT ?: 'all'})"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
91
README.md
Normal file
91
README.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# 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.
|
||||||
25
inventories/inventory.proxmox.yml
Normal file
25
inventories/inventory.proxmox.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Proxmox Dynamic Inventory
|
||||||
|
# Requires PROXMOX_TOKEN_SECRET environment variable to be set
|
||||||
|
plugin: community.proxmox.proxmox
|
||||||
|
url: https://192.168.0.166:8006
|
||||||
|
user: dynamic-inventory@pve
|
||||||
|
token_id: dynamic-inventory
|
||||||
|
validate_certs: false
|
||||||
|
want_facts: true
|
||||||
|
|
||||||
|
# Filter to only running machines
|
||||||
|
filters:
|
||||||
|
- proxmox_status == 'running'
|
||||||
|
|
||||||
|
# Group by Proxmox tags and type
|
||||||
|
groups:
|
||||||
|
vms: "'qemu' in proxmox_type"
|
||||||
|
lxcs: "'lxc' in proxmox_type"
|
||||||
|
# Tag-based groups - add tags in Proxmox to auto-group
|
||||||
|
update_targets: "'update' in (proxmox_tags | default([]))"
|
||||||
|
docker_hosts: "'docker' in (proxmox_tags | default([]))"
|
||||||
|
kubernetes: "'k8s' in (proxmox_tags | default([]))"
|
||||||
|
|
||||||
|
compose:
|
||||||
|
ansible_host: name + '.lan'
|
||||||
|
ansible_user: 'jenkins'
|
||||||
45
roles/container_isolation/files/group.containers
Normal file
45
roles/container_isolation/files/group.containers
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# /etc/group.containers
|
||||||
|
# Source of truth for container service groups. Sync to all Docker VMs
|
||||||
|
# and the NFS server using sync-container-users.sh. Append-only — add new
|
||||||
|
# lines here when adding containers, never renumber existing ones.
|
||||||
|
#
|
||||||
|
# Primary per-app groups mirror passwd.containers UIDs (2000-2099).
|
||||||
|
# Shared groups start at 3000 for cross-container access.
|
||||||
|
# format: name:x:GID:secondary,members
|
||||||
|
2fauth:x:2000:
|
||||||
|
audiobookshelf:x:2001:
|
||||||
|
authelia:x:2002:
|
||||||
|
bazarr:x:2003:
|
||||||
|
cronjobs:x:2004:
|
||||||
|
dashy:x:2005:
|
||||||
|
dingus-archiver:x:2006:
|
||||||
|
finance-app:x:2007:
|
||||||
|
firefly3:x:2008:
|
||||||
|
gitea:x:2009:
|
||||||
|
gotify:x:2010:
|
||||||
|
immich:x:2011:
|
||||||
|
it-tools:x:2012:
|
||||||
|
jellyfin:x:2013:
|
||||||
|
joplin:x:2014:
|
||||||
|
kiwix:x:2015:
|
||||||
|
music-orchestrator:x:2016:
|
||||||
|
nginxproxy:x:2017:
|
||||||
|
ombi:x:2018:
|
||||||
|
picoshare:x:2019:
|
||||||
|
prowlarr:x:2020:
|
||||||
|
qbittorrent:x:2021:
|
||||||
|
radarr:x:2022:
|
||||||
|
romm:x:2023:
|
||||||
|
sonarr:x:2024:
|
||||||
|
tandoor_recipes:x:2025:
|
||||||
|
vault:x:2026:
|
||||||
|
#
|
||||||
|
# Shared groups (cross-container access, GID range 3000+)
|
||||||
|
# mediapipeline: *arr apps + qbittorrent + jellyfin share the media/download
|
||||||
|
# folders (e.g. /var/NFSFolder/AppData/media). Ombi is request-only (talks
|
||||||
|
# to APIs, doesn't touch the filesystem) so it's excluded.
|
||||||
|
mediapipeline:x:3000:bazarr,prowlarr,qbittorrent,radarr,sonarr,jellyfin
|
||||||
|
#
|
||||||
|
# finance-app and dingus-archiver are isolated custom apps with no shared
|
||||||
|
# access — their primary groups above (2007, 2006) already cover them.
|
||||||
|
# No secondary group needed unless that changes.
|
||||||
34
roles/container_isolation/files/passwd.containers
Normal file
34
roles/container_isolation/files/passwd.containers
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# /etc/passwd.containers
|
||||||
|
# Source of truth for container service accounts. Sync to all Docker VMs
|
||||||
|
# and the NFS server using sync-container-users.sh. Append-only — add new
|
||||||
|
# lines here when adding containers, never renumber existing ones.
|
||||||
|
#
|
||||||
|
# UID range reserved: 2000-2099 (container service accounts)
|
||||||
|
# format: name:x:UID:GID::/nonexistent:/usr/sbin/nologin
|
||||||
|
2fauth:x:2000:2000::/nonexistent:/usr/sbin/nologin
|
||||||
|
audiobookshelf:x:2001:2001::/nonexistent:/usr/sbin/nologin
|
||||||
|
authelia:x:2002:2002::/nonexistent:/usr/sbin/nologin
|
||||||
|
bazarr:x:2003:2003::/nonexistent:/usr/sbin/nologin
|
||||||
|
cronjobs:x:2004:2004::/nonexistent:/usr/sbin/nologin
|
||||||
|
dashy:x:2005:2005::/nonexistent:/usr/sbin/nologin
|
||||||
|
dingus-archiver:x:2006:2006::/nonexistent:/usr/sbin/nologin
|
||||||
|
finance-app:x:2007:2007::/nonexistent:/usr/sbin/nologin
|
||||||
|
firefly3:x:2008:2008::/nonexistent:/usr/sbin/nologin
|
||||||
|
gitea:x:2009:2009::/nonexistent:/usr/sbin/nologin
|
||||||
|
gotify:x:2010:2010::/nonexistent:/usr/sbin/nologin
|
||||||
|
immich:x:2011:2011::/nonexistent:/usr/sbin/nologin
|
||||||
|
it-tools:x:2012:2012::/nonexistent:/usr/sbin/nologin
|
||||||
|
jellyfin:x:2013:2013::/nonexistent:/usr/sbin/nologin
|
||||||
|
joplin:x:2014:2014::/nonexistent:/usr/sbin/nologin
|
||||||
|
kiwix:x:2015:2015::/nonexistent:/usr/sbin/nologin
|
||||||
|
music-orchestrator:x:2016:2016::/nonexistent:/usr/sbin/nologin
|
||||||
|
nginxproxy:x:2017:2017::/nonexistent:/usr/sbin/nologin
|
||||||
|
ombi:x:2018:2018::/nonexistent:/usr/sbin/nologin
|
||||||
|
picoshare:x:2019:2019::/nonexistent:/usr/sbin/nologin
|
||||||
|
prowlarr:x:2020:2020::/nonexistent:/usr/sbin/nologin
|
||||||
|
qbittorrent:x:2021:2021::/nonexistent:/usr/sbin/nologin
|
||||||
|
radarr:x:2022:2022::/nonexistent:/usr/sbin/nologin
|
||||||
|
romm:x:2023:2023::/nonexistent:/usr/sbin/nologin
|
||||||
|
sonarr:x:2024:2024::/nonexistent:/usr/sbin/nologin
|
||||||
|
tandoor_recipes:x:2025:2025::/nonexistent:/usr/sbin/nologin
|
||||||
|
vault:x:2026:2026::/nonexistent:/usr/sbin/nologin
|
||||||
45
roles/container_isolation/tasks/jerick_access.yml
Normal file
45
roles/container_isolation/tasks/jerick_access.yml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
# roles/container_isolation/tasks/jerick_access.yml
|
||||||
|
#
|
||||||
|
# jerick needs read-write access across every app folder for admin/
|
||||||
|
# maintenance purposes, without weakening isolation between apps from
|
||||||
|
# each other. Achieved by making jerick a secondary member of every
|
||||||
|
# app's primary group, combined with 770 permissions on app folders
|
||||||
|
# (see nfs_folders.yml) — owner: full access, group (incl. jerick):
|
||||||
|
# full access, others: none.
|
||||||
|
|
||||||
|
- name: Check whether jerick exists on this host (read-only, does not create the account)
|
||||||
|
ansible.builtin.getent:
|
||||||
|
database: passwd
|
||||||
|
key: "{{ jerick_user }}"
|
||||||
|
register: jerick_lookup
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Warn if jerick user does not exist on this host
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: >-
|
||||||
|
WARNING: user '{{ jerick_user }}' was not found on this host.
|
||||||
|
This role does not create jerick's account (assumed to be a
|
||||||
|
pre-existing human user, not a service account). Create it first,
|
||||||
|
then re-run this role so jerick gets added to the app groups below.
|
||||||
|
when: jerick_lookup.failed | default(false)
|
||||||
|
|
||||||
|
- name: Add jerick to every app's primary group
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ jerick_user }}"
|
||||||
|
groups: "{{ item.name }}"
|
||||||
|
append: true
|
||||||
|
loop: "{{ container_apps }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ jerick_user }} -> {{ item.name }}"
|
||||||
|
when: not (jerick_lookup.failed | default(false))
|
||||||
|
|
||||||
|
- name: Add jerick to every shared group
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ jerick_user }}"
|
||||||
|
groups: "{{ item.name }}"
|
||||||
|
append: true
|
||||||
|
loop: "{{ shared_groups }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ jerick_user }} -> {{ item.name }}"
|
||||||
|
when: not (jerick_lookup.failed | default(false))
|
||||||
9
roles/container_isolation/tasks/main.yml
Normal file
9
roles/container_isolation/tasks/main.yml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
# roles/container_isolation/tasks/main.yml
|
||||||
|
|
||||||
|
- name: Sync container service groups and users (all hosts)
|
||||||
|
import_tasks: sync_users.yml
|
||||||
|
|
||||||
|
- name: Add jerick to every app and shared group (all hosts)
|
||||||
|
import_tasks: jerick_access.yml
|
||||||
|
|
||||||
49
roles/container_isolation/tasks/sync_users.yml
Normal file
49
roles/container_isolation/tasks/sync_users.yml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
---
|
||||||
|
# roles/container_isolation/tasks/sync_users.yml
|
||||||
|
#
|
||||||
|
# Creates each app's primary group + user, and each shared group, using
|
||||||
|
# Ansible's built-in group/user modules instead of hand-rolled file
|
||||||
|
# appends — this is idempotent and safe to re-run, and avoids the
|
||||||
|
# malformed-/etc/passwd risk of manual editing.
|
||||||
|
|
||||||
|
- name: Create primary group for each container app
|
||||||
|
ansible.builtin.group:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
gid: "{{ item.uid }}"
|
||||||
|
state: present
|
||||||
|
loop: "{{ container_apps }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }} (gid {{ item.uid }})"
|
||||||
|
|
||||||
|
- name: Create shared (secondary) groups
|
||||||
|
ansible.builtin.group:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
gid: "{{ item.gid }}"
|
||||||
|
state: present
|
||||||
|
loop: "{{ shared_groups }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }} (gid {{ item.gid }})"
|
||||||
|
|
||||||
|
- name: Create service user for each container app
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
uid: "{{ item.uid }}"
|
||||||
|
group: "{{ item.name }}"
|
||||||
|
shell: /usr/sbin/nologin
|
||||||
|
home: /nonexistent
|
||||||
|
create_home: false
|
||||||
|
system: true
|
||||||
|
state: present
|
||||||
|
loop: "{{ container_apps }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }} (uid {{ item.uid }})"
|
||||||
|
|
||||||
|
- name: Add app users to their shared groups
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ item.0.name }}"
|
||||||
|
groups: "{{ item.1.name }}"
|
||||||
|
append: true
|
||||||
|
loop: "{{ container_apps | product(shared_groups) | list }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.0.name }} -> {{ item.1.name }}"
|
||||||
|
when: item.0.name in item.1.members
|
||||||
58
roles/container_isolation/vars/main.yml
Normal file
58
roles/container_isolation/vars/main.yml
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
# roles/container_isolation/vars/main.yml
|
||||||
|
#
|
||||||
|
# Single source of truth for container service accounts. Mirrors
|
||||||
|
# files/passwd.containers and files/group.containers — keep in sync if
|
||||||
|
# you edit one, edit the other. Append-only: never renumber existing
|
||||||
|
# UIDs/GIDs once folders have been chowned on the NFS server.
|
||||||
|
|
||||||
|
jerick_user: jerick
|
||||||
|
|
||||||
|
# Every container service account. uid == primary gid for each.
|
||||||
|
# jerick is added as a secondary member of every app's primary group
|
||||||
|
# in the group sync task, giving him rw access (770) without weakening
|
||||||
|
# isolation between apps.
|
||||||
|
container_apps:
|
||||||
|
- { name: "2fauth", uid: 2000 }
|
||||||
|
- { name: "audiobookshelf", uid: 2001 }
|
||||||
|
- { name: "authelia", uid: 2002 }
|
||||||
|
- { name: "bazarr", uid: 2003 }
|
||||||
|
- { name: "cronjobs", uid: 2004 }
|
||||||
|
- { name: "dashy", uid: 2005 }
|
||||||
|
- { name: "dingus-archiver", uid: 2006 }
|
||||||
|
- { name: "finance-app", uid: 2007 }
|
||||||
|
- { name: "firefly3", uid: 2008 }
|
||||||
|
- { name: "gitea", uid: 2009 }
|
||||||
|
- { name: "gotify", uid: 2010 }
|
||||||
|
- { name: "immich", uid: 2011 }
|
||||||
|
- { name: "it-tools", uid: 2012 }
|
||||||
|
- { name: "jellyfin", uid: 2013 }
|
||||||
|
- { name: "joplin", uid: 2014 }
|
||||||
|
- { name: "kiwix", uid: 2015 }
|
||||||
|
- { name: "music-orchestrator", uid: 2016 }
|
||||||
|
- { name: "nginxproxy", uid: 2017 }
|
||||||
|
- { name: "ombi", uid: 2018 }
|
||||||
|
- { name: "picoshare", uid: 2019 }
|
||||||
|
- { name: "prowlarr", uid: 2020 }
|
||||||
|
- { name: "qbittorrent", uid: 2021 }
|
||||||
|
- { name: "radarr", uid: 2022 }
|
||||||
|
- { name: "romm", uid: 2023 }
|
||||||
|
- { name: "sonarr", uid: 2024 }
|
||||||
|
- { name: "tandoor_recipes", uid: 2025 }
|
||||||
|
- { name: "vault", uid: 2026 }
|
||||||
|
|
||||||
|
# Shared secondary groups for cross-container access. "members" lists
|
||||||
|
# app names from container_apps that need to be added to this group
|
||||||
|
# IN ADDITION to their own primary group. jerick is added automatically
|
||||||
|
# to every shared group as well as every per-app primary group — see
|
||||||
|
# tasks/sync_users.yml.
|
||||||
|
shared_groups:
|
||||||
|
- name: mediapipeline
|
||||||
|
gid: 3000
|
||||||
|
members:
|
||||||
|
- bazarr
|
||||||
|
- prowlarr
|
||||||
|
- qbittorrent
|
||||||
|
- radarr
|
||||||
|
- sonarr
|
||||||
|
- jellyfin
|
||||||
13
site.yml
Normal file
13
site.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
# site.yml
|
||||||
|
#
|
||||||
|
# Applies the container_isolation role to every host in inventory.
|
||||||
|
# Scope: service accounts only (groups + users + jerick's group
|
||||||
|
# memberships). Run against your dynamic inventory as-is — no group
|
||||||
|
# targeting needed since every host gets the same treatment.
|
||||||
|
|
||||||
|
- name: Configure container service accounts
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- container_isolation
|
||||||
Reference in New Issue
Block a user