Compare commits

...
91 Commits
Author SHA1 Message Date
il 927b5b4934 feat(repo): IaaS baseline 2026-06-17 13:17:24 +09:00
il a6bba986a5 fix(crowdsec): update whitelist.yaml to prevent false positive
false positive:
- outline session problem (LePresidente/http-generic-401-bf)
2026-05-17 00:00:46 +09:00
il 24eff8f3eb chore(outline): fix HSTS annotation typo 2026-05-16 21:16:28 +09:00
il 9be4276676 feat(memos): release memos
deployment notes:
- compare to Affine, maybe outline + memos can be substituted for affine
2026-05-16 21:04:53 +09:00
il 1256122081 feat(outline): release outline
deployment notes:
- compare to Affine (Affine is heavy and their whtieboard and canvas is not used enough)
- don't restart this when it initiates, redis lock causes failure
2026-05-16 20:56:43 +09:00
il f28661e664 refactor(convention): add existing 'site' tag to convention 2026-05-15 10:16:36 +09:00
il a09712c142 refactor(script): update edit_secret.sh to optimize log print logic 2026-05-15 10:12:42 +09:00
il a7e2320b21 chore(script): archive a extract_secret.sh script
archived stack: extract_secret.sh
2026-05-15 09:19:59 +09:00
il 24c83029e9 refactor(playbook): update convention and remove deprecated tag
update notes:
- remove tags 'update', 'upgrade' from convention.yaml
- remove tags 'update' from playbooks/app/site.yaml
2026-05-15 09:04:51 +09:00
il ac64b3c04e docs(readme): add RPO on readme 2026-05-13 17:12:59 +09:00
il 26d696f813 refactor(all): update hardcoded internal domain to ansible variable 2026-05-12 08:08:04 +09:00
il 1096981ef2 feat(paperless): change paperless OCR engine model from tesseract_fast to tesseract_best 2026-05-12 08:00:37 +09:00
il e1936b494d fix(crowdsec): update whitelist.yaml to prevent false positive
false positive:
- nextcloud chunk problem (crowdsecurity/http-crawl-non_statics)
- change expression 'chunks.mjs' to 'chunk.mjs'
2026-05-11 19:40:50 +09:00
il 0afc841b69 chore(chromium): archive a removed stack from console
archived stack: chromium
2026-05-11 19:37:25 +09:00
il a39122eb4b fix(crowdsec): update whitelist.yaml to prevent false positive
false positive:
- nextcloud chunk problem (crowdsecurity/http-crawl-non_statics)
2026-05-11 19:34:22 +09:00
il 0f4da0bb53 feat(backup): add archiving of runtime binary packages 2026-05-11 01:37:15 +09:00
il 1dd1c53e2a feat(backup): add archiving of deployed container images 2026-05-11 00:52:28 +09:00
il 530407c162 refactor(all): update hardcoded timezone 'Asia/Seoul' to ansible variable 'timezone' 2026-05-10 18:44:28 +09:00
il 11ab2f5205 fix(sure): correct task name and subuid variable reference 2026-05-10 14:39:54 +09:00
il 4527e39d0f chore(app): archive removed stacks from app
archived stacks:
- actual-budget
- ezbookkeeping
- opencloud
- trilium
- vikunja
- wikijs
2026-05-10 00:07:51 +09:00
il 02fa912cb1 feat(trilium): release trilium
deployment notes:
- oidc error (users cannot access at once, it needs login twice when using oidc
2026-05-09 22:38:57 +09:00
il aceef4bdaa refactor(authelia): update authelia.yaml.j2 to fix redirect_uris from hardcoded uris to ansible variables 2026-05-09 21:44:11 +09:00
il 64aad4fcf0 docs(all): fix markdown syntax and snippets 2026-05-09 20:54:32 +09:00
il 81244d55a7 feat(wiki.js): release wiki.js
deployment notes:
- use this as personal/family wiki system
- compare to affine / memos and triliumNext
2026-05-09 17:50:05 +09:00
il 1cfd024285 refactor(x509-exporter): update notification to restart x509-exporter when its config.yaml is changed 2026-05-09 17:42:35 +09:00
il 26115c5660 feat(redis): update redis from 8.6.1 to 8.6.3
update notes:
- run 'ansible-playbook playbooks/app/site.yaml --tags "site"' so that update all redis at onece
2026-05-09 13:55:28 +09:00
il acef35ca8b feat(postgresql): update postgresql and vectorchord extension
update notes:
- update postgresql version from 18.2 to 18.3
- update vectorchord version from 0.5.3 to 1.1.1
- add update flow and notice to postgresql.md
2026-05-09 13:54:10 +09:00
il b531170bd7 feat(vaultwardne): update vaultwarden from 1.35.8 to 1.36.0 2026-05-09 12:56:22 +09:00
il ad586c3cd3 feat(grafana): update grafana from 12.3.3 to 13.0.1 2026-05-09 12:50:36 +09:00
il 6dfef08f7b feat(prometheus): update prometheus from v3.9.1 to v3.11.3 2026-05-09 12:44:44 +09:00
il 934dd314a8 feat(x509-exporter): update x509-exporter from 3.21.0 to 4.1.0
update notes:
- '--listen-address' and '--watch-dir' cli flags are deprecated
- add '--config' cli flag and config.yaml
2026-05-09 12:44:05 +09:00
il 2529a918df feat(loki): update loki version from 3.6.5 to 3.7.1 2026-05-09 12:17:16 +09:00
il 7dfa20d3dd feat(ldap): update lldap version from 0.6.2 to 0.6.3 2026-05-09 11:56:19 +09:00
il 329620c7d7 feat(alloy): update alloy version from 1.13.0 to 1.16.1 2026-05-09 11:52:25 +09:00
il f820e89cf6 refactor(roles): update binary application installation flow
update notes:
- keep set_cli_tools responsible only for console CLI tools
- download and install kopia from the kopia role
- download and install blocky from the blocky role
- download and install alloy from the alloy role
- reduce console artifact staging for service binaries
2026-05-09 10:46:29 +09:00
il a05951f883 fix(crowdsec): optimize whitelist expressions
update notes:
- add http_status and http_verb for each expressions (actual budget, immich, opencloud)
- fix crowdsec and issues documents
2026-05-07 10:32:11 +09:00
il b404a9e459 fix(crowdsec): update whitelist.yaml to prevent false positive
false positive:
- nextcloud thumbnail/preview 404 problem (crowdsecurity/http-probing)
2026-05-07 10:27:34 +09:00
il 3b4b56f53f fix(nftables): update fw nftables to allow vpn connection regardless of crowdsec ban 2026-05-07 09:22:49 +09:00
il f697715065 feat(sure): release sure (we-promise/sure)
deployment notes:
- let's try three of budget apps, actual budget, ezbookkeeping, and sure
2026-05-06 18:52:31 +09:00
il be7f215380 feat(ezbookkeeping): release ezbookkeeping
deployment notes:
- use ezbookkeeping for budget
- compare to actual budget
- it has no RBAC and sharing budget, try to sure (we-promise/sure)
2026-05-06 15:56:19 +09:00
il 26e0fe4f8b docs(ADR): update ADR 007 - backup to add checking rule and flows 2026-05-06 14:30:25 +09:00
il 2bb1f015e0 fix(kopia): update the bound home path from %h to ansible variable
update note:
- hotfix
- backups haven't run since commit '9f236b6fa5'
- the root service unit's %h always indicates root's home path
- backup service is verified
2026-05-06 14:06:22 +09:00
il 0f546e13b3 fix(btrfs): update btrfs scrub path
update notes:
- from '{{ node['home_path'] }}/data' to '{{ storage['btrfs']['mount_point'] }}'
2026-05-06 10:33:57 +09:00
il ba8b312bf2 feat(btrfs): update btrfs scrub service and timer on app vm 2026-05-06 08:15:53 +09:00
il 6fcedd9162 feat(collabora): release collabora
deployment note:
- link to nextcloud
- document opening is verified (including korean fonts)
2026-05-05 21:20:31 +09:00
il 6ca4f61d50 docs(nextcloud): update security warning decisions and background job annotation
update notes:
- trusted_proxies warning
- HSTS option warning
- background job mode annotation
2026-05-05 20:09:00 +09:00
il 15c09cb899 docs(nextcloud): update how to disable auto generated contacts from nextcloud account 2026-05-03 12:05:11 +09:00
il 880857a70a fix(crowdsec): update parser 'crowdsecurity/nextcloud-whitelist'
update note:
- deprecate custom whitelist expression
- apply 'crowdsecurity/nextcloud-whitelist' parser
2026-05-03 07:19:59 +09:00
il 70bf539546 docs(issues): fix crowdsec whitelist regex to whitelist expressions 2026-05-02 20:40:10 +09:00
il 5dd38b7e49 fix(crowdsec): update whitelist.yaml to prevent false positive
false positive:
- chunk problems (crowdsecurity/http-crawl-non_statics)
- directory upload 404 problem (crowdsecurity/http-probing)
2026-05-02 20:38:48 +09:00
il 33d94211d1 docs(issues): fix crowdsec command 'cscli decision list' to 'cscli decision delete' 2026-05-02 19:46:51 +09:00
il 278dd3cebe feat(nextcloud): release nextcloud
deployment note:
- use nextcloud for groupware
- consider replacing vikunja and opencloud
2026-05-02 19:22:05 +09:00
il d1dcb1984a feat(vaultwarden): update vaultwarden version from 1.35.4 to 1.35.8 2026-04-30 10:03:33 +09:00
il 37c986177b feat(blocky): update blocky version from 0.28.2 to 0.29.0 2026-04-30 10:01:18 +09:00
il 17326b1b15 feat(step-ca): update step-ca version from 0.29.0 to 0.30.2
update note:
- step-ca container doesn't support $PWDPATH anymore
- add --password-file argument to exec
2026-04-30 09:56:22 +09:00
il 88e1383202 feat(x509-exporter): update x509-exporter version from 3.19.1 to 3.21.0 2026-04-30 09:19:42 +09:00
il c9b4707cb2 refactor(x509-exporter): change handler from enable to restart 2026-04-30 09:18:44 +09:00
il da9c610426 feat(caddy): update caddy version from 2.10.2 to 2.11.2
update note:
- https upstream Host rewrite is automated
- Caddyfile already defines Host rewrite explicitly
2026-04-30 09:09:40 +09:00
il c1a6da2aa8 feat(authelia): update authelia version from 4.39.15 to 4.39.19 2026-04-30 09:07:16 +09:00
il f1cd8c9a60 feat(gitea): update gitea version from 1.25.5 to 1.26.1
deployment note:
- stop gitea container
- create manual database backup
- update gitea
2026-04-30 08:28:51 +09:00
il 6010230a14 feat(paperless): update paperless version from 2.20.13 to 2.20.15 2026-04-30 08:10:50 +09:00
il c3d8b62504 feat(opencloud): update opencloud version from 4.0.4 to 4.0.6 2026-04-30 08:03:33 +09:00
il 4a409e37e9 docs(issues): fix service name in timeline 2026-04-28 11:19:50 +09:00
il cb4d17f99e docs(issues): add the past issues which existed before tracking issues
add crowdsec false positive issues

fix the file name of affine android oidc issues
2026-04-27 19:50:04 +09:00
il 9569492e42 docs(issues): add affine android OIDC sign-up failure issue
start tracking service issues on the docs/issues directory
2026-04-20 17:55:26 +09:00
il 2a7b234f4e docs(affine): update flags on affine doc to check blocking guest user 2026-04-20 15:53:27 +09:00
il 621d5310a3 feat(immich): update immich version from 2.7.4 to 2.7.5 2026-04-17 14:16:44 +09:00
il 6377a56d95 refactor(ldap): Add annotation in ldap roles file
the reason why task doesn't use init logic which uses .init file
2026-04-17 14:10:36 +09:00
il dbd72f43a4 refactor(postgresql): update postgresql roles and handler to optimize init check logic 2026-04-17 13:58:22 +09:00
il 9f236b6fa5 refactor(kopia): fix the homepath from hardcoded path to %h the systemd specifier 2026-04-14 07:44:39 +09:00
il b4a0874deb refactor(authelia): fix publish port from hardcoded number to variable 2026-04-14 07:43:12 +09:00
il c51216ff9b refactor(gitea): fix publish port from hardcoded number to varible 2026-04-14 07:42:32 +09:00
il 7debdfcb93 fix(alloy): fix log level parser
- remove parser for JSON and logfmt, and add regex expression to extract the level of log
2026-04-13 10:42:10 +09:00
il da016343c0 feat(alloy): add json parser to categorize log level 2026-04-12 14:09:44 +09:00
il bf749ebbde chore(chromium): delete the roles from the console playbook 2026-04-12 10:58:07 +09:00
il 41d509a49d feat(immich): update immich version from 2.6.3 to 2.7.4
- IMMICH_HELMET_FILE environment can set CSP from v2.7.0
2026-04-12 10:45:59 +09:00
il f062f6862f docs(git): define git convention 2026-04-12 10:31:13 +09:00
il 2dfc0f734e roles, docs: update set_podman.yaml and environments.md to fix typo 2026-04-08 15:21:22 +09:00
il f9211dfa24 inventory: update host_vars/console.yaml to add the hostname of console in local_san to fix sudo speed problem 2026-04-08 14:34:05 +09:00
il 8713631e0b docs: update affine.md to clarify limitation of affine's community edition 2026-04-07 11:34:08 +09:00
il 01ad4350b0 docs: update environments.md to reflect current server status 2026-04-07 00:04:51 +09:00
il 8a4ce488f1 roles: update handlers/main.yaml and set_opencloud.yaml to optimize init check logic in roles 2026-04-06 23:40:06 +09:00
il 664cf2956d 1.9.0 Release affine 2026-04-06 23:33:44 +09:00
il 8c3fe409ae 1.8.2 Update manticore 2026-04-06 20:35:34 +09:00
il 075b796608 config, docs: update whitelists.yaml.j2 and crowdsec.md to add whitelist expression to fix false positive of opencloud chunk problem 2026-04-04 09:59:58 +09:00
il 0b7d1c4d78 1.8.0 Release opencloud 2026-04-04 09:45:48 +09:00
il 017de863d9 inventory, roles: update group_vars/all.yaml and set service files to centralize subuid for containers 2026-04-01 22:22:40 +09:00
il b52a6f6f0d config: update postgresql.conf.j2 to fix port from hardcoded number to ansible variable 2026-04-01 21:54:55 +09:00
il 84d961c7e3 inventory, roles, config, docs: update all files to refactor the ansible variables structure 2026-04-01 21:30:56 +09:00
il d1e0eb30c0 config, docs: update secrets.yaml, vikunja.container.j2, vikunja.md to remove oidc fallback options and local-oidc dual login configuration 2026-03-31 20:31:51 +09:00
il 0f38df0100 config: update fw/nftables.conf.j2 to add the rule that allow connection from console to printer 2026-03-29 13:01:59 +09:00
328 changed files with 4768 additions and 28572 deletions
+7 -5
View File
@@ -1,8 +1,10 @@
.ansible
data/bin/* data/bin/*
data/volumes/* data/images/containers/*
data/images/* data/images/seeds/*
docs/archives/textfiles/ data/vmm_init/*
docs/notes/* *.raw
*.tar
*.qcow2
*.sql *.sql
*.iso
!.gitkeep !.gitkeep
-26
View File
@@ -1,26 +0,0 @@
# ilnmors homelab README
This homelab project implements single-node On-premise IaaS system. The homelab contains virtual machines which are divided by their roles, such as private firewall, DNS, PKI, LDAP and database, SSO\(OIDC\). The standard domain is used to implement this system without specific vendors. All components are defined as code and initiated by IaC \(Ansible\) except hypervisor initial configuration.
## RTO times
- Feb/25/2026 - Reprovisioning Hypervisor and vms
- RTO: 1 hour 30 min - verified
- Manual install and set vmm: 20 min
- Create and reprovision fw including services: 15 min
- Create and reprovision infra including services: 20 min
- Create and reprovision auth including services: 10 min
- Create and reprovision app except services: 10 min
- Intermediate tasks (ACME issuance, DNS propagation, etc.): 15 min
- Mar/5/2026 - Reprovisioning Hardware and Hypervisor and vms
- RTO: 2 hour 20 min
- console: 15min - verified
- certificate: 0 min \(When it needs to be created, RTO will be 20 min) - not verified
- wireguard: 0 min \(When it needs to be created, RTO will be 1 min) - not verified
- hypervisor\(+fw\): 45 min - verified
- switch: 1 min - verified
- dsm: 30 min - verified
- kopia: 0 min \(When it needs to be created, RTO will be 10 min) - verified
- Extra vms: 30 min - verified
- Etc: 30 min
+13 -11
View File
@@ -1,27 +1,28 @@
--- ---
# `""` should be used for every string values # String values need `""`
# except name, boolean, varible(environment) name, number (only for decimal) # Task names, boolean values, environment names, decimal numbers don't need `""`
- name: Convention task - name: Convention task
delegate_to: "host" delegate_to: "host"
delegate_facts: true delegate_facts: true
environment: environment:
env: "environment" env: "value"
ansible.builtin.file: ansible.builtin.file:
# Identifier: name:, src, dest, url # Identifier: name, src, dest, url, etc.
path: "/path/of/example" path: "/example/path"
# State # state parameters
state: "directory" state: "directory"
owner: "root" owner: "root"
group: "root" group: "root"
mode: "0640" mode: "0640"
# optional data # optional parameters
recurse: true recurse: true
loop: loop:
- "list" - "list"
loop_control: loop_control:
label: "{{ item }}" label: "{{ item }}"
become: true become: true
# become_user: "root" # default become user is root
become_user: "user"
when: condition.stat.exists when: condition.stat.exists
changed_when: condition.rc != 0 changed_when: condition.rc != 0
failed_when: condition.rc == 0 failed_when: condition.rc == 0
@@ -30,10 +31,11 @@
listen: "notification_example" listen: "notification_example"
no_log: true no_log: true
run_once: true run_once: true
# Ensure execution even if it fails (it prints errors on the screen, but it ignores them)
ignore_errors: true
tags: tags:
- "always" - "always"
- "init" - "init"
- "upgrade" - "site"
- "update" - "[service_name]"
# when: "'tags' is not in ansible_run_tags" # when: "'tags' is not in ansible_run_tags"
+155 -36
View File
@@ -1,82 +1,201 @@
--- ---
# Global vars # Global vars
timezone: "Asia/Seoul"
ansible_ssh_private_key_file: "/etc/secrets/{{ hostvars['console']['node']['uid'] }}/id_console" ansible_ssh_private_key_file: "/etc/secrets/{{ hostvars['console']['node']['uid'] }}/id_console"
# URL infromation, you can use {{ infra_uri['services'] | split(':') | first|last }} to seperate domain and ports # CA
infra_uri: root_cert_filename: "ilnmors_root_ca.crt"
intermediate_cert_filename: "ilnmors_intermediate_ca.crt"
intermediate_key_filename: "ilnmors_intermediate_ca.key"
# Domains
domain:
public: "ilnmors.com"
internal: "ilnmors.internal"
dc: "dc=ilnmors,dc=internal"
org: "ilnmors"
# DNS configuration including bind and blocky should be set manually.
# named.conf.j2 is also set manually.
# Check the hosts.j2 when cname records are fixed
services:
crowdsec: crowdsec:
domain: "crowdsec.ilnmors.internal" domain: "crowdsec"
ports: ports:
https: "8080" https: "8080"
bind: bind:
domain: "bind.ilnmors.internal" domain: "bind"
ports: ports:
dns: "53" dns: "53"
blocky: blocky:
domain: "blocky.ilnmors.internal" domain: "blocky"
ports: ports:
https: "443" https: "443"
dns: "53" dns: "53"
postgresql: postgresql:
domain: "postgresql.ilnmors.internal" domain: "postgresql"
ports: ports:
tcp: "5432" # postgresql db connection port tcp: "5432" # postgresql db connection port
subuid: "100998"
ldap: ldap:
domain: "ldap.ilnmors.internal" domain: "ldap"
ports: ports:
http: "17170" http: "17170"
ldaps: "636" ldaps: "6360"
subuid: "100999"
ca: ca:
domain: "ca.ilnmors.internal" domain: "ca"
ports: ports:
https: "9000" https: "9000"
subuid: "100999"
x509-exporter:
ports:
http: "9793"
subuid: "165533"
prometheus: prometheus:
domain: "prometheus.ilnmors.internal" domain: "prometheus"
ports: ports:
https: "9090" https: "9090"
subuid: "165533"
loki: loki:
domain: "loki.ilnmors.internal" domain: "loki"
ports: ports:
https: "3100" https: "3100"
subuid: "110000"
grafana:
domain: "grafana"
ports:
http: "3000"
subuid: "100471"
caddy:
ports:
http: "2080"
https: "2443"
nas: nas:
domain: "nas.ilnmors.internal" domain: "nas"
ports: ports:
https: "5001" https: "5001"
kopia: kopia:
domain: "nas.ilnmors.internal" domain: "nas"
ports: ports:
https: "51515" https: "51515"
authelia:
domain: "authelia"
ports:
http: "9091"
redis:
subuid: "100998"
vaultwarden:
domain:
public: "vault"
internal: "vault.app"
ports:
http: "8000"
gitea:
domain:
public: "gitea"
internal: "gitea.app"
ports:
http: "3001"
subuid: "100999"
immich:
domain:
public: "immich"
internal: "immich.app"
ports:
http: "2283"
redis: "6379"
immich-ml:
ports:
http: "3003"
paperless:
domain:
public: "paperless"
internal: "paperless.app"
ports:
http: "8001"
redis: "6380"
subuid: "100999"
nextcloud:
domain:
public: "nextcloud"
internal: "nextcloud.app"
ports:
http: "8002"
redis: "6382"
subuid: "100032"
collabora:
domain:
public: "collabora"
internal: "collabora.app"
ports:
http: "9980"
subuid: "101000"
sure:
domain:
public: "sure"
internal: "sure.app"
ports:
http: "3002"
redis: "6383"
subuid: "100999"
outline:
domain:
public: "outline"
internal: "outline.app"
ports:
http: "3004"
redis: "6384"
subuid: "101000"
memos:
domain:
public: "memos"
internal: "memos.app"
ports:
http: "3005"
subuid: "110000"
mealie:
domain:
public: "mealie"
internal: "mealie.app"
ports:
http: "9001"
subuid: "100910"
version: version:
packages: packages:
sops: "3.12.1" sops: "3.13.1"
step: "0.29.0" step: "0.30.2"
kopia: "0.22.3" kopia: "0.23.0"
blocky: "0.28.2" blocky: "0.29.0"
alloy: "1.13.0" alloy: "1.16.1"
# telegraf: "1.37.1"
containers: containers:
# common # common
caddy: "2.10.2" caddy: "2.11.4"
# infra # infra
step: "0.29.0" step: "0.30.2"
ldap: "v0.6.2" ldap: "v0.6.3"
x509-exporter: "3.19.1" x509-exporter: "4.1.0"
prometheus: "v3.9.1" prometheus: "v3.12.0"
loki: "3.6.5" loki: "3.7.1"
grafana: "12.3.3" grafana: "13.0.1"
## Postgresql ## Postgresql
postgresql: "18.2" postgresql: "18.4"
# For immich - https://github.com/immich-app/base-images/blob/main/postgres/versions.yaml # For immich - https://github.com/immich-app/base-images/blob/main/postgres/versions.yaml
# pgvector: "v0.8.1" # pgvector: "v0.8.1"
vectorchord: "0.5.3" vectorchord: "1.1.1"
# Auth # Auth
authelia: "4.39.15" authelia: "4.39.20"
# App # App
vaultwarden: "1.35.4" vaultwarden: "1.36.0"
gitea: "1.25.5" gitea: "1.26.1"
redis: "8.6.1" redis: "8.8.0"
immich: "v2.6.3" immich: "v2.7.5"
actualbudget: "26.3.0" paperless: "2.20.15"
paperless: "2.20.13" nextcloud: "33.0.5"
vikunja: "2.2.2" collabora: "25.04.10.3.1"
sure: "0.7.1"
outline: "1.8.1"
memos: "0.29.1"
mealie: "v3.19.2"
+28 -2
View File
@@ -1,7 +1,33 @@
--- ---
node: node:
name: "vmm" name: "vmm"
group: "svadmins"
uid: 2000 uid: 2000
home_path: "/home/vmm" home_path: "/home/vmm"
ssh_san: "vmm,vmm_init,vmm.ilnmors.internal,init.vmm.ilnmors.internal" libvirt_path: "/var/lib/libvirt"
local_san: "localhost vmm.ilnmors.internal" ssh_san: "{{ node['name'] }},{{ node['name'] }}_init,{{ node['name'] }}.{{ domain['internal'] }},init.{{ node['name'] }}.{{ domain['internal'] }}"
local_san: "localhost {{ node['name'] }}.{{ domain['internal'] }}"
hardware:
mac:
nic0: "c8:ff:bf:07:02:34"
nic1: "c8:ff:bf:07:02:33"
sfpp0: "c8:ff:bf:07:02:31"
sfpp1: "c8:ff:bf:07:02:32"
igpu:
id: "8086:4628"
address: "0000:00:02.0"
domain: "0x0000"
bus: "0x00"
slot: "0x02"
function: "0x0"
hdd:
data:
hdd0: "WMC6N0E617S8"
hdd1: "P6HVTL0W"
hdd2: "P2GH354H"
hdd3: "P6GJKSMP"
btrfs:
label: "DATA"
level: "raid10"
mount_point: "{{ node['libvirt_path'] }}/data"
+15 -20
View File
@@ -2,17 +2,29 @@
# Node Factors # Node Factors
node: node:
name: "app" name: "app"
group: "svadmins"
uid: 2004 uid: 2004
home_path: "/home/app" home_path: "/home/app"
ssh_san: "app,app.ilnmors.internal" ssh_san: "{{ node['name'] }},{{ node['name'] }}.{{ domain['internal'] }}"
local_san: "localhost app.ilnmors.internal" local_san: "localhost {{ node['name'] }}.{{ domain['internal'] }}"
# VM Factors # VM Factors
vm: vm:
name: "app" name: "app"
cpu: 4 cpu: 6
cpu_pin: |
<vcpupin vcpu='0' cpuset='0'/>
<vcpupin vcpu='1' cpuset='1'/>
<vcpupin vcpu='2' cpuset='2'/>
<vcpupin vcpu='3' cpuset='3'/>
<vcpupin vcpu='4' cpuset='10'/>
<vcpupin vcpu='5' cpuset='11'/>
<emulatorpin cpuset='10-11'/>
shares: 1024 shares: 1024
memory: 16 memory: 16
storage: 256 storage: 256
data_storage:
name: "vdb"
size: 3.5
lan_mac: "0a:49:6e:4d:03:00" lan_mac: "0a:49:6e:4d:03:00"
lan_net: "lan-net" lan_net: "lan-net"
lan_group: "vlan10-access" lan_group: "vlan10-access"
@@ -26,20 +38,3 @@ vm:
bus: "0x00" bus: "0x00"
slot: "0x02" slot: "0x02"
function: "0x0" function: "0x0"
sata_controller: # Additional SATA Controller
address: "0000:04:00.0"
domain: "0x0000"
bus: "0x04"
slot: "0x00"
function: "0x0"
# BTRFS configuration for hdd which is passthroughed
storage:
btrfs:
label: "APP_DATA"
level: "raid10"
mount_point: "/home/app/data"
redis:
immich: "6379"
paperless: "6380"
+8 -3
View File
@@ -2,15 +2,20 @@
# Node Factors # Node Factors
node: node:
name: "auth" name: "auth"
group: "svadmins"
uid: 2003 uid: 2003
home_path: "/home/auth" home_path: "/home/auth"
ssh_san: "auth,auth.ilnmors.internal" ssh_san: "{{ node['name'] }},{{ node['name'] }}.{{ domain['internal'] }}"
local_san: "localhost auth.ilnmors.internal" local_san: "localhost {{ node['name'] }}.{{ domain['internal'] }}"
# VM Factors # VM Factors
vm: vm:
name: "auth" name: "auth"
cpu: 2 cpu: 2
shares: 512 cpu_pin: |
<vcpupin vcpu='0' cpuset='8'/>
<vcpupin vcpu='1' cpuset='9'/>
<emulatorpin cpuset='8-9'/>
shares: 1024
memory: 2 memory: 2
storage: 64 storage: 64
lan_mac: "0a:49:6e:4d:02:00" lan_mac: "0a:49:6e:4d:02:00"
+9 -8
View File
@@ -10,16 +10,17 @@ age_key: !vault |
33653638373537323363316363646534323362353836373665636265663939353862663532313230 33653638373537323363316363646534323362353836373665636265663939353862663532313230
30643038313138626464626161373835646665326334393834616234643931656536343130316238 30643038313138626464626161373835646665326334393834616234643931656536343130316238
61656264643830616639 61656264643830616639
# Node Factors
node: node:
name: "console" name: "console"
group: "svadmins"
uid: 2999 uid: 2999
home_path: "/home/console" home_path: "/home/console"
workspace_path: "{{ node.home_path }}/workspace" workspace_path: "{{ node['home_path'] }}/workspace"
homelab_path: "{{ node.home_path }}/workspace/homelab" homelab_path: "{{ node['home_path'] }}/workspace/homelab"
data_path: "{{ node.homelab_path }}/data" data_path: "{{ node['homelab_path'] }}/data"
config_path: "{{ node.homelab_path }}/config" config_path: "{{ node['homelab_path'] }}/config"
ssh_san: "console,console.ilnmors.internal" ssh_san: "{{ node['name'] }},{{ node['name'] }}.{{ domain['internal'] }}"
ssh_users: "vmm,fw,infra,auth,app" ssh_users: "vmm,fw,infra,auth,app"
local_san: "localhost console.ilnmors.internal" # add the hostname of wsl, it is needed to improve the sudo problem
# ansible_python_interpreter: "{{ ansible_playbook_python }}" local_san: "localhost {{ node['name'] }} {{ node['name'] }}.{{ domain['internal'] }}"
+11 -4
View File
@@ -2,15 +2,22 @@
# Node Factors # Node Factors
node: node:
name: "fw" name: "fw"
group: "svadmins"
uid: 2001 uid: 2001
home_path: "/home/fw" home_path: "/home/fw"
ssh_san: "fw,fw.ilnmors.internal" ssh_san: "{{ node['name'] }},{{ node['name'] }}.{{ domain['internal'] }}"
local_san: "localhost fw.ilnmors.internal" local_san: "localhost {{ node['name'] }}.{{ domain['internal'] }}"
# VM Factors # VM Factors
vm: vm:
name: "fw" name: "fw"
cpu: 2 cpu: 4
cpu_pin: |
<vcpupin vcpu='0' cpuset='0'/>
<vcpupin vcpu='1' cpuset='1'/>
<vcpupin vcpu='2' cpuset='4'/>
<vcpupin vcpu='3' cpuset='5'/>
<emulatorpin cpuset='4-5'/>
shares: 2048 shares: 2048
memory: 4 memory: 4
storage: 64 storage: 64
@@ -21,7 +28,7 @@ vm:
lan_group: "vlan-trunk" lan_group: "vlan-trunk"
# Network Factors # Network Factors
# LLA is like MAC address for L3 (Network layer). Usually, subnet is used to seperate network. # LLA is like MAC address for L3 (Network layer). Usually, subnet is used to separate network.
network4: network4:
subnet: subnet:
client: "192.168.1.0/24" client: "192.168.1.0/24"
+11 -4
View File
@@ -2,16 +2,23 @@
# Node Factors # Node Factors
node: node:
name: "infra" name: "infra"
group: "svadmins"
uid: 2002 uid: 2002
home_path: "/home/infra" home_path: "/home/infra"
ssh_san: "infra,infra.ilnmors.internal" ssh_san: "{{ node['name'] }},{{ node['name'] }}.{{ domain['internal'] }}"
local_san: "localhost infra.ilnmors.internal" local_san: "localhost {{ node['name'] }}.{{ domain['internal'] }}"
# VM Factors # VM Factors
vm: vm:
name: "infra" name: "infra"
cpu: 2 cpu: 4
shares: 1024 cpu_pin: |
<vcpupin vcpu='0' cpuset='2'/>
<vcpupin vcpu='1' cpuset='3'/>
<vcpupin vcpu='2' cpuset='6'/>
<vcpupin vcpu='3' cpuset='7'/>
<emulatorpin cpuset='6-7'/>
shares: 2048
memory: 6 memory: 6
storage: 256 storage: 256
lan_mac: "0a:49:6e:4d:01:00" lan_mac: "0a:49:6e:4d:01:00"
+1 -1
View File
@@ -11,4 +11,4 @@ vmm ansible_host=vmm.ilnmors.internal ansible_user=vmm
fw ansible_host=fw.ilnmors.internal ansible_user=fw fw ansible_host=fw.ilnmors.internal ansible_user=fw
infra ansible_host=infra.ilnmors.internal ansible_user=infra infra ansible_host=infra.ilnmors.internal ansible_user=infra
auth ansible_host=auth.ilnmors.internal ansible_user=auth auth ansible_host=auth.ilnmors.internal ansible_user=auth
app ansible_host=app.ilnmors.internal ansible_user=app app ansible_host=app.ilnmors.internal ansible_user=app
+51 -18
View File
@@ -20,12 +20,13 @@
- name: Set become password - name: Set become password
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_become_pass: "{{ hostvars['console']['sudo']['password']['app'] }}" ansible_become_pass: "{{ hostvars['console']['sudo']['password']['app'] }}"
no_log: true
tags: ["always"] tags: ["always"]
tasks: tasks:
- name: Set timezone to Asia/Seoul - name: Set timezone
community.general.timezone: community.general.timezone:
name: Asia/Seoul name: "{{ timezone }}"
become: true become: true
tags: ["init", "timezone"] tags: ["init", "timezone"]
@@ -97,10 +98,10 @@
become: true become: true
tags: ["init", "install-packages"] tags: ["init", "install-packages"]
- name: Set raid - name: Set data volume
ansible.builtin.include_role: ansible.builtin.include_role:
name: "app" name: "app"
tasks_from: "node/set_raid" tasks_from: "node/set_data_volume"
apply: apply:
tags: ["init", "raid"] tags: ["init", "raid"]
tags: ["init", "raid"] tags: ["init", "raid"]
@@ -142,8 +143,8 @@
name: "common" name: "common"
tasks_from: "services/set_alloy" tasks_from: "services/set_alloy"
apply: apply:
tags: ["init", "update", "alloy"] tags: ["init", "alloy"]
tags: ["init", "update", "alloy"] tags: ["init", "alloy"]
- name: Set kopia - name: Set kopia
ansible.builtin.include_role: ansible.builtin.include_role:
@@ -185,14 +186,6 @@
tags: ["site", "immich"] tags: ["site", "immich"]
tags: ["site", "immich"] tags: ["site", "immich"]
- name: Set actual budget
ansible.builtin.include_role:
name: "app"
tasks_from: "services/set_actual-budget"
apply:
tags: ["site", "actual-budget"]
tags: ["site", "actual-budget"]
- name: Set paperless - name: Set paperless
ansible.builtin.include_role: ansible.builtin.include_role:
name: "app" name: "app"
@@ -201,13 +194,53 @@
tags: ["site", "paperless"] tags: ["site", "paperless"]
tags: ["site", "paperless"] tags: ["site", "paperless"]
- name: Set vikunja - name: Set nextcloud
ansible.builtin.include_role: ansible.builtin.include_role:
name: "app" name: "app"
tasks_from: "services/set_vikunja" tasks_from: "services/set_nextcloud"
apply: apply:
tags: ["site", "vikunja"] tags: ["site", "nextcloud"]
tags: ["site", "vikunja"] tags: ["site", "nextcloud"]
- name: Set collabora
ansible.builtin.include_role:
name: "app"
tasks_from: "services/set_collabora"
apply:
tags: ["site", "collabora"]
tags: ["site", "collabora"]
- name: Set sure
ansible.builtin.include_role:
name: "app"
tasks_from: "services/set_sure"
apply:
tags: ["site", "sure"]
tags: ["site", "sure"]
- name: Set outline
ansible.builtin.include_role:
name: "app"
tasks_from: "services/set_outline"
apply:
tags: ["site", "outline"]
tags: ["site", "outline"]
- name: Set memos
ansible.builtin.include_role:
name: "app"
tasks_from: "services/set_memos"
apply:
tags: ["site", "memos"]
tags: ["site", "memos"]
- name: Set mealie
ansible.builtin.include_role:
name: "app"
tasks_from: "services/set_mealie"
apply:
tags: ["site", "mealie"]
tags: ["site", "mealie"]
- name: Flush handlers right now - name: Flush handlers right now
ansible.builtin.meta: "flush_handlers" ansible.builtin.meta: "flush_handlers"
+3 -2
View File
@@ -20,12 +20,13 @@
- name: Set become password - name: Set become password
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_become_pass: "{{ hostvars['console']['sudo']['password']['auth'] }}" ansible_become_pass: "{{ hostvars['console']['sudo']['password']['auth'] }}"
no_log: true
tags: ["always"] tags: ["always"]
tasks: tasks:
- name: Set timezone to Asia/Seoul - name: Set timezone
community.general.timezone: community.general.timezone:
name: Asia/Seoul name: "{{ timezone }}"
become: true become: true
tags: ["init", "timezone"] tags: ["init", "timezone"]
+25 -35
View File
@@ -20,13 +20,14 @@
- name: Set become password - name: Set become password
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_become_pass: "{{ hostvars['console']['sudo']['password']['console'] }}" ansible_become_pass: "{{ hostvars['console']['sudo']['password']['console'] }}"
no_log: true
tags: ["always"] tags: ["always"]
tasks: tasks:
# init # init
- name: Set timezone to Asia/Seoul - name: Set timezone
community.general.timezone: community.general.timezone:
name: Asia/Seoul name: "{{ timezone }}"
become: true become: true
tags: ["init", "timezone"] tags: ["init", "timezone"]
@@ -70,32 +71,6 @@
tags: ["init", "ssh_client"] tags: ["init", "ssh_client"]
tags: ["init", "ssh_client"] tags: ["init", "ssh_client"]
- name: Check file permissions
ansible.builtin.file:
path: "{{ node['workspace_path'] }}/{{ item }}"
state: "directory"
owner: "{{ ansible_user }}"
group: "svadmins"
mode: "u=rwX,g=,o="
recurse: true
loop:
- "homelab/ansible"
- "homelab/config"
- "homelab/docs"
- "university"
tags: ["init", "site", "file_permission"]
# kopia snashot is mounted on homelab/data/volumes.
# NEVER CHANGE permission and owners
- name: Download vm cloud-init
ansible.builtin.get_url:
url: "https://cdimage.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2"
dest: "{{ node['data_path'] }}/images/debian-13-generic-amd64.qcow2"
owner: "console"
group: "svadmins"
mode: "0600"
tags: ["init", "site", "cloud-init-image"]
- name: Install packages - name: Install packages
ansible.builtin.apt: ansible.builtin.apt:
name: name:
@@ -108,14 +83,12 @@
- "logrotate" - "logrotate"
- "nftables" - "nftables"
- "build-essential" - "build-essential"
- "g++"
- "gcc"
- "fuse3" - "fuse3"
state: "present" state: "present"
become: true become: true
tags: ["init", "site", "install-packages"] tags: ["init", "site", "install-packages"]
- name: Install CLI tools - name: Set CLI tools
ansible.builtin.include_role: ansible.builtin.include_role:
name: "console" name: "console"
tasks_from: "services/set_cli_tools" tasks_from: "services/set_cli_tools"
@@ -123,10 +96,27 @@
tags: ["init", "site", "tools"] tags: ["init", "site", "tools"]
tags: ["init", "site", "tools"] tags: ["init", "site", "tools"]
- name: Install chromium with font - name: Set vmm_init config
ansible.builtin.include_role: ansible.builtin.include_role:
name: "console" name: "console"
tasks_from: "services/set_chromium" tasks_from: "node/create_vmm_init"
apply: apply:
tags: ["init", "site", "chromium"] tags: ["site", "vmm_init"]
tags: ["init", "site", "chromium"] tags: ["site", "vmm_init"]
- name: Download vm cloud-init
ansible.builtin.get_url:
url: "https://cdimage.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2"
dest: "{{ node['data_path'] }}/images/debian-13-generic-amd64.qcow2"
owner: "console"
group: "svadmins"
mode: "0600"
tags: ["init", "site", "cloud-init-image"]
- name: Set kopia
ansible.builtin.include_role:
name: "common"
tasks_from: "services/set_kopia"
apply:
tags: ["init", "site", "kopia"]
tags: ["init", "site", "kopia"]
+5 -4
View File
@@ -20,12 +20,13 @@
- name: Set become password - name: Set become password
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_become_pass: "{{ hostvars['console']['sudo']['password']['fw'] }}" ansible_become_pass: "{{ hostvars['console']['sudo']['password']['fw'] }}"
no_log: true
tags: ["always"] tags: ["always"]
tasks: tasks:
- name: Set timezone to Asia/Seoul - name: Set timezone
community.general.timezone: community.general.timezone:
name: Asia/Seoul name: "{{ timezone }}"
become: true become: true
tags: ["init", "timezone"] tags: ["init", "timezone"]
@@ -162,8 +163,8 @@
name: "fw" name: "fw"
tasks_from: "services/set_bind" tasks_from: "services/set_bind"
apply: apply:
tags: ["init", "update", "bind"] tags: ["init", "bind"]
tags: ["init", "update", "bind"] tags: ["init", "bind"]
- name: Set blocky - name: Set blocky
ansible.builtin.include_role: ansible.builtin.include_role:
+3 -2
View File
@@ -20,12 +20,13 @@
- name: Set become password - name: Set become password
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_become_pass: "{{ hostvars['console']['sudo']['password']['infra'] }}" ansible_become_pass: "{{ hostvars['console']['sudo']['password']['infra'] }}"
no_log: true
tags: ["always"] tags: ["always"]
tasks: tasks:
- name: Set timezone to Asia/Seoul - name: Set timezone
community.general.timezone: community.general.timezone:
name: Asia/Seoul name: "{{ timezone }}"
become: true become: true
tags: ["init", "timezone"] tags: ["init", "timezone"]
+1
View File
@@ -36,6 +36,7 @@
- name: Set become password - name: Set become password
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_become_pass: "{{ hostvars['console']['sudo']['password']['vmm'] }}" ansible_become_pass: "{{ hostvars['console']['sudo']['password']['vmm'] }}"
no_log: true
- name: Create seed file - name: Create seed file
ansible.builtin.include_role: ansible.builtin.include_role:
+12 -2
View File
@@ -27,12 +27,13 @@
- name: Set become password - name: Set become password
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_become_pass: "{{ hostvars['console']['sudo']['password']['vmm'] }}" ansible_become_pass: "{{ hostvars['console']['sudo']['password']['vmm'] }}"
no_log: true
tags: ["always"] tags: ["always"]
tasks: tasks:
# init # init
- name: Set timezone to Asia/Seoul - name: Set timezone
community.general.timezone: community.general.timezone:
name: Asia/Seoul name: "{{ timezone }}"
become: true become: true
tags: ["init", "timezone"] tags: ["init", "timezone"]
@@ -100,6 +101,14 @@
tags: ["init", "linger"] tags: ["init", "linger"]
tags: ["init", "linger"] tags: ["init", "linger"]
- name: Set raid
ansible.builtin.include_role:
name: "vmm"
tasks_from: "node/set_raid"
apply:
tags: ["init", "raid"]
tags: ["init", "raid"]
- name: Set libvirt - name: Set libvirt
ansible.builtin.include_role: ansible.builtin.include_role:
name: "vmm" name: "vmm"
@@ -155,6 +164,7 @@
- ksmtuned - ksmtuned
- libvirt-daemon-system - libvirt-daemon-system
- virt-top - virt-top
- btrfs-progs
- python3 - python3
- python3-apt - python3-apt
- python3-libvirt - python3-libvirt
+63 -14
View File
@@ -43,17 +43,6 @@
listen: "notification_restart_immich-ml" listen: "notification_restart_immich-ml"
ignore_errors: true # noqa: ignore-errors ignore_errors: true # noqa: ignore-errors
- name: Restart actual-budget
ansible.builtin.systemd:
name: "actual-budget.service"
state: "restarted"
enabled: true
scope: "user"
daemon_reload: true
changed_when: false
listen: "notification_restart_actual-budget"
ignore_errors: true # noqa: ignore-errors
- name: Restart paperless - name: Restart paperless
ansible.builtin.systemd: ansible.builtin.systemd:
name: "paperless.service" name: "paperless.service"
@@ -65,13 +54,73 @@
listen: "notification_restart_paperless" listen: "notification_restart_paperless"
ignore_errors: true # noqa: ignore-errors ignore_errors: true # noqa: ignore-errors
- name: Restart vikunja - name: Restart nextcloud
ansible.builtin.systemd: ansible.builtin.systemd:
name: "vikunja.service" name: "nextcloud.service"
state: "restarted"
enabled: true
daemon_reload: true
scope: "user"
when: is_nextcloud_init.stat.exists
changed_when: false
listen: "notification_restart_nextcloud"
ignore_errors: true # noqa: ignore-errors
- name: Restart collabora
ansible.builtin.systemd:
name: "collabora.service"
state: "restarted" state: "restarted"
enabled: true enabled: true
scope: "user" scope: "user"
daemon_reload: true daemon_reload: true
changed_when: false changed_when: false
listen: "notification_restart_vikunja" listen: "notification_restart_collabora"
ignore_errors: true # noqa: ignore-errors
- name: Restart sure
ansible.builtin.systemd:
name: "{{ item }}"
state: "restarted"
enabled: true
scope: "user"
daemon_reload: true
loop:
- "sure-web.service"
- "sure-worker.service"
changed_when: false
listen: "notification_restart_sure"
ignore_errors: true # noqa: ignore-errors
- name: Restart outline
ansible.builtin.systemd:
name: "outline.service"
state: "restarted"
enabled: true
scope: "user"
daemon_reload: true
when: is_outline_init.stat.exists
changed_when: false
listen: "notification_restart_outline"
ignore_errors: true # noqa: ignore-errors
- name: Restart memos
ansible.builtin.systemd:
name: "memos.service"
state: "restarted"
enabled: true
scope: "user"
daemon_reload: true
changed_when: false
listen: "notification_restart_memos"
ignore_errors: true # noqa: ignore-errors
- name: Restart mealie
ansible.builtin.systemd:
name: "mealie.service"
state: "restarted"
enabled: true
scope: "user"
daemon_reload: true
changed_when: false
listen: "notification_restart_mealie"
ignore_errors: true # noqa: ignore-errors ignore_errors: true # noqa: ignore-errors
@@ -0,0 +1,41 @@
---
- name: Check app data volume filesystem already exists
ansible.builtin.command:
cmd: "blkid /dev/{{ vm['data_storage']['name'] }}"
register: is_app_data
changed_when: false
failed_when: false
become: true
- name: Create ext4 filesystem on app data raw
ansible.builtin.command:
cmd: "mkfs.ext4 -F /dev/{{ vm['data_storage']['name'] }}"
when: is_app_data.rc != 0
changed_when: true
become: true
- name: Set data volume path
ansible.builtin.file:
path: "{{ node['home_path'] }}/data"
state: "directory"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0770"
- name: Mount app data volume
ansible.posix.mount:
path: "{{ node['home_path'] }}/data"
src: "/dev/{{ vm['data_storage']['name'] }}"
opts: "noatime"
state: "mounted"
fstype: "ext4"
become: true
- name: Set app data volume path permissions
ansible.builtin.file:
path: "{{ node['home_path'] }}/data"
state: "directory"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0770"
become: true
@@ -1,70 +0,0 @@
---
- name: Check btrfs installation
ansible.builtin.shell: |
command -v btrfs
become: true # btrfs is located in /usr/sbin, which means root permission is needed.
changed_when: false
failed_when: false
register: "is_btrfs_installed"
ignore_errors: true
- name: Install btrfs
ansible.builtin.apt:
name: "btrfs-progs"
state: "present"
become: true
when: is_btrfs_installed.rc != 0
- name: Set hard disk path
ansible.builtin.shell: |
set -o pipefail
ls -1 /dev/disk/by-path/*{{ vm['pass_through']['sata_controller']['address'] }}* | \
grep -v '\.0$' | \
sort
changed_when: false
register: "hdd_path_list"
- name: Check app_hdd filesystem already exists
ansible.builtin.command: |
blkid -L {{ storage['btrfs']['label'] }}
register: is_app_data
changed_when: false
failed_when: false
become: true
- name: Check disk number
ansible.builtin.fail:
msg: "Below 4 disks for RAID10, found {{ hdd_path_list.stdout_lines | length }}"
when: (hdd_path_list.stdout_lines | length) < 4
- name: Set btrfs raid10 volume
ansible.builtin.shell: |
mkfs.btrfs -f \
-L {{ storage['btrfs']['label'] }} \
-d {{ storage['btrfs']['level'] }} \
-m {{ storage['btrfs']['level'] }} \
{{ hdd_path_list.stdout_lines | join(' ') }}
become: true
when:
- is_app_data.rc != 0
- (hdd_path_list.stdout_lines | length) >= 4
changed_when: is_mkfs.rc == 0
register: "is_mkfs"
- name: Mount btrfs raid10 volume
ansible.posix.mount:
path: "{{ storage['btrfs']['mount_point'] }}"
src: "LABEL={{ storage['btrfs']['label'] }}"
state: "mounted"
fstype: "btrfs"
opts: "defaults,noatime,compress=zstd:3,autodefrag,degraded,nofail"
become: true
- name: Set hard disk path permissions
ansible.builtin.file:
path: "{{ storage['btrfs']['mount_point'] }}"
state: "directory"
owner: "{{ ansible_user }}"
group: "svadmins"
mode: "0770"
become: true
@@ -0,0 +1,37 @@
---
- name: Deploy container file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/collabora/collabora.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/collabora.container"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
notify: "notification_restart_collabora"
- name: Enable collabora.service
ansible.builtin.systemd:
name: "collabora.service"
state: "started"
enabled: true
daemon_reload: true
scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/docker.io_collabora_code_{{ version['containers']['collabora'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "docker.io/collabora/code:{{ version['containers']['collabora'] }}"
dest: "{{ node['home_path'] }}/archives/containers/docker.io_collabora_code_{{ version['containers']['collabora'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/docker.io_collabora_code_{{ version['containers']['collabora'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
+26 -10
View File
@@ -1,14 +1,10 @@
--- ---
- name: Set gitea container subuid
ansible.builtin.set_fact:
gitea_subuid: "100999"
- name: Create gitea directory - name: Create gitea directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}" path: "{{ node['home_path'] }}/{{ item }}"
state: "directory" state: "directory"
owner: "{{ gitea_subuid }}" owner: "{{ services['gitea']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0770" mode: "0770"
loop: loop:
- "data/containers/gitea" - "data/containers/gitea"
@@ -20,9 +16,9 @@
ansible.builtin.copy: ansible.builtin.copy:
content: | content: |
{{ hostvars['console']['ca']['root']['crt'] }} {{ hostvars['console']['ca']['root']['crt'] }}
dest: "{{ node['home_path'] }}/containers/gitea/ssl/ilnmors_root_ca.crt" dest: "{{ node['home_path'] }}/containers/gitea/ssl/{{ root_cert_filename }}"
owner: "{{ gitea_subuid }}" owner: "{{ services['gitea']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0440" mode: "0440"
become: true become: true
notify: "notification_restart_gitea" notify: "notification_restart_gitea"
@@ -42,7 +38,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/gitea/gitea.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/gitea/gitea.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/gitea.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/gitea.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_gitea" notify: "notification_restart_gitea"
@@ -53,3 +49,23 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/docker.io_gitea_gitea_{{ version['containers']['gitea'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "docker.io/gitea/gitea:{{ version['containers']['gitea'] }}"
dest: "{{ node['home_path'] }}/archives/containers/docker.io_gitea_gitea_{{ version['containers']['gitea'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/docker.io_gitea_gitea_{{ version['containers']['gitea'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -2,14 +2,13 @@
- name: Set redis service name - name: Set redis service name
ansible.builtin.set_fact: ansible.builtin.set_fact:
redis_service: "immich" redis_service: "immich"
redis_subuid: "100998"
- name: Create redis_immich directory - name: Create redis_immich directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}" path: "{{ node['home_path'] }}/{{ item }}"
state: "directory" state: "directory"
owner: "{{ redis_subuid }}" owner: "{{ services['redis']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0770" mode: "0770"
loop: loop:
- "containers/redis" - "containers/redis"
@@ -22,7 +21,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2"
dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf" dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
register: "is_redis_conf" register: "is_redis_conf"
@@ -31,7 +30,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
register: "is_redis_containerfile" register: "is_redis_containerfile"
@@ -57,7 +56,7 @@
path: "{{ node['home_path'] }}/{{ item }}" path: "{{ node['home_path'] }}/{{ item }}"
state: "directory" state: "directory"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0770" mode: "0770"
loop: loop:
- "data/containers/immich" - "data/containers/immich"
@@ -70,9 +69,9 @@
ansible.builtin.copy: ansible.builtin.copy:
content: | content: |
{{ hostvars['console']['ca']['root']['crt'] }} {{ hostvars['console']['ca']['root']['crt'] }}
dest: "{{ node['home_path'] }}/containers/immich/ssl/ilnmors_root_ca.crt" dest: "{{ node['home_path'] }}/containers/immich/ssl/{{ root_cert_filename }}"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0440" mode: "0440"
notify: "notification_restart_immich" notify: "notification_restart_immich"
no_log: true no_log: true
@@ -91,7 +90,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/immich/immich.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/immich/immich.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/immich.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/immich.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_immich" notify: "notification_restart_immich"
@@ -100,7 +99,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/immich/immich-ml.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/immich/immich-ml.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/immich-ml.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/immich-ml.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_immich-ml" notify: "notification_restart_immich-ml"
@@ -119,3 +118,38 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/{{ item.file }}.tar"
loop:
- image: "docker.io/library/redis:{{ version['containers']['redis'] }}"
file: "docker.io_library_redis_{{ version['containers']['redis'] }}"
- image: "ghcr.io/immich-app/immich-machine-learning:{{ version['containers']['immich'] }}-openvino"
file: "ghcr.io_immich-app_immich-machine-learning_{{ version['containers']['immich'] }}-openvino"
- image: "ghcr.io/immich-app/immich-server:{{ version['containers']['immich'] }}"
file: "ghcr.io_immich-app_immich-server_{{ version['containers']['immich'] }}"
loop_control:
label: "{{ item.file }}"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "{{ item.item.image }}"
dest: "{{ node['home_path'] }}/archives/containers/{{ item.item.file }}.tar"
format: "oci-archive"
force: false
loop: "{{ container_archive_images.results }}"
loop_control:
label: "{{ item.item.file }}"
when: not item.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/{{ item.item.file }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
loop: "{{ container_archive_images.results }}"
loop_control:
label: "{{ item.item.file }}"
@@ -0,0 +1,77 @@
---
- name: Create mealie directory
ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}"
state: "directory"
owner: "{{ services['mealie']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0770"
loop:
- "data/containers/mealie"
- "data/containers/mealie/data"
- "containers/mealie"
- "containers/mealie/ssl"
become: true
- name: Deploy root certificate
ansible.builtin.copy:
content: |
{{ hostvars['console']['ca']['root']['crt'] }}
dest: "{{ node['home_path'] }}/containers/mealie/ssl/{{ root_cert_filename }}"
owner: "{{ services['mealie']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0440"
become: true
notify: "notification_restart_mealie"
no_log: true
- name: Register secret value to podman secret
containers.podman.podman_secret:
name: "{{ item.name }}"
data: "{{ item.value }}"
state: "present"
force: true
loop:
- name: "MEALIE_POSTGRES_PASSWORD"
value: "{{ hostvars['console']['postgresql']['password']['mealie'] }}"
- name: "MEALIE_OIDC_CLIENT_SECRET"
value: "{{ hostvars['console']['mealie']['oidc']['secret'] }}"
notify: "notification_restart_mealie"
no_log: true
- name: Deploy mealie.container file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/mealie/mealie.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/mealie.container"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
notify: "notification_restart_mealie"
- name: Enable mealie.service
ansible.builtin.systemd:
name: "mealie.service"
state: "started"
enabled: true
daemon_reload: true
scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/ghcr.io_mealie-recipes_mealie_{{ version['containers']['mealie'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "ghcr.io/mealie-recipes/mealie:{{ version['containers']['mealie'] }}"
dest: "{{ node['home_path'] }}/archives/containers/ghcr.io_mealie-recipes_mealie_{{ version['containers']['mealie'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/ghcr.io_mealie-recipes_mealie_{{ version['containers']['mealie'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -0,0 +1,74 @@
---
- name: Create memos directory
ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}"
state: "directory"
owner: "{{ services['memos']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0770"
loop:
- "data/containers/memos"
- "data/containers/memos/data"
- "containers/memos"
- "containers/memos/ssl"
become: true
- name: Deploy root certificate
ansible.builtin.copy:
content: |
{{ hostvars['console']['ca']['root']['crt'] }}
dest: "{{ node['home_path'] }}/containers/memos/ssl/{{ root_cert_filename }}"
owner: "{{ services['memos']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0440"
become: true
notify: "notification_restart_memos"
no_log: true
- name: Register secret value to podman secret
containers.podman.podman_secret:
name: "MEMOS_DSN"
data: "postgresql://memos:{{ hostvars['console']['postgresql']['password']['memos'] | urlencode | replace('/', '%2F') }}\
@{{ services['postgresql']['domain'] }}.{{ domain['internal'] }}/memos_db?sslmode=verify-full&\
sslrootcert=/etc/ssl/memos/{{ root_cert_filename }}"
state: "present"
force: true
no_log: true
notify: "notification_restart_memos"
- name: Deploy memos.container file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/memos/memos.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/memos.container"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
notify: "notification_restart_memos"
- name: Enable memos.service
ansible.builtin.systemd:
name: "memos.service"
state: "started"
enabled: true
daemon_reload: true
scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/docker.io_neosmemo_memos_{{ version['containers']['memos'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "docker.io/neosmemo/memos:{{ version['containers']['memos'] }}"
dest: "{{ node['home_path'] }}/archives/containers/docker.io_neosmemo_memos_{{ version['containers']['memos'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/docker.io_neosmemo_memos_{{ version['containers']['memos'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -0,0 +1,209 @@
---
- name: Set redis service name
ansible.builtin.set_fact:
redis_service: "nextcloud"
- name: Create redis_nextcloud directory
ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}"
state: "directory"
owner: "{{ services['redis']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0770"
loop:
- "containers/redis"
- "containers/redis/{{ redis_service }}"
- "containers/redis/{{ redis_service }}/data"
become: true
- name: Deploy redis config file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2"
dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
register: "is_redis_conf"
- name: Deploy redis container file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
register: "is_redis_containerfile"
- name: Enable (Restart) redis service
ansible.builtin.systemd:
name: "redis_{{ redis_service }}.service"
state: "restarted"
enabled: true
daemon_reload: true
scope: "user"
when: is_redis_conf.changed or is_redis_containerfile.changed # noqa: no-handler
- name: Create nextcloud directory
ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}"
state: "directory"
owner: "{{ services['nextcloud']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0770"
loop:
- "data/containers/nextcloud"
- "data/containers/nextcloud/html"
- "containers/nextcloud"
- "containers/nextcloud/ssl"
- "containers/nextcloud/ini"
become: true
- name: Check data directory empty
ansible.builtin.stat:
path: "{{ node['home_path'] }}/data/containers/nextcloud/.init"
register: "is_nextcloud_init"
- name: Deploy root certificate
ansible.builtin.copy:
content: |
{{ hostvars['console']['ca']['root']['crt'] }}
dest: "{{ node['home_path'] }}/containers/nextcloud/ssl/{{ root_cert_filename }}"
owner: "{{ services['nextcloud']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0440"
become: true
notify: "notification_restart_nextcloud"
no_log: true
- name: Initialize nextcloud
when: not is_nextcloud_init.stat.exists
block:
- name: Execute init command (Including pulling image)
containers.podman.podman_container:
name: "nextcloud_init"
image: "docker.io/library/nextcloud:{{ version['containers']['nextcloud'] }}"
command: "/bin/true"
state: "started"
rm: true
detach: false
env:
NEXTCLOUD_UPDATE: "1"
NEXTCLOUD_ADMIN_USER: "{{ hostvars['console']['nextcloud']['admin']['id'] }}"
NEXTCLOUD_ADMIN_PASSWORD: "{{ hostvars['console']['nextcloud']['admin']['password'] }}"
POSTGRES_HOST: "{{ services['postgresql']['domain'] }}.{{ domain['internal'] }}:{{ services['postgresql']['ports']['tcp'] }}"
POSTGRES_DB: "nextcloud_db"
POSTGRES_USER: "nextcloud"
POSTGRES_PASSWORD: "{{ hostvars['console']['postgresql']['password']['nextcloud'] }}"
PGSSLMODE: "verify-full"
PGSSLROOTCERT: "/etc/ssl/nextcloud/{{ root_cert_filename }}"
PGSSLCERTMODE: "disable"
REDIS_HOST: "host.containers.internal"
REDIS_HOST_PORT: "{{ services['nextcloud']['ports']['redis'] }}"
volume:
- "{{ node['home_path'] }}/containers/nextcloud/ssl:/etc/ssl/nextcloud:ro"
- "{{ node['home_path'] }}/data/containers/nextcloud/html:/var/www/html:rw"
no_log: true
- name: Create .init file
ansible.builtin.file:
path: "{{ node['home_path'] }}/data/containers/nextcloud/.init"
state: "touch"
mode: "0644"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
- name: Deploy config files
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/nextcloud/config/{{ item }}.j2"
dest: "{{ node['home_path'] }}/data/containers/nextcloud/html/config/{{ item }}"
owner: "{{ services['nextcloud']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0640"
loop:
- "background.config.php"
- "cache.config.php"
- "domain.config.php"
- "local_remote.config.php"
- "user_oidc.config.php"
become: true
notify: "notification_restart_nextcloud"
- name: Deploy opcache.ini file
ansible.builtin.copy:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/nextcloud/ini/{{ item }}"
dest: "{{ node['home_path'] }}/containers/nextcloud/ini/{{ item }}"
group: "{{ node['group'] }}"
mode: "0644"
loop:
- "opcache.ini"
- "upload.ini"
notify: "notification_restart_nextcloud"
- name: Deploy nextcloud.container file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/nextcloud/nextcloud.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/nextcloud.container"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
notify: "notification_restart_nextcloud"
- name: Deploy nextcloud-cron service
ansible.builtin.copy:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/nextcloud/systemd/{{ item }}"
dest: "{{ node['home_path'] }}/.config/systemd/user/{{ item }}"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
loop:
- "nextcloud-cron.service"
- "nextcloud-cron.timer"
- name: Enable nextcloud.service
ansible.builtin.systemd:
name: "nextcloud.service"
state: "started"
enabled: true
daemon_reload: true
scope: "user"
- name: Enable nextcloud-cron.timer
ansible.builtin.systemd:
name: "nextcloud-cron.timer"
state: "started"
enabled: true
daemon_reload: true
scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/{{ item.file }}.tar"
loop:
- image: "docker.io/library/redis:{{ version['containers']['redis'] }}"
file: "docker.io_library_redis_{{ version['containers']['redis'] }}"
- image: "docker.io/library/nextcloud:{{ version['containers']['nextcloud'] }}"
file: "docker.io_library_nextcloud_{{ version['containers']['nextcloud'] }}"
loop_control:
label: "{{ item.file }}"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "{{ item.item.image }}"
dest: "{{ node['home_path'] }}/archives/containers/{{ item.item.file }}.tar"
format: "oci-archive"
force: false
loop: "{{ container_archive_images.results }}"
loop_control:
label: "{{ item.item.file }}"
when: not item.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/{{ item.item.file }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
loop: "{{ container_archive_images.results }}"
loop_control:
label: "{{ item.item.file }}"
@@ -0,0 +1,152 @@
---
- name: Set redis service name
ansible.builtin.set_fact:
redis_service: "outline"
- name: Create redis_outline directory
ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}"
state: "directory"
owner: "{{ services['redis']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0770"
loop:
- "containers/redis"
- "containers/redis/{{ redis_service }}"
- "containers/redis/{{ redis_service }}/data"
become: true
- name: Deploy redis config file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2"
dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
register: "is_redis_conf"
- name: Deploy redis container file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
register: "is_redis_containerfile"
- name: Enable (Restart) redis service
ansible.builtin.systemd:
name: "redis_{{ redis_service }}.service"
state: "restarted"
enabled: true
daemon_reload: true
scope: "user"
when: is_redis_conf.changed or is_redis_containerfile.changed # noqa: no-handler
- name: Create outline directory
ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}"
state: "directory"
owner: "{{ services['outline']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0770"
loop:
- "data/containers/outline"
- "data/containers/outline/data"
- "containers/outline"
- "containers/outline/ssl"
become: true
- name: Check data directory empty
ansible.builtin.stat:
path: "{{ node['home_path'] }}/data/containers/outline/.init"
register: "is_outline_init"
- name: Create .init file
ansible.builtin.file:
path: "{{ node['home_path'] }}/data/containers/outline/.init"
state: "touch"
mode: "0644"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
when: not is_outline_init.stat.exists
- name: Deploy root certificate
ansible.builtin.copy:
content: |
{{ hostvars['console']['ca']['root']['crt'] }}
dest: "{{ node['home_path'] }}/containers/outline/ssl/{{ root_cert_filename }}"
owner: "{{ services['outline']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0440"
become: true
notify: "notification_restart_outline"
no_log: true
- name: Register secret value to podman secret
containers.podman.podman_secret:
name: "{{ item.name }}"
data: "{{ item.value }}"
state: "present"
force: true
loop:
- name: "OUTLINE_SECRET_KEY"
value: "{{ hostvars['console']['outline']['session_secret'] }}"
- name: "OUTLINE_UTILS_SECRET"
value: "{{ hostvars['console']['outline']['utils_secret'] }}"
- name: "OUTLINE_DATABASE_PASSWORD"
value: "{{ hostvars['console']['postgresql']['password']['outline'] }}"
- name: "OUTLINE_OIDC_CLIENT_SECRET"
value: "{{ hostvars['console']['outline']['oidc']['secret'] }}"
notify: "notification_restart_outline"
no_log: true
- name: Deploy outline.container file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/outline/outline.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/outline.container"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
notify: "notification_restart_outline"
- name: Enable outline.service
ansible.builtin.systemd:
name: "outline.service"
state: "started"
enabled: true
daemon_reload: true
scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/{{ item.file }}.tar"
loop:
- image: "docker.io/library/redis:{{ version['containers']['redis'] }}"
file: "docker.io_library_redis_{{ version['containers']['redis'] }}"
- image: "docker.io/outlinewiki/outline:{{ version['containers']['outline'] }}"
file: "docker.io_outlinewiki_outline_{{ version['containers']['outline'] }}"
loop_control:
label: "{{ item.file }}"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "{{ item.item.image }}"
dest: "{{ node['home_path'] }}/archives/containers/{{ item.item.file }}.tar"
format: "oci-archive"
force: false
loop: "{{ container_archive_images.results }}"
loop_control:
label: "{{ item.item.file }}"
when: not item.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/{{ item.item.file }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
loop: "{{ container_archive_images.results }}"
loop_control:
label: "{{ item.item.file }}"
@@ -2,14 +2,13 @@
- name: Set redis service name - name: Set redis service name
ansible.builtin.set_fact: ansible.builtin.set_fact:
redis_service: "paperless" redis_service: "paperless"
redis_subuid: "100998"
- name: Create redis_paperless directory - name: Create redis_paperless directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}" path: "{{ node['home_path'] }}/{{ item }}"
state: "directory" state: "directory"
owner: "{{ redis_subuid }}" owner: "{{ services['redis']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0770" mode: "0770"
loop: loop:
- "containers/redis" - "containers/redis"
@@ -22,7 +21,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2"
dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf" dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
register: "is_redis_conf" register: "is_redis_conf"
@@ -31,7 +30,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
register: "is_redis_containerfile" register: "is_redis_containerfile"
@@ -44,16 +43,12 @@
scope: "user" scope: "user"
when: is_redis_conf.changed or is_redis_containerfile.changed # noqa: no-handler when: is_redis_conf.changed or is_redis_containerfile.changed # noqa: no-handler
- name: Set paperless subuid
ansible.builtin.set_fact:
paperless_subuid: "100999"
- name: Create paperless directory - name: Create paperless directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}" path: "{{ node['home_path'] }}/{{ item }}"
state: "directory" state: "directory"
owner: "{{ paperless_subuid }}" owner: "{{ services['paperless']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0770" mode: "0770"
loop: loop:
- "data/containers/paperless" - "data/containers/paperless"
@@ -62,21 +57,41 @@
- "data/containers/paperless/consume" - "data/containers/paperless/consume"
- "containers/paperless" - "containers/paperless"
- "containers/paperless/ssl" - "containers/paperless/ssl"
- "containers/paperless/build"
become: true become: true
- name: Deploy containerfile for build
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/paperless/build/paperless.containerfile.j2"
dest: "{{ node['home_path'] }}/containers/paperless/build/Containerfile"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0640"
- name: Deploy root certificate - name: Deploy root certificate
ansible.builtin.copy: ansible.builtin.copy:
content: | content: |
{{ hostvars['console']['ca']['root']['crt'] }} {{ hostvars['console']['ca']['root']['crt'] }}
dest: "{{ node['home_path'] }}/containers/paperless/ssl/ilnmors_root_ca.crt" dest: "{{ node['home_path'] }}/containers/paperless/ssl/{{ root_cert_filename }}"
owner: "{{ paperless_subuid }}" owner: "{{ services['paperless']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0440" mode: "0440"
become: true become: true
notify: "notification_restart_paperless" notify: "notification_restart_paperless"
no_log: true no_log: true
- name: Build paperless container image
containers.podman.podman_image:
name: "{{ domain['internal'] }}/{{ node['name'] }}/paperless-ngx"
# check tags from container file
tag: "{{ version['containers']['paperless'] }}"
state: "build"
path: "{{ node['home_path'] }}/containers/paperless/build"
- name: Prune paperless dangling images
containers.podman.podman_prune:
image: true
- name: Register secret value to podman secret - name: Register secret value to podman secret
containers.podman.podman_secret: containers.podman.podman_secret:
name: "{{ item.name }}" name: "{{ item.name }}"
@@ -101,7 +116,7 @@
"client_id": "paperless", "client_id": "paperless",
"secret": "{{ hostvars['console']['paperless']['oidc']['secret'] }}", "secret": "{{ hostvars['console']['paperless']['oidc']['secret'] }}",
"settings": { "settings": {
"server_url": "https://authelia.ilnmors.com/.well-known/openid-configuration", "server_url": "https://{{ services['authelia']['domain'] }}.{{ domain['public'] }}/.well-known/openid-configuration",
"token_auth_method": "client_secret_post" "token_auth_method": "client_secret_post"
} }
} }
@@ -116,7 +131,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/paperless/paperless.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/paperless/paperless.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/paperless.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/paperless.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_paperless" notify: "notification_restart_paperless"
@@ -127,3 +142,36 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/{{ item.file }}.tar"
loop:
- image: "docker.io/library/redis:{{ version['containers']['redis'] }}"
file: "docker.io_library_redis_{{ version['containers']['redis'] }}"
- image: "{{ domain['internal'] }}/{{ node['name'] }}/paperless-ngx:{{ version['containers']['paperless'] }}"
file: "{{ domain['internal'] }}_{{ node['name'] }}_paperless-ngx_{{ version['containers']['paperless'] }}"
loop_control:
label: "{{ item.file }}"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "{{ item.item.image }}"
dest: "{{ node['home_path'] }}/archives/containers/{{ item.item.file }}.tar"
format: "oci-archive"
force: false
loop: "{{ container_archive_images.results }}"
loop_control:
label: "{{ item.item.file }}"
when: not item.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/{{ item.item.file }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
loop: "{{ container_archive_images.results }}"
loop_control:
label: "{{ item.item.file }}"
@@ -0,0 +1,143 @@
---
- name: Set redis service name
ansible.builtin.set_fact:
redis_service: "sure"
- name: Create redis_sure directory
ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}"
state: "directory"
owner: "{{ services['redis']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0770"
loop:
- "containers/redis"
- "containers/redis/{{ redis_service }}"
- "containers/redis/{{ redis_service }}/data"
become: true
- name: Deploy redis config file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2"
dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
register: "is_redis_conf"
- name: Deploy redis container file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
register: "is_redis_containerfile"
- name: Enable (Restart) redis service
ansible.builtin.systemd:
name: "redis_{{ redis_service }}.service"
state: "restarted"
enabled: true
daemon_reload: true
scope: "user"
when: is_redis_conf.changed or is_redis_containerfile.changed # noqa: no-handler
- name: Create sure directory
ansible.builtin.file:
path: "{{ node['home_path'] }}/{{ item }}"
state: "directory"
owner: "{{ services['sure']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0770"
loop:
- "data/containers/sure"
- "data/containers/sure/storage"
- "containers/sure"
- "containers/sure/ssl"
become: true
- name: Deploy root certificate
ansible.builtin.copy:
content: |
{{ hostvars['console']['ca']['root']['crt'] }}
dest: "{{ node['home_path'] }}/containers/sure/ssl/{{ root_cert_filename }}"
owner: "{{ services['sure']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0440"
become: true
notify: "notification_restart_sure"
no_log: true
- name: Register secret value to podman secret
containers.podman.podman_secret:
name: "{{ item.name }}"
data: "{{ item.value }}"
state: "present"
force: true
loop:
- name: "SURE_SECRET_KEY_BASE"
value: "{{ hostvars['console']['sure']['session_secret'] }}"
- name: "SURE_POSTGRES_PASSWORD"
value: "{{ hostvars['console']['postgresql']['password']['sure'] }}"
- name: "SURE_OIDC_CLIENT_SECRET"
value: "{{ hostvars['console']['sure']['oidc']['secret'] }}"
notify: "notification_restart_sure"
no_log: true
- name: Deploy sure.container file
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/sure/{{ item }}.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/{{ item }}"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0644"
loop:
- "sure-web.container"
- "sure-worker.container"
notify: "notification_restart_sure"
- name: Enable sure.service
ansible.builtin.systemd:
name: "{{ item }}"
state: "started"
enabled: true
daemon_reload: true
scope: "user"
loop:
- "sure-web.service"
- "sure-worker.service"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/{{ item.file }}.tar"
loop:
- image: "docker.io/library/redis:{{ version['containers']['redis'] }}"
file: "docker.io_library_redis_{{ version['containers']['redis'] }}"
- image: "ghcr.io/we-promise/sure:{{ version['containers']['sure'] }}"
file: "ghcr.io_we-promise_sure_{{ version['containers']['sure'] }}"
loop_control:
label: "{{ item.file }}"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "{{ item.item.image }}"
dest: "{{ node['home_path'] }}/archives/containers/{{ item.item.file }}.tar"
format: "oci-archive"
force: false
loop: "{{ container_archive_images.results }}"
loop_control:
label: "{{ item.item.file }}"
when: not item.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/{{ item.item.file }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
loop: "{{ container_archive_images.results }}"
loop_control:
label: "{{ item.item.file }}"
@@ -4,7 +4,7 @@
path: "{{ node['home_path'] }}/{{ item }}" path: "{{ node['home_path'] }}/{{ item }}"
state: "directory" state: "directory"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0770" mode: "0770"
loop: loop:
- "data/containers/vaultwarden" - "data/containers/vaultwarden"
@@ -15,9 +15,9 @@
ansible.builtin.copy: ansible.builtin.copy:
content: | content: |
{{ hostvars['console']['ca']['root']['crt'] }} {{ hostvars['console']['ca']['root']['crt'] }}
dest: "{{ node['home_path'] }}/containers/vaultwarden/ssl/ilnmors_root_ca.crt" dest: "{{ node['home_path'] }}/containers/vaultwarden/ssl/{{ root_cert_filename }}"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0440" mode: "0440"
become: true become: true
notify: "notification_restart_vaultwarden" notify: "notification_restart_vaultwarden"
@@ -34,7 +34,8 @@
value: "{{ hostvars['console']['vaultwarden']['admin']['hash'] }}" value: "{{ hostvars['console']['vaultwarden']['admin']['hash'] }}"
- name: "VW_DATABASE_URL" - name: "VW_DATABASE_URL"
value: "postgresql://vaultwarden:{{ hostvars['console']['postgresql']['password']['vaultwarden'] | urlencode | replace('/', '%2F') }}\ value: "postgresql://vaultwarden:{{ hostvars['console']['postgresql']['password']['vaultwarden'] | urlencode | replace('/', '%2F') }}\
@{{ infra_uri['postgresql']['domain'] }}/vaultwarden_db?sslmode=verify-full&sslrootcert=/etc/ssl/vaultwarden/ilnmors_root_ca.crt" @{{ services['postgresql']['domain'] }}.{{ domain['internal'] }}/vaultwarden_db?sslmode=verify-full&\
sslrootcert=/etc/ssl/vaultwarden/{{ root_cert_filename }}"
notify: "notification_restart_vaultwarden" notify: "notification_restart_vaultwarden"
no_log: true no_log: true
@@ -43,7 +44,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/vaultwarden/vaultwarden.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/vaultwarden/vaultwarden.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/vaultwarden.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/vaultwarden.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_vaultwarden" notify: "notification_restart_vaultwarden"
@@ -54,3 +55,23 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/docker.io_vaultwarden_server_{{ version['containers']['vaultwarden'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "docker.io/vaultwarden/server:{{ version['containers']['vaultwarden'] }}"
dest: "{{ node['home_path'] }}/archives/containers/docker.io_vaultwarden_server_{{ version['containers']['vaultwarden'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/docker.io_vaultwarden_server_{{ version['containers']['vaultwarden'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -4,7 +4,7 @@
path: "{{ node['home_path'] }}/containers/{{ item }}" path: "{{ node['home_path'] }}/containers/{{ item }}"
state: "directory" state: "directory"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0770" mode: "0770"
loop: loop:
- "authelia" - "authelia"
@@ -17,7 +17,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/auth/authelia/config/authelia.yaml.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/auth/authelia/config/authelia.yaml.j2"
dest: "{{ node['home_path'] }}/containers/authelia/config/authelia.yaml" dest: "{{ node['home_path'] }}/containers/authelia/config/authelia.yaml"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0600" mode: "0600"
become: true become: true
notify: "notification_restart_authelia" notify: "notification_restart_authelia"
@@ -27,9 +27,9 @@
ansible.builtin.copy: ansible.builtin.copy:
content: | content: |
{{ hostvars['console']['ca']['root']['crt'] }} {{ hostvars['console']['ca']['root']['crt'] }}
dest: "{{ node['home_path'] }}/containers/authelia/certs/ilnmors_root_ca.crt" dest: "{{ node['home_path'] }}/containers/authelia/certs/{{ root_cert_filename }}"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0440" mode: "0440"
become: true become: true
no_log: true no_log: true
@@ -65,7 +65,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/auth/authelia/authelia.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/auth/authelia/authelia.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/authelia.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/authelia.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_authelia" notify: "notification_restart_authelia"
@@ -76,3 +76,23 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/docker.io_authelia_authelia_{{ version['containers']['authelia'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "docker.io/authelia/authelia:{{ version['containers']['authelia'] }}"
dest: "{{ node['home_path'] }}/archives/containers/docker.io_authelia_authelia_{{ version['containers']['authelia'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/docker.io_authelia_authelia_{{ version['containers']['authelia'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -22,7 +22,7 @@
path: "{{ node['home_path'] }}/.config/systemd/user" path: "{{ node['home_path'] }}/.config/systemd/user"
state: "directory" state: "directory"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0700" mode: "0700"
- name: Create quadlet directory - name: Create quadlet directory
@@ -30,5 +30,14 @@
path: "{{ node['home_path'] }}/.config/containers/systemd" path: "{{ node['home_path'] }}/.config/containers/systemd"
state: "directory" state: "directory"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0700" mode: "0700"
- name: Set data volume path
ansible.builtin.file:
path: "{{ node['home_path'] }}/data"
state: "directory"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0770"
when: node['name'] in ["infra", "app"]
@@ -2,7 +2,7 @@
- name: Deploy root_ca.crt - name: Deploy root_ca.crt
ansible.builtin.copy: ansible.builtin.copy:
content: "{{ hostvars['console']['ca']['root']['crt'] }}" content: "{{ hostvars['console']['ca']['root']['crt'] }}"
dest: "/usr/local/share/ca-certificates/ilnmors_root_ca.crt" dest: "/usr/local/share/ca-certificates/{{ root_cert_filename }}"
owner: "root" owner: "root"
group: "root" group: "root"
mode: "0644" mode: "0644"
@@ -11,7 +11,7 @@
- name: Deploy networkd files - name: Deploy networkd files
ansible.builtin.template: ansible.builtin.template:
src: "{{ item }}" src: "{{ item }}"
dest: "/etc/systemd/network/{{ item | basename }}" dest: "/etc/systemd/network/{{ item | basename | replace('.j2', '') }}"
owner: "root" owner: "root"
group: "systemd-network" group: "systemd-network"
mode: "0640" mode: "0640"
@@ -1,13 +1,14 @@
--- ---
- name: Gather system facts (hardware) - name: Gather ystem facts (hardware)
ansible.builtin.setup: ansible.builtin.setup:
gather_subset: gather_subset:
- hardware - hardware
become: true become: true
- name: Deploy alloy deb file (x86_64) - name: Download alloy deb file (x86_64)
ansible.builtin.copy: ansible.builtin.get_url:
src: "{{ hostvars['console']['node']['data_path'] }}/bin/alloy-{{ version['packages']['alloy'] }}-amd64.deb" url: "https://github.com/grafana/alloy/releases/download/v{{ version['packages']['alloy'] }}/\
alloy-{{ version['packages']['alloy'] }}-1.amd64.deb"
dest: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb" dest: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb"
owner: "root" owner: "root"
group: "root" group: "root"
@@ -15,9 +16,10 @@
become: true become: true
when: ansible_facts['architecture'] == "x86_64" when: ansible_facts['architecture'] == "x86_64"
- name: Deploy alloy deb file (aarch64) - name: Download alloy deb file (aarch64)
ansible.builtin.copy: ansible.builtin.get_url:
src: "{{ hostvars['console']['node']['data_path'] }}/bin/alloy-{{ version['packages']['alloy'] }}-arm64.deb" url: "https://github.com/grafana/alloy/releases/download/v{{ version['packages']['alloy'] }}/\
alloy-{{ version['packages']['alloy'] }}-1.arm64.deb"
dest: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb" dest: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb"
owner: "root" owner: "root"
group: "root" group: "root"
@@ -30,6 +32,7 @@
deb: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb" deb: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb"
state: "present" state: "present"
become: true become: true
notify: "notification_restart_alloy"
- name: Deploy alloy config - name: Deploy alloy config
ansible.builtin.template: ansible.builtin.template:
@@ -64,6 +67,19 @@
become: true become: true
notify: "notification_restart_alloy" notify: "notification_restart_alloy"
- name: Set ACL for data directory
ansible.posix.acl:
path: "{{ item }}"
entity: "alloy"
etype: "user"
permissions: "x"
state: "present"
loop:
- "{{ node['home_path'] }}"
- "{{ node['home_path'] }}/data"
become: true
when: node['name'] == "app"
- name: Enable alloy service - name: Enable alloy service
ansible.builtin.systemd: ansible.builtin.systemd:
name: "alloy.service" name: "alloy.service"
@@ -71,3 +87,10 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
become: true become: true
- name: Fetch deb bin file
ansible.builtin.fetch:
src: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb"
dest: "{{ hostvars['console']['node']['data_path'] }}/bin/"
flat: true
become: true
@@ -4,7 +4,7 @@
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/containers/{{ item }}" path: "{{ node['home_path'] }}/containers/{{ item }}"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
state: "directory" state: "directory"
mode: "0770" mode: "0770"
loop: loop:
@@ -18,7 +18,7 @@
ansible.builtin.file: ansible.builtin.file:
path: /var/log/caddy path: /var/log/caddy
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
state: "directory" state: "directory"
mode: "0755" mode: "0755"
become: true become: true
@@ -48,21 +48,21 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/common/caddy/build/caddy.containerfile.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/common/caddy/build/caddy.containerfile.j2"
dest: "{{ node['home_path'] }}/containers/caddy/build/Containerfile" dest: "{{ node['home_path'] }}/containers/caddy/build/Containerfile"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0640" mode: "0640"
- name: Deploy root crt for build - name: Deploy root crt for build
ansible.builtin.copy: ansible.builtin.copy:
content: "{{ hostvars['console']['ca']['root']['crt'] }}" content: "{{ hostvars['console']['ca']['root']['crt'] }}"
dest: "{{ node['home_path'] }}/containers/caddy/build/ilnmors_root_ca.crt" dest: "{{ node['home_path'] }}/containers/caddy/build/{{ root_cert_filename }}"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0640" mode: "0640"
no_log: true no_log: true
- name: Build caddy container image - name: Build caddy container image
containers.podman.podman_image: containers.podman.podman_image:
name: "ilnmors.internal/{{ node['name'] }}/caddy" name: "{{ domain['internal'] }}/{{ node['name'] }}/caddy"
# check tags from container file # check tags from container file
tag: "{{ version['containers']['caddy'] }}" tag: "{{ version['containers']['caddy'] }}"
state: "build" state: "build"
@@ -77,7 +77,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/common/caddy/etc/{{ node['name'] }}/Caddyfile.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/common/caddy/etc/{{ node['name'] }}/Caddyfile.j2"
dest: "{{ node['home_path'] }}/containers/caddy/etc/Caddyfile" dest: "{{ node['home_path'] }}/containers/caddy/etc/Caddyfile"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0600" mode: "0600"
notify: "notification_restart_caddy" notify: "notification_restart_caddy"
@@ -86,7 +86,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/common/caddy/caddy.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/common/caddy/caddy.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/caddy.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/caddy.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_caddy" notify: "notification_restart_caddy"
@@ -97,3 +97,23 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/{{ domain['internal'] }}_{{ node['name'] }}_caddy_{{ version['containers']['caddy'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "{{ domain['internal'] }}/{{ node['name'] }}/caddy:{{ version['containers']['caddy'] }}"
dest: "{{ node['home_path'] }}/archives/containers/{{ domain['internal'] }}_{{ node['name'] }}_caddy_{{ version['containers']['caddy'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/{{ domain['internal'] }}_{{ node['name'] }}_caddy_{{ version['containers']['caddy'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -36,10 +36,15 @@
ansible.builtin.set_fact: ansible.builtin.set_fact:
acquisd_list: acquisd_list:
fw: fw:
collection: "crowdsecurity/suricata" collection:
- "crowdsecurity/suricata"
parser: []
config: "suricata.yaml" config: "suricata.yaml"
auth: auth:
collection: "crowdsecurity/caddy" collection:
- "crowdsecurity/caddy"
parser:
- "crowdsecurity/nextcloud-whitelist"
config: "caddy.yaml" config: "caddy.yaml"
- name: Deploy crowdsec-update service files - name: Deploy crowdsec-update service files
@@ -181,7 +186,8 @@
block: block:
- name: Install crowdsec collection - name: Install crowdsec collection
ansible.builtin.command: ansible.builtin.command:
cmd: "cscli collections install {{ acquisd_list[node['name']]['collection'] }}" cmd: "cscli collections install {{ item }}"
loop: "{{ acquisd_list[node['name']]['collection'] }}"
become: true become: true
changed_when: "'overwrite' not in is_collection_installed.stderr" changed_when: "'overwrite' not in is_collection_installed.stderr"
failed_when: failed_when:
@@ -189,6 +195,17 @@
- "'already installed' not in is_collection_installed.stderr" - "'already installed' not in is_collection_installed.stderr"
register: "is_collection_installed" register: "is_collection_installed"
- name: Install crowdsec parser
ansible.builtin.command:
cmd: "cscli parsers install {{ item }}"
loop: "{{ acquisd_list[node['name']]['parser'] }}"
become: true
changed_when: "'overwrite' not in is_parser_installed.stderr"
failed_when:
- is_parser_installed.rc != 0
- "'already installed' not in is_parser_installed.stderr"
register: "is_parser_installed"
- name: Create crowdsec acquis.d directory - name: Create crowdsec acquis.d directory
ansible.builtin.file: ansible.builtin.file:
path: "/etc/crowdsec/acquis.d" path: "/etc/crowdsec/acquis.d"
@@ -298,7 +315,3 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
become: true become: true
# cscli bouncers list
# cscli machines list
# cscli metrics
@@ -5,41 +5,43 @@
- hardware - hardware
become: true become: true
- name: Check kopia installation
ansible.builtin.shell: |
command -v kopia
changed_when: false
failed_when: false
register: "is_kopia_installed"
ignore_errors: true
- name: Set console kopia - name: Set console kopia
when: node['name'] == 'console' when: node['name'] == 'console'
block: block:
- name: Apply cli tools (x86_64) - name: Download kopia
ansible.builtin.get_url:
url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\
kopia_{{ version['packages']['kopia'] }}_linux_{{ item }}.deb"
dest: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-{{ item }}.deb"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0600"
loop:
- "amd64"
- "arm64"
- name: Install kopia (x86_64)
ansible.builtin.apt: ansible.builtin.apt:
deb: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-amd64.deb" deb: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-amd64.deb"
state: "present" state: "present"
become: true become: true
when: when: ansible_facts['architecture'] == "x86_64"
- ansible_facts['architecture'] == "x86_64"
- is_kopia_installed.rc != 0 - name: Install kopia (aarch64)
- name: Apply cli tools (aarch64)
ansible.builtin.apt: ansible.builtin.apt:
deb: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-arm64.deb" deb: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-arm64.deb"
state: "present" state: "present"
become: true become: true
when: when: ansible_facts['architecture'] == "aarch64"
- ansible_facts['architecture'] == "aarch64"
- is_kopia_installed.rc != 0 - name: Connect console kopia server
- name: Connect kopia server
environment: environment:
KOPIA_PASSWORD: "{{ hostvars['console']['kopia']['user']['console'] }}" KOPIA_PASSWORD: "{{ hostvars['console']['kopia']['users']['console'] }}"
ansible.builtin.shell: | ansible.builtin.shell: |
/usr/bin/kopia repository connect server \ /usr/bin/kopia repository connect server \
--url=https://{{ infra_uri['kopia']['domain'] }}:{{ infra_uri['kopia']['ports']['https'] }} \ --url=https://{{ services['kopia']['domain'] }}.{{ domain['internal'] }}:{{ services['kopia']['ports']['https'] }} \
--override-username=console \ --override-username=console \
--override-hostname=console.ilnmors.internal --override-hostname=console.{{ domain['internal'] }}
changed_when: false changed_when: false
failed_when: is_kopia_connected.rc != 0 failed_when: is_kopia_connected.rc != 0
register: "is_kopia_connected" register: "is_kopia_connected"
@@ -51,30 +53,36 @@
- name: Set kopia uid - name: Set kopia uid
ansible.builtin.set_fact: ansible.builtin.set_fact:
kopia_uid: 951 kopia_uid: 951
- name: Deploy kopia deb file (x86_64)
ansible.builtin.copy: - name: Download kopia deb file (x86_64)
src: "{{ hostvars['console']['node']['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-amd64.deb" ansible.builtin.get_url:
url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\
kopia_{{ version['packages']['kopia'] }}_linux_amd64.deb"
dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb" dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb"
owner: "root" owner: "root"
group: "root" group: "root"
mode: "0644" mode: "0644"
become: true become: true
when: ansible_facts['architecture'] == "x86_64" when: ansible_facts['architecture'] == "x86_64"
- name: Deploy kopia deb file (aarch64)
ansible.builtin.copy: - name: Download kopia deb file (aarch64)
src: "{{ hostvars['console']['node']['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-arm64.deb" ansible.builtin.get_url:
url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\
kopia_{{ version['packages']['kopia'] }}_linux_arm64.deb"
dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb" dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb"
owner: "root" owner: "root"
group: "root" group: "root"
mode: "0644" mode: "0644"
become: true become: true
when: ansible_facts['architecture'] == "aarch64" when: ansible_facts['architecture'] == "aarch64"
- name: Create kopia group - name: Create kopia group
ansible.builtin.group: ansible.builtin.group:
name: "kopia" name: "kopia"
gid: "{{ kopia_uid }}" gid: "{{ kopia_uid }}"
state: "present" state: "present"
become: true become: true
- name: Create kopia user - name: Create kopia user
ansible.builtin.user: ansible.builtin.user:
name: "kopia" name: "kopia"
@@ -85,6 +93,7 @@
comment: "Kopia backup User" comment: "Kopia backup User"
state: "present" state: "present"
become: true become: true
- name: Create kopia directory - name: Create kopia directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ item.name }}" path: "{{ item.name }}"
@@ -101,12 +110,13 @@
mode: "0700" mode: "0700"
become: true become: true
no_log: true no_log: true
- name: Install kopia - name: Install kopia
ansible.builtin.apt: ansible.builtin.apt:
deb: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb" deb: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb"
state: "present" state: "present"
become: true become: true
when: is_kopia_installed.rc != 0
- name: Deploy kopia env - name: Deploy kopia env
ansible.builtin.template: ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/kopia.env.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/kopia.env.j2"
@@ -116,6 +126,7 @@
mode: "0400" mode: "0400"
become: true become: true
no_log: true no_log: true
- name: Deploy kopia service files - name: Deploy kopia service files
ansible.builtin.template: ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/{{ item }}.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/{{ item }}.j2"
@@ -128,6 +139,7 @@
- "kopia-backup.service" - "kopia-backup.service"
- "kopia-backup.timer" - "kopia-backup.timer"
become: true become: true
- name: Enable auto kopia rules update - name: Enable auto kopia rules update
ansible.builtin.systemd: ansible.builtin.systemd:
name: "kopia-backup.timer" name: "kopia-backup.timer"
@@ -11,19 +11,30 @@
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/containers" path: "{{ node['home_path'] }}/containers"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
state: "directory" state: "directory"
mode: "0700" mode: "0700"
- name: Create contaienr data directory for app - name: Create container data directory for app
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/data/containers" path: "{{ node['home_path'] }}/data/containers"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
state: "directory" state: "directory"
mode: "0770" mode: "0770"
when: node['name'] == "app" when: node['name'] == "app"
- name: Create container image archive directory
ansible.builtin.file:
path: "{{ item }}"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
state: "directory"
mode: "0700"
loop:
- "{{ node['home_path'] }}/archives"
- "{{ node['home_path'] }}/archives/containers"
- name: Install podman and reset ssh connection for initiating - name: Install podman and reset ssh connection for initiating
when: is_podman_installed.rc != 0 when: is_podman_installed.rc != 0
become: true become: true
-7
View File
@@ -1,8 +1 @@
--- ---
- name: Register font
ansible.builtin.shell: |
fc-cache -f -v
become: true
changed_when: false
listen: "notification_update_font"
ignore_errors: true # noqa: ignore-errors
@@ -0,0 +1,90 @@
---
- name: Create vmm_init directory
ansible.builtin.file:
path: "{{ node['data_path'] }}/{{ item }}"
state: "directory"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0750"
loop:
- "vmm_init"
- "vmm_init/grub.d"
- "vmm_init/modprobe.d"
- "vmm_init/networkd"
- "vmm_init/ssh"
- "vmm_init/ssh/sshd_config.d"
- "vmm_init/sysctl.d"
- name: Create nftables.conf
ansible.builtin.template:
src: "{{ node['config_path'] }}/node/vmm/nftables.conf.j2"
dest: "{{ node['data_path'] }}/vmm_init/nftables.conf"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0640"
- name: Create grub.d iommu config
ansible.builtin.copy:
content: |
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"
dest: "{{ node['data_path'] }}/vmm_init/grub.d/iommu.cfg"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0640"
- name: Create modprobe.d vfio config
ansible.builtin.copy:
content: |
options vfio-pci ids={{ hostvars['vmm']['hardware']['igpu']['id'] }}
softdep i915 pre: vfio-pci
# softdep ahci pre: vfio-pci # sata controller
dest: "{{ node['data_path'] }}/vmm_init/modprobe.d/vfio.conf"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0640"
- name: Create networkd network config
ansible.builtin.template:
src: "{{ item }}"
dest: "{{ node['data_path'] }}/vmm_init/networkd/{{ item | basename | replace('.j2', '') }}"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0640"
loop: "{{ query('fileglob', hostvars['console']['node']['config_path'] + '/node/vmm/networkd/*') | sort }}"
- name: Create ssh CA
ansible.builtin.copy:
content: |
{{ hostvars['console']['ssh']['ca']['pub'] }}
dest: "{{ node['data_path'] }}/vmm_init/ssh/local_ssh_ca.pub"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0640"
- name: Create ssh config
ansible.builtin.copy:
content: "{{ item.value }}"
dest: "{{ node['data_path'] }}/vmm_init/ssh/sshd_config.d/{{ item.name }}"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0640"
loop:
- name: "prohibit_root.conf"
value: |
PermitRootLogin no
- name: "ssh_ca.conf"
value: |
TrustedUserCAKeys /etc/ssh/local_ssh_ca.pub
loop_control:
label: "{{ item.name }}"
- name: Create sysctl.d bridge config
ansible.builtin.copy:
content: |
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
dest: "{{ node['data_path'] }}/vmm_init/sysctl.d/bridge.conf"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
mode: "0640"
@@ -22,7 +22,7 @@
run_once: true run_once: true
no_log: true no_log: true
- name: Load decrypted secret vaules in console - name: Load decrypted secret values in console
ansible.builtin.set_fact: ansible.builtin.set_fact:
"{{ item.key }}": "{{ item.value }}" "{{ item.key }}": "{{ item.value }}"
loop: "{{ decrypted_secrets.stdout | from_yaml | dict2items }}" loop: "{{ decrypted_secrets.stdout | from_yaml | dict2items }}"
@@ -23,7 +23,7 @@
become: true become: true
ansible.builtin.copy: ansible.builtin.copy:
content: | content: |
@cert-authority *.ilnmors.internal {{ hostvars['console']['ssh']['ca']['pub'] }} @cert-authority *.{{ domain['internal'] }} {{ hostvars['console']['ssh']['ca']['pub'] }}
dest: "/etc/ssh/ssh_known_hosts" dest: "/etc/ssh/ssh_known_hosts"
owner: "root" owner: "root"
group: "root" group: "root"
@@ -66,8 +66,8 @@
content: | content: |
{{ hostvars['console']['ssh']['ca']['key'] }} {{ hostvars['console']['ssh']['ca']['key'] }}
dest: "/run/user/{{ node['uid'] }}/local_ssh_ca_private_key" dest: "/run/user/{{ node['uid'] }}/local_ssh_ca_private_key"
owner: "console" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0400" mode: "0400"
no_log: true no_log: true
- name: Sign on ssh console key (pub file) - name: Sign on ssh console key (pub file)
@@ -91,7 +91,7 @@
path: "{{ node['home_path'] }}/.ssh" path: "{{ node['home_path'] }}/.ssh"
state: "directory" state: "directory"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0700" mode: "0700"
- name: Create ssh config file - name: Create ssh config file
@@ -105,5 +105,5 @@
{% endfor %} {% endfor %}
dest: "{{ node['home_path'] }}/.ssh/config" dest: "{{ node['home_path'] }}/.ssh/config"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0600" mode: "0600"
@@ -31,7 +31,7 @@
sops_{{ version['packages']['sops'] }}_{{ item }}.deb" sops_{{ version['packages']['sops'] }}_{{ item }}.deb"
dest: "{{ node['data_path'] }}/bin/sops-{{ version['packages']['sops'] }}-{{ item }}.deb" dest: "{{ node['data_path'] }}/bin/sops-{{ version['packages']['sops'] }}-{{ item }}.deb"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0600" mode: "0600"
loop: loop:
- "amd64" - "amd64"
@@ -43,43 +43,7 @@
step-cli_{{ version['packages']['step'] }}-1_{{ item }}.deb" step-cli_{{ version['packages']['step'] }}-1_{{ item }}.deb"
dest: "{{ node['data_path'] }}/bin/step-{{ version['packages']['step'] }}-{{ item }}.deb" dest: "{{ node['data_path'] }}/bin/step-{{ version['packages']['step'] }}-{{ item }}.deb"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0600"
loop:
- "amd64"
- "arm64"
- name: Download kopia
ansible.builtin.get_url:
url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\
kopia_{{ version['packages']['kopia'] }}_linux_{{ item }}.deb"
dest: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-{{ item }}.deb"
owner: "{{ ansible_user }}"
group: "svadmins"
mode: "0600"
loop:
- "amd64"
- "arm64"
- name: Download blocky
ansible.builtin.get_url:
url: "https://github.com/0xERR0R/blocky/releases/download/v{{ version['packages']['blocky'] }}/\
blocky_v{{ version['packages']['blocky'] }}_Linux_{{ item }}.tar.gz"
dest: "{{ node['data_path'] }}/bin/blocky-{{ version['packages']['blocky'] }}-{{ item }}.tar.gz"
owner: "{{ ansible_user }}"
group: "svadmins"
mode: "0600"
loop:
- "x86_64"
- "arm64"
- name: Download alloy
ansible.builtin.get_url:
url: "https://github.com/grafana/alloy/releases/download/v{{ version['packages']['alloy'] }}/\
alloy-{{ version['packages']['alloy'] }}-1.{{ item }}.deb"
dest: "{{ node['data_path'] }}/bin/alloy-{{ version['packages']['alloy'] }}-{{ item }}.deb"
owner: "{{ ansible_user }}"
group: "svadmins"
mode: "0600" mode: "0600"
loop: loop:
- "amd64" - "amd64"
@@ -92,7 +56,6 @@
loop: loop:
- "sops-{{ version['packages']['sops'] }}-amd64.deb" - "sops-{{ version['packages']['sops'] }}-amd64.deb"
- "step-{{ version['packages']['step'] }}-amd64.deb" - "step-{{ version['packages']['step'] }}-amd64.deb"
- "kopia-{{ version['packages']['kopia'] }}-amd64.deb"
become: true become: true
when: ansible_facts['architecture'] == "x86_64" when: ansible_facts['architecture'] == "x86_64"
@@ -103,6 +66,5 @@
loop: loop:
- "sops-{{ version['packages']['sops'] }}-arm64.deb" - "sops-{{ version['packages']['sops'] }}-arm64.deb"
- "step-{{ version['packages']['step'] }}-arm64.deb" - "step-{{ version['packages']['step'] }}-arm64.deb"
- "kopia-{{ version['packages']['kopia'] }}-arm64.deb"
become: true become: true
when: ansible_facts['architecture'] == "aarch64" when: ansible_facts['architecture'] == "aarch64"
+1 -1
View File
@@ -44,7 +44,7 @@
ansible.builtin.systemd: ansible.builtin.systemd:
name: "blocky.service" name: "blocky.service"
state: "restarted" state: "restarted"
enabled: "true" enabled: true
daemon_reload: true daemon_reload: true
become: true become: true
changed_when: false changed_when: false
@@ -25,7 +25,7 @@
become: true become: true
when: is_bind_installed.rc != 0 when: is_bind_installed.rc != 0
- name: Deploy acem.key - name: Deploy acme.key
ansible.builtin.copy: ansible.builtin.copy:
content: "{{ hostvars['console']['bind']['acme_key'] }}" content: "{{ hostvars['console']['bind']['acme_key'] }}"
dest: "/etc/bind/acme.key" dest: "/etc/bind/acme.key"
+32 -16
View File
@@ -23,7 +23,7 @@
state: "present" state: "present"
become: true become: true
- name: Create blocky etc directory - name: Create blocky directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ item }}" path: "{{ item }}"
owner: "blocky" owner: "blocky"
@@ -31,28 +31,38 @@
mode: "0750" mode: "0750"
state: "directory" state: "directory"
loop: loop:
- "/home/blocky"
- "/home/blocky/bin"
- "/etc/blocky" - "/etc/blocky"
- "/etc/blocky/ssl" - "/etc/blocky/ssl"
become: true become: true
- name: Deploy blocky binary file (x86_64) - name: Download blocky (x86_64)
ansible.builtin.unarchive: ansible.builtin.get_url:
src: "{{ hostvars['console']['node']['data_path'] }}/bin/blocky-{{ version['packages']['blocky'] }}-x86_64.tar.gz" url: "https://github.com/0xERR0R/blocky/releases/download/v{{ version['packages']['blocky'] }}/\
dest: "/usr/local/bin/" blocky_v{{ version['packages']['blocky'] }}_Linux_x86_64.tar.gz"
owner: "root" dest: "/home/blocky/bin/blocky-{{ version['packages']['blocky'] }}.tar.gz"
group: "root" owner: "blocky"
mode: "0755" group: "blocky"
extra_opts: mode: "0600"
- "--strip-components=0"
- "--wildcards"
- "blocky"
become: true become: true
when: ansible_facts['architecture'] == "x86_64" when: ansible_facts['architecture'] == "x86_64"
notify: "notification_restart_blocky"
- name: Deploy blocky binary file (aarch64) - name: Download blocky (aarch64)
ansible.builtin.get_url:
url: "https://github.com/0xERR0R/blocky/releases/download/v{{ version['packages']['blocky'] }}/\
blocky_v{{ version['packages']['blocky'] }}_Linux_arm64.tar.gz"
dest: "/home/blocky/bin/blocky-{{ version['packages']['blocky'] }}.tar.gz"
owner: "blocky"
group: "blocky"
mode: "0600"
become: true
when: ansible_facts['architecture'] == "aarch64"
- name: Deploy blocky binary file
ansible.builtin.unarchive: ansible.builtin.unarchive:
src: "{{ hostvars['console']['node']['data_path'] }}/bin/blocky-{{ version['packages']['blocky'] }}-arm64.tar.gz" src: "/home/blocky/bin/blocky-{{ version['packages']['blocky'] }}.tar.gz"
remote_src: true
dest: "/usr/local/bin/" dest: "/usr/local/bin/"
owner: "root" owner: "root"
group: "root" group: "root"
@@ -62,7 +72,6 @@
- "--wildcards" - "--wildcards"
- "blocky" - "blocky"
become: true become: true
when: ansible_facts['architecture'] == "aarch64"
notify: "notification_restart_blocky" notify: "notification_restart_blocky"
- name: Deploy blocky config - name: Deploy blocky config
@@ -115,3 +124,10 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
become: true become: true
- name: Fetch deb bin file
ansible.builtin.fetch:
src: "/home/blocky/bin/blocky-{{ version['packages']['blocky'] }}.tar.gz"
dest: "{{ hostvars['console']['node']['data_path'] }}/bin/"
flat: true
become: true
@@ -6,7 +6,7 @@
API_KEY={{ hostvars['console']['ddns']['api_key'] }} API_KEY={{ hostvars['console']['ddns']['api_key'] }}
dest: "/etc/secrets/{{ node['uid'] }}/ddns.env" dest: "/etc/secrets/{{ node['uid'] }}/ddns.env"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0400" mode: "0400"
become: true become: true
no_log: true no_log: true
@@ -16,16 +16,16 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/fw/ddns/ddns.sh" src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/fw/ddns/ddns.sh"
dest: "/usr/local/bin" dest: "/usr/local/bin"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0711" mode: "0711"
become: true become: true
- name: Deploy ddns service files - name: Deploy ddns service files
ansible.builtin.copy: ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/fw/ddns/{{ item }}" src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/fw/ddns/{{ item }}.j2"
dest: "{{ node['home_path'] }}/.config/systemd/user/{{ item }}" dest: "{{ node['home_path'] }}/.config/systemd/user/{{ item }}"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0600" mode: "0600"
validate: "/usr/bin/systemd-analyze verify %s" validate: "/usr/bin/systemd-analyze verify %s"
loop: loop:
+2 -2
View File
@@ -26,7 +26,7 @@
become: true become: true
notify: "notification_restart_kea4" notify: "notification_restart_kea4"
- name: Create kea-dhcp-server.service.d - name: Create kea-dhcp4-server.service.d
ansible.builtin.file: ansible.builtin.file:
path: "/etc/systemd/system/kea-dhcp4-server.service.d" path: "/etc/systemd/system/kea-dhcp4-server.service.d"
state: "directory" state: "directory"
@@ -35,7 +35,7 @@
mode: "0755" mode: "0755"
become: true become: true
- name: Set kea-dhcp-server.service.d/override.conf - name: Set kea-dhcp4-server.service.d/override.conf
ansible.builtin.copy: ansible.builtin.copy:
dest: "/etc/systemd/system/kea-dhcp4-server.service.d/override.conf" dest: "/etc/systemd/system/kea-dhcp4-server.service.d/override.conf"
content: | content: |
+5 -5
View File
@@ -2,7 +2,7 @@
ansible.builtin.systemd: ansible.builtin.systemd:
name: "ca.service" name: "ca.service"
state: "restarted" state: "restarted"
enabled: "true" enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
changed_when: false changed_when: false
@@ -12,7 +12,7 @@
- name: Reload postgresql - name: Reload postgresql
ansible.builtin.command: ansible.builtin.command:
/usr/bin/podman exec -u postgres postgresql sh -c "pg_ctl reload" /usr/bin/podman exec -u postgres postgresql sh -c "pg_ctl reload"
when: not (is_postgresql_init_run | default(false)) when: is_postgresql_init.stat.exists
changed_when: false changed_when: false
listen: "notification_reload_postgresql" listen: "notification_reload_postgresql"
ignore_errors: true # noqa: ignore-errors ignore_errors: true # noqa: ignore-errors
@@ -24,7 +24,7 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
when: not (is_postgresql_init_run | default(false)) when: is_postgresql_init.stat.exists
changed_when: false changed_when: false
listen: "notification_restart_postgresql" listen: "notification_restart_postgresql"
ignore_errors: true # noqa: ignore-errors ignore_errors: true # noqa: ignore-errors
@@ -73,10 +73,10 @@
listen: "notification_restart_grafana" listen: "notification_restart_grafana"
ignore_errors: true # noqa: ignore-errors ignore_errors: true # noqa: ignore-errors
- name: Enable x509-exporter.service - name: Restart x509-exporter.service
ansible.builtin.systemd: ansible.builtin.systemd:
name: "x509-exporter.service" name: "x509-exporter.service"
state: "started" state: "restarted"
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
@@ -1,13 +1,9 @@
--- ---
- name: Set ca container subuid
ansible.builtin.set_fact:
ca_subuid: "100999"
- name: Create ca directory - name: Create ca directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/containers/{{ item }}" path: "{{ node['home_path'] }}/containers/{{ item }}"
owner: "{{ ca_subuid }}" owner: "{{ services['ca']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
state: "directory" state: "directory"
mode: "0770" mode: "0770"
loop: loop:
@@ -32,8 +28,8 @@
ansible.builtin.template: ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/ca/config/{{ item }}.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/ca/config/{{ item }}.j2"
dest: "{{ node['home_path'] }}/containers/ca/config/{{ item }}" dest: "{{ node['home_path'] }}/containers/ca/config/{{ item }}"
owner: "{{ ca_subuid }}" owner: "{{ services['ca']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0400" mode: "0400"
loop: loop:
- "ca.json" - "ca.json"
@@ -46,19 +42,19 @@
content: | content: |
{{ item.value }} {{ item.value }}
dest: "{{ item.path }}/{{ item.name }}" dest: "{{ item.path }}/{{ item.name }}"
owner: "{{ ca_subuid }}" owner: "{{ services['ca']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "{{ item.mode }}" mode: "{{ item.mode }}"
loop: loop:
- name: "ilnmors_root_ca.crt" - name: "{{ root_cert_filename }}"
value: "{{ hostvars['console']['ca']['root']['crt'] }}" value: "{{ hostvars['console']['ca']['root']['crt'] }}"
path: "{{ node['home_path'] }}/containers/ca/certs" path: "{{ node['home_path'] }}/containers/ca/certs"
mode: "0440" mode: "0440"
- name: "ilnmors_intermediate_ca.crt" - name: "{{ intermediate_cert_filename }}"
value: "{{ hostvars['console']['ca']['intermediate']['crt'] }}" value: "{{ hostvars['console']['ca']['intermediate']['crt'] }}"
path: "{{ node['home_path'] }}/containers/ca/certs" path: "{{ node['home_path'] }}/containers/ca/certs"
mode: "0440" mode: "0440"
- name: "ilnmors_intermediate_ca.key" - name: "{{ intermediate_key_filename }}"
value: "{{ hostvars['console']['ca']['intermediate']['key'] }}" value: "{{ hostvars['console']['ca']['intermediate']['key'] }}"
path: "{{ node['home_path'] }}/containers/ca/secrets" path: "{{ node['home_path'] }}/containers/ca/secrets"
mode: "0400" mode: "0400"
@@ -71,7 +67,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/ca/ca.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/ca/ca.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/ca.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/ca.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_ca" notify: "notification_restart_ca"
@@ -82,3 +78,23 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/docker.io_smallstep_step-ca_{{ version['containers']['step'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "docker.io/smallstep/step-ca:{{ version['containers']['step'] }}"
dest: "{{ node['home_path'] }}/archives/containers/docker.io_smallstep_step-ca_{{ version['containers']['step'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/docker.io_smallstep_step-ca_{{ version['containers']['step'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -1,13 +1,9 @@
--- ---
- name: Set grafana container subuid
ansible.builtin.set_fact:
grafana_subuid: "100471"
- name: Create grafana directory - name: Create grafana directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/containers/{{ item }}" path: "{{ node['home_path'] }}/containers/{{ item }}"
owner: "{{ grafana_subuid }}" owner: "{{ services['grafana']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
state: "directory" state: "directory"
mode: "0770" mode: "0770"
loop: loop:
@@ -15,6 +11,7 @@
- "grafana/data" - "grafana/data"
- "grafana/etc" - "grafana/etc"
- "grafana/etc/provisioning" - "grafana/etc/provisioning"
- "grafana/etc/provisioning/datasources"
- "grafana/etc/dashboards" - "grafana/etc/dashboards"
- "grafana/ssl" - "grafana/ssl"
become: true become: true
@@ -23,9 +20,9 @@
ansible.builtin.copy: ansible.builtin.copy:
content: | content: |
{{ hostvars['console']['ca']['root']['crt'] }} {{ hostvars['console']['ca']['root']['crt'] }}
dest: "{{ node['home_path'] }}/containers/grafana/ssl/ilnmors_root_ca.crt" dest: "{{ node['home_path'] }}/containers/grafana/ssl/{{ root_cert_filename }}"
owner: "{{ grafana_subuid }}" owner: "{{ services['grafana']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0400" mode: "0400"
become: true become: true
notify: "notification_restart_grafana" notify: "notification_restart_grafana"
@@ -43,16 +40,16 @@
- name: "LDAP_BIND_PASSWORD" - name: "LDAP_BIND_PASSWORD"
value: "{{ hostvars['console']['ldap']['password']['grafana'] }}" value: "{{ hostvars['console']['ldap']['password']['grafana'] }}"
- name: "GF_ADMIN_PASSWORD" - name: "GF_ADMIN_PASSWORD"
value: "{{ hostvars['console']['grafana']['user']['password'] }}" value: "{{ hostvars['console']['grafana']['admin']['password'] }}"
notify: "notification_restart_grafana" notify: "notification_restart_grafana"
no_log: true no_log: true
- name: Deploy configruation files - name: Deploy configuration files
ansible.builtin.template: ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/grafana/etc/{{ item }}.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/grafana/etc/{{ item }}.j2"
dest: "{{ node['home_path'] }}/containers/grafana/etc/{{ item }}" dest: "{{ node['home_path'] }}/containers/grafana/etc/{{ item }}"
owner: "{{ grafana_subuid }}" owner: "{{ services['grafana']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0400" mode: "0400"
loop: loop:
- "grafana.ini" - "grafana.ini"
@@ -61,12 +58,12 @@
notify: "notification_restart_grafana" notify: "notification_restart_grafana"
no_log: true no_log: true
- name: Deploy provisioing and dashboard files - name: Deploy provisioing file
ansible.builtin.copy: ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/grafana/etc/provisioning/" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/grafana/etc/provisioning/datasources/datasources.yaml.j2"
dest: "{{ node['home_path'] }}/containers/grafana/etc/provisioning/" dest: "{{ node['home_path'] }}/containers/grafana/etc/provisioning/datasources/datasources.yaml"
owner: "{{ grafana_subuid }}" owner: "{{ services['grafana']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0400" mode: "0400"
become: true become: true
notify: "notification_restart_grafana" notify: "notification_restart_grafana"
@@ -76,7 +73,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/grafana/grafana.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/grafana/grafana.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/grafana.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/grafana.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_grafana" notify: "notification_restart_grafana"
@@ -87,3 +84,23 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/docker.io_grafana_grafana_{{ version['containers']['grafana'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "docker.io/grafana/grafana:{{ version['containers']['grafana'] }}"
dest: "{{ node['home_path'] }}/archives/containers/docker.io_grafana_grafana_{{ version['containers']['grafana'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/docker.io_grafana_grafana_{{ version['containers']['grafana'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -1,13 +1,9 @@
--- ---
- name: Set ldap container subuid
ansible.builtin.set_fact:
ldap_subuid: "100999"
- name: Create ldap directory - name: Create ldap directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/containers/{{ item }}" path: "{{ node['home_path'] }}/containers/{{ item }}"
owner: "{{ ldap_subuid }}" owner: "{{ services['ldap']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
state: "directory" state: "directory"
mode: "0770" mode: "0770"
loop: loop:
@@ -21,11 +17,11 @@
content: | content: |
{{ item.value }} {{ item.value }}
dest: "{{ node['home_path'] }}/containers/ldap/ssl/{{ item.name }}" dest: "{{ node['home_path'] }}/containers/ldap/ssl/{{ item.name }}"
owner: "{{ ldap_subuid }}" owner: "{{ services['ldap']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "{{ item.mode }}" mode: "{{ item.mode }}"
loop: loop:
- name: "ilnmors_root_ca.crt" - name: "{{ root_cert_filename }}"
value: "{{ hostvars['console']['ca']['root']['crt'] }}" value: "{{ hostvars['console']['ca']['root']['crt'] }}"
mode: "0440" mode: "0440"
- name: "ldap.crt" - name: "ldap.crt"
@@ -37,8 +33,8 @@
value: "{{ hostvars['console']['ldap']['key'] }}" value: "{{ hostvars['console']['ldap']['key'] }}"
mode: "0400" mode: "0400"
become: true become: true
notify: "notification_restart_ldap"
no_log: true no_log: true
notify: "notification_restart_ldap"
- name: Register secret value to podman secret - name: Register secret value to podman secret
containers.podman.podman_secret: containers.podman.podman_secret:
@@ -50,17 +46,20 @@
# urlencode doesn't fix `/` as `%2F`. It needs replace # urlencode doesn't fix `/` as `%2F`. It needs replace
- name: "LLDAP_DATABASE_URL" - name: "LLDAP_DATABASE_URL"
value: "postgres://ldap:{{ hostvars['console']['postgresql']['password']['ldap'] | urlencode | replace('/', '%2F') }}\ value: "postgres://ldap:{{ hostvars['console']['postgresql']['password']['ldap'] | urlencode | replace('/', '%2F') }}\
@{{ infra_uri['postgresql']['domain'] }}/ldap_db?sslmode=verify-full&sslrootcert=/etc/ssl/ldap/ilnmors_root_ca.crt" @{{ services['postgresql']['domain'] }}.{{ domain['internal'] }}/ldap_db?sslmode=verify-full&sslrootcert=/etc/ssl/ldap/{{ root_cert_filename }}"
- name: "LLDAP_KEY_SEED" - name: "LLDAP_KEY_SEED"
value: "{{ hostvars['console']['ldap']['seed_key'] }}" value: "{{ hostvars['console']['ldap']['seed_key'] }}"
- name: "LLDAP_JWT_SECRET" - name: "LLDAP_JWT_SECRET"
value: "{{ hostvars['console']['ldap']['jwt_secret'] }}" value: "{{ hostvars['console']['ldap']['jwt_secret'] }}"
notify: "notification_restart_ldap"
no_log: true no_log: true
notify: "notification_restart_ldap"
- name: Initiate ldap (When = false, If DB data does not exist in postgresql, activate this block) - name: Initiate ldap (When = false, If DB data does not exist in postgresql, activate this block)
# The reason why this task doesn't use the way to check ".init" file is this tasks can override original database.
# Absent of ".init" file cannot guarantee DB is empty.
when: false when: false
become: true become: true
no_log: true
block: block:
- name: Register extra secret value to podman secret - name: Register extra secret value to podman secret
containers.podman.podman_secret: containers.podman.podman_secret:
@@ -77,8 +76,8 @@
rm: true rm: true
detach: false detach: false
env: env:
TZ: "Asia/Seoul" TZ: "{{ timezone }}"
LLDAP_LDAP_BASE_DN: "dc=ilnmors,dc=internal" LLDAP_LDAP_BASE_DN: "{{ domain['dc'] }}"
secrets: secrets:
- "LLDAP_DATABASE_URL,type=env" - "LLDAP_DATABASE_URL,type=env"
- "LLDAP_KEY_SEED,type=env" - "LLDAP_KEY_SEED,type=env"
@@ -99,7 +98,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/ldap/ldap.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/ldap/ldap.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/ldap.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/ldap.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_ldap" notify: "notification_restart_ldap"
@@ -110,3 +109,23 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/docker.io_lldap_lldap_{{ version['containers']['ldap'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "docker.io/lldap/lldap:{{ version['containers']['ldap'] }}"
dest: "{{ node['home_path'] }}/archives/containers/docker.io_lldap_lldap_{{ version['containers']['ldap'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/docker.io_lldap_lldap_{{ version['containers']['ldap'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -1,14 +1,10 @@
--- ---
- name: Set loki container subuid
ansible.builtin.set_fact:
loki_subuid: "110000" # 10001
- name: Create loki directory - name: Create loki directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/containers/{{ item }}" path: "{{ node['home_path'] }}/containers/{{ item }}"
state: "directory" state: "directory"
owner: "{{ loki_subuid }}" owner: "{{ services['loki']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0770" mode: "0770"
loop: loop:
- "loki" - "loki"
@@ -18,11 +14,11 @@
become: true become: true
- name: Deploy loki configuration file - name: Deploy loki configuration file
ansible.builtin.copy: ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/loki/etc/loki.yaml" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/loki/etc/loki.yaml.j2"
dest: "{{ node['home_path'] }}/containers/loki/etc/loki.yaml" dest: "{{ node['home_path'] }}/containers/loki/etc/loki.yaml"
owner: "{{ loki_subuid }}" owner: "{{ services['loki']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0600" mode: "0600"
become: true become: true
notify: "notification_restart_loki" notify: "notification_restart_loki"
@@ -33,11 +29,11 @@
content: | content: |
{{ item.value }} {{ item.value }}
dest: "{{ node['home_path'] }}/containers/loki/ssl/{{ item.name }}" dest: "{{ node['home_path'] }}/containers/loki/ssl/{{ item.name }}"
owner: "{{ loki_subuid }}" owner: "{{ services['loki']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "{{ item.mode }}" mode: "{{ item.mode }}"
loop: loop:
- name: "ilnmors_root_ca.crt" - name: "{{ root_cert_filename }}"
value: "{{ hostvars['console']['ca']['root']['crt'] }}" value: "{{ hostvars['console']['ca']['root']['crt'] }}"
mode: "0440" mode: "0440"
- name: "loki.crt" - name: "loki.crt"
@@ -57,7 +53,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/loki/loki.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/loki/loki.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/loki.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/loki.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_loki" notify: "notification_restart_loki"
@@ -68,3 +64,23 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/docker.io_grafana_loki_{{ version['containers']['loki'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "docker.io/grafana/loki:{{ version['containers']['loki'] }}"
dest: "{{ node['home_path'] }}/archives/containers/docker.io_grafana_loki_{{ version['containers']['loki'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/docker.io_grafana_loki_{{ version['containers']['loki'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -1,35 +1,35 @@
--- ---
- name: Set postgresql container subuid
ansible.builtin.set_fact:
postgresql_subuid: "100998"
- name: Set connected services list - name: Set connected services list
ansible.builtin.set_fact: ansible.builtin.set_fact:
connected_services: connected_services:
- "ldap" - "ldap"
- "authelia"
- "grafana" - "grafana"
- "authelia"
- "vaultwarden" - "vaultwarden"
- "gitea" - "gitea"
- "immich" - "immich"
- "paperless" - "paperless"
- "vikunja" - "nextcloud"
- "sure"
- "outline"
- "memos"
- "mealie"
- name: Create postgresql directory - name: Create postgresql directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/containers/{{ item }}" path: "{{ node['home_path'] }}/{{ item }}"
state: "directory" state: "directory"
owner: "{{ postgresql_subuid }}" owner: "{{ services['postgresql']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0770" mode: "0770"
loop: loop:
- "postgresql" - "data/containers/postgresql/backups"
- "postgresql/data" - "containers/postgresql"
- "postgresql/config" - "containers/postgresql/data"
- "postgresql/ssl" - "containers/postgresql/config"
- "postgresql/init" - "containers/postgresql/ssl"
- "postgresql/backups" - "containers/postgresql/init"
- "postgresql/build" - "containers/postgresql/build"
become: true become: true
- name: Deploy containerfile for build - name: Deploy containerfile for build
@@ -37,12 +37,12 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/build/postgresql.containerfile.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/build/postgresql.containerfile.j2"
dest: "{{ node['home_path'] }}/containers/postgresql/build/Containerfile" dest: "{{ node['home_path'] }}/containers/postgresql/build/Containerfile"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0640" mode: "0640"
- name: Build postgresql container image - name: Build postgresql container image
containers.podman.podman_image: containers.podman.podman_image:
name: "ilnmors.internal/{{ node['name'] }}/postgres" name: "{{ domain['internal'] }}/{{ node['name'] }}/postgres"
# check tags from container file # check tags from container file
tag: "pg{{ version['containers']['postgresql'] }}-vectorchord{{ version['containers']['vectorchord'] }}" tag: "pg{{ version['containers']['postgresql'] }}-vectorchord{{ version['containers']['vectorchord'] }}"
state: "build" state: "build"
@@ -56,8 +56,8 @@
ansible.builtin.template: ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/config/{{ item }}.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/config/{{ item }}.j2"
dest: "{{ node['home_path'] }}/containers/postgresql/config/{{ item }}" dest: "{{ node['home_path'] }}/containers/postgresql/config/{{ item }}"
owner: "{{ postgresql_subuid }}" owner: "{{ services['postgresql']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0600" mode: "0600"
loop: loop:
- "postgresql.conf" - "postgresql.conf"
@@ -71,11 +71,11 @@
content: | content: |
{{ item.value }} {{ item.value }}
dest: "{{ node['home_path'] }}/containers/postgresql/ssl/{{ item.name }}" dest: "{{ node['home_path'] }}/containers/postgresql/ssl/{{ item.name }}"
owner: "{{ postgresql_subuid }}" owner: "{{ services['postgresql']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "{{ item.mode }}" mode: "{{ item.mode }}"
loop: loop:
- name: "ilnmors_root_ca.crt" - name: "{{ root_cert_filename }}"
value: "{{ hostvars['console']['ca']['root']['crt'] }}" value: "{{ hostvars['console']['ca']['root']['crt'] }}"
mode: "0440" mode: "0440"
- name: "postgresql.crt" - name: "postgresql.crt"
@@ -91,46 +91,51 @@
no_log: true no_log: true
- name: Check data directory empty - name: Check data directory empty
ansible.builtin.find: ansible.builtin.stat:
paths: "{{ node['home_path'] }}/containers/postgresql/data/" path: "{{ node['home_path'] }}/containers/postgresql/data/.init"
hidden: true
file_type: "any"
become: true become: true
register: "is_data_dir_empty" register: "is_postgresql_init"
- name: Prepare initiating DB - name: Prepare initiating DB
when: is_data_dir_empty.matched == 0 when:
- not is_postgresql_init.stat.exists
- (connected_services | default([]) | length) > 0
become: true become: true
block: block:
# `init/pg_cluster.sql` should be fetched from postgresql's backup directory before running initiating # `init/pg_cluster.sql` should be fetched from postgresql's backup directory before running initiating
- name: Deploy init cluster sql file - name: Deploy init cluster sql file
ansible.builtin.copy: ansible.builtin.copy:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/init/pg_cluster.sql" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/init/pg_cluster.sql"
dest: "{{ node['home_path'] }}/containers/postgresql/init/0_pg_cluster.sql" dest: "{{ node['home_path'] }}/containers/postgresql/init/00_pg_cluster.sql"
owner: "{{ postgresql_subuid }}" owner: "{{ services['postgresql']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0600" mode: "0600"
- name: Deploy restoring data sql files - name: Deploy restoring data sql files
ansible.builtin.copy: ansible.builtin.copy:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/init/pg_{{ item }}.sql" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/init/pg_{{ item }}.sql"
dest: "{{ node['home_path'] }}/containers/postgresql/init/{{ index_num + 1 }}_pg_{{ item }}.sql" dest: "{{ node['home_path'] }}/containers/postgresql/init/{{ '%02d' | format(index_num + 1) }}_pg_{{ item }}.sql"
owner: "{{ postgresql_subuid }}" owner: "{{ services['postgresql']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0600" mode: "0600"
loop: "{{ connected_services }}" loop: "{{ connected_services }}"
loop_control: loop_control:
index_var: index_num index_var: index_num
- name: Set is_postgresql_init_run
ansible.builtin.set_fact: - name: Create .init file
is_postgresql_init_run: true ansible.builtin.file:
path: "{{ node['home_path'] }}/containers/postgresql/data/.init"
state: "touch"
mode: "0644"
owner: "{{ ansible_user }}"
group: "{{ node['group'] }}"
- name: Deploy container file - name: Deploy container file
ansible.builtin.template: ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/postgresql.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/postgresql.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/postgresql.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/postgresql.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_postgresql" notify: "notification_restart_postgresql"
@@ -139,7 +144,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/services/{{ item }}" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/services/{{ item }}"
dest: "{{ node['home_path'] }}/.config/systemd/user/{{ item }}" dest: "{{ node['home_path'] }}/.config/systemd/user/{{ item }}"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
loop: loop:
- "postgresql-cluster-backup.service" - "postgresql-cluster-backup.service"
@@ -171,3 +176,29 @@
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
loop: "{{ connected_services }}" loop: "{{ connected_services }}"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/\
{{ domain['internal'] }}_{{ node['name'] }}_postgres_\
pg{{ version['containers']['postgresql'] }}-vectorchord{{ version['containers']['vectorchord'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "{{ domain['internal'] }}/{{ node['name'] }}/postgres:pg{{ version['containers']['postgresql'] }}-vectorchord{{ version['containers']['vectorchord'] }}"
dest: "{{ node['home_path'] }}/archives/containers/\
{{ domain['internal'] }}_{{ node['name'] }}_postgres_\
pg{{ version['containers']['postgresql'] }}-vectorchord{{ version['containers']['vectorchord'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/\
{{ domain['internal'] }}_{{ node['name'] }}_postgres_\
pg{{ version['containers']['postgresql'] }}-vectorchord{{ version['containers']['vectorchord'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -1,14 +1,10 @@
--- ---
- name: Set prometheus container subuid
ansible.builtin.set_fact:
prometheus_subuid: "165533" # nobody - 65534
- name: Create prometheus directory - name: Create prometheus directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/containers/{{ item }}" path: "{{ node['home_path'] }}/containers/{{ item }}"
state: "directory" state: "directory"
owner: "{{ prometheus_subuid }}" owner: "{{ services['prometheus']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0770" mode: "0770"
loop: loop:
- "prometheus" - "prometheus"
@@ -21,8 +17,8 @@
ansible.builtin.template: ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/prometheus/etc/{{ item }}.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/prometheus/etc/{{ item }}.j2"
dest: "{{ node['home_path'] }}/containers/prometheus/etc/{{ item }}" dest: "{{ node['home_path'] }}/containers/prometheus/etc/{{ item }}"
owner: "{{ prometheus_subuid }}" owner: "{{ services['prometheus']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0600" mode: "0600"
loop: loop:
- "prometheus.yaml" - "prometheus.yaml"
@@ -37,11 +33,11 @@
content: | content: |
{{ item.value }} {{ item.value }}
dest: "{{ node['home_path'] }}/containers/prometheus/ssl/{{ item.name }}" dest: "{{ node['home_path'] }}/containers/prometheus/ssl/{{ item.name }}"
owner: "{{ prometheus_subuid }}" owner: "{{ services['prometheus']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "{{ item.mode }}" mode: "{{ item.mode }}"
loop: loop:
- name: "ilnmors_root_ca.crt" - name: "{{ root_cert_filename }}"
value: "{{ hostvars['console']['ca']['root']['crt'] }}" value: "{{ hostvars['console']['ca']['root']['crt'] }}"
mode: "0440" mode: "0440"
- name: "prometheus.crt" - name: "prometheus.crt"
@@ -61,7 +57,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/prometheus/prometheus.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/prometheus/prometheus.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/prometheus.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/prometheus.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_prometheus" notify: "notification_restart_prometheus"
@@ -72,3 +68,23 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/docker.io_prom_prometheus_{{ version['containers']['prometheus'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "docker.io/prom/prometheus:{{ version['containers']['prometheus'] }}"
dest: "{{ node['home_path'] }}/archives/containers/docker.io_prom_prometheus_{{ version['containers']['prometheus'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/docker.io_prom_prometheus_{{ version['containers']['prometheus'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -1,27 +1,34 @@
--- ---
- name: Set x509-exporter container subuid
ansible.builtin.set_fact:
x509_exporter_subuid: "165533" # nobody - 65534
- name: Create x509-exporter directory - name: Create x509-exporter directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ node['home_path'] }}/containers/{{ item }}" path: "{{ node['home_path'] }}/containers/{{ item }}"
state: "directory" state: "directory"
owner: "{{ x509_exporter_subuid }}" owner: "{{ services['x509-exporter']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0770" mode: "0770"
loop: loop:
- "x509-exporter" - "x509-exporter"
- "x509-exporter/config"
- "x509-exporter/certs" - "x509-exporter/certs"
become: true become: true
- name: Deploy config.yaml
ansible.builtin.copy:
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/x509-exporter/config/config.yaml"
dest: "{{ node['home_path'] }}/containers/x509-exporter/config/config.yaml"
owner: "{{ services['x509-exporter']['subuid'] }}"
group: "{{ node['group'] }}"
mode: "0440"
become: true
notify: "notification_restart_x509-exporter"
- name: Deploy certificates - name: Deploy certificates
ansible.builtin.copy: ansible.builtin.copy:
content: | content: |
{{ item.value }} {{ item.value }}
dest: "{{ node['home_path'] }}/containers/x509-exporter/certs/{{ item.name }}" dest: "{{ node['home_path'] }}/containers/x509-exporter/certs/{{ item.name }}"
owner: "{{ x509_exporter_subuid }}" owner: "{{ services['x509-exporter']['subuid'] }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0440" mode: "0440"
loop: loop:
- name: "root.crt" - name: "root.crt"
@@ -50,7 +57,7 @@
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/x509-exporter/x509-exporter.container.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/x509-exporter/x509-exporter.container.j2"
dest: "{{ node['home_path'] }}/.config/containers/systemd/x509-exporter.container" dest: "{{ node['home_path'] }}/.config/containers/systemd/x509-exporter.container"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
notify: "notification_restart_x509-exporter" notify: "notification_restart_x509-exporter"
@@ -61,3 +68,23 @@
enabled: true enabled: true
daemon_reload: true daemon_reload: true
scope: "user" scope: "user"
- name: Check container archive images
ansible.builtin.stat:
path: "{{ node['home_path'] }}/archives/containers/docker.io_enix_x509-certificate-exporter_{{ version['containers']['x509-exporter'] }}.tar"
register: container_archive_images
- name: Save container archive images
containers.podman.podman_save:
image:
- "docker.io/enix/x509-certificate-exporter:{{ version['containers']['x509-exporter'] }}"
dest: "{{ node['home_path'] }}/archives/containers/docker.io_enix_x509-certificate-exporter_{{ version['containers']['x509-exporter'] }}.tar"
format: "oci-archive"
force: false
when: not container_archive_images.stat.exists
- name: Fetch container archive images
ansible.builtin.fetch:
src: "{{ node['home_path'] }}/archives/containers/docker.io_enix_x509-certificate-exporter_{{ version['containers']['x509-exporter'] }}.tar"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/containers/"
flat: true
@@ -9,15 +9,16 @@
- name: Check libvirt directory - name: Check libvirt directory
ansible.builtin.stat: ansible.builtin.stat:
path: "/var/lib/libvirt/{{ item }}" path: "{{ node['libvirt_path'] }}/{{ item }}"
loop: loop:
- "images" - "images"
- "seeds" - "seeds"
- "data"
register: "is_libvirt_dir" register: "is_libvirt_dir"
- name: Create libvirt directory - name: Create libvirt directory
ansible.builtin.file: ansible.builtin.file:
path: "/var/lib/libvirt/{{ item.item }}" path: "{{ node['libvirt_path'] }}/{{ item.item }}"
state: "directory" state: "directory"
owner: "root" owner: "root"
group: "root" group: "root"
@@ -72,6 +73,7 @@
loop: loop:
- "images-pool" - "images-pool"
- "seeds-pool" - "seeds-pool"
- "data-pool"
- name: Start virtual storage pool - name: Start virtual storage pool
community.libvirt.virt_pool: community.libvirt.virt_pool:
@@ -81,6 +83,7 @@
loop: loop:
- "images-pool" - "images-pool"
- "seeds-pool" - "seeds-pool"
- "data-pool"
- name: Autostart virtual storage pool - name: Autostart virtual storage pool
community.libvirt.virt_pool: community.libvirt.virt_pool:
@@ -90,3 +93,4 @@
loop: loop:
- "images-pool" - "images-pool"
- "seeds-pool" - "seeds-pool"
- "data-pool"
+100
View File
@@ -0,0 +1,100 @@
---
- name: Check btrfs installation
ansible.builtin.shell: |
command -v btrfs
become: true # btrfs is located in /usr/sbin, which means root permission is needed.
changed_when: false
failed_when: false
register: "is_btrfs_installed"
ignore_errors: true
- name: Install btrfs
ansible.builtin.apt:
name: "btrfs-progs"
state: "present"
become: true
when: is_btrfs_installed.rc != 0
- name: Set hard disk path
ansible.builtin.shell: |
set -o pipefail
ls -1 /dev/disk/by-id/ata-* | \
grep -F -e "{{ hardware['hdd']['data'].values() | join('" -e "') }}" | \
grep -vE -- '-part[0-9]+$' | \
sort
changed_when: false
register: "hdd_path_list"
- name: Check vmm_hdd filesystem already exists
ansible.builtin.command: |
blkid -L {{ hardware['btrfs']['label'] }}
register: is_vmm_data
changed_when: false
failed_when: false
become: true
- name: Check disk number
ansible.builtin.fail:
msg: "Below 4 disks for RAID10, found {{ hdd_path_list.stdout_lines | length }}"
when: (hdd_path_list.stdout_lines | length) < 4
- name: Set btrfs raid10 volume
ansible.builtin.shell: |
mkfs.btrfs -f \
-L {{ hardware['btrfs']['label'] }} \
-d {{ hardware['btrfs']['level'] }} \
-m {{ hardware['btrfs']['level'] }} \
{{ hdd_path_list.stdout_lines | join(' ') }}
become: true
when:
- is_vmm_data.rc != 0
- (hdd_path_list.stdout_lines | length) >= 4
changed_when: is_mkfs.rc == 0
register: "is_mkfs"
- name: Create mount volume
ansible.builtin.file:
path: "{{ hardware['btrfs']['mount_point'] }}"
state: "directory"
owner: "root"
group: "root"
mode: "0711"
become: true
- name: Mount btrfs raid10 volume
ansible.posix.mount:
path: "{{ hardware['btrfs']['mount_point'] }}"
src: "LABEL={{ hardware['btrfs']['label'] }}"
state: "mounted"
fstype: "btrfs"
opts: "defaults,noatime,nodatacow,degraded,nofail"
become: true
- name: Set mounted btrfs volume permissions
ansible.builtin.file:
path: "{{ hardware['btrfs']['mount_point'] }}"
state: "directory"
owner: "root"
group: "root"
mode: "0711"
become: true
- name: Deploy btrfs scrub service and timer
ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/vmm/btrfs/{{ item }}.j2"
dest: "/etc/systemd/system/{{ item }}"
owner: "root"
group: "root"
mode: "0644"
loop:
- "btrfs-scrub.service"
- "btrfs-scrub.timer"
become: true
- name: Enable auto btrfs scrub
ansible.builtin.systemd:
name: "btrfs-scrub.timer"
state: "started"
enabled: true
daemon_reload: true
become: true
+9 -9
View File
@@ -1,13 +1,13 @@
--- ---
# This task is located in vmm roles because of its attributes, # This task is located in vmm roles because of its attributes,
# but all process should be run in "console". # but all process should be run in "console".
# At the playbook, `delegate_to: "console"` option is applyed by `apply:`. # At the playbook, `delegate_to: "console"` option is applied by `apply:`.
- name: Create images directory - name: Create images directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ hostvars['console']['node']['data_path'] }}/images/seeds/{{ target_vm }}" path: "{{ hostvars['console']['node']['data_path'] }}/images/seeds/{{ target_vm }}"
state: "directory" state: "directory"
owner: "console" owner: "{{ hostvars['console']['node']['name'] }}"
group: "svadmins" group: "{{ hostvars['console']['node']['group'] }}"
mode: "0700" mode: "0700"
- name: Create temp meta-data - name: Create temp meta-data
@@ -16,8 +16,8 @@
instance-id: vm-{{ target_vm }} instance-id: vm-{{ target_vm }}
local-hostname: {{ target_vm }} local-hostname: {{ target_vm }}
dest: "{{ hostvars['console']['node']['data_path'] }}/images/seeds/{{ target_vm }}/meta-data" dest: "{{ hostvars['console']['node']['data_path'] }}/images/seeds/{{ target_vm }}/meta-data"
owner: "console" owner: "{{ hostvars['console']['node']['name'] }}"
group: "svadmins" group: "{{ hostvars['console']['node']['group'] }}"
mode: "0600" mode: "0600"
register: "vm_meta_data" register: "vm_meta_data"
no_log: true no_log: true
@@ -26,8 +26,8 @@
ansible.builtin.template: ansible.builtin.template:
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/vmm/libvirt/seeds/user-data.j2" src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/vmm/libvirt/seeds/user-data.j2"
dest: "{{ hostvars['console']['node']['data_path'] }}/images/seeds/{{ target_vm }}/user-data" dest: "{{ hostvars['console']['node']['data_path'] }}/images/seeds/{{ target_vm }}/user-data"
owner: "console" owner: "{{ hostvars['console']['node']['name'] }}"
group: "svadmins" group: "{{ hostvars['console']['node']['group'] }}"
mode: "0600" mode: "0600"
register: "vm_user_data" register: "vm_user_data"
no_log: true no_log: true
@@ -37,8 +37,8 @@
content: | content: |
network: {config: disabled} network: {config: disabled}
dest: "{{ hostvars['console']['node']['data_path'] }}/images/seeds/{{ target_vm }}/network-config" dest: "{{ hostvars['console']['node']['data_path'] }}/images/seeds/{{ target_vm }}/network-config"
owner: "console" owner: "{{ hostvars['console']['node']['name'] }}"
group: "svadmins" group: "{{ hostvars['console']['node']['group'] }}"
mode: "0600" mode: "0600"
register: "vm_network_config" register: "vm_network_config"
no_log: true no_log: true
+29 -10
View File
@@ -1,16 +1,16 @@
--- ---
- name: Check vm cloud-init - name: Check vm cloud-init
ansible.builtin.stat: ansible.builtin.stat:
path: "/var/lib/libvirt/images/debian-13.qcow2" path: "{{ node['libvirt_path'] }}/images/debian-13.qcow2"
become: true become: true
register: is_cloud_init_file register: is_cloud_init_file
- name: Deploy vm cloud-init - name: Deploy vm cloud-init
ansible.builtin.copy: ansible.builtin.copy:
src: "{{ hostvars['console']['node']['data_path'] }}/images/debian-13-generic-amd64.qcow2" src: "{{ hostvars['console']['node']['data_path'] }}/images/debian-13-generic-amd64.qcow2"
dest: "/var/lib/libvirt/images/debian-13.qcow2" dest: "{{ node['libvirt_path'] }}/images/debian-13.qcow2"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
force: false force: false
become: true become: true
@@ -18,10 +18,10 @@
- name: Remote copy vm cloud-init file - name: Remote copy vm cloud-init file
ansible.builtin.copy: ansible.builtin.copy:
src: "/var/lib/libvirt/images/debian-13.qcow2" src: "{{ node['libvirt_path'] }}/images/debian-13.qcow2"
dest: "/var/lib/libvirt/images/{{ target_vm }}.qcow2" dest: "{{ node['libvirt_path'] }}/images/{{ target_vm }}.qcow2"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
remote_src: true remote_src: true
force: false force: false
@@ -29,7 +29,7 @@
- name: Check deployed cloud-init file info - name: Check deployed cloud-init file info
ansible.builtin.command: ansible.builtin.command:
cmd: "qemu-img info /var/lib/libvirt/images/{{ target_vm }}.qcow2 --output json" cmd: "qemu-img info {{ node['libvirt_path'] }}/images/{{ target_vm }}.qcow2 --output json"
changed_when: false changed_when: false
failed_when: failed_when:
- deployed_cloudfile_info.rc != 0 - deployed_cloudfile_info.rc != 0
@@ -38,18 +38,37 @@
- name: Resize deployed cloud-init file - name: Resize deployed cloud-init file
ansible.builtin.command: ansible.builtin.command:
cmd: "qemu-img resize /var/lib/libvirt/images/{{ target_vm }}.qcow2 {{ hostvars[target_vm]['vm']['storage'] }}G" cmd: "qemu-img resize {{ node['libvirt_path'] }}/images/{{ target_vm }}.qcow2 {{ hostvars[target_vm]['vm']['storage'] }}G"
when: when:
- deployed_cloudfile_info.rc == 0 - deployed_cloudfile_info.rc == 0
- (deployed_cloudfile_info.stdout | from_json)['virtual-size'] < (hostvars[target_vm]['vm']['storage'] | int * 1024 * 1024 * 1024) - (deployed_cloudfile_info.stdout | from_json)['virtual-size'] < (hostvars[target_vm]['vm']['storage'] | int * 1024 * 1024 * 1024)
changed_when: true changed_when: true
- name: Check app data raw image
ansible.builtin.stat:
path: "{{ hardware['btrfs']['mount_point'] }}/{{ target_vm }}.raw"
get_checksum: false
get_mime: false
get_attributes: false
when: target_vm == "app"
register: "is_app_data"
- name: Create app data raw image
ansible.builtin.command:
# 3.5T
cmd: "qemu-img create -f raw {{ hardware['btrfs']['mount_point'] }}/{{ target_vm }}.raw {{ hostvars[target_vm]['vm']['data_storage']['size'] }}T"
become: true
when:
- target_vm == "app"
- not is_app_data.stat.exists
changed_when: true
- name: Deploy vm seed.iso - name: Deploy vm seed.iso
ansible.builtin.copy: ansible.builtin.copy:
src: "{{ hostvars['console']['node']['data_path'] }}/images/seeds/{{ target_vm }}/seed.iso" src: "{{ hostvars['console']['node']['data_path'] }}/images/seeds/{{ target_vm }}/seed.iso"
dest: "/var/lib/libvirt/seeds/{{ target_vm }}_seed.iso" dest: "{{ node['libvirt_path'] }}/seeds/{{ target_vm }}_seed.iso"
owner: "{{ ansible_user }}" owner: "{{ ansible_user }}"
group: "svadmins" group: "{{ node['group'] }}"
mode: "0644" mode: "0644"
become: true become: true
when: deployed_cloudfile_info.rc == 0 when: deployed_cloudfile_info.rc == 0
+23 -20
View File
@@ -3,32 +3,35 @@
::1 {{ node['local_san'] }} ::1 {{ node['local_san'] }}
{% if node['name'] == 'console' %} {% if node['name'] == 'console' %}
# Hosts IPv4 # Hosts IPv4
{{ hostvars['fw']['network4']['firewall']['server'] }} fw.ilnmors.internal {{ hostvars['fw']['network4']['firewall']['server'] }} fw.{{ domain['internal'] }}
{{ hostvars['fw']['network4']['vmm']['client'] }} init.vmm.ilnmors.internal {{ hostvars['fw']['network4']['vmm']['client'] }} init.vmm.{{ domain['internal'] }}
{{ hostvars['fw']['network4']['vmm']['server'] }} vmm.ilnmors.internal {{ hostvars['fw']['network4']['vmm']['server'] }} vmm.{{ domain['internal'] }}
{{ hostvars['fw']['network4']['infra']['server'] }} infra.ilnmors.internal {{ hostvars['fw']['network4']['infra']['server'] }} infra.{{ domain['internal'] }}
{{ hostvars['fw']['network4']['auth']['server'] }} auth.ilnmors.internal {{ hostvars['fw']['network4']['auth']['server'] }} auth.{{ domain['internal'] }}
{{ hostvars['fw']['network4']['app']['server'] }} app.ilnmors.internal {{ hostvars['fw']['network4']['app']['server'] }} app.{{ domain['internal'] }}
# Hosts IPv6 # Hosts IPv6
{{ hostvars['fw']['network6']['firewall']['server'] }} fw.ilnmors.internal {{ hostvars['fw']['network6']['firewall']['server'] }} fw.{{ domain['internal'] }}
{{ hostvars['fw']['network6']['vmm']['client'] }} init.vmm.ilnmors.internal {{ hostvars['fw']['network6']['vmm']['client'] }} init.vmm.{{ domain['internal'] }}
{{ hostvars['fw']['network6']['vmm']['server'] }} vmm.ilnmors.internal {{ hostvars['fw']['network6']['vmm']['server'] }} vmm.{{ domain['internal'] }}
{{ hostvars['fw']['network6']['infra']['server'] }} infra.ilnmors.internal {{ hostvars['fw']['network6']['infra']['server'] }} infra.{{ domain['internal'] }}
{{ hostvars['fw']['network6']['auth']['server'] }} auth.ilnmors.internal {{ hostvars['fw']['network6']['auth']['server'] }} auth.{{ domain['internal'] }}
{{ hostvars['fw']['network6']['app']['server'] }} app.ilnmors.internal {{ hostvars['fw']['network6']['app']['server'] }} app.{{ domain['internal'] }}
# kopia repository
{{ hostvars['fw']['network4']['nas']['client'] }} nas.{{ domain['internal'] }}
{{ hostvars['fw']['network6']['nas']['client'] }} nas.{{ domain['internal'] }}
{% else %} {% else %}
# IPv4 # IPv4
# Crowdsec, blocky, bind(fw) # Crowdsec, blocky, bind(fw)
{{ hostvars['fw']['network4']['firewall']['server'] }} ntp.ilnmors.internal crowdsec.ilnmors.internal {{ hostvars['fw']['network4']['firewall']['server'] }} ntp.{{ domain['internal'] }} crowdsec.{{ domain['internal'] }}
{{ hostvars['fw']['network4']['blocky']['server'] }} blocky.ilnmors.internal {{ hostvars['fw']['network4']['blocky']['server'] }} blocky.{{ domain['internal'] }}
{{ hostvars['fw']['network4']['bind']['server'] }} bind.ilnmors.internal {{ hostvars['fw']['network4']['bind']['server'] }} bind.{{ domain['internal'] }}
# DB, LDAP, CA, Prometheus, Loki, mail (infra) # DB, LDAP, CA, Prometheus, Loki, mail (infra)
{{ hostvars['fw']['network4']['infra']['server'] }} postgresql.ilnmors.internal ldap.ilnmors.internal prometheus.ilnmors.internal loki.ilnmors.internal mail.ilnmors.internal ca.ilnmors.internal {{ hostvars['fw']['network4']['infra']['server'] }} postgresql.{{ domain['internal'] }} ldap.{{ domain['internal'] }} prometheus.{{ domain['internal'] }} loki.{{ domain['internal'] }} mail.{{ domain['internal'] }} ca.{{ domain['internal'] }}
# IPv6 # IPv6
# Crowdsec, blocky, bind(fw) # Crowdsec, blocky, bind(fw)
{{ hostvars['fw']['network6']['firewall']['server'] }} ntp.ilnmors.internal crowdsec.ilnmors.internal {{ hostvars['fw']['network6']['firewall']['server'] }} ntp.{{ domain['internal'] }} crowdsec.{{ domain['internal'] }}
{{ hostvars['fw']['network6']['blocky']['server'] }} blocky.ilnmors.internal {{ hostvars['fw']['network6']['blocky']['server'] }} blocky.{{ domain['internal'] }}
{{ hostvars['fw']['network6']['bind']['server'] }} bind.ilnmors.internal {{ hostvars['fw']['network6']['bind']['server'] }} bind.{{ domain['internal'] }}
# DB, LDAP, CA, Prometheus, Loki, mail (infra) # DB, LDAP, CA, Prometheus, Loki, mail (infra)
{{ hostvars['fw']['network6']['infra']['server'] }} postgresql.ilnmors.internal ldap.ilnmors.internal prometheus.ilnmors.internal loki.ilnmors.internal mail.ilnmors.internal ca.ilnmors.internal {{ hostvars['fw']['network6']['infra']['server'] }} postgresql.{{ domain['internal'] }} ldap.{{ domain['internal'] }} prometheus.{{ domain['internal'] }} loki.{{ domain['internal'] }} mail.{{ domain['internal'] }} ca.{{ domain['internal'] }}
{% endif %} {% endif %}
+1 -1
View File
@@ -1,3 +1,3 @@
[Time] [Time]
NTP=ntp.ilnmors.internal NTP=ntp.{{ domain['internal'] }}
FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org
+7 -2
View File
@@ -30,6 +30,7 @@ define HOSTS4_INFRA = {{ hostvars['fw']['network4']['infra']['server'] }}
define HOSTS4_AUTH = {{ hostvars['fw']['network4']['auth']['server'] }} define HOSTS4_AUTH = {{ hostvars['fw']['network4']['auth']['server'] }}
define HOSTS4_APP = {{ hostvars['fw']['network4']['app']['server'] }} define HOSTS4_APP = {{ hostvars['fw']['network4']['app']['server'] }}
define HOSTS4_NAS = {{ hostvars['fw']['network4']['nas']['client'] }} define HOSTS4_NAS = {{ hostvars['fw']['network4']['nas']['client'] }}
define HOSTS4_PRINTER = {{ hostvars['fw']['network4']['printer']['client'] }}
define HOSTS6_FW = { {{ hostvars['fw']['network6']['firewall'].values() | join(', ') }} } define HOSTS6_FW = { {{ hostvars['fw']['network6']['firewall'].values() | join(', ') }} }
define HOSTS6_BLOCKY = {{ hostvars['fw']['network6']['blocky']['server'] }} define HOSTS6_BLOCKY = {{ hostvars['fw']['network6']['blocky']['server'] }}
@@ -77,10 +78,12 @@ table inet filter {
set crowdsec6-blacklists { set crowdsec6-blacklists {
type ipv6_addr type ipv6_addr
flags timeout flags timeout
} }
chain global { chain global {
# invalid packets # invalid packets
ct state invalid drop comment "deny invalid connection" ct state invalid drop comment "deny invalid connection"
# VPN connection exception handling
udp dport $PORTS_VPN return comment "return vpn connection to input and forward chain"
# crowdsec # crowdsec
ip saddr @crowdsec-blacklists counter drop comment "deny all crowdsec blacklist" ip saddr @crowdsec-blacklists counter drop comment "deny all crowdsec blacklist"
ip6 saddr @crowdsec6-blacklists counter drop comment "deny all ipv6 crowdsec blacklist" ip6 saddr @crowdsec6-blacklists counter drop comment "deny all ipv6 crowdsec blacklist"
@@ -111,7 +114,7 @@ table inet filter {
iifname "lo" accept comment "allow local connection: FW > FW" iifname "lo" accept comment "allow local connection: FW > FW"
udp dport $PORTS_VPN accept comment "allow vpn connection: > FW" udp dport $PORTS_VPN accept comment "allow vpn connection: > FW"
iifname { $IF_CLIENT, $IF_SERVER, $IF_USER, $IF_WG } meta l4proto { icmp, icmpv6 } accept comment "allow icmp, icmpv6 connection: CLIENT/SERVER/USER/WG > FW" iifname { $IF_CLIENT, $IF_SERVER, $IF_USER, $IF_WG } meta l4proto { icmp, icmpv6 } accept comment "allow icmp, icmpv6 connection: CLIENT/SERVER/USER/WG > FW"
iifname { $IF_CLIENT, $IF_SERVER, $IF_USER, $IF_WG } udp dport $PORTS_NTP accept comment "allow ntp connection: CLIENT/SERVER/USER/WG > FW" iifname { $IF_CLIENT, $IF_SERVER, $IF_WG } udp dport $PORTS_NTP accept comment "allow ntp connection: CLIENT/SERVER/USER/WG > FW"
# Global chain contains "WAN !> :SSH_PORT" # Global chain contains "WAN !> :SSH_PORT"
ip saddr $HOSTS4_CONSOLE tcp dport $PORTS_SSH accept comment "allow ipv4 ssh connection: CONSOLE > FW" ip saddr $HOSTS4_CONSOLE tcp dport $PORTS_SSH accept comment "allow ipv4 ssh connection: CONSOLE > FW"
ip6 saddr $HOSTS6_CONSOLE tcp dport $PORTS_SSH accept comment "allow ipv6 ssh connection: CONSOLE > FW" ip6 saddr $HOSTS6_CONSOLE tcp dport $PORTS_SSH accept comment "allow ipv6 ssh connection: CONSOLE > FW"
@@ -146,6 +149,8 @@ table inet filter {
# Kopia/NAS Console > NAS # Kopia/NAS Console > NAS
oifname $IF_CLIENT ip saddr $HOSTS4_CONSOLE ip daddr $HOSTS4_NAS tcp dport { $PORTS_NAS, $PORTS_KOPIA } accept comment "allow ipv4 web connection (DSM, KOPIA): CONSOLE > FW > CLIENT NAS" oifname $IF_CLIENT ip saddr $HOSTS4_CONSOLE ip daddr $HOSTS4_NAS tcp dport { $PORTS_NAS, $PORTS_KOPIA } accept comment "allow ipv4 web connection (DSM, KOPIA): CONSOLE > FW > CLIENT NAS"
oifname $IF_CLIENT ip6 saddr $HOSTS6_CONSOLE ip6 daddr $HOSTS6_NAS tcp dport { $PORTS_NAS, $PORTS_KOPIA } accept comment "allow ipv6 web connection (DSM, KOPIA): CONSOLE > FW > CLIENT NAS" oifname $IF_CLIENT ip6 saddr $HOSTS6_CONSOLE ip6 daddr $HOSTS6_NAS tcp dport { $PORTS_NAS, $PORTS_KOPIA } accept comment "allow ipv6 web connection (DSM, KOPIA): CONSOLE > FW > CLIENT NAS"
# Printer
oifname $IF_CLIENT ip saddr $HOSTS4_CONSOLE ip daddr $HOSTS4_PRINTER accept comment "allow ipv4 printer connection: CONSOLE > FW > PRINTER"
iifname $IF_WAN jump wan comment "set WAN interface rules" iifname $IF_WAN jump wan comment "set WAN interface rules"
iifname $IF_CLIENT jump client comment "set CLIENT interface rules" iifname $IF_CLIENT jump client comment "set CLIENT interface rules"
@@ -1,5 +0,0 @@
[Match]
MACAddress=c8:ff:bf:05:aa:b0
[Link]
Name=eth0
@@ -0,0 +1,5 @@
[Match]
MACAddress={{ hostvars['vmm']['hardware']['mac']['nic0'] }}
[Link]
Name=eth0
@@ -1,5 +0,0 @@
[Match]
MACAddress=c8:ff:bf:05:aa:b1
[Link]
Name=eth1
@@ -0,0 +1,5 @@
[Match]
MACAddress={{ hostvars['vmm']['hardware']['mac']['nic1'] }}
[Link]
Name=eth1
@@ -1,28 +0,0 @@
[Match]
Name=vlan1
[Network]
# IPv4
Address=192.168.1.10/24
# IPv6
Address=fd00:1::10/64
[RoutingPolicyRule]
From=192.168.1.10/32
Table=1
Priority=100
[Route]
Destination=192.168.1.0/24
Scope=link
Table=1
[RoutingPolicyRule]
From=fd00:1::10/128
Table=61
Priority=100
[Route]
Destination=fd00:1::/64
Scope=link
Table=61
@@ -0,0 +1,28 @@
[Match]
Name=vlan1
[Network]
# IPv4
Address={{ hostvars['fw']['network4']['vmm']['client'] }}/24
# IPv6
Address={{ hostvars['fw']['network6']['vmm']['client'] }}/64
[RoutingPolicyRule]
From={{ hostvars['fw']['network4']['vmm']['client'] }}/32
Table=1
Priority=100
[Route]
Destination={{ hostvars['fw']['network4']['subnet']['client'] }}
Scope=link
Table=1
[RoutingPolicyRule]
From={{ hostvars['fw']['network6']['vmm']['client'] }}/128
Table=61
Priority=100
[Route]
Destination={{ hostvars['fw']['network6']['subnet']['client'] }}
Scope=link
Table=61
@@ -1,32 +0,0 @@
[Match]
Name=vlan10
[Network]
RequiredForOnline=false
# IPv4
Address=192.168.10.10/24
Gateway=192.168.10.1
DNS=192.168.10.2
# IPv6
Address=fd00:10::10/64
Gateway=fd00:10::1
DNS=fd00:10::2
[RoutingPolicyRule]
From=192.168.10.10/32
Table=2
Priority=100
[Route]
Destination=0.0.0.0/0
Gateway=192.168.10.1
Table=2
[RoutingPolicyRule]
From=fd00:10::10/128
Table=62
Priority=100
[Route]
Destination=::/0
Gateway=fd00:10::1
Table=62
@@ -0,0 +1,32 @@
[Match]
Name=vlan10
[Network]
RequiredForOnline=false
# IPv4
Address={{ hostvars['fw']['network4']['vmm']['server'] }}/24
Gateway={{ hostvars['fw']['network4']['firewall']['server'] }}
DNS={{ hostvars['fw']['network4']['blocky']['server'] }}
# IPv6
Address={{ hostvars['fw']['network6']['vmm']['server'] }}/64
Gateway={{ hostvars['fw']['network6']['firewall']['server'] }}
DNS={{ hostvars['fw']['network6']['blocky']['server'] }}
[RoutingPolicyRule]
From={{ hostvars['fw']['network4']['vmm']['server'] }}/32
Table=2
Priority=100
[Route]
Destination=0.0.0.0/0
Gateway={{ hostvars['fw']['network4']['firewall']['server'] }}
Table=2
[RoutingPolicyRule]
From={{ hostvars['fw']['network6']['vmm']['server'] }}/128
Table=62
Priority=100
[Route]
Destination=::/0
Gateway={{ hostvars['fw']['network6']['firewall']['server'] }}
Table=62
+9 -5
View File
@@ -3,7 +3,7 @@
set -e set -e
# Varibles # Variables
KEY_PATH="$HOME/workspace/homelab/config/secrets" KEY_PATH="$HOME/workspace/homelab/config/secrets"
TMP_PATH="/run/user/$UID" TMP_PATH="/run/user/$UID"
SECRET_FILE="$1" SECRET_FILE="$1"
@@ -19,7 +19,11 @@ log() {
local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
local level="$1" local level="$1"
local msg="$2" local msg="$2"
echo "time=\"$timestamp\" level=\"$level\" msg=\"$msg\" source=\"edit_secret.sh\"">&2 if [ "$level" == "error" ]; then
echo "time=\"$timestamp\" level=\"$level\" msg=\"$msg\" source=\"edit_secret.sh\"">&2
else
echo "time=\"$timestamp\" level=\"$level\" msg=\"$msg\" source=\"edit_secret.sh\"">&1
fi
} }
# Secret file check # Secret file check
@@ -58,9 +62,9 @@ cleanup() {
trap cleanup EXIT trap cleanup EXIT
# Get GPG password from prompt # Get GPG password from prompt
echo -n "Enter GPG passphrase: " >&2 echo -n "Enter GPG passphrase: " >&1
read -s GPG_PASSPHRASE read -s GPG_PASSPHRASE
echo "" >&2 echo "" >&1
# Decrypt age-key on the tmpfs (memory) # Decrypt age-key on the tmpfs (memory)
echo "$GPG_PASSPHRASE" | gpg --batch --yes --passphrase-fd 0 \ echo "$GPG_PASSPHRASE" | gpg --batch --yes --passphrase-fd 0 \
@@ -68,7 +72,7 @@ echo "$GPG_PASSPHRASE" | gpg --batch --yes --passphrase-fd 0 \
--decrypt "$KEY_PATH/age-key.gpg" &&\ --decrypt "$KEY_PATH/age-key.gpg" &&\
chmod 600 "$TMP_PATH/age-key" chmod 600 "$TMP_PATH/age-key"
# Unset environment varibles # Unset environment Variables
unset GPG_PASSPHRASE unset GPG_PASSPHRASE
# Check the key on memory # Check the key on memory
+87 -44
View File
@@ -59,10 +59,10 @@ wireguard:
#ENC[AES256_GCM,data:+kiy17Z7q3EiPgo4Ykk=,iv:vOi54XHHLNIO9U0ybpU9Cn68Ymj5W4vtQ2OhTkGAmRo=,tag:h3wdCo5UfNGlHqMpeeBf/A==,type:comment] #ENC[AES256_GCM,data:+kiy17Z7q3EiPgo4Ykk=,iv:vOi54XHHLNIO9U0ybpU9Cn68Ymj5W4vtQ2OhTkGAmRo=,tag:h3wdCo5UfNGlHqMpeeBf/A==,type:comment]
kopia: kopia:
repository: ENC[AES256_GCM,data:16V50bVVtecbF+TJcXHCx46ZPGNMgAhUOA0YbZHVTsCrOWQvTvcK2k8Iq3E=,iv:/wNbrE5GaFiQPNEp8wZ0JehbXkmah/gPm5ywNE6WVVM=,tag:vW82KTKtJ44++tqXON/SYw==,type:str] repository: ENC[AES256_GCM,data:16V50bVVtecbF+TJcXHCx46ZPGNMgAhUOA0YbZHVTsCrOWQvTvcK2k8Iq3E=,iv:/wNbrE5GaFiQPNEp8wZ0JehbXkmah/gPm5ywNE6WVVM=,tag:vW82KTKtJ44++tqXON/SYw==,type:str]
user: users:
console: ENC[AES256_GCM,data:LZQEz7JS8CMMSlGB2/FS15VHAbko6YpCaWDZDa9tXVnmYLwFs8F39/u8kLI=,iv:WrYox/3LweqafWl96fxmezTFhKHB/2XSDSLwHljdpw0=,tag:bPwqkdeexXItkbpPQQ6klg==,type:str] console: ENC[AES256_GCM,data:v1QY7h6vMmzYq/PTmnLg3M5Iwc/Ljr/1M3nJGuUJMfPN2ATY+GIMUyhYu+0=,iv:32c4YrZfTiu7sv/c9tDItmAE8G1lvc1sm6JD1GRkYr0=,tag:kj1a32+bMUsRdusadoXDvg==,type:str]
infra: ENC[AES256_GCM,data:fwvu96Zhao5RthZptxhuv2NobY1riQzpvD4Ardc8UTwN6+HyfFVR31yTTqk=,iv:jqFEKsP2npZgeRL3E3Va7oLzbHShBO4FxLRYwnfLtys=,tag:qXescWki6oPaaSrhMsUw9g==,type:str] infra: ENC[AES256_GCM,data:WdugcvTJEy3/kxjCMeN16u96XM+59sOBF/z88p9f0lPVzi78ZmIZPjf835M=,iv:6G4rry8fCjhB+MF5B3TVf1w0LDSA6farVwyxAp8nKQE=,tag:+mCSrVmo7zuj782swmRFPw==,type:str]
app: ENC[AES256_GCM,data:VVs8lfo8ZsbYfeKIwtaFCrpV82SguR/xxNnMZXXp8YOBP+6F2Vs5jeDtTTs=,iv:L2mS2RhiUlB9Oq4gwVs8WNF4r8vYv6zg6Fqnpe9hSoM=,tag:WYjtPdD2Lny9Kc+dWVupjw==,type:str] app: ENC[AES256_GCM,data:5A17rXYUBPkFRpcHTOBCGmm9j6uMHtvKkLTpHsYZeRJkoSrA4k9IhVpjNA0=,iv:kJzowaheVckLUKae6xXeIVi+Jc+Mhee/jjmS91im9dc=,tag:f1uXU6JRD4mxAYMlFTWoew==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment] #ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
# #
# #
@@ -117,7 +117,11 @@ postgresql:
gitea: ENC[AES256_GCM,data:l+pBCzyQa3000SE9z1R4htD0V0ONsBtKy92dfgsVYsZ3XlEyVJDIBOsugwM=,iv:5t/oHW1vFAmV/s2Ze/cV9Vuqo96Qu6QvZeRbio7VX2s=,tag:4zeQaXiXIzBpy+tXsxmN7Q==,type:str] gitea: ENC[AES256_GCM,data:l+pBCzyQa3000SE9z1R4htD0V0ONsBtKy92dfgsVYsZ3XlEyVJDIBOsugwM=,iv:5t/oHW1vFAmV/s2Ze/cV9Vuqo96Qu6QvZeRbio7VX2s=,tag:4zeQaXiXIzBpy+tXsxmN7Q==,type:str]
immich: ENC[AES256_GCM,data:11jvxTKA/RL0DGL6y2/X092hnDohj6yTrYGK4IVojqBd1gCOBnDvUjgmx14=,iv:oBfHxsx9nxhyKY/WOuWfybxEX2bf+lHEtsaifFRS9lg=,tag:tAfkBdgQ8ZEkLIFcDICKDw==,type:str] immich: ENC[AES256_GCM,data:11jvxTKA/RL0DGL6y2/X092hnDohj6yTrYGK4IVojqBd1gCOBnDvUjgmx14=,iv:oBfHxsx9nxhyKY/WOuWfybxEX2bf+lHEtsaifFRS9lg=,tag:tAfkBdgQ8ZEkLIFcDICKDw==,type:str]
paperless: ENC[AES256_GCM,data:6VBrBbjVoam7SkZCSvoBTdrfkUoDghdGTiBmFLul04X/okXOHeC5zusJffY=,iv:iZumcJ3TWwZD77FzYx8THwCqC+EbnXUBrEKuPh3zgV8=,tag:u2m8SppAdxZ/duNdpuS3oQ==,type:str] paperless: ENC[AES256_GCM,data:6VBrBbjVoam7SkZCSvoBTdrfkUoDghdGTiBmFLul04X/okXOHeC5zusJffY=,iv:iZumcJ3TWwZD77FzYx8THwCqC+EbnXUBrEKuPh3zgV8=,tag:u2m8SppAdxZ/duNdpuS3oQ==,type:str]
vikunja: ENC[AES256_GCM,data:/+wQdoFPTBG2elI9kZbAVWrHZ0DhMaYr4dc+2z9QNdb3TcDS2PEia0JuSAg=,iv:MViZTyUD8YqMmxSTWCQpJ30f/KQdQGOzPlRHHsQ8lAw=,tag:zov3POno139dkMxFDpj2gg==,type:str] nextcloud: ENC[AES256_GCM,data:ROsximNuWYMTZktmLJPx7W1Qol/uT+APgwoCtFO/6ZYYc3KxKvlk344eqEc=,iv:4d+MrfIHjJKAcwhvZ3g4go66uZcieuL7lngKErJd+fg=,tag:QbWOtxeCbiu62GyrE2atXg==,type:str]
sure: ENC[AES256_GCM,data:FULJ2gjJ2gZC3s324itW+CjGRBHIP9RnOqw5TT1UaiUhb7UHAPm1na+LsZk=,iv:c0GnVZkxprJUzPPq3TCQaZvAes9QQuvDXqgVLLaiQIg=,tag:uDxy/Lkd2hNK4AWwMNMslw==,type:str]
outline: ENC[AES256_GCM,data:0eJFCfHgS4olWXHOnUPixs4Dl5PoxJa+2H1mk3YgC4GUv+nX8gTPmzKTMVM=,iv:HGxX7aLODUc2nVLC8YXdet9qphU/wxMapWhk93YmHDM=,tag:6/2uckW/a24LgVFRH6E85Q==,type:str]
memos: ENC[AES256_GCM,data:BaNTnZFZH4oMTnDkgrf2/fMTkO43rc9bSsgnDWrHJ/Z6+MZdMitpIMkrMN4=,iv:JsG3B0YweZYO96MW9NmoSsIG++gFq+jRUsozwJtWl3M=,tag:orLTUiW0inOJdD4YSp4baQ==,type:str]
mealie: ENC[AES256_GCM,data:XbYHQv6HBWCXUBRmcbQZN5Y1Gw+V+Wra28Mp+m+ZGl8VRXsKMu5507vGHQM=,iv:zp4ZarqG9KshiBV8F8UksfI2QXmXHwqPw631r/5bYy8=,tag:jvsvXrUsCvpQGIbLV9jTYQ==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment] #ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
# #
# #
@@ -135,8 +139,9 @@ ldap:
user: ENC[AES256_GCM,data:DT9h51o6z70A4QeoKvCbUo98JFxILgB5tkHeX60CZuCl0GHTa//mRpIUEvo=,iv:Pa9iqXeKDHHBz524zeRImYEkXmY50s7Z+Z4KYt3sNT4=,tag:UTS5VIqbRA66UVDrDXwuPQ==,type:str] user: ENC[AES256_GCM,data:DT9h51o6z70A4QeoKvCbUo98JFxILgB5tkHeX60CZuCl0GHTa//mRpIUEvo=,iv:Pa9iqXeKDHHBz524zeRImYEkXmY50s7Z+Z4KYt3sNT4=,tag:UTS5VIqbRA66UVDrDXwuPQ==,type:str]
authelia: ENC[AES256_GCM,data:G8ZGsLKqEmMzQ5NMAgirF5BQraHNqixtI6dyyaeNhTdXebjJZML52xL36p4=,iv:ZtHAsFYmrQxr+qoQLPW/eme0+nsT148KRsXmW/LNLlU=,tag:Pvjs/eylkgxJpmGBsRmjcw==,type:str] authelia: ENC[AES256_GCM,data:G8ZGsLKqEmMzQ5NMAgirF5BQraHNqixtI6dyyaeNhTdXebjJZML52xL36p4=,iv:ZtHAsFYmrQxr+qoQLPW/eme0+nsT148KRsXmW/LNLlU=,tag:Pvjs/eylkgxJpmGBsRmjcw==,type:str]
grafana: ENC[AES256_GCM,data:vWmU3ZKcolETWAY74C3OMD8gMXDeYk+DqssACL0xefIPi5IkbrhYWmnWAnA=,iv:wcRms3Zp8kPM4USRPVa0UHpCTK36SWhK9C8yHSWu2Cs=,tag:gU5S/6fdMZVd/ih3Yd5uJA==,type:str] grafana: ENC[AES256_GCM,data:vWmU3ZKcolETWAY74C3OMD8gMXDeYk+DqssACL0xefIPi5IkbrhYWmnWAnA=,iv:wcRms3Zp8kPM4USRPVa0UHpCTK36SWhK9C8yHSWu2Cs=,tag:gU5S/6fdMZVd/ih3Yd5uJA==,type:str]
il: ENC[AES256_GCM,data:/CyMeo1+rIUAYiB25nI0,iv:jsyiiRN5z9GqcUnTZ0CZo4s+umTc2zeY2FPp+tVOC9o=,tag:cwOHcqMysCxX57w3a+Pzpg==,type:str] users:
morsalin: null il: ENC[AES256_GCM,data:9b9OU4Nt60/XdUrwnhJh,iv:7ZqOYqM2aibgcFRxw1ZvOdBJMZUfOVbNa+2sMzrXAns=,tag:x87IG/HETASiC9/HwyW1Ig==,type:str]
morsalin: ENC[AES256_GCM,data:rERjBNLZXSKT,iv:VuD8ZGfrd0wQ/5TCgLhLN459ZHPepcZyv8Kdl7TsMc4=,tag:Xp/fjve1xn0Wjk7ExShCLw==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment] #ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
# #
# #
@@ -156,9 +161,9 @@ loki:
# #
#ENC[AES256_GCM,data:yHgd8KBDPYeMjKzUOimdOA==,iv:ozyRymtPEII2luBads2GHyLf4Vdhf4EXNaF82SNmQm4=,tag:1mOJAmR5kVRBjm0SbQkqlw==,type:comment] #ENC[AES256_GCM,data:yHgd8KBDPYeMjKzUOimdOA==,iv:ozyRymtPEII2luBads2GHyLf4Vdhf4EXNaF82SNmQm4=,tag:1mOJAmR5kVRBjm0SbQkqlw==,type:comment]
grafana: grafana:
user: admin:
id: ENC[AES256_GCM,data:32LNqOb8pzi0/18=,iv:YJrYaQRE+veDhaEUefGWLbNJo1toHGmEOpqrNV3IDfg=,tag:ENryvH9ec3EbDhBB2bdHug==,type:str] id: ENC[AES256_GCM,data:qwz/L8jQXvZKlic=,iv:s0PL4GwTvr/SfzuFgZESADnepagt+QKwt8XmqsMLr0c=,tag:2ozh3jpPFuqXJAx/DpgF6A==,type:str]
password: ENC[AES256_GCM,data:MFw7TAvzpL0EW2o+w6hF5qrLYVkn0HsQOXqBk9AQq7GxK4uAEDCi/YL3goI=,iv:HSpJL2CZKXHQYhOJLy6HzWARootl8Y1yMGhaMT0XRfM=,tag:t0VHDYHCZJwDcR1VcRFdCw==,type:str] password: ENC[AES256_GCM,data:BDTWzGBsyr6dw3tQSCn5tFDk0IZxNc/Y6LYX6ytn1EpLhBr2CW3YE5Dsk7g=,iv:cbYmvG3EZO5ytYtoIAKpewdE81NMqP4YXrdsj7n87SA=,tag:wuFamPPldQYJAKeX7zLFnA==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment] #ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
# #
# #
@@ -180,18 +185,25 @@ vaultwarden:
admin: admin:
password: ENC[AES256_GCM,data:FzD80H5lPNyjTRGd/IcIGir35KLF8gN3qmTzEQrlfutHh08mk0Vh9X8irHA=,iv:cfn5432g2MvkuBJLB2zDJmU0sLgMefVvpy0bP/4/oPY=,tag:7MHEv8XswdQZNTARvxs55g==,type:str] password: ENC[AES256_GCM,data:FzD80H5lPNyjTRGd/IcIGir35KLF8gN3qmTzEQrlfutHh08mk0Vh9X8irHA=,iv:cfn5432g2MvkuBJLB2zDJmU0sLgMefVvpy0bP/4/oPY=,tag:7MHEv8XswdQZNTARvxs55g==,type:str]
hash: ENC[AES256_GCM,data:Ae7bhnL5pxfNV3+r/PCDIpxx0tHcNiB/s4sm7OoxVpp+tcEpXZ9vsv38sZjx+Z8t2vlmiYHc72PEdapcAihleuLMBPM1dAVn8LqzzWtVhfmCOoUZI8Z5L3VL8eyyz6npiw==,iv:c2MEIbrnVsR+bUx3zLLTnKSElFTH7JRl23HmmTlWEBg=,tag:mnMrER9pQEKAdloYMeRa3g==,type:str] hash: ENC[AES256_GCM,data:Ae7bhnL5pxfNV3+r/PCDIpxx0tHcNiB/s4sm7OoxVpp+tcEpXZ9vsv38sZjx+Z8t2vlmiYHc72PEdapcAihleuLMBPM1dAVn8LqzzWtVhfmCOoUZI8Z5L3VL8eyyz6npiw==,iv:c2MEIbrnVsR+bUx3zLLTnKSElFTH7JRl23HmmTlWEBg=,tag:mnMrER9pQEKAdloYMeRa3g==,type:str]
il: users:
password: ENC[AES256_GCM,data:mhLb55ENatpE59Rbzk2Uq6iBKc0Jj/9x4fOANJOHR0WvSxTQRKJ94cCq9Ykp/chWbdgYYPrwU5oD0Yo17zqb,iv:6bzKq5WaKhuOsQ8zSSH9ZrQYbDPB1nv/bFoQou1ycL4=,tag:bSmuUodl+/9nzxZ7YBoezA==,type:str] il:
morsalin: id: ENC[AES256_GCM,data:V4kWLbzhIM7ONCt7PtxB56oilw==,iv:b9mkOmmOmyvlYI11ASRh4GQl3NxnvtoC9jAx5DuRSwM=,tag:Eo5a5UnvGVXY1jofbMgqQQ==,type:str]
password: ENC[AES256_GCM,data:ibg5/MfLH7pSY2pEmjM=,iv:+aV5muP/9BYoKwTGQxKEL+IGY9P+O3GVKGgSuTzT+U0=,tag:rgqcmJvd1RtvWJ91PCxYIg==,type:str] password: ENC[AES256_GCM,data:Ay0aPgrP75z3n/xyELAPhi4Ov4a62M3lhtpByDkc++TGq+a2bmpdt0OhBfsCSjY/6ads1EUhqQYscTE86Eln,iv://EEyABWzFn9kiKxjz92zKbzUtbnAPf9oNxf9s0nlLo=,tag:cZpqyTXJuO2yQByHMTWwtA==,type:str]
morsalin:
id: ENC[AES256_GCM,data:fXTVMR2iUa1lfyLjG3UI1Xuys80ylFEQ+A==,iv:KqRhjFULUc9BjGEepBu9I3aZparaxRhLos8Ztz3jPyE=,tag:1E8DgiXt810B7UYZLE+0yw==,type:str]
password: ENC[AES256_GCM,data:e8H0wYtCbVEDDXctbJQ=,iv:Bewk1rEsDPD5NVzZfEM2QfzNttwklI6KL7kFgFU3qvY=,tag:0U8Vg39ZD05AWMp6hQkkzA==,type:str]
eunkyoung:
id: ENC[AES256_GCM,data:OubNz5ueQU/KksljCvS/X29rhDjvipkgzik=,iv:mULicCrst9ciC7lAJrYIPV8Kx4Z/JAEbupO/Kti5DoA=,tag:0U/WQnZ8ZCL5yfkbd7Y6oA==,type:str]
password: ENC[AES256_GCM,data:M3MqxQTZdd+SS/nd,iv:KEBZ8eBAwVm0mTwDf3bJRWwtUN/M+an6BMV9N34pXq4=,tag:Qxxca3kq5NH6YbJWK002Gg==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment] #ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
# #
# #
#ENC[AES256_GCM,data:HAN9BBEl1CW11LAf3x8=,iv:hwqCErtmPqGJ+y86D9MoxJwixvbcJONlyT900Y5DOug=,tag:kCxsG353ltbOCKLe85adCg==,type:comment] #ENC[AES256_GCM,data:HAN9BBEl1CW11LAf3x8=,iv:hwqCErtmPqGJ+y86D9MoxJwixvbcJONlyT900Y5DOug=,tag:kCxsG353ltbOCKLe85adCg==,type:comment]
gitea: gitea:
il: admin:
password: ENC[AES256_GCM,data:Bs5/t5mNbSv5+ek9gNHZp5qqxitM4Kq0Xgh2JV6LiFw9lZJSOVT4JPLRP5M=,iv:z50+naWOTVL8lEgBgm51j6hLjS8ve2UcRRKukvtykM0=,tag:TF9rPxjoLe/vAyvl23PiCg==,type:str] id: ENC[AES256_GCM,data:PtE=,iv:44l071j9ZLt3T2BbpAho70soiHxzBqp4KeITxrjdem8=,tag:yQt8jyEadk/GnrxnCPVKdA==,type:str]
token: ENC[AES256_GCM,data:CiYEXEKLLRDp++iga5YmhyPB2bSvqhhDgSOhmiulp9n9SsBVQ3s5MQ==,iv:+oetgEH/IORz74Xoz5zgDjD3BLyledZTqlYlCWaDrRk=,tag:S9O09YEMuSexuNW3ojEw5Q==,type:str] password: ENC[AES256_GCM,data:EazzQF9D/s5TtYKBApzLQT3S7a0itGm7wGtHRMi6J0C3I/gBNhpgeF6dk8k=,iv:SGSiAlqOO7LvTlyVmOHU13Vq7OANo3eAeBCwioFpi3Y=,tag:4Vz8FRHEv9G+at/zZq4YMg==,type:str]
token: ENC[AES256_GCM,data:z12Oq4OFCCjCXn85cVSfSzxWt7b0ytuA6TAn3Xf5CIhvKuoQD43WnA==,iv:BP8WDOAXkuA9fMjfLR7BTyTqjEbjSmwgSrJfqCutwmQ=,tag:s7ys3V+QnU/Nmkccm3rcDw==,type:str]
oidc: oidc:
secret: ENC[AES256_GCM,data:qjQosi83oaK47wX4VtDktDFlIU3FQgmDpwyiSgJNPDq2Dtc/QEKzdv5/ZpQ=,iv:aUJx5a6Wj7lhaD19aPiZWIE/MWKUgH0muxtTSkwfg8M=,tag:DttjXee7ntxRAbqbFq6qeQ==,type:str] secret: ENC[AES256_GCM,data:qjQosi83oaK47wX4VtDktDFlIU3FQgmDpwyiSgJNPDq2Dtc/QEKzdv5/ZpQ=,iv:aUJx5a6Wj7lhaD19aPiZWIE/MWKUgH0muxtTSkwfg8M=,tag:DttjXee7ntxRAbqbFq6qeQ==,type:str]
hash: ENC[AES256_GCM,data:iVls8UzdP6JTfRosET6nsk3RcEtFQ8ak6GtPuBjcqAv3lyA9oSLwvvC8MvGaT1aHCB+5y/lspuloHEaAcVGNuzGCIVLg9Adut4a7LYDTHNOZnJIKLj8ldL1ytD5XVdbeBhZGCqoTs088oO0HVCQiDzpJL5NdmM3Ru6egyYBCLLUOlPA=,iv:er63GEC+kxNDscvspvvLiq17VSg0GeZ2w3jmGojF9PM=,tag:F1pDpaQrVdomIlZ8psVpAw==,type:str] hash: ENC[AES256_GCM,data:iVls8UzdP6JTfRosET6nsk3RcEtFQ8ak6GtPuBjcqAv3lyA9oSLwvvC8MvGaT1aHCB+5y/lspuloHEaAcVGNuzGCIVLg9Adut4a7LYDTHNOZnJIKLj8ldL1ytD5XVdbeBhZGCqoTs088oO0HVCQiDzpJL5NdmM3Ru6egyYBCLLUOlPA=,iv:er63GEC+kxNDscvspvvLiq17VSg0GeZ2w3jmGojF9PM=,tag:F1pDpaQrVdomIlZ8psVpAw==,type:str]
@@ -200,47 +212,77 @@ gitea:
# #
#ENC[AES256_GCM,data:HvMeGuC8JwK50pO1E/nm,iv:5NFTyjesMX0ZnBpH+hEv8jQ0G2NvrDtT23CUyLbQcUo=,tag:qWmPvQpADTeD+W8nWXRQvA==,type:comment] #ENC[AES256_GCM,data:HvMeGuC8JwK50pO1E/nm,iv:5NFTyjesMX0ZnBpH+hEv8jQ0G2NvrDtT23CUyLbQcUo=,tag:qWmPvQpADTeD+W8nWXRQvA==,type:comment]
immich: immich:
il: admin:
password: ENC[AES256_GCM,data:PbDFc4m7rNPPN1mCjcvhbKwf/EbiJxdvO/iMspf9jMuCqQyGv7h6VrZqk98=,iv:hlMAp5wXXkFO9+ekq3A2/ioF/EX8Uau0puhb4TAHkRQ=,tag:pfS0W2JNaFNMpBlKgZ3Pjw==,type:str] id: ENC[AES256_GCM,data:DclWIxkt7yZl/8EXSWpOKhVR8g==,iv:ekuWHM9tzQEGRj5Dz6txgh5H89dWVRojjICd7td3QSo=,tag:ZSBvlXtGrNn9T82Agn/vtg==,type:str]
password: ENC[AES256_GCM,data:AcaAeRVzeKCp9Hhx202DMuVTOmoPdXrUqpgwg6Nj/F7b9rCnQRwpsGGmuw0=,iv:z/PhfW75B08K+zbxBrEtBKFYWxTdRdgaicSYHe6yyJ0=,tag:8K+9QHjUF6lHhwnNDT9L8A==,type:str]
oidc: oidc:
secret: ENC[AES256_GCM,data:9ENcp2Ns21OLXDY05zRoSdP+93EiwSH8MGzZZpxK7sToe4QLUXWt9w6xQIE=,iv:Q/VcnArZHs/J2YLRVFXt3Mp+LYfuq4PD/trqO8Simig=,tag:BY/mOyZpYmoAc7NrASlmSA==,type:str] secret: ENC[AES256_GCM,data:9ENcp2Ns21OLXDY05zRoSdP+93EiwSH8MGzZZpxK7sToe4QLUXWt9w6xQIE=,iv:Q/VcnArZHs/J2YLRVFXt3Mp+LYfuq4PD/trqO8Simig=,tag:BY/mOyZpYmoAc7NrASlmSA==,type:str]
hash: ENC[AES256_GCM,data:mrML2CWFFtGjq8wfWipVpv+pjJRSHe74VGC7Eoa6588R5C/sCnC3W5aI+dsRCZN3LRCjHAkOJJgjeYrwcXYdKRauXsAYR51dNSsHqqSN3WebLxapRDwcYu5e4j5RN1aPHsysr7GaQ4hhe5rKW4ORCGC3Cp3Ob+LChPy4bdCAZG3bN9k=,iv:Q4hmqhq+dvIr7DxCpcqP4E0NKyFZkOeTnDpGctmCxXM=,tag:/gji6AFkHnYwkQf3FSQUxA==,type:str] hash: ENC[AES256_GCM,data:mrML2CWFFtGjq8wfWipVpv+pjJRSHe74VGC7Eoa6588R5C/sCnC3W5aI+dsRCZN3LRCjHAkOJJgjeYrwcXYdKRauXsAYR51dNSsHqqSN3WebLxapRDwcYu5e4j5RN1aPHsysr7GaQ4hhe5rKW4ORCGC3Cp3Ob+LChPy4bdCAZG3bN9k=,iv:Q4hmqhq+dvIr7DxCpcqP4E0NKyFZkOeTnDpGctmCxXM=,tag:/gji6AFkHnYwkQf3FSQUxA==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment] #ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
# #
# #
#ENC[AES256_GCM,data:bzMt0Ox0Za4dOhoo7S6dYCdK32JI9Q==,iv:PRTryIJk0tR545XY0LoHwklvsJp5+A5bEljNmzUvRhY=,tag:EVsjRUGMOadaNbMu0Xr4XA==,type:comment]
actualbudget:
oidc:
secret: ENC[AES256_GCM,data:TE2umZ9Vvr7cSfA2+TAfRadIWZN3hyOKQ6U9NqJFm5e9iiw1avI+QlnYcKI=,iv:rUWoclBRqh0tsGnMq29395Fn2NP7AXnSCd0s+S8jQ6I=,tag:qPX/TcdIo6BJeex7wmi02Q==,type:str]
hash: ENC[AES256_GCM,data:UjhNkGj+sxbnmPUx1V5kVYwZnzsB0aEvN8YV29lcvMbSnf9xpQWwD5C93Zu8SYrnS/p88qZpGBgAjr9Pcly3y0H1YMRt9zzbHZU3Uo0DPDrSWRQdeB/8LkcM/cwMAs8arS6PO03ECNnN5Z6aTmFdFnLjUkvUuSWMFscItAzMzhWCpeY=,iv:B06LI7Cq3NN8haOLfN3gWIpUFnvdUlq6D2XmARojDpk=,tag:MflE8qcY5j/aAA7xfPCqng==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
#
#
#ENC[AES256_GCM,data:McPUAbIUvtC1gdPaxTgAxAMCMWcLfg==,iv:Tp6idRf7he3sYzo8LW596C905JAaoTIhIoDUzSyRT0k=,tag:4mZQ0Swu1X9uuwjsRNhr2A==,type:comment] #ENC[AES256_GCM,data:McPUAbIUvtC1gdPaxTgAxAMCMWcLfg==,iv:Tp6idRf7he3sYzo8LW596C905JAaoTIhIoDUzSyRT0k=,tag:4mZQ0Swu1X9uuwjsRNhr2A==,type:comment]
paperless: paperless:
session_secret: ENC[AES256_GCM,data:siwCs2noeVpg9DCEZybnmo/oz11BdrHSTnHciMOu/6g=,iv:XVjhu10TIujIdUopN9+TVVqRade9EvItDWxym6YXnZs=,tag:TxLYm+4Bo7IMaTQBtMg9pQ==,type:str] session_secret: ENC[AES256_GCM,data:siwCs2noeVpg9DCEZybnmo/oz11BdrHSTnHciMOu/6g=,iv:XVjhu10TIujIdUopN9+TVVqRade9EvItDWxym6YXnZs=,tag:TxLYm+4Bo7IMaTQBtMg9pQ==,type:str]
il: admin:
password: ENC[AES256_GCM,data:9bJHf+chTg1rppgNVafNgEuvwQ69Gx+w5d65hu68q9XeeaVb2pO9HE4BOgg=,iv:1kaXBg/iOoIZxDjEVEdaMJLDtp6zQjep3vxLmIgQN5o=,tag:+MgX8Oa3tmhjx6u9aHkDfQ==,type:str] id: ENC[AES256_GCM,data:8uo=,iv:f/qtpDb1Xe0M6Gd2VFP2vXULCd7WOn7TCxLlaK1dDbA=,tag:eNRMPJtLlA3Vjj79bSFxuA==,type:str]
password: ENC[AES256_GCM,data:TAA+TRTYRUSw47nE7oPDQmOtCBZpf2WyxUIIzftWq16wQhseODhH0R74X+Q=,iv:V0tzSvW5iYzEUgcxempmyD9ermVAqg673liiysT4jJ4=,tag:GuxtZ7EvgwvlFWwg+C6Jsg==,type:str]
oidc: oidc:
secret: ENC[AES256_GCM,data:wjRDVCJsINM4z5946a6uZD+6bhN5BChLMdRzgMEJFGRGFNcXd7A1p2Iqn4I=,iv:Y4QDA09L8ULKr4hhvoiduzCD8Hifo1gAnpzjCr8e520=,tag:R0RvGxYnXo3zwykXJykRug==,type:str] secret: ENC[AES256_GCM,data:wjRDVCJsINM4z5946a6uZD+6bhN5BChLMdRzgMEJFGRGFNcXd7A1p2Iqn4I=,iv:Y4QDA09L8ULKr4hhvoiduzCD8Hifo1gAnpzjCr8e520=,tag:R0RvGxYnXo3zwykXJykRug==,type:str]
hash: ENC[AES256_GCM,data:pali6WwPNhJA+6QL4O+tKv42PnpGqmojb8JQUZLqxGizv1bJSCgdUN8upCy5Ke0DYZs5P+JY5vh23xfMZFnHduGxGwOuPX6J5lYgvJRV58LqS3/+yIBBprTJyro3MwsurTTEWesgKMr8/2H9lirhaLjWUOSPxAmQ6e4wPNpHycDVyj4=,iv:cg2trI7t1MfIcMo1/M+IY6JEl2msDoKRGgAx/Y5nyGk=,tag:gnOq7sBq9z5zrRY0yhIabg==,type:str] hash: ENC[AES256_GCM,data:pali6WwPNhJA+6QL4O+tKv42PnpGqmojb8JQUZLqxGizv1bJSCgdUN8upCy5Ke0DYZs5P+JY5vh23xfMZFnHduGxGwOuPX6J5lYgvJRV58LqS3/+yIBBprTJyro3MwsurTTEWesgKMr8/2H9lirhaLjWUOSPxAmQ6e4wPNpHycDVyj4=,iv:cg2trI7t1MfIcMo1/M+IY6JEl2msDoKRGgAx/Y5nyGk=,tag:gnOq7sBq9z5zrRY0yhIabg==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment] #ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
# #
# #
#ENC[AES256_GCM,data:V7DJHA2JQirfBsrCGhXrhg==,iv:+jYqX9hGNnuyYj9o9LpCYFVOoD6nSrtc4t40Ag0mMzo=,tag:1wSxKtkJm42reUxdwYDvlg==,type:comment] #ENC[AES256_GCM,data:PZS7EbvMHqHGorNUGAWj4dk1,iv:vOE+djRAvBTMM51kHi6kG5Arw3uPXlJt1d/BpcEaD0c=,tag:AuoCHLQz42CYvVVdKFWu1Q==,type:comment]
vikunja: nextcloud:
session_secret: ENC[AES256_GCM,data:CMyw8JGHyTczGsrOJJwQBKfXMU4Sudvwkur1Lgx4o64=,iv:F2VmpqddiDT4jGaGDKGl6FARsQOt3lLz3X6TjC2MIVU=,tag:UJYyzrl/FX1BNwY4ROFncA==,type:str] admin:
il: id: ENC[AES256_GCM,data:uSov7SN1yB1PhTc=,iv:5yxabQcY/XsBhn531xZg3XYsnxl3K59WuN7Vz9M4XG0=,tag:BBnfZPppw+SDGsV8dK2F+Q==,type:str]
password: ENC[AES256_GCM,data:wDYAVUTFyL/CaXQXYviP3WAILmnREwYui8PZq9nXJPNa3FlwX6b/fzxbCvw=,iv:We+jb4W62O8tYRjGPv+lwlhyVF8eIeTiPNoELdLU+6M=,tag:y7vTZ+6TAsv4XajB4JOL7A==,type:str] password: ENC[AES256_GCM,data:j/wFr5EV00WegWxIGj1k3U13sQjf1GgUofGbh9+i916uudfdklhcurujhiY=,iv:aHEKjLvS5lnayRX/NJ98DxQ40mfqssidubDaP2RVb3k=,tag:zQRE9AsiAlXe58r4VFJiaQ==,type:str]
oidc: oidc:
secret: ENC[AES256_GCM,data:QwqndYsfr+fh9OLkHYtLYCa6WUdhnL7A4btz1d1eelTwq3Kps5S6BUN5qZg=,iv:51N8byIAAUh4ky7YBAuEJOBEWu1d9AX5W1m37/cLlCM=,tag:GD7jbxNGd748TCPgqsxyMg==,type:str] secret: ENC[AES256_GCM,data:Sr4KkKkYdkU0UWdpfUF7PyiGoerjBiw+sOFcENyLxw0FRXGG0Y8gv5uGb4Q=,iv:LbGsNM3+iY7bWFQe88TepVKUdiRQWZ+K7Ubn6ze6lV4=,tag:SbcfIAMW9ZprgahOFU4IQQ==,type:str]
hash: ENC[AES256_GCM,data:ORifyT4u1V2CyBCNBgF72wwS2i05mlzA4iIVEa1cH9aaE69PdiQvGGzMHK+tmlfpVaVQEENSt1QDUSSlMyeuZT/3a0JwAvlz+XDbpS7bicL2cB6DCa4JyEd/rbGRXs0/COfxPxXzYv7jq9gd2uSJ+cCGYb/93WuEXSEI6PHi+FF7N94=,iv:FVSGySa4YB2vwenqSagBzxeIexg91ewvcQMix+etmng=,tag:yyQtOgzOZypba+rV3A1K9g==,type:str] hash: ENC[AES256_GCM,data:CkstbIYQmi72QhsbJZN0lQedgCn7TmGpYcYj0n+NvJIoTlol8G9N/88cwGbVoGK9nEISv54FL94cEJFppnMIuj0BHrhasrZsyI2/Lj52YLWdwNJWNQ+iYt+Ifp/1kI0zqmdoajzZ5DS2w/1evCBC1+JdfTRlpVXmSsHUIPIHelBRj90=,iv:vwvT5TTkF4woxXOvrRRqmrdLXf19s47NIDtdT+zLp0U=,tag:KC0MS0DTH6j3zIHOjCFOSA==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
#
#
#ENC[AES256_GCM,data:Fsqc2JDp9dvfgiCjdQ==,iv:3DALKKEXaP8hzXRvxD4CgfFpOiPPsOa16OB94n8WKp8=,tag:K+FF3zGrc0YLXWK/R2L3Ow==,type:comment]
sure:
session_secret: ENC[AES256_GCM,data:InHsz/jld8E9TwI8MWpxk9x2I7dxlIsY9R6jtDK2pBA=,iv:HY5yXEC2Dce26e9/vXTIWELvVd9ZjhcCwFD0jhz5pPw=,tag:LLSJovZ0RH3CUK+se7R4Ag==,type:str]
oidc:
secret: ENC[AES256_GCM,data:9BSvpcU9BJctSN9bkPIAsRxg8JNHTWvOKdpJFhm//CUDm/Xc7oC/ANHf5no=,iv:JVQLl/rp65kZSK/4SpVXxtiac3Z35XNkxWm2+lEdq/c=,tag:WgfaORiNlrO+wHSdnl4CWQ==,type:str]
hash: ENC[AES256_GCM,data:EjJ+1fP7/9wG2jG0Jv2hxMLtErqxjHBstRjru79dd5ZXhqwT7S+jpLfl9WpZU9qi20ps9YP4qe7G08p6NJNXjYhQj852GQxEORRh/9StAZsPt3p8w+ePZSVbivPQH+FpPKWYxoH0VR7y3TnL66R0tKRLh1fNTc5jRy5rU5r1bfs1jZ0=,iv:0y9FxW4QdD7qHz3bPRWlwHFpvOsvlYhVrOItB6BzaE8=,tag:Wc7MZhP3QRYmvZcjpoEWtQ==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
#
#
#ENC[AES256_GCM,data:H6BtfLuevnDCEpHSmf6pxQ==,iv:9Jw0UZwVwS2It7c4e1rAN/BEiqDKp9DHD4W9xdpJ/Vs=,tag:Xj8HKvxgCA260CXBVK2S1A==,type:comment]
outline:
session_secret: ENC[AES256_GCM,data:A26j8/ghGA9MjDiuq+H84iTFXkHZp3l3LbGKO9w+Cgv+u1dkTF5q4zuBnOSBi+Tnz+2Y4jIoxsac+CS0dguRMg==,iv:NzJiJxVxOvud3e4mP8urnHrqugE8SmjFVnZtwfzrUzs=,tag:YR/jexb3G0HfC2qHpn6fPA==,type:str]
utils_secret: ENC[AES256_GCM,data:ACI+NZzqHBsYeb4WwTJ1nfJcy6zNwJn2hBqA93aM5cgNWQ4KtQHDXgmS6UTwmSpxrteiaH25J3Np03H3eQoVeA==,iv:nitwxxwTPQvoQXGLVMnk2zsdC7M+JIXkTY4zJdQ3DFo=,tag:IQewG7EE9IgQk+Rfz7M5Iw==,type:str]
oidc:
secret: ENC[AES256_GCM,data:zR6sN205C51BIiQxLYOwC4ZbTYGr2AveiPeEbdadairmfnNJkGOtm0zT4Gg=,iv:uyYoJYuAuH/Gy2dlLr2SkkLYq+lMdwBgmzUsEj1EAKc=,tag:uhgvE6BagvPPKf7Y3NaGfA==,type:str]
hash: ENC[AES256_GCM,data:xOibOUdmfhvUk6HABHf/MGIaUqRtrmbBpD5eTIrlt+Ll5IxuIaECMIyBufqV6KStoNsAxtlWmPqoVYROnVh7Z50ntywP6w6YNFbihMGr5tYnNBAS2ITViCq0Z7GQpNVmhNkFbmZv4bX14YOI557CS1KeDVrKrHnZ3fPgEgDwEiUdCwo=,iv:3lVQEw/gmTvJ6wteyKhAHAYUUw1AfKku8YEveddJTZU=,tag:0jimA4vof+nKOQtCOrVFdw==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
#
#
#ENC[AES256_GCM,data:Fis0K+QOQwUfHItGI5U=,iv:kRmt4WhV6bBwN7Xl2xLrbxnKuLKTBC5nI9ZnQSIgIwo=,tag:whb1oOEX+fry9GS1+RlPrA==,type:comment]
memos:
oidc:
secret: ENC[AES256_GCM,data:+rX8znej0jjXybmUjoI7DkybNkNeg15Py7bav665Uej48I5ZAZbUiKwccNo=,iv:UzcCqXxvweosRL8afhyRBB2ERm1PNs+tuxeDwL7Mcu8=,tag:+gJWSAq2BpSlSw/iwhIbpA==,type:str]
hash: ENC[AES256_GCM,data:D7+37XTpDFRabT5YEh9nfxO1Q9Sdc98jAxPsjkPzj7bthn1H0dlLYZSJ2Fy8Ye4vjIFO+TZ6HWx8N4cSwHTfgls3EYFh1TW0FUnyCY1kYd/+ljfZB9Y6M+i5zb5nEIBHI32Sk7/B20cGnr0SUb3EKU+SmnACgZ0fjKKyUpSzGu75MH8=,iv:3RkTpgy85JPJqu6AEKrw8RY2O+L/CldPuPpN9ln54u8=,tag:Nl0DL5tVenA/fdRNOGyPkA==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
#
#
#ENC[AES256_GCM,data:ATLTbBi1RsBr2ldHDDH4,iv:RFbPz/46BIGYv9Wo5Jxw5Swi4Xo2JgIEI4IsO4rCQoQ=,tag:i7/2ItQSFurrmdNaBWwWAA==,type:comment]
mealie:
oidc:
secret: ENC[AES256_GCM,data:ldsfwWnexNNM4r+aP2h+woQROwbp9MpxAz8E/o1Q53GxcEwtixqvP6QZGoo=,iv:6M/lfuDU3IOd0nxLi2l02OD5FopErhSCp6AhxBGTI1k=,tag:3w0p+wi9T1PqNmgoM59gug==,type:str]
hash: ENC[AES256_GCM,data:YmziHxsFPJ93uMNG6/EUiPEfMvvAZM8/S5854GJ/fPPTMvXj9cM2sovkSrcNd7H0ac5KDJIcJoD9SC5lWKCAbjKzxHvI6CdI63SM8bExrDL2PVSGAf29VLU/cz8rQtZS39GWz2v5GWlpk67Emy0T115vruIGfDlan8zgQKK7YIWyVMs=,iv:xmnBYjBIWq6P2g5DyMh+wYskmJRcVDREGL/yYhJHyRs=,tag:qMWXHiLmAy5UvWFvv3Ct8g==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment] #ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
# #
# #
#ENC[AES256_GCM,data:T4Wtn49AAxPd2QUFTR+q,iv:bH5goGWBDqumAat9dUv2OwfCUJUpuVqncTMqMBZUXhI=,tag:G+W6hHA+yftQ+4RJpXrxHg==,type:comment] #ENC[AES256_GCM,data:T4Wtn49AAxPd2QUFTR+q,iv:bH5goGWBDqumAat9dUv2OwfCUJUpuVqncTMqMBZUXhI=,tag:G+W6hHA+yftQ+4RJpXrxHg==,type:comment]
switch: switch:
password: ENC[AES256_GCM,data:qu0f9L7A0eFq/UCpaRs=,iv:W8LLOp3MSfd/+EfNEZNf91K8GgI5eUfVPoWTRES2C0Y=,tag:Q5FlAOfwqwJwPvd7k6i+0g==,type:str] admin:
password: ENC[AES256_GCM,data:cwBJRIO3eUgezyN60dU=,iv:Ab+EpURW+MYT7RTcPHi4FvQiv4m6TDhAb1/xexkIHCE=,tag:JEWZ3cqoAfAPfwXz7KmINQ==,type:str]
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment] #ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
# #
# #
@@ -248,8 +290,9 @@ switch:
dsm: dsm:
key: ENC[AES256_GCM,data:jxQRPNuioZbznadJa7sdhbntABsi+nc6Y5TJsyMXwKRvVUbQw8p3snp75d9WVmOfq4uj8wBGen0noa/6xtWo4ZiHsIg1Svh/5xAN37zueB6NmK/z+BW2y8HaIkNhjcinusnT2SWE2ahguizMNM90FpXgmTt9Zv7wVwRkifDLWpH+rs5zmyMWPtpT2RN3+k7tVh8XWVevek/DxG4h+jtoYhTVzndMC5oe/A60MHBJCj6kaksGlX3vIDbRo5A0FEKX8uWI6k6U2osFc4SHIvpljYmPagj3EwPaTc3mbl8IJsXFVH4=,iv:7O5oQa1fELjIt6f3nQ+fWDFirAexgioS36/Nozh656o=,tag:t1RHmY8QC6mE9PVPJg426Q==,type:str] key: ENC[AES256_GCM,data:jxQRPNuioZbznadJa7sdhbntABsi+nc6Y5TJsyMXwKRvVUbQw8p3snp75d9WVmOfq4uj8wBGen0noa/6xtWo4ZiHsIg1Svh/5xAN37zueB6NmK/z+BW2y8HaIkNhjcinusnT2SWE2ahguizMNM90FpXgmTt9Zv7wVwRkifDLWpH+rs5zmyMWPtpT2RN3+k7tVh8XWVevek/DxG4h+jtoYhTVzndMC5oe/A60MHBJCj6kaksGlX3vIDbRo5A0FEKX8uWI6k6U2osFc4SHIvpljYmPagj3EwPaTc3mbl8IJsXFVH4=,iv:7O5oQa1fELjIt6f3nQ+fWDFirAexgioS36/Nozh656o=,tag:t1RHmY8QC6mE9PVPJg426Q==,type:str]
crt: ENC[AES256_GCM,data:N32+8CItiwbW8drpnL65weS35SY8uP8vcw9wBDFOxGFQjs6EyEwsMUVh1ndMpmDSUKWz7c7ji0HisC710RqnZw9l2NMg6R57DeXR/WsLW4LiAT7sFuDBcqorTB+6Nk0K9wLLdnsKpUQgl8oV9ffnWXZdfI5skKCDMNB40WJAYY/3wx9iT3wDQWaunq/1NT0SZHrtXXTj1JYiLbfDaTwTvkuqqUv1cXvOjonL2Cp4aNT/zjwK6c/TRbKdhIs/7tnUUE/lJx74eARfrMQy/3y6h2xK9pgruASuJxMw9Tyaj6Ya0FMNMIezO3GPQbFCE/IRfmCE6vX2RXUjVqX8wd/d4m4KNuMsN3hbwC3vQ6r+DcYdaTUfGIu96xfKSiSax/ZPQ4JhTyqthkGgpE0Ob67aVELrZkyhc/kvvSxafVSvP63C/nHPQnXMgitdRddYFq7487Vbq03frxiyID1WkqeUavc+Tn3dyA8c7aqVvbW6vZCAwUzbKD0nwPuBUtKZQpJKxHvtx2390PW7a214zkPLcw5LH3FnNacopiNfs6dNEeW/UsGysYkoBRXfrAPMX4UL53TvUTrpuCBhthJ4rgqjhgTfq9GtomP7piuf/tnMAO33qSHPM3w2ocLWeLyOiqYESFmXoBAsiu33LVzuVryFVw75pgrGAsc2wwKhcu4JC0cNgUE44ENIIjffVQX/mcvPvHxuI05vtzM0N8kOFPwG7iAVrO1eUEpwUjZwUwkk8QRsuIhZ6W7aYx7TLdPDpjmy6XCYGNHZgHg6jU7v18KkPep1YarAnsVYFzHQwfZIMOzW7DHlHq38NJW8lWq7zkg+kY6JDVy0nttlAUSskWNeCHdI5Xy3Rz3t7V6t1+UxkSy3roQCZOYjiaknwrXSctsgqucKaJCq4w0Tty36kaIXwOQYVm9JqDIztOmer4fW8Es7OEbLwA==,iv:26fGb288JEbtA0UcAmiYcN+UunrUOw2S6fKjGMetgwE=,tag:GmUJb9LJ186HNOF4AhfmLg==,type:str] crt: ENC[AES256_GCM,data:N32+8CItiwbW8drpnL65weS35SY8uP8vcw9wBDFOxGFQjs6EyEwsMUVh1ndMpmDSUKWz7c7ji0HisC710RqnZw9l2NMg6R57DeXR/WsLW4LiAT7sFuDBcqorTB+6Nk0K9wLLdnsKpUQgl8oV9ffnWXZdfI5skKCDMNB40WJAYY/3wx9iT3wDQWaunq/1NT0SZHrtXXTj1JYiLbfDaTwTvkuqqUv1cXvOjonL2Cp4aNT/zjwK6c/TRbKdhIs/7tnUUE/lJx74eARfrMQy/3y6h2xK9pgruASuJxMw9Tyaj6Ya0FMNMIezO3GPQbFCE/IRfmCE6vX2RXUjVqX8wd/d4m4KNuMsN3hbwC3vQ6r+DcYdaTUfGIu96xfKSiSax/ZPQ4JhTyqthkGgpE0Ob67aVELrZkyhc/kvvSxafVSvP63C/nHPQnXMgitdRddYFq7487Vbq03frxiyID1WkqeUavc+Tn3dyA8c7aqVvbW6vZCAwUzbKD0nwPuBUtKZQpJKxHvtx2390PW7a214zkPLcw5LH3FnNacopiNfs6dNEeW/UsGysYkoBRXfrAPMX4UL53TvUTrpuCBhthJ4rgqjhgTfq9GtomP7piuf/tnMAO33qSHPM3w2ocLWeLyOiqYESFmXoBAsiu33LVzuVryFVw75pgrGAsc2wwKhcu4JC0cNgUE44ENIIjffVQX/mcvPvHxuI05vtzM0N8kOFPwG7iAVrO1eUEpwUjZwUwkk8QRsuIhZ6W7aYx7TLdPDpjmy6XCYGNHZgHg6jU7v18KkPep1YarAnsVYFzHQwfZIMOzW7DHlHq38NJW8lWq7zkg+kY6JDVy0nttlAUSskWNeCHdI5Xy3Rz3t7V6t1+UxkSy3roQCZOYjiaknwrXSctsgqucKaJCq4w0Tty36kaIXwOQYVm9JqDIztOmer4fW8Es7OEbLwA==,iv:26fGb288JEbtA0UcAmiYcN+UunrUOw2S6fKjGMetgwE=,tag:GmUJb9LJ186HNOF4AhfmLg==,type:str]
il: admin:
password: ENC[AES256_GCM,data:6LiNif7aIGgGBBdVYpl4K8L8ev6EPru5x6HvX2yJ0oiDQb6G9AI+ZsaKamc=,iv:Y+eijt1PmNZR9c9uCzBnzJT9BDc3w/P4VzsbvrPRU64=,tag:2KKRtTSYzrJKy9VX/2J5eQ==,type:str] id: ENC[AES256_GCM,data:/Js=,iv:GyEcag6KxEHy6xApfzEo+dZF9NOtkOoYaJZEzPa8ing=,tag:W/4zaDxdw42Ap4DVE9ogAQ==,type:str]
password: ENC[AES256_GCM,data:/rgn1Eogw3F2EqArMJXL8Ri4y1W04hGzxy4w1Ct5/ysBjjHGgRbxd9tXSf0=,iv:PISJ0a113rlEL0z0yo+nBYNQNU6Ht0PgFWZzooxIgi0=,tag:UZl0EiVcaVPq1v0MtNCXFQ==,type:str]
oidc: oidc:
secret: ENC[AES256_GCM,data:IXJNy9PmMPn9uowSMMrNPYqaW5PZ13JTeu1t7eNlapxmnV3EAl3I3xbMK5A=,iv:UcG2E6zgoKkPfUiHr0A+gvnApCkBJG2GROfacwD634Q=,tag:nSFn9yaCadJGlGy/aCvc2A==,type:str] secret: ENC[AES256_GCM,data:IXJNy9PmMPn9uowSMMrNPYqaW5PZ13JTeu1t7eNlapxmnV3EAl3I3xbMK5A=,iv:UcG2E6zgoKkPfUiHr0A+gvnApCkBJG2GROfacwD634Q=,tag:nSFn9yaCadJGlGy/aCvc2A==,type:str]
hash: ENC[AES256_GCM,data:Y2/FNYbID0trRS5UpP2MX6UcLWxlRoXu9VLeU9DU9whEwNLbf4gYrxI7Q7etQe6HidBuoIJNxKajf3t0fI0ptbXnJaxzMh/v/CsiDg2p568o3KIyfB1PruGRKUrTuJneREUHg5jRXMYCwcRUQ4C5WgAyjd2spGlTQO0OLEqh0wkTtvs=,iv:YTYoaBy3QwlSrmx/K5woiXAHrh0RkawF+uQ4rQuP7WU=,tag:Ej6ZjTFvKjw6BrXbd0lf0g==,type:str] hash: ENC[AES256_GCM,data:Y2/FNYbID0trRS5UpP2MX6UcLWxlRoXu9VLeU9DU9whEwNLbf4gYrxI7Q7etQe6HidBuoIJNxKajf3t0fI0ptbXnJaxzMh/v/CsiDg2p568o3KIyfB1PruGRKUrTuJneREUHg5jRXMYCwcRUQ4C5WgAyjd2spGlTQO0OLEqh0wkTtvs=,iv:YTYoaBy3QwlSrmx/K5woiXAHrh0RkawF+uQ4rQuP7WU=,tag:Ej6ZjTFvKjw6BrXbd0lf0g==,type:str]
@@ -258,8 +301,7 @@ dsm:
# #
sops: sops:
age: age:
- recipient: age120wuwcmsm845ztsvsz46pswj5je53uc2n35vadklrfqudu6cxuusxetk7y - enc: |
enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0TVVta2V6UHB4V3NmV0tR YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0TVVta2V6UHB4V3NmV0tR
V0hmbUw1bUpSSk4zQXZ4MHlaVzdJU0VSWm1VCnZaMUg1cjJyOEFyOWxPNm9lWkVm V0hmbUw1bUpSSk4zQXZ4MHlaVzdJU0VSWm1VCnZaMUg1cjJyOEFyOWxPNm9lWkVm
@@ -267,7 +309,8 @@ sops:
UmliaFNxVTBqRkI1QWJpWGpTRWxETW8KEY/8AfU73UOzCGhny1cNnd5dCNv7bHXt UmliaFNxVTBqRkI1QWJpWGpTRWxETW8KEY/8AfU73UOzCGhny1cNnd5dCNv7bHXt
k+uyWPPi+enFkVaceSwMFrA66uaWWrwAj11sXEB7yzvGFPrnAGezjQ== k+uyWPPi+enFkVaceSwMFrA66uaWWrwAj11sXEB7yzvGFPrnAGezjQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2026-03-28T01:12:44Z" recipient: age120wuwcmsm845ztsvsz46pswj5je53uc2n35vadklrfqudu6cxuusxetk7y
mac: ENC[AES256_GCM,data:hGvVNYQ2qUf9zGMbY5lupY9NI4rCnbza7OruAho12UTcTpD9vktWj559U/UoZpKDknR9n+d50UOGcukeFgLtPBo6xy0+Yf0FRCZU59SQ9k02f3wyIck5ANikBImeN6gGKUbiuIcQUqD3jWH1b2u6V02KN8UkKs7CywHKhI2IoKg=,iv:orXjewDUalAxGOdMjXs18Al98MLzYHTyaWnCz0VqRU4=,tag:hZ5aV3E2kB0US4zAk66Z2Q==,type:str] lastmodified: "2026-06-12T13:44:23Z"
mac: ENC[AES256_GCM,data:FMOY7qMDSCzvOUL44zmwLwUVAXfYkat1JbiNeBVQFuUrC4lAwuukxW9MCPs5plj84LOAUMVgMofyudFJh5VKTR6Y0EnB5ft0NnbGgwMwzQnQn7d9Mcg9xPca3ccSbSGNx0UrC+8lTjXuzhoawMQ5ZXZ3ZK0k7JrFQ2El7UUwxEA=,iv:+oj0bvsDo8gidUn6m0FOeWsJOxIXPHhzvtiIbQ1VgcY=,tag:8xLcthizKqWjqg2eQvJlRA==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.12.1 version: 3.13.1
@@ -0,0 +1,25 @@
[Quadlet]
DefaultDependencies=false
[Unit]
Description=Collabora Online
[Container]
Image=docker.io/collabora/code:{{ version['containers']['collabora'] }}
ContainerName=collabora
HostName=collabora
PublishPort={{ services['collabora']['ports']['http'] }}:9980/tcp
Environment="TZ={{ timezone }}"
Environment="aliasgroup1=https://{{ services['nextcloud']['domain']['public'] }}.{{ domain['public'] }}"
# Environment="aliasgroup2=other_server_FQDN"
Environment="extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:server_name={{ services['collabora']['domain']['public'] }}.{{ domain['public'] }} --o:admin_console.enable=false"
[Service]
Restart=always
RestartSec=10s
TimeoutStopSec=120
[Install]
WantedBy=default.target
@@ -13,28 +13,28 @@ Image=docker.io/gitea/gitea:{{ version['containers']['gitea'] }}
ContainerName=gitea ContainerName=gitea
HostName=gitea HostName=gitea
PublishPort=3000:3000/tcp PublishPort={{ services['gitea']['ports']['http'] }}:3000/tcp
Volume=%h/data/containers/gitea:/data:rw Volume=%h/data/containers/gitea:/data:rw
Volume=%h/containers/gitea/ssl:/etc/ssl/gitea:ro Volume=%h/containers/gitea/ssl:/etc/ssl/gitea:ro
# General # General
Environment="TZ=Asia/Seoul" Environment="TZ={{ timezone }}"
Environment="GITEA__server__DISABLE_SSH=true" Environment="GITEA__server__DISABLE_SSH=true"
# Database # Database
Environment="GITEA__database__DB_TYPE=postgres" Environment="GITEA__database__DB_TYPE=postgres"
Environment="GITEA__database__HOST={{ infra_uri['postgresql']['domain'] }}:{{ infra_uri['postgresql']['ports']['tcp'] }}" Environment="GITEA__database__HOST={{ services['postgresql']['domain'] }}.{{ domain['internal'] }}:{{ services['postgresql']['ports']['tcp'] }}"
Environment="GITEA__database__NAME=gitea_db" Environment="GITEA__database__NAME=gitea_db"
Environment="GITEA__database__USER=gitea" Environment="GITEA__database__USER=gitea"
Secret=GITEA__database__PASSWD,type=env Secret=GITEA__database__PASSWD,type=env
Environment="GITEA__database__SSL_MODE=verify-full" Environment="GITEA__database__SSL_MODE=verify-full"
Environment="PGSSLROOTCERT=/etc/ssl/gitea/ilnmors_root_ca.crt" Environment="PGSSLROOTCERT=/etc/ssl/gitea/{{ root_cert_filename }}"
# OAuth2 client # OAuth2 client
Environment="GITEA__oauth2_client__ACCOUNT_LINKING=auto" Environment="GITEA__oauth2_client__ACCOUNT_LINKING=auto"
# OIDC configuration # OIDC configuration
Environment="GITEA__openid__ENABLE_OPENID_SIGNIN=false" Environment="GITEA__openid__ENABLE_OPENID_SIGNIN=false"
Environment="GITEA__openid__ENABLE_OPENID_SIGNUP=true" Environment="GITEA__openid__ENABLE_OPENID_SIGNUP=true"
Environment="GITEA__openid__WHITELISTED_URIS=authelia.ilnmors.com" Environment="GITEA__openid__WHITELISTED_URIS={{ services['authelia']['domain'] }}.{{ domain['public'] }}"
# automatic create user via authelia # automatic create user via authelia
Environment="GITEA__service__DISABLE_REGISTRATION=false" Environment="GITEA__service__DISABLE_REGISTRATION=false"
Environment="GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION=true" Environment="GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION=true"
@@ -42,7 +42,7 @@ Environment="GITEA__service__SHOW_REGISTRATION_BUTTON=false"
[Service] [Service]
ExecStartPre=/usr/bin/nc -zv {{ infra_uri['postgresql']['domain'] }} {{ infra_uri['postgresql']['ports']['tcp'] }} ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
Restart=always Restart=always
RestartSec=10s RestartSec=10s
TimeoutStopSec=120 TimeoutStopSec=120
@@ -13,7 +13,7 @@ Image=ghcr.io/immich-app/immich-machine-learning:{{ version['containers']['immic
ContainerName=immich-ml ContainerName=immich-ml
HostName=immich-ml HostName=immich-ml
PublishPort=3003:3003 PublishPort={{ services['immich-ml']['ports']['http'] }}:3003
# iGPU access for OpenVINO # iGPU access for OpenVINO
AddDevice=/dev/dri:/dev/dri AddDevice=/dev/dri:/dev/dri
@@ -21,7 +21,7 @@ PodmanArgs=--group-add keep-groups
Volume=%h/containers/immich/ml/cache:/cache:rw Volume=%h/containers/immich/ml/cache:/cache:rw
Environment="TZ=Asia/Seoul" Environment="TZ={{ timezone }}"
[Service] [Service]
Restart=always Restart=always
@@ -13,7 +13,7 @@ Image=ghcr.io/immich-app/immich-server:{{ version['containers']['immich'] }}
ContainerName=immich ContainerName=immich
HostName=immich HostName=immich
PublishPort=2283:2283 PublishPort={{ services['immich']['ports']['http'] }}:2283
# iGPU access # iGPU access
AddDevice=/dev/dri:/dev/dri AddDevice=/dev/dri:/dev/dri
@@ -24,23 +24,27 @@ Volume=%h/data/containers/immich:/data:rw
Volume=%h/containers/immich/ssl:/etc/ssl/immich:ro Volume=%h/containers/immich/ssl:/etc/ssl/immich:ro
# Environment # Environment
Environment="TZ=Asia/Seoul" Environment="TZ={{ timezone }}"
# The new environment from version 2.7.0 to enable CSP
Environment="IMMICH_HELMET_FILE=true"
# Redis
Environment="REDIS_HOSTNAME=host.containers.internal" Environment="REDIS_HOSTNAME=host.containers.internal"
Environment="REDIS_PORT={{ hostvars['app']['redis']['immich'] }}" Environment="REDIS_PORT={{ services['immich']['ports']['redis'] }}"
Environment="REDIS_DBINDEX=0" Environment="REDIS_DBINDEX=0"
# Database # Database
Environment="DB_HOSTNAME={{ infra_uri['postgresql']['domain'] }}" Environment="DB_HOSTNAME={{ services['postgresql']['domain'] }}.{{ domain['internal'] }}"
Environment="DB_PORT={{ infra_uri['postgresql']['ports']['tcp'] }}" Environment="DB_PORT={{ services['postgresql']['ports']['tcp'] }}"
Environment="DB_USERNAME=immich" Environment="DB_USERNAME=immich"
Environment="DB_DATABASE_NAME=immich_db" Environment="DB_DATABASE_NAME=immich_db"
Environment="DB_PASSWORD_FILE=/run/secrets/DB_PASSWORD" Environment="DB_PASSWORD_FILE=/run/secrets/DB_PASSWORD"
Environment="DB_SSL_MODE=verify-full" Environment="DB_SSL_MODE=verify-full"
Environment="NODE_EXTRA_CA_CERTS=/etc/ssl/immich/ilnmors_root_ca.crt" Environment="NODE_EXTRA_CA_CERTS=/etc/ssl/immich/{{ root_cert_filename }}"
Secret=IMMICH_DB_PASSWORD,target=/run/secrets/DB_PASSWORD Secret=IMMICH_DB_PASSWORD,target=/run/secrets/DB_PASSWORD
[Service] [Service]
ExecStartPre=/usr/bin/nc -zv {{ infra_uri['postgresql']['domain'] }} {{ infra_uri['postgresql']['ports']['tcp'] }} ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
Restart=always Restart=always
RestartSec=10s RestartSec=10s
TimeoutStopSec=120 TimeoutStopSec=120
@@ -0,0 +1,49 @@
[Quadlet]
DefaultDependencies=false
[Unit]
Description=Mealie
[Container]
Image=ghcr.io/mealie-recipes/mealie:{{ version['containers']['mealie'] }}
ContainerName=mealie
HostName=mealie
PublishPort={{ services['mealie']['ports']['http'] }}:9000/tcp
# Volumes
Volume=%h/data/containers/mealie/data:/app/data:rw
Volume=%h/containers/mealie/ssl:/etc/ssl/mealie:ro
# General
Environment="TZ={{ timezone }}"
Environment="BASE_URL=https://{{ services['mealie']['domain']['public'] }}.{{ domain['public'] }}"
Environment="ALLOW_PASSWORD_LOGIN=false"
# Database (PostgreSQL)
Environment="DB_ENGINE=postgres"
Environment="POSTGRES_SERVER={{ services['postgresql']['domain'] }}.{{ domain['internal'] }}"
Environment="POSTGRES_PORT={{ services['postgresql']['ports']['tcp'] }}"
Environment="POSTGRES_USER=mealie"
Environment="POSTGRES_DB=mealie_db"
Environment="PGSSLMODE=verify-full"
Environment="PGSSLROOTCERT=/etc/ssl/mealie/{{ root_cert_filename }}"
Secret=MEALIE_POSTGRES_PASSWORD,type=env,target=POSTGRES_PASSWORD
# OIDC
Environment="OIDC_AUTH_ENABLED=true"
Environment="OIDC_SIGNUP_ENABLED=true"
Environment="OIDC_CONFIGURATION_URL=https://{{ services['authelia']['domain'] }}.{{ domain['public'] }}/.well-known/openid-configuration"
Environment="OIDC_CLIENT_ID=mealie"
Environment="OIDC_AUTO_REDIRECT=false"
Environment="OIDC_ADMIN_GROUP=admins"
Environment="OIDC_USER_GROUP=users"
Secret=MEALIE_OIDC_CLIENT_SECRET,type=env,target=OIDC_CLIENT_SECRET
[Service]
ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
Restart=always
RestartSec=10s
TimeoutStopSec=120
[Install]
WantedBy=default.target
@@ -0,0 +1,34 @@
[Quadlet]
DefaultDependencies=false
[Unit]
Description=Memos
[Container]
Image=docker.io/neosmemo/memos:{{ version['containers']['memos'] }}
ContainerName=memos
HostName=memos
PublishPort={{ services['memos']['ports']['http'] }}:5230/tcp
# Volumes
Volume=%h/data/containers/memos/data:/var/opt/memos:rw
Volume=%h/containers/memos/ssl:/etc/ssl/memos:ro
# General
Environment="TZ={{ timezone }}"
Environment="MEMOS_MODE=prod"
Environment="MEMOS_PORT=5230"
Environment="MEMOS_INSTANCE_URL=https://{{ services['memos']['domain']['public'] }}.{{ domain['public'] }}"
# Database (PostgreSQL)
Environment="MEMOS_DRIVER=postgres"
Secret=MEMOS_DSN,type=env
[Service]
ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
Restart=always
RestartSec=10s
TimeoutStopSec=120
[Install]
WantedBy=default.target
@@ -0,0 +1,5 @@
<?php
$CONFIG = [
// Background jobs mode is auto-detected as 'cron' when nextcloud-cron.timer runs cron.php via CLI. No explicit config required.
'maintenance_window_start' => 18,
];
@@ -0,0 +1,12 @@
<?php
$CONFIG = [
'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => [
'host' => 'host.containers.internal',
'port' => {{ services['nextcloud']['ports']['redis'] }},
'timeout' => 1.5,
'dbindex' => 0,
],
];
@@ -0,0 +1,9 @@
<?php
$CONFIG = [
'trusted_domains' => [
'{{ services['nextcloud']['domain']['public'] }}.{{ domain['public'] }}',
],
'overwritehost' => '{{ services['nextcloud']['domain']['public'] }}.{{ domain['public'] }}',
'overwriteprotocol' => 'https',
'overwrite.cli.url' => 'https://{{ services['nextcloud']['domain']['public'] }}.{{ domain['public'] }}',
];
@@ -0,0 +1,4 @@
<?php
$CONFIG = [
'allow_local_remote_servers' => true,
];
@@ -0,0 +1,9 @@
<?php
$CONFIG = [
'user_oidc' => [
'default_token_endpoint_auth_method' => 'client_secret_post',
'auto_provision' => true,
'soft_auto_provision' => true,
'disable_account_creation' => false,
],
];
@@ -0,0 +1,14 @@
; /usr/local/etc/php/conf.d/opcache-recommended.ini
; OPcache tuning
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=512
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.save_comments=1
opcache.revalidate_freq=60
opcache.fast_shutdown=1
; APCu CLI activate
apc.enable_cli=1
@@ -0,0 +1,6 @@
; /usr/local/etc/php/conf.d/nextcloud-upload.ini
upload_max_filesize=16G
post_max_size=16G
memory_limit=1024M
max_execution_time=3600
max_input_time=3600
@@ -0,0 +1,36 @@
[Quadlet]
DefaultDependencies=false
[Unit]
Description=Nextcloud
[Container]
Image=docker.io/library/nextcloud:{{ version['containers']['nextcloud'] }}
ContainerName=nextcloud
HostName=nextcloud
PublishPort={{ services['nextcloud']['ports']['http'] }}:80
Volume=%h/containers/nextcloud/ssl:/etc/ssl/nextcloud:ro
Volume=%h/containers/nextcloud/ini/opcache.ini:/usr/local/etc/php/conf.d/opcache-recommended.ini:ro
Volume=%h/containers/nextcloud/ini/upload.ini:/usr/local/etc/php/conf.d/upload.ini:ro
Volume=%h/data/containers/nextcloud/html:/var/www/html:rw
# General
Environment="TZ={{ timezone }}"
# PostgreSQL
Environment="PGSSLMODE=verify-full"
Environment="PGSSLROOTCERT=/etc/ssl/nextcloud/{{ root_cert_filename }}"
## libpq in Nextcloud automatically tries to use a client certificate for mTLS. Therefore, when only TLS is required, then disable the option explicitly.
Environment="PGSSLCERTMODE=disable"
# Redis
Environment="REDIS_HOST=host.containers.internal"
Environment="REDIS_HOST_PORT={{ services['nextcloud']['ports']['redis'] }}"
[Service]
Restart=always
RestartSec=10s
TimeoutStopSec=120
[Install]
WantedBy=default.target
@@ -0,0 +1,8 @@
[Unit]
Description=Nextcloud cron.php
Requires=nextcloud.service
After=nextcloud.service
[Service]
Type=oneshot
ExecStart=/usr/bin/podman exec -u www-data nextcloud php -f /var/www/html/cron.php

Some files were not shown because too many files have changed in this diff Show More