mirror of
https://github.com/fscotto/infra.git
synced 2026-09-27 19:03:47 +00:00
Add Rocky 9 Atlas NAS profile
This commit is contained in:
42
AGENTS.md
42
AGENTS.md
@@ -16,6 +16,7 @@ Ansible-driven personal infrastructure repo for Fedora and Void desktops, FreeBS
|
|||||||
- Void desktop profile is also the base for other future/reference hosts via `platform_void + graphical_desktop`
|
- Void desktop profile is also the base for other future/reference hosts via `platform_void + graphical_desktop`
|
||||||
- Workstation: `deadalus` is Windows + Fedora WSL.
|
- Workstation: `deadalus` is Windows + Fedora WSL.
|
||||||
- Ubuntu server: `prometheus`
|
- Ubuntu server: `prometheus`
|
||||||
|
- NAS: `atlas` (Rocky Linux 9, reached through SSH)
|
||||||
- Hosts intentionally belong to multiple groups; trust `ansible/site.yml` over hostname assumptions.
|
- Hosts intentionally belong to multiple groups; trust `ansible/site.yml` over hostname assumptions.
|
||||||
- Inventory axes are independent: `platform_*`, `role_*`, and `desktop_*`. Legacy `void` and `desktop` remain compatibility parents.
|
- Inventory axes are independent: `platform_*`, `role_*`, and `desktop_*`. Legacy `void` and `desktop` remain compatibility parents.
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ Ansible-driven personal infrastructure repo for Fedora and Void desktops, FreeBS
|
|||||||
- Fedora laptop work: `ansible-playbook ansible/site.yml --limit nymph --check --diff`
|
- Fedora laptop work: `ansible-playbook ansible/site.yml --limit nymph --check --diff`
|
||||||
- WSL workstation dev: `ansible-playbook ansible/site.yml --limit deadalus --check --diff`
|
- WSL workstation dev: `ansible-playbook ansible/site.yml --limit deadalus --check --diff`
|
||||||
- Server: `ansible-playbook ansible/site.yml --limit prometheus --check --diff`
|
- Server: `ansible-playbook ansible/site.yml --limit prometheus --check --diff`
|
||||||
|
- Atlas NAS: `ansible-playbook ansible/site.yml --limit atlas --check --diff`
|
||||||
- Focused checks:
|
- Focused checks:
|
||||||
- Emacs is disabled by default; temporary Emacs check: `ansible-playbook ansible/site.yml --limit <host> --tags emacs --check --diff -e emacs_enabled=true`
|
- Emacs is disabled by default; temporary Emacs check: `ansible-playbook ansible/site.yml --limit <host> --tags emacs --check --diff -e emacs_enabled=true`
|
||||||
- Mail bootstrap: `sh -n scripts/bootstrap_mail.sh` and `shellcheck scripts/bootstrap_mail.sh`
|
- Mail bootstrap: `sh -n scripts/bootstrap_mail.sh` and `shellcheck scripts/bootstrap_mail.sh`
|
||||||
@@ -83,6 +85,46 @@ The dotfile vars follow the same split: `desktop_common_dotfiles` carries mode-i
|
|||||||
- Fedora WSL belongs to `platform_fedora`, `workstation_dev_fedora`, and the shared WSL layer. It must not receive Flatpak or Snap runtimes.
|
- Fedora WSL belongs to `platform_fedora`, `workstation_dev_fedora`, and the shared WSL layer. It must not receive Flatpak or Snap runtimes.
|
||||||
- Windows applications are installed manually and are not managed from the WSL profile.
|
- Windows applications are installed manually and are not managed from the WSL profile.
|
||||||
|
|
||||||
|
## Atlas NAS Notes
|
||||||
|
- `atlas` is a remote Rocky Linux 9 NAS. Keep its connection, LAN, pool and mountpoint values in
|
||||||
|
`host_vars/atlas.yml`. Bootstrap it once with `-e atlas_connection_username=<existing-admin>`;
|
||||||
|
subsequent runs use the dedicated Atlas account.
|
||||||
|
- The pool is pre-existing: never add pool creation, disk partitioning, RAIDZ creation, rollback,
|
||||||
|
or destruction to the Atlas profile.
|
||||||
|
- `atlas_manage_storage` and `atlas_manage_firewall` remain false until their placeholders are
|
||||||
|
replaced; only then may the profile manage datasets, shares and LAN-restricted firewall rules.
|
||||||
|
- Atlas requires `vault_atlas_authorized_ssh_keys`, `vault_atlas_admin_password_hash` for Cockpit
|
||||||
|
and, when storage is enabled, `vault_atlas_samba_password`. Never print these values.
|
||||||
|
- Atlas uses NFSv4 for Linux and SMB for Windows/WSL, restricted to the configured LAN. Snapshot,
|
||||||
|
Rclone, Prometheus pull and USB backup automation are intentionally deferred.
|
||||||
|
|
||||||
|
## Atlas NAS TODO
|
||||||
|
- Replace every Atlas `CHANGEME` value, provide the required Vault variables and validate the first
|
||||||
|
remote bootstrap on the real Rocky Linux 9 host. Enable `atlas_manage_storage` first and
|
||||||
|
`atlas_manage_firewall` only after confirming the pool, mountpoints, LAN subnet and firewalld zone.
|
||||||
|
- Validate the complete baseline on the target: OpenZFS kmod loading, existing pool import, dataset
|
||||||
|
mounts, SSH reconnect, Cockpit and all selected 45Drives plugins, NFSv4, SMB and Syncthing.
|
||||||
|
- Finalize dataset properties and the shared UID/GID, group and POSIX ACL model; test the same files
|
||||||
|
through both NFS and SMB before considering multiprotocol access complete.
|
||||||
|
- Add Ansible-managed ZFS snapshot retention and scrub timers. Use Cockpit Scheduler for visibility
|
||||||
|
or manual operations, not as the only source of configuration, and never automate snapshot rollback.
|
||||||
|
- Manage the Syncthing star topology, device IDs, folders, folder modes, ignore rules and protected GUI
|
||||||
|
or API access for the selected clients.
|
||||||
|
- Add Tailscale or WireGuard and corresponding LAN/VPN-only firewalld rules before enabling remote
|
||||||
|
services; never expose SSH, Cockpit, NFS, SMB or Syncthing through public port forwarding.
|
||||||
|
- Add the least-privilege Prometheus backup flow: remote dump generation, dedicated SSH identity,
|
||||||
|
pinned host key, atomic pull, verification, retention and an Atlas systemd service/timer.
|
||||||
|
- Add the encrypted Google Drive backup with Rclone Drive plus Crypt remotes, Vault-managed secrets,
|
||||||
|
snapshot-consistent sources, retries, logging, retention policy and a tested restore procedure.
|
||||||
|
- Add the UUID-bound offline USB backup with versioned rsync, locking, capacity checks, verification,
|
||||||
|
safe unmounting and a tested restore procedure; never trigger it for an arbitrary USB disk.
|
||||||
|
- Add monitoring and alerting for pool health, scrub/resilver, SMART data, temperatures, free space and
|
||||||
|
failed backup timers, plus a controlled Rocky kernel/OpenZFS update and reboot procedure.
|
||||||
|
- Document and test disaster recovery: rebuild Atlas with Ansible, import the existing pool, restore
|
||||||
|
from snapshot/USB/cloud, preserve Vault and Rclone recovery material offline, and define RPO/RTO.
|
||||||
|
- Optionally design iCloud photo ingestion as a separate workflow after the storage and backup layers
|
||||||
|
are validated; do not make it a dependency of the Atlas baseline.
|
||||||
|
|
||||||
## Coding Agent Notes
|
## Coding Agent Notes
|
||||||
- Shared agent packages live in `ai_agents_npm_packages` in `ansible/inventory/group_vars/all.yml`.
|
- Shared agent packages live in `ai_agents_npm_packages` in `ansible/inventory/group_vars/all.yml`.
|
||||||
- Shared agent dotfiles live in `ai_agents_dotfiles`; rendered configs live in `ai_agents_templates`.
|
- Shared agent dotfiles live in `ai_agents_dotfiles`; rendered configs live in `ai_agents_templates`.
|
||||||
|
|||||||
40
README.it.md
40
README.it.md
@@ -56,8 +56,8 @@ Il repository è diviso in due componenti principali:
|
|||||||
|
|
||||||
# Macchine gestite
|
# Macchine gestite
|
||||||
|
|
||||||
Il repository modella attualmente host Fedora/GNOME, una workstation Fedora WSL e un server Ubuntu.
|
Il repository modella attualmente host Fedora/GNOME, una workstation Fedora WSL, un server Ubuntu e
|
||||||
La composizione resta separata in assi indipendenti:
|
un NAS Rocky Linux 9. La composizione resta separata in assi indipendenti:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
common user environment
|
common user environment
|
||||||
@@ -75,6 +75,7 @@ Matrice target:
|
|||||||
| nymph | Fedora | Desktop laptop | GNOME |
|
| nymph | Fedora | Desktop laptop | GNOME |
|
||||||
| deadalus | Fedora WSL | Workstation dev | — |
|
| deadalus | Fedora WSL | Workstation dev | — |
|
||||||
| prometheus | Ubuntu | Server | — |
|
| prometheus | Ubuntu | Server | — |
|
||||||
|
| atlas | Rocky 9 | NAS | — |
|
||||||
|
|
||||||
Regola operativa:
|
Regola operativa:
|
||||||
|
|
||||||
@@ -93,6 +94,7 @@ Nota sullo stato attuale del playbook principale:
|
|||||||
- `ansible/site.yml` applica oggi in automatico Fedora/GNOME su `ikaros` e `nymph`
|
- `ansible/site.yml` applica oggi in automatico Fedora/GNOME su `ikaros` e `nymph`
|
||||||
- `ansible/site.yml` applica il profilo Fedora WSL alla workstation `deadalus`
|
- `ansible/site.yml` applica il profilo Fedora WSL alla workstation `deadalus`
|
||||||
- `ansible/site.yml` applica anche il profilo `ubuntu_server` con baseline apt, systemd, dotfiles server e firewall UFW
|
- `ansible/site.yml` applica anche il profilo `ubuntu_server` con baseline apt, systemd, dotfiles server e firewall UFW
|
||||||
|
- `ansible/site.yml` applica il profilo NAS Rocky su `atlas` tramite SSH remoto
|
||||||
|
|
||||||
## Desktop
|
## Desktop
|
||||||
|
|
||||||
@@ -200,6 +202,33 @@ ansible-playbook ansible/site.yml --limit prometheus -e server_username=myuser -
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## NAS
|
||||||
|
|
||||||
|
`atlas` e un NAS Rocky Linux 9 raggiunto tramite SSH. Il pool ZFS esiste gia: il profilo gestisce
|
||||||
|
solo i dataset figli e non deve mai creare, partizionare, distruggere, fare rollback o modificare il
|
||||||
|
pool. I client Linux usano NFSv4, quelli Windows/WSL SMB; entrambi restano limitati alla LAN
|
||||||
|
configurata.
|
||||||
|
|
||||||
|
Per il primo avvio sostituire i placeholder Atlas e fornire
|
||||||
|
`vault_atlas_authorized_ssh_keys`, `vault_atlas_admin_password_hash` e
|
||||||
|
`vault_atlas_samba_password`. Eseguire il bootstrap tramite l'amministratore esistente:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook ansible/site.yml --limit atlas \
|
||||||
|
-e atlas_connection_username=<existing-admin>
|
||||||
|
```
|
||||||
|
|
||||||
|
`vault_atlas_admin_password_hash` deve essere un hash compatibile con `/etc/shadow`, non una
|
||||||
|
password Cockpit in chiaro. Le esecuzioni successive usano `atlas_admin_username`. Abilitare
|
||||||
|
`atlas_manage_storage` solo dopo aver verificato pool e mountpoint esistenti; abilitare
|
||||||
|
`atlas_manage_firewall` solo dopo aver verificato subnet LAN e zona firewalld attiva.
|
||||||
|
|
||||||
|
Restano da implementare retention delle snapshot, topologia Syncthing, VPN, pull da Prometheus,
|
||||||
|
Rclone, backup USB, monitoraggio e test di disaster recovery. Il backlog operativo dettagliato e in
|
||||||
|
`AGENTS.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# Composizione della configurazione
|
# Composizione della configurazione
|
||||||
|
|
||||||
Emacs è abilitato sui profili Fedora/GNOME e workstation; la configurazione canonica è distribuita da `dotfiles_common`, con Org in `~/Org/`, template versionati e export PDF/HTML/Markdown/DOCX/ODT. Per abilitarlo temporaneamente su un altro profilo:
|
Emacs è abilitato sui profili Fedora/GNOME e workstation; la configurazione canonica è distribuita da `dotfiles_common`, con Org in `~/Org/`, template versionati e export PDF/HTML/Markdown/DOCX/ODT. Per abilitarlo temporaneamente su un altro profilo:
|
||||||
@@ -247,6 +276,7 @@ I principali ruoli attualmente presenti sono:
|
|||||||
| packages_freebsd | installazione pacchetti su FreeBSD via pkg |
|
| packages_freebsd | installazione pacchetti su FreeBSD via pkg |
|
||||||
| packages_ubuntu | installazione pacchetti su Ubuntu |
|
| packages_ubuntu | installazione pacchetti su Ubuntu |
|
||||||
| packages_fedora | installazione pacchetti su Fedora |
|
| packages_fedora | installazione pacchetti su Fedora |
|
||||||
|
| packages_rocky | installazione pacchetti su Rocky Linux 9 |
|
||||||
| services_runit | gestione servizi runit |
|
| services_runit | gestione servizi runit |
|
||||||
| services_systemd | gestione servizi systemd |
|
| services_systemd | gestione servizi systemd |
|
||||||
| services_freebsd | gestione servizi FreeBSD dichiarati per host |
|
| services_freebsd | gestione servizi FreeBSD dichiarati per host |
|
||||||
@@ -259,6 +289,7 @@ I principali ruoli attualmente presenti sono:
|
|||||||
| profile_workstation_dev_common | configurazione dev workstation condivisa |
|
| profile_workstation_dev_common | configurazione dev workstation condivisa |
|
||||||
| profile_workstation_dev_wsl | configurazione WSL condivisa per sviluppo |
|
| profile_workstation_dev_wsl | configurazione WSL condivisa per sviluppo |
|
||||||
| profile_server | configurazione server |
|
| profile_server | configurazione server |
|
||||||
|
| profile_atlas | configurazione NAS Rocky Linux 9 |
|
||||||
| dotfiles_common | distribuzione dotfiles comuni |
|
| dotfiles_common | distribuzione dotfiles comuni |
|
||||||
| dotfiles | distribuzione configurazioni utente |
|
| dotfiles | distribuzione configurazioni utente |
|
||||||
|
|
||||||
@@ -274,6 +305,8 @@ platform_void -> packages_void + services_runit
|
|||||||
platform_void & graphical_desktop -> profile_desktop_common + profile_desktop_sway + profile_desktop_niri + profile_desktop_host
|
platform_void & graphical_desktop -> profile_desktop_common + profile_desktop_sway + profile_desktop_niri + profile_desktop_host
|
||||||
platform_freebsd -> packages_freebsd + services_freebsd
|
platform_freebsd -> packages_freebsd + services_freebsd
|
||||||
platform_fedora -> packages_fedora + services_systemd
|
platform_fedora -> packages_fedora + services_systemd
|
||||||
|
platform_rocky -> packages_rocky + services_systemd
|
||||||
|
atlas -> profile_atlas
|
||||||
platform_fedora & role_personal_workstation -> profile_personal_workstation
|
platform_fedora & role_personal_workstation -> profile_personal_workstation
|
||||||
platform_fedora & desktop_gnome -> profile_desktop_gnome
|
platform_fedora & desktop_gnome -> profile_desktop_gnome
|
||||||
workstation_dev_fedora -> profile_workstation_dev_common
|
workstation_dev_fedora -> profile_workstation_dev_common
|
||||||
@@ -288,6 +321,7 @@ Questo significa che, allo stato attuale:
|
|||||||
- il profilo Void resta selezionabile tramite `platform_void + graphical_desktop` per host futuri
|
- il profilo Void resta selezionabile tramite `platform_void + graphical_desktop` per host futuri
|
||||||
- `deadalus` riceve il profilo Fedora WSL tramite play dev dedicati
|
- `deadalus` riceve il profilo Fedora WSL tramite play dev dedicati
|
||||||
- il server Ubuntu (`prometheus`) e gestito con pacchetti, servizi, dotfiles server e firewall
|
- il server Ubuntu (`prometheus`) e gestito con pacchetti, servizi, dotfiles server e firewall
|
||||||
|
- il NAS Rocky (`atlas`) usa un pool ZFS gia esistente, condivisioni NFSv4/SMB limitate alla LAN e Cockpit/45Drives
|
||||||
- lo stack container server include `navidrome`, `postgres`, `gitea`, `nginx-proxy-manager` e `syncthing`, con GUI Syncthing raggiungibile tramite la rete Docker `web`
|
- lo stack container server include `navidrome`, `postgres`, `gitea`, `nginx-proxy-manager` e `syncthing`, con GUI Syncthing raggiungibile tramite la rete Docker `web`
|
||||||
|
|
||||||
# Dotfiles
|
# Dotfiles
|
||||||
@@ -364,6 +398,7 @@ Allo stato attuale questo comando:
|
|||||||
- per `platform_fedora & desktop_gnome` applica il profilo GNOME a `ikaros` e `nymph`
|
- per `platform_fedora & desktop_gnome` applica il profilo GNOME a `ikaros` e `nymph`
|
||||||
- per `workstation_dev_wsl` applica i tweak WSL dopo il layer Fedora a `deadalus`, escludendo Flatpak e Snap
|
- per `workstation_dev_wsl` applica i tweak WSL dopo il layer Fedora a `deadalus`, escludendo Flatpak e Snap
|
||||||
- per gli host `ubuntu_server` applica pacchetti Ubuntu, servizi systemd, profilo server, UFW, dotfiles e template dedicati
|
- per gli host `ubuntu_server` applica pacchetti Ubuntu, servizi systemd, profilo server, UFW, dotfiles e template dedicati
|
||||||
|
- per `platform_rocky` applica pacchetti Rocky e servizi systemd ad `atlas`, quindi il profilo NAS dedicato
|
||||||
- non riavvia automaticamente il display manager
|
- non riavvia automaticamente il display manager
|
||||||
- carica `secrets/vault.yml` solo se presente
|
- carica `secrets/vault.yml` solo se presente
|
||||||
- carica `secrets/vault.local.yml` solo se presente, dopo `vault.yml`, cosi gli override locali hanno precedenza
|
- carica `secrets/vault.local.yml` solo se presente, dopo `vault.yml`, cosi gli override locali hanno precedenza
|
||||||
@@ -377,6 +412,7 @@ ansible-playbook ansible/site.yml --limit ikaros --check --diff
|
|||||||
ansible-playbook ansible/site.yml --limit nymph --check --diff
|
ansible-playbook ansible/site.yml --limit nymph --check --diff
|
||||||
ansible-playbook ansible/site.yml --limit deadalus --check --diff
|
ansible-playbook ansible/site.yml --limit deadalus --check --diff
|
||||||
ansible-playbook ansible/site.yml --limit prometheus --check --diff
|
ansible-playbook ansible/site.yml --limit prometheus --check --diff
|
||||||
|
ansible-playbook ansible/site.yml --limit atlas --check --diff
|
||||||
ansible-lint ansible/site.yml
|
ansible-lint ansible/site.yml
|
||||||
ansible-lint ansible/roles
|
ansible-lint ansible/roles
|
||||||
yamllint ansible/
|
yamllint ansible/
|
||||||
|
|||||||
35
README.md
35
README.md
@@ -36,7 +36,8 @@ infra/
|
|||||||
|
|
||||||
## Managed machines
|
## Managed machines
|
||||||
|
|
||||||
The repo currently covers Fedora/GNOME desktops, one Fedora WSL workstation, and an Ubuntu server. Configuration is layered instead of being tied to host names:
|
The repo currently covers Fedora/GNOME desktops, one Fedora WSL workstation, an Ubuntu server, and
|
||||||
|
a Rocky Linux 9 NAS. Configuration is layered instead of being tied to host names:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
common user environment
|
common user environment
|
||||||
@@ -52,6 +53,7 @@ common user environment
|
|||||||
| `nymph` | Fedora | Desktop laptop | GNOME |
|
| `nymph` | Fedora | Desktop laptop | GNOME |
|
||||||
| `deadalus` | Fedora WSL | Development workstation | — |
|
| `deadalus` | Fedora WSL | Development workstation | — |
|
||||||
| `prometheus` | Ubuntu | Server | — |
|
| `prometheus` | Ubuntu | Server | — |
|
||||||
|
| `atlas` | Rocky 9 | NAS | — |
|
||||||
|
|
||||||
```text
|
```text
|
||||||
ikaros must be boring
|
ikaros must be boring
|
||||||
@@ -110,6 +112,31 @@ ansible-playbook ansible/site.yml --limit prometheus \
|
|||||||
-e server_user_home=/srv/myuser
|
-e server_user_home=/srv/myuser
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## NAS
|
||||||
|
|
||||||
|
`atlas` is a Rocky Linux 9 NAS reached through SSH. Its pool already exists: the profile only
|
||||||
|
manages child datasets and must never create, partition, destroy, roll back, or otherwise alter the
|
||||||
|
pool itself. Linux clients use NFSv4 and Windows/WSL clients use SMB; both are restricted to the
|
||||||
|
configured LAN.
|
||||||
|
|
||||||
|
For the first run, replace the Atlas placeholders and provide
|
||||||
|
`vault_atlas_authorized_ssh_keys`, `vault_atlas_admin_password_hash`, and
|
||||||
|
`vault_atlas_samba_password`. Bootstrap the host through its existing administrator:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook ansible/site.yml --limit atlas \
|
||||||
|
-e atlas_connection_username=<existing-admin>
|
||||||
|
```
|
||||||
|
|
||||||
|
`vault_atlas_admin_password_hash` must be an `/etc/shadow`-compatible hash, not a clear-text
|
||||||
|
Cockpit password. Subsequent runs use `atlas_admin_username`. Enable
|
||||||
|
`atlas_manage_storage` only after checking the existing pool and mountpoints; enable
|
||||||
|
`atlas_manage_firewall` only after checking the LAN subnet and active firewalld zone.
|
||||||
|
|
||||||
|
Snapshot retention, Syncthing topology, VPN access, Prometheus pulls, Rclone, USB backup,
|
||||||
|
monitoring, and disaster-recovery tests remain follow-up work. The detailed operational backlog is
|
||||||
|
kept in `AGENTS.md`.
|
||||||
|
|
||||||
## How layering works
|
## How layering works
|
||||||
|
|
||||||
A host can intentionally belong to more than one inventory group. The final configuration is the combination of the host and its groups, not a one-host/one-play mapping.
|
A host can intentionally belong to more than one inventory group. The final configuration is the combination of the host and its groups, not a one-host/one-play mapping.
|
||||||
@@ -146,6 +173,7 @@ ansible-playbook ansible/site.yml --limit <host> --tags emacs -e emacs_enabled=t
|
|||||||
| `packages_freebsd` | Installs packages on FreeBSD with pkg. |
|
| `packages_freebsd` | Installs packages on FreeBSD with pkg. |
|
||||||
| `packages_ubuntu` | Installs packages on Ubuntu. |
|
| `packages_ubuntu` | Installs packages on Ubuntu. |
|
||||||
| `packages_fedora` | Installs packages on Fedora. |
|
| `packages_fedora` | Installs packages on Fedora. |
|
||||||
|
| `packages_rocky` | Installs packages on Rocky Linux 9. |
|
||||||
| `services_runit` | Manages runit services. |
|
| `services_runit` | Manages runit services. |
|
||||||
| `services_systemd` | Manages systemd services. |
|
| `services_systemd` | Manages systemd services. |
|
||||||
| `services_freebsd` | Manages declared FreeBSD rc services. |
|
| `services_freebsd` | Manages declared FreeBSD rc services. |
|
||||||
@@ -158,6 +186,7 @@ ansible-playbook ansible/site.yml --limit <host> --tags emacs -e emacs_enabled=t
|
|||||||
| `profile_workstation_dev_common` | Shared workstation development setup. |
|
| `profile_workstation_dev_common` | Shared workstation development setup. |
|
||||||
| `profile_workstation_dev_wsl` | WSL development setup. |
|
| `profile_workstation_dev_wsl` | WSL development setup. |
|
||||||
| `profile_server` | Server setup. |
|
| `profile_server` | Server setup. |
|
||||||
|
| `profile_atlas` | Rocky Linux 9 NAS setup. |
|
||||||
| `dotfiles_common` | Shared user dotfiles. |
|
| `dotfiles_common` | Shared user dotfiles. |
|
||||||
|
|
||||||
## What `site.yml` runs
|
## What `site.yml` runs
|
||||||
@@ -168,6 +197,8 @@ platform_void -> packages_void + services_runit
|
|||||||
platform_void & graphical_desktop -> profile_desktop_common + profile_desktop_sway + profile_desktop_niri + profile_desktop_host
|
platform_void & graphical_desktop -> profile_desktop_common + profile_desktop_sway + profile_desktop_niri + profile_desktop_host
|
||||||
platform_freebsd -> packages_freebsd + services_freebsd
|
platform_freebsd -> packages_freebsd + services_freebsd
|
||||||
platform_fedora -> packages_fedora + services_systemd
|
platform_fedora -> packages_fedora + services_systemd
|
||||||
|
platform_rocky -> packages_rocky + services_systemd
|
||||||
|
atlas -> profile_atlas
|
||||||
platform_fedora & role_personal_workstation -> profile_personal_workstation
|
platform_fedora & role_personal_workstation -> profile_personal_workstation
|
||||||
platform_fedora & desktop_gnome -> profile_desktop_gnome
|
platform_fedora & desktop_gnome -> profile_desktop_gnome
|
||||||
workstation_dev_fedora -> profile_workstation_dev_common
|
workstation_dev_fedora -> profile_workstation_dev_common
|
||||||
@@ -180,6 +211,7 @@ So, in practice:
|
|||||||
- `platform_fedora` configures `ikaros`, `nymph`, and `deadalus`.
|
- `platform_fedora` configures `ikaros`, `nymph`, and `deadalus`.
|
||||||
- `deadalus` gets the Fedora development layer followed by the WSL layer.
|
- `deadalus` gets the Fedora development layer followed by the WSL layer.
|
||||||
- `ubuntu_server` configures `prometheus`.
|
- `ubuntu_server` configures `prometheus`.
|
||||||
|
- `atlas` receives the Rocky platform layer and the NAS profile through SSH.
|
||||||
- Empty `platform_void` and `platform_freebsd` groups do nothing until they get a host.
|
- Empty `platform_void` and `platform_freebsd` groups do nothing until they get a host.
|
||||||
- The playbook never restarts the display manager during a run.
|
- The playbook never restarts the display manager during a run.
|
||||||
- `secrets/vault.yml` and then `secrets/vault.local.yml` are loaded only when present.
|
- `secrets/vault.yml` and then `secrets/vault.local.yml` are loaded only when present.
|
||||||
@@ -218,6 +250,7 @@ ansible-playbook ansible/site.yml --limit ikaros --check --diff
|
|||||||
ansible-playbook ansible/site.yml --limit nymph --check --diff
|
ansible-playbook ansible/site.yml --limit nymph --check --diff
|
||||||
ansible-playbook ansible/site.yml --limit deadalus --check --diff
|
ansible-playbook ansible/site.yml --limit deadalus --check --diff
|
||||||
ansible-playbook ansible/site.yml --limit prometheus --check --diff
|
ansible-playbook ansible/site.yml --limit prometheus --check --diff
|
||||||
|
ansible-playbook ansible/site.yml --limit atlas --check --diff
|
||||||
ansible-lint ansible/site.yml
|
ansible-lint ansible/site.yml
|
||||||
ansible-lint ansible/roles
|
ansible-lint ansible/roles
|
||||||
yamllint ansible/
|
yamllint ansible/
|
||||||
|
|||||||
32
ansible/inventory/group_vars/platform_rocky.yml
Normal file
32
ansible/inventory/group_vars/platform_rocky.yml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
platform_profile: rocky
|
||||||
|
platform_family: redhat
|
||||||
|
platform_package_manager: dnf
|
||||||
|
platform_service_manager: systemd
|
||||||
|
|
||||||
|
rocky_openzfs_release_rpm: https://zfsonlinux.org/epel/zfs-release-3-0.el9.noarch.rpm
|
||||||
|
rocky_syncthing_version: 2.1.3
|
||||||
|
rocky_syncthing_archive_checksum: sha256:f929eb8e5b72a85543eeeefb2c38f34a68e0c530e70758a2905b78840c76602c
|
||||||
|
rocky_syncthing_archive_url: >-
|
||||||
|
{{
|
||||||
|
'https://github.com/syncthing/syncthing/releases/download/v'
|
||||||
|
~ rocky_syncthing_version
|
||||||
|
~ '/syncthing-linux-amd64-v'
|
||||||
|
~ rocky_syncthing_version
|
||||||
|
~ '.tar.gz'
|
||||||
|
}}
|
||||||
|
|
||||||
|
enabled_services:
|
||||||
|
- firewalld
|
||||||
|
|
||||||
|
rocky_packages_base:
|
||||||
|
- cockpit
|
||||||
|
- dnf-plugins-core
|
||||||
|
- firewalld
|
||||||
|
- nfs-utils
|
||||||
|
- openssh-server
|
||||||
|
- policycoreutils-python-utils
|
||||||
|
- rsync
|
||||||
|
- samba
|
||||||
|
- sudo
|
||||||
|
- zfs
|
||||||
50
ansible/inventory/host_vars/atlas.yml
Normal file
50
ansible/inventory/host_vars/atlas.yml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
# Replace every CHANGEME value before enabling Atlas storage management.
|
||||||
|
hostname: atlas
|
||||||
|
ansible_host: CHANGEME_ATLAS_HOST
|
||||||
|
ansible_user: "{{ atlas_connection_username }}"
|
||||||
|
ansible_port: 22
|
||||||
|
ansible_ssh_private_key_file: CHANGEME_ATLAS_SSH_PRIVATE_KEY_PATH
|
||||||
|
|
||||||
|
atlas_admin_username: CHANGEME_ATLAS_ADMIN
|
||||||
|
atlas_connection_username: "{{ atlas_admin_username }}"
|
||||||
|
atlas_admin_group: "{{ atlas_admin_username }}"
|
||||||
|
atlas_admin_home: "/home/{{ atlas_admin_username }}"
|
||||||
|
atlas_admin_uid: 1000
|
||||||
|
atlas_admin_gid: 1000
|
||||||
|
atlas_admin_ssh_keys: "{{ vault_atlas_authorized_ssh_keys | default([]) }}"
|
||||||
|
atlas_admin_password_hash: "{{ vault_atlas_admin_password_hash | default('!') }}"
|
||||||
|
|
||||||
|
atlas_lan_subnet: CHANGEME_LAN_SUBNET
|
||||||
|
atlas_manage_firewall: false
|
||||||
|
atlas_firewalld_zone: public
|
||||||
|
atlas_zfs_pool: CHANGEME_ZFS_POOL
|
||||||
|
atlas_zfs_dataset_work: work
|
||||||
|
atlas_zfs_dataset_syncthing: syncthing
|
||||||
|
atlas_zfs_dataset_backup_prometheus: backup_prometheus
|
||||||
|
atlas_zfs_dataset_icloud_photos: icloud_photos
|
||||||
|
atlas_mount_root: /CHANGEME_ATLAS_MOUNT_ROOT
|
||||||
|
atlas_manage_storage: false
|
||||||
|
|
||||||
|
atlas_nfs_exports:
|
||||||
|
- path: "{{ atlas_work_mountpoint }}"
|
||||||
|
clients: "{{ atlas_lan_subnet }}(rw,sync,no_subtree_check,root_squash)"
|
||||||
|
|
||||||
|
atlas_samba_share_name: work
|
||||||
|
atlas_samba_workgroup: WORKGROUP
|
||||||
|
atlas_samba_valid_users:
|
||||||
|
- "{{ atlas_admin_username }}"
|
||||||
|
atlas_samba_password: "{{ vault_atlas_samba_password | default('') }}"
|
||||||
|
|
||||||
|
atlas_firewalld_rich_rules:
|
||||||
|
- 'rule family="ipv4" source address="{{ atlas_lan_subnet }}" service name="ssh" accept'
|
||||||
|
- 'rule family="ipv4" source address="{{ atlas_lan_subnet }}" service name="cockpit" accept'
|
||||||
|
- 'rule family="ipv4" source address="{{ atlas_lan_subnet }}" port port="2049" protocol="tcp" accept'
|
||||||
|
- 'rule family="ipv4" source address="{{ atlas_lan_subnet }}" service name="samba" accept'
|
||||||
|
|
||||||
|
host_enabled_services:
|
||||||
|
- sshd
|
||||||
|
- cockpit.socket
|
||||||
|
- nfs-server
|
||||||
|
- smb
|
||||||
|
- zfs.target
|
||||||
@@ -16,6 +16,10 @@ all:
|
|||||||
platform_freebsd:
|
platform_freebsd:
|
||||||
hosts: {}
|
hosts: {}
|
||||||
|
|
||||||
|
platform_rocky:
|
||||||
|
hosts:
|
||||||
|
atlas:
|
||||||
|
|
||||||
void:
|
void:
|
||||||
children:
|
children:
|
||||||
platform_void:
|
platform_void:
|
||||||
@@ -24,6 +28,10 @@ all:
|
|||||||
children:
|
children:
|
||||||
platform_fedora:
|
platform_fedora:
|
||||||
|
|
||||||
|
rocky:
|
||||||
|
children:
|
||||||
|
platform_rocky:
|
||||||
|
|
||||||
graphical_desktop:
|
graphical_desktop:
|
||||||
hosts:
|
hosts:
|
||||||
ikaros:
|
ikaros:
|
||||||
|
|||||||
151
ansible/roles/packages_rocky/tasks/main.yml
Normal file
151
ansible/roles/packages_rocky/tasks/main.yml
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
---
|
||||||
|
- name: Require Rocky Linux 9
|
||||||
|
tags: [packages]
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- ansible_facts['distribution'] == 'Rocky'
|
||||||
|
- ansible_facts['distribution_major_version'] == '9'
|
||||||
|
fail_msg: This platform role supports Rocky Linux 9 only.
|
||||||
|
|
||||||
|
- name: Install DNF configuration plugin
|
||||||
|
tags: [packages]
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: dnf-plugins-core
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Enable Rocky CodeReady Builder repository
|
||||||
|
tags: [packages]
|
||||||
|
community.general.dnf_config_manager:
|
||||||
|
name:
|
||||||
|
- crb
|
||||||
|
state: enabled
|
||||||
|
when: rocky_enable_crb | default(true) | bool
|
||||||
|
|
||||||
|
- name: Install EPEL repository package
|
||||||
|
tags: [packages]
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: epel-release
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install official OpenZFS repository package
|
||||||
|
tags: [packages, storage]
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: "{{ rocky_openzfs_release_rpm }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Disable OpenZFS DKMS repository
|
||||||
|
tags: [packages, storage]
|
||||||
|
community.general.dnf_config_manager:
|
||||||
|
name:
|
||||||
|
- zfs
|
||||||
|
state: disabled
|
||||||
|
|
||||||
|
- name: Enable OpenZFS kmod repository
|
||||||
|
tags: [packages, storage]
|
||||||
|
community.general.dnf_config_manager:
|
||||||
|
name:
|
||||||
|
- zfs-kmod
|
||||||
|
state: enabled
|
||||||
|
|
||||||
|
- name: Refresh Rocky package metadata
|
||||||
|
tags: [packages]
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Install packages on Rocky Linux
|
||||||
|
tags: [packages]
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: >-
|
||||||
|
{{
|
||||||
|
(
|
||||||
|
(common_packages | default([]))
|
||||||
|
+ (rocky_packages_base | default([]))
|
||||||
|
+ (profile_packages | default([]))
|
||||||
|
+ (host_packages | default([]))
|
||||||
|
) | unique
|
||||||
|
}}
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Require supported architecture for Syncthing
|
||||||
|
tags: [packages, syncthing]
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- ansible_facts['architecture'] == 'x86_64'
|
||||||
|
fail_msg: The pinned Atlas Syncthing binary currently supports x86_64 only.
|
||||||
|
|
||||||
|
- name: Read installed Syncthing version
|
||||||
|
tags: [packages, syncthing]
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- /usr/local/bin/syncthing
|
||||||
|
- --version
|
||||||
|
register: rocky_syncthing_version_check
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
check_mode: false
|
||||||
|
|
||||||
|
- name: Determine whether Syncthing must be installed
|
||||||
|
tags: [packages, syncthing]
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
rocky_syncthing_install_required: >-
|
||||||
|
{{
|
||||||
|
('syncthing v' ~ rocky_syncthing_version ~ ' ')
|
||||||
|
not in (rocky_syncthing_version_check.stdout | default(''))
|
||||||
|
}}
|
||||||
|
|
||||||
|
- name: Create temporary Syncthing extraction directory
|
||||||
|
tags: [packages, syncthing]
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/tmp/syncthing-{{ rocky_syncthing_version }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
when: rocky_syncthing_install_required | bool
|
||||||
|
|
||||||
|
- name: Download pinned Syncthing release
|
||||||
|
tags: [packages, syncthing]
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "{{ rocky_syncthing_archive_url }}"
|
||||||
|
dest: "/tmp/syncthing-{{ rocky_syncthing_version }}.tar.gz"
|
||||||
|
checksum: "{{ rocky_syncthing_archive_checksum }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
when: rocky_syncthing_install_required | bool
|
||||||
|
|
||||||
|
- name: Extract pinned Syncthing release
|
||||||
|
tags: [packages, syncthing]
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: "/tmp/syncthing-{{ rocky_syncthing_version }}.tar.gz"
|
||||||
|
dest: "/tmp/syncthing-{{ rocky_syncthing_version }}"
|
||||||
|
remote_src: true
|
||||||
|
when: rocky_syncthing_install_required | bool
|
||||||
|
|
||||||
|
- name: Install pinned Syncthing binary
|
||||||
|
tags: [packages, syncthing]
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: >-
|
||||||
|
{{
|
||||||
|
'/tmp/syncthing-' ~ rocky_syncthing_version
|
||||||
|
~ '/syncthing-linux-amd64-v' ~ rocky_syncthing_version
|
||||||
|
~ '/syncthing'
|
||||||
|
}}
|
||||||
|
dest: /usr/local/bin/syncthing
|
||||||
|
remote_src: true
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
when: rocky_syncthing_install_required | bool
|
||||||
|
|
||||||
|
- name: Remove Syncthing release archive
|
||||||
|
tags: [packages, syncthing]
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/tmp/syncthing-{{ rocky_syncthing_version }}.tar.gz"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Remove Syncthing extraction directory
|
||||||
|
tags: [packages, syncthing]
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/tmp/syncthing-{{ rocky_syncthing_version }}"
|
||||||
|
state: absent
|
||||||
51
ansible/roles/profile_atlas/defaults/main.yml
Normal file
51
ansible/roles/profile_atlas/defaults/main.yml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
atlas_manage_storage: false
|
||||||
|
atlas_admin_username: CHANGEME_ATLAS_ADMIN
|
||||||
|
atlas_admin_group: "{{ atlas_admin_username }}"
|
||||||
|
atlas_admin_home: "/home/{{ atlas_admin_username }}"
|
||||||
|
atlas_admin_uid: 1000
|
||||||
|
atlas_admin_gid: 1000
|
||||||
|
atlas_admin_ssh_keys: []
|
||||||
|
atlas_admin_password_hash: "!"
|
||||||
|
|
||||||
|
atlas_lan_subnet: CHANGEME_LAN_SUBNET
|
||||||
|
atlas_manage_firewall: false
|
||||||
|
atlas_firewalld_zone: public
|
||||||
|
atlas_zfs_pool: CHANGEME_ZFS_POOL
|
||||||
|
atlas_zfs_dataset_work: work
|
||||||
|
atlas_zfs_dataset_syncthing: syncthing
|
||||||
|
atlas_zfs_dataset_backup_prometheus: backup_prometheus
|
||||||
|
atlas_zfs_dataset_icloud_photos: icloud_photos
|
||||||
|
atlas_mount_root: /CHANGEME_ATLAS_MOUNT_ROOT
|
||||||
|
|
||||||
|
atlas_work_mountpoint: "{{ atlas_mount_root }}/{{ atlas_zfs_dataset_work }}"
|
||||||
|
atlas_syncthing_mountpoint: "{{ atlas_mount_root }}/{{ atlas_zfs_dataset_syncthing }}"
|
||||||
|
atlas_backup_prometheus_mountpoint: "{{ atlas_mount_root }}/{{ atlas_zfs_dataset_backup_prometheus }}"
|
||||||
|
atlas_icloud_photos_mountpoint: "{{ atlas_mount_root }}/{{ atlas_zfs_dataset_icloud_photos }}"
|
||||||
|
atlas_syncthing_config_dir: "{{ atlas_admin_home }}/.local/state/syncthing"
|
||||||
|
atlas_syncthing_default_dir: "{{ atlas_syncthing_mountpoint }}/Sync"
|
||||||
|
|
||||||
|
atlas_45drives_repo_url: https://repo.45drives.com/repofiles/rocky/45drives-enterprise.repo
|
||||||
|
atlas_45drives_repo_file: /etc/yum.repos.d/45drives-enterprise.repo
|
||||||
|
atlas_45drives_packages:
|
||||||
|
- cockpit-file-sharing
|
||||||
|
- cockpit-navigator
|
||||||
|
- cockpit-identities
|
||||||
|
- cockpit-zfs
|
||||||
|
- cockpit-scheduler
|
||||||
|
|
||||||
|
atlas_nfs_exports: []
|
||||||
|
atlas_samba_share_name: work
|
||||||
|
atlas_samba_workgroup: WORKGROUP
|
||||||
|
atlas_samba_valid_users: []
|
||||||
|
atlas_samba_password: ""
|
||||||
|
atlas_samba_password_marker: /var/lib/samba/private/.atlas-password.sha256
|
||||||
|
atlas_firewalld_rich_rules: []
|
||||||
|
atlas_firewalld_restricted_services:
|
||||||
|
- ssh
|
||||||
|
- cockpit
|
||||||
|
- nfs
|
||||||
|
- samba
|
||||||
|
atlas_selinux_booleans:
|
||||||
|
- samba_export_all_rw
|
||||||
|
- nfs_export_all_rw
|
||||||
34
ansible/roles/profile_atlas/handlers/main.yml
Normal file
34
ansible/roles/profile_atlas/handlers/main.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
- name: Reload SSH service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: sshd
|
||||||
|
state: reloaded
|
||||||
|
|
||||||
|
- name: Reload NFS exports
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- exportfs
|
||||||
|
- -ra
|
||||||
|
changed_when: true
|
||||||
|
when: not ansible_check_mode
|
||||||
|
|
||||||
|
- name: Restart NFS server
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: nfs-server
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: Restart NFS mount daemon
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: nfs-mountd
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
|
|
||||||
|
- name: Restart Samba service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: smb
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: Restart Atlas Syncthing service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: atlas-syncthing
|
||||||
|
state: restarted
|
||||||
118
ansible/roles/profile_atlas/tasks/account.yml
Normal file
118
ansible/roles/profile_atlas/tasks/account.yml
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
---
|
||||||
|
- name: Reject incomplete Atlas account configuration
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- atlas_admin_username != 'CHANGEME_ATLAS_ADMIN'
|
||||||
|
- (atlas_admin_ssh_keys | default([])) | length > 0
|
||||||
|
- atlas_admin_password_hash not in ['', '!', '*']
|
||||||
|
fail_msg: >-
|
||||||
|
Define atlas_admin_username, vault_atlas_authorized_ssh_keys and
|
||||||
|
vault_atlas_admin_password_hash before applying the Atlas profile.
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Create Atlas administrator group
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.builtin.group:
|
||||||
|
name: "{{ atlas_admin_group }}"
|
||||||
|
gid: "{{ atlas_admin_gid }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create Atlas administrator account
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ atlas_admin_username }}"
|
||||||
|
uid: "{{ atlas_admin_uid }}"
|
||||||
|
group: "{{ atlas_admin_group }}"
|
||||||
|
home: "{{ atlas_admin_home }}"
|
||||||
|
shell: /bin/bash
|
||||||
|
password: "{{ atlas_admin_password_hash }}"
|
||||||
|
create_home: true
|
||||||
|
state: present
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Grant Atlas administrator passwordless sudo
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: "{{ atlas_admin_username }} ALL=(ALL) NOPASSWD: ALL\n"
|
||||||
|
dest: "/etc/sudoers.d/{{ atlas_admin_username }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0440"
|
||||||
|
validate: "visudo -cf %s"
|
||||||
|
|
||||||
|
- name: Manage Atlas administrator authorized SSH keys exclusively
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.posix.authorized_key:
|
||||||
|
user: "{{ atlas_admin_username }}"
|
||||||
|
key: "{{ atlas_admin_ssh_keys | join('\n') }}"
|
||||||
|
state: present
|
||||||
|
exclusive: true
|
||||||
|
|
||||||
|
- name: Check whether the Atlas SSH host key exists
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /etc/ssh/ssh_host_ed25519_key
|
||||||
|
register: atlas_ssh_host_ed25519_key
|
||||||
|
|
||||||
|
- name: Generate missing Atlas SSH host keys
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- ssh-keygen
|
||||||
|
- -A
|
||||||
|
changed_when: true
|
||||||
|
when: not atlas_ssh_host_ed25519_key.stat.exists
|
||||||
|
|
||||||
|
- name: Ensure Atlas SSH configuration drop-in directory exists
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/ssh/sshd_config.d
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Ensure Atlas SSH drop-ins are loaded before other settings
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
regexp: '^\s*Include\s+/etc/ssh/sshd_config\.d/\*\.conf\s*$'
|
||||||
|
line: Include /etc/ssh/sshd_config.d/*.conf
|
||||||
|
insertbefore: BOF
|
||||||
|
state: present
|
||||||
|
validate: "sshd -t -f %s"
|
||||||
|
|
||||||
|
- name: Render Atlas SSH hardening drop-in
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: 00-atlas-hardening.conf.j2
|
||||||
|
dest: /etc/ssh/sshd_config.d/00-atlas-hardening.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0600"
|
||||||
|
notify: Reload SSH service
|
||||||
|
|
||||||
|
- name: Read effective Atlas SSH daemon configuration
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- sshd
|
||||||
|
- -T
|
||||||
|
- -C
|
||||||
|
- "user={{ atlas_admin_username }},host=atlas,addr=127.0.0.1"
|
||||||
|
register: atlas_sshd_effective_configuration
|
||||||
|
changed_when: false
|
||||||
|
when: not ansible_check_mode
|
||||||
|
|
||||||
|
- name: Verify effective Atlas SSH hardening
|
||||||
|
tags: [atlas, services]
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- "'permitrootlogin no' in atlas_sshd_effective_configuration.stdout_lines"
|
||||||
|
- "'pubkeyauthentication yes' in atlas_sshd_effective_configuration.stdout_lines"
|
||||||
|
- "'passwordauthentication no' in atlas_sshd_effective_configuration.stdout_lines"
|
||||||
|
- "'kbdinteractiveauthentication no' in atlas_sshd_effective_configuration.stdout_lines"
|
||||||
|
- "('allowusers ' ~ atlas_admin_username) in atlas_sshd_effective_configuration.stdout_lines"
|
||||||
|
fail_msg: The effective Atlas SSH configuration does not match the required hardening.
|
||||||
|
when: not ansible_check_mode
|
||||||
15
ansible/roles/profile_atlas/tasks/cockpit.yml
Normal file
15
ansible/roles/profile_atlas/tasks/cockpit.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
- name: Configure the official 45Drives repository
|
||||||
|
tags: [atlas, packages]
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "{{ atlas_45drives_repo_url }}"
|
||||||
|
dest: "{{ atlas_45drives_repo_file }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: Install 45Drives Cockpit plugins
|
||||||
|
tags: [atlas, packages]
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: "{{ atlas_45drives_packages }}"
|
||||||
|
state: present
|
||||||
15
ansible/roles/profile_atlas/tasks/main.yml
Normal file
15
ansible/roles/profile_atlas/tasks/main.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
- name: Import Atlas account tasks
|
||||||
|
ansible.builtin.import_tasks: account.yml
|
||||||
|
|
||||||
|
- name: Import Atlas 45Drives tasks
|
||||||
|
ansible.builtin.import_tasks: cockpit.yml
|
||||||
|
|
||||||
|
- name: Import Atlas storage tasks
|
||||||
|
ansible.builtin.import_tasks: storage.yml
|
||||||
|
|
||||||
|
- name: Import Atlas file sharing tasks
|
||||||
|
ansible.builtin.import_tasks: sharing.yml
|
||||||
|
|
||||||
|
- name: Import Atlas Syncthing tasks
|
||||||
|
ansible.builtin.import_tasks: syncthing.yml
|
||||||
211
ansible/roles/profile_atlas/tasks/sharing.yml
Normal file
211
ansible/roles/profile_atlas/tasks/sharing.yml
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
---
|
||||||
|
- name: Render Atlas NFS exports
|
||||||
|
tags: [atlas, sharing]
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: atlas.exports.j2
|
||||||
|
dest: /etc/exports.d/atlas.exports
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
notify: Reload NFS exports
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Configure Atlas NFSv4-only service
|
||||||
|
tags: [atlas, sharing]
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: atlas-nfs.conf.j2
|
||||||
|
dest: /etc/nfs.conf.d/atlas.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
notify: Restart NFS server
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Mask Atlas NFSv3 RPC services
|
||||||
|
tags: [atlas, sharing, services]
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "{{ item }}"
|
||||||
|
enabled: false
|
||||||
|
state: stopped
|
||||||
|
masked: true
|
||||||
|
loop:
|
||||||
|
- rpc-statd.service
|
||||||
|
- rpcbind.service
|
||||||
|
- rpcbind.socket
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item }}"
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Ensure Atlas NFS mount daemon drop-in directory exists
|
||||||
|
tags: [atlas, sharing, services]
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/systemd/system/nfs-mountd.service.d
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Disable Atlas NFSv3 mount daemon listeners
|
||||||
|
tags: [atlas, sharing, services]
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: nfs-mountd-v4only.conf.j2
|
||||||
|
dest: /etc/systemd/system/nfs-mountd.service.d/v4only.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
notify: Restart NFS mount daemon
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Enable SELinux access for Atlas file sharing
|
||||||
|
tags: [atlas, sharing, services]
|
||||||
|
ansible.posix.seboolean:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: true
|
||||||
|
persistent: true
|
||||||
|
loop: "{{ atlas_selinux_booleans }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item }}"
|
||||||
|
when:
|
||||||
|
- atlas_manage_storage | bool
|
||||||
|
- (ansible_facts['selinux'] | default({})).get('status', 'disabled') == 'enabled'
|
||||||
|
|
||||||
|
- name: Render Atlas Samba configuration
|
||||||
|
tags: [atlas, sharing]
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: smb.conf.j2
|
||||||
|
dest: /etc/samba/smb.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
validate: "testparm --suppress-prompt %s"
|
||||||
|
notify: Restart Samba service
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Require Atlas Samba password
|
||||||
|
tags: [atlas, sharing]
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- atlas_samba_password | length > 0
|
||||||
|
fail_msg: Define vault_atlas_samba_password before enabling Atlas storage.
|
||||||
|
no_log: true
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Read Atlas Samba account
|
||||||
|
tags: [atlas, sharing]
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- pdbedit
|
||||||
|
- --list
|
||||||
|
- --user
|
||||||
|
- "{{ atlas_admin_username }}"
|
||||||
|
register: atlas_samba_account
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Ensure Atlas Samba private state directory exists
|
||||||
|
tags: [atlas, sharing]
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ atlas_samba_password_marker | dirname }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0700"
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Check Atlas Samba password marker
|
||||||
|
tags: [atlas, sharing]
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ atlas_samba_password_marker }}"
|
||||||
|
register: atlas_samba_password_marker_stat
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Read Atlas Samba password marker
|
||||||
|
tags: [atlas, sharing]
|
||||||
|
ansible.builtin.slurp:
|
||||||
|
src: "{{ atlas_samba_password_marker }}"
|
||||||
|
register: atlas_samba_password_marker_content
|
||||||
|
no_log: true
|
||||||
|
when:
|
||||||
|
- atlas_manage_storage | bool
|
||||||
|
- atlas_samba_password_marker_stat.stat.exists
|
||||||
|
|
||||||
|
- name: Determine whether Atlas Samba credentials must change
|
||||||
|
tags: [atlas, sharing]
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
atlas_samba_password_digest: "{{ atlas_samba_password | hash('sha256') }}"
|
||||||
|
atlas_samba_password_update_required: >-
|
||||||
|
{{
|
||||||
|
atlas_samba_account.rc != 0
|
||||||
|
or not atlas_samba_password_marker_stat.stat.exists
|
||||||
|
or (
|
||||||
|
atlas_samba_password_marker_content.content | default('')
|
||||||
|
| b64decode | trim
|
||||||
|
) != (atlas_samba_password | hash('sha256'))
|
||||||
|
}}
|
||||||
|
no_log: true
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Set Atlas Samba account password
|
||||||
|
tags: [atlas, sharing]
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- smbpasswd
|
||||||
|
- -s
|
||||||
|
- -a
|
||||||
|
- "{{ atlas_admin_username }}"
|
||||||
|
stdin: "{{ atlas_samba_password }}\n{{ atlas_samba_password }}"
|
||||||
|
changed_when: true
|
||||||
|
no_log: true
|
||||||
|
when:
|
||||||
|
- atlas_manage_storage | bool
|
||||||
|
- atlas_samba_password_update_required | bool
|
||||||
|
|
||||||
|
- name: Record managed Atlas Samba password digest
|
||||||
|
tags: [atlas, sharing]
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: "{{ atlas_samba_password_digest }}\n"
|
||||||
|
dest: "{{ atlas_samba_password_marker }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0600"
|
||||||
|
no_log: true
|
||||||
|
when:
|
||||||
|
- atlas_manage_storage | bool
|
||||||
|
- atlas_samba_password_update_required | bool
|
||||||
|
|
||||||
|
- name: Require completed Atlas firewall placeholders
|
||||||
|
tags: [atlas, sharing, services]
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- atlas_lan_subnet != 'CHANGEME_LAN_SUBNET'
|
||||||
|
- atlas_firewalld_zone | length > 0
|
||||||
|
fail_msg: Replace the Atlas LAN subnet and firewall zone placeholders.
|
||||||
|
when: atlas_manage_firewall | bool
|
||||||
|
|
||||||
|
- name: Apply Atlas firewalld rich rules
|
||||||
|
tags: [atlas, sharing, services]
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
rich_rule: "{{ item }}"
|
||||||
|
permanent: true
|
||||||
|
immediate: true
|
||||||
|
state: enabled
|
||||||
|
zone: "{{ atlas_firewalld_zone }}"
|
||||||
|
loop: "{{ atlas_firewalld_rich_rules }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item }}"
|
||||||
|
when: atlas_manage_firewall | bool
|
||||||
|
|
||||||
|
- name: Remove unrestricted Atlas services from firewalld zone
|
||||||
|
tags: [atlas, sharing, services]
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
service: "{{ item }}"
|
||||||
|
permanent: true
|
||||||
|
immediate: true
|
||||||
|
state: disabled
|
||||||
|
zone: "{{ atlas_firewalld_zone }}"
|
||||||
|
loop: "{{ atlas_firewalld_restricted_services }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item }}"
|
||||||
|
when: atlas_manage_firewall | bool
|
||||||
77
ansible/roles/profile_atlas/tasks/storage.yml
Normal file
77
ansible/roles/profile_atlas/tasks/storage.yml
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
- name: Define Atlas ZFS datasets
|
||||||
|
tags: [atlas, storage]
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
atlas_zfs_datasets:
|
||||||
|
- name: "{{ atlas_zfs_pool }}/{{ atlas_zfs_dataset_work }}"
|
||||||
|
mountpoint: "{{ atlas_work_mountpoint }}"
|
||||||
|
- name: "{{ atlas_zfs_pool }}/{{ atlas_zfs_dataset_syncthing }}"
|
||||||
|
mountpoint: "{{ atlas_syncthing_mountpoint }}"
|
||||||
|
- name: "{{ atlas_zfs_pool }}/{{ atlas_zfs_dataset_backup_prometheus }}"
|
||||||
|
mountpoint: "{{ atlas_backup_prometheus_mountpoint }}"
|
||||||
|
- name: "{{ atlas_zfs_pool }}/{{ atlas_zfs_dataset_icloud_photos }}"
|
||||||
|
mountpoint: "{{ atlas_icloud_photos_mountpoint }}"
|
||||||
|
|
||||||
|
- name: Require completed Atlas storage placeholders
|
||||||
|
tags: [atlas, storage]
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- atlas_zfs_pool != 'CHANGEME_ZFS_POOL'
|
||||||
|
- atlas_mount_root != '/CHANGEME_ATLAS_MOUNT_ROOT'
|
||||||
|
- atlas_mount_root.startswith('/')
|
||||||
|
- (atlas_zfs_datasets | map(attribute='name') | unique | list | length) == (atlas_zfs_datasets | length)
|
||||||
|
- (atlas_zfs_datasets | map(attribute='mountpoint') | unique | list | length) == (atlas_zfs_datasets | length)
|
||||||
|
fail_msg: >-
|
||||||
|
Replace the Atlas ZFS pool and mount-root placeholders, then set
|
||||||
|
atlas_manage_storage to true before managing datasets.
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Check whether the configured Atlas ZFS pool exists
|
||||||
|
tags: [atlas, storage]
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- zpool
|
||||||
|
- list
|
||||||
|
- -H
|
||||||
|
- -o
|
||||||
|
- name
|
||||||
|
- "{{ atlas_zfs_pool }}"
|
||||||
|
register: atlas_zfs_pool_check
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Require the configured Atlas ZFS pool
|
||||||
|
tags: [atlas, storage]
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- atlas_zfs_pool_check.rc == 0
|
||||||
|
fail_msg: >-
|
||||||
|
The configured Atlas ZFS pool does not exist. The Atlas profile only
|
||||||
|
manages child datasets and never creates pools.
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Manage Atlas ZFS datasets declaratively
|
||||||
|
tags: [atlas, storage]
|
||||||
|
community.general.zfs:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
state: present
|
||||||
|
extra_zfs_properties:
|
||||||
|
mountpoint: "{{ item.mountpoint }}"
|
||||||
|
loop: "{{ atlas_zfs_datasets }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Set Atlas dataset ownership
|
||||||
|
tags: [atlas, storage]
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item.mountpoint }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ atlas_admin_username }}"
|
||||||
|
group: "{{ atlas_admin_group }}"
|
||||||
|
mode: "0770"
|
||||||
|
loop: "{{ atlas_zfs_datasets }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.mountpoint }}"
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
40
ansible/roles/profile_atlas/tasks/syncthing.yml
Normal file
40
ansible/roles/profile_atlas/tasks/syncthing.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
- name: Create Atlas Syncthing configuration directory
|
||||||
|
tags: [atlas, syncthing]
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ atlas_syncthing_config_dir }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ atlas_admin_username }}"
|
||||||
|
group: "{{ atlas_admin_group }}"
|
||||||
|
mode: "0700"
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Create Atlas Syncthing default data directory
|
||||||
|
tags: [atlas, syncthing]
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ atlas_syncthing_default_dir }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ atlas_admin_username }}"
|
||||||
|
group: "{{ atlas_admin_group }}"
|
||||||
|
mode: "0770"
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Render Atlas Syncthing systemd service
|
||||||
|
tags: [atlas, syncthing]
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: atlas-syncthing.service.j2
|
||||||
|
dest: /etc/systemd/system/atlas-syncthing.service
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
notify: Restart Atlas Syncthing service
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
|
|
||||||
|
- name: Enable Atlas Syncthing service
|
||||||
|
tags: [atlas, syncthing]
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: atlas-syncthing
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
daemon_reload: true
|
||||||
|
when: atlas_manage_storage | bool
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Managed by Ansible. Do not edit manually.
|
||||||
|
PermitRootLogin no
|
||||||
|
PubkeyAuthentication yes
|
||||||
|
PasswordAuthentication no
|
||||||
|
KbdInteractiveAuthentication no
|
||||||
|
AllowUsers {{ atlas_admin_username }}
|
||||||
3
ansible/roles/profile_atlas/templates/atlas-nfs.conf.j2
Normal file
3
ansible/roles/profile_atlas/templates/atlas-nfs.conf.j2
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Managed by Ansible. Do not edit manually.
|
||||||
|
[nfsd]
|
||||||
|
vers3 = n
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Atlas Syncthing service
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User={{ atlas_admin_username }}
|
||||||
|
Group={{ atlas_admin_group }}
|
||||||
|
WorkingDirectory={{ atlas_syncthing_mountpoint }}
|
||||||
|
Environment=HOME={{ atlas_syncthing_mountpoint }}
|
||||||
|
ExecStart=/usr/local/bin/syncthing serve --no-browser --no-restart --no-upgrade --home={{ atlas_syncthing_config_dir }}
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
4
ansible/roles/profile_atlas/templates/atlas.exports.j2
Normal file
4
ansible/roles/profile_atlas/templates/atlas.exports.j2
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Managed by Ansible. Do not edit manually.
|
||||||
|
{% for export in atlas_nfs_exports %}
|
||||||
|
{{ export.path }} {{ export.clients }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[Service]
|
||||||
|
ExecStart=
|
||||||
|
ExecStart=/usr/sbin/rpc.mountd --no-tcp --no-udp
|
||||||
16
ansible/roles/profile_atlas/templates/smb.conf.j2
Normal file
16
ansible/roles/profile_atlas/templates/smb.conf.j2
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Managed by Ansible. Do not edit manually.
|
||||||
|
[global]
|
||||||
|
workgroup = {{ atlas_samba_workgroup }}
|
||||||
|
security = user
|
||||||
|
map to guest = Never
|
||||||
|
server min protocol = SMB2
|
||||||
|
include = registry
|
||||||
|
|
||||||
|
[{{ atlas_samba_share_name }}]
|
||||||
|
path = {{ atlas_work_mountpoint }}
|
||||||
|
browseable = yes
|
||||||
|
read only = no
|
||||||
|
valid users = {{ atlas_samba_valid_users | join(' ') }}
|
||||||
|
force group = {{ atlas_admin_group }}
|
||||||
|
create mask = 0660
|
||||||
|
directory mask = 0770
|
||||||
@@ -20,7 +20,8 @@
|
|||||||
errors='ignore', wantlist=True) | length > 0
|
errors='ignore', wantlist=True) | length > 0
|
||||||
|
|
||||||
roles:
|
roles:
|
||||||
- dotfiles_common
|
- role: dotfiles_common
|
||||||
|
when: "'platform_rocky' not in group_names"
|
||||||
|
|
||||||
- name: Configure Void platform
|
- name: Configure Void platform
|
||||||
hosts: platform_void
|
hosts: platform_void
|
||||||
@@ -56,6 +57,21 @@
|
|||||||
- packages_fedora
|
- packages_fedora
|
||||||
- services_systemd
|
- services_systemd
|
||||||
|
|
||||||
|
- name: Configure Rocky Linux platform
|
||||||
|
hosts: platform_rocky
|
||||||
|
become: true
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- packages_rocky
|
||||||
|
- services_systemd
|
||||||
|
|
||||||
|
- name: Configure Atlas NAS profile
|
||||||
|
hosts: atlas
|
||||||
|
become: true
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- profile_atlas
|
||||||
|
|
||||||
- name: Configure personal workstation role on Fedora
|
- name: Configure personal workstation role on Fedora
|
||||||
hosts: platform_fedora:&role_personal_workstation
|
hosts: platform_fedora:&role_personal_workstation
|
||||||
become: true
|
become: true
|
||||||
|
|||||||
Reference in New Issue
Block a user