From bebcd714afae09700d7c8b211495c0291672135c Mon Sep 17 00:00:00 2001 From: thesabear Date: Sat, 22 Aug 2026 07:44:11 +0300 Subject: [PATCH] Restructure compose mirror: stacks/ grouped by purpose, not by host Replaces rocky-docker-lxc/, caddy-vm/, monitoring-vm/, and automation/ with a single stacks/ tree grouped by function (identity-and-security, platform, media, productivity, dev-tools) - 55 stacks total, every one a real directory in the private repos today. Resolves all outstanding drift: adds Wazuh (previously entirely missing), Firefly III and Postiz (never mirrored), the internal-zone Caddy instance and the Cron Scheduler's separate NocoDB instance (both previously conflated with their counterparts under one shared folder); renames Calibre-Web to calibre-web-automated and splits Kodi-MariaDB into kodi + mariadb-latest to match what the private repos actually run now; drops the decommissioned NetBox stack. Also removes automation/iac/old-content/ and automation/ansible/old-playbooks/ in the same pass - both folders were entirely stale content describing a superseded architecture (GitLab instead of Gitea, HAProxy+mTLS SSO instead of the current Caddy+Authentik setup), now replaced by docs/iac-pipeline.md. --- .../old-playbooks/playbooks/clean-docker.yml | 57 ----- .../ansible/old-playbooks/playbooks/ping.yml | 9 - .../old-playbooks/playbooks/remove_apps.yml | 65 ----- .../old-playbooks/playbooks/remove_repo.yml | 8 - .../playbooks/upgrade-packages.yml | 89 ------- .../automation-vm/NetBox/docker-compose.yaml | 112 --------- .../iac/old-content/Ansible/.vault_pass.txt | 1 - automation/iac/old-content/Ansible/README.md | 3 - .../iac/old-content/Ansible/ansible.cfg | 8 - .../old-content/Ansible/group_vars/all.yml | 2 - .../Ansible/group_vars/all/vault_token.yml | 14 -- .../host_vars/docker-host/host_tags.yml | 31 --- .../host_vars/haproxy-vm/host_tags.yml | 32 --- .../iac/old-content/Ansible/inventory.yml | 14 -- .../Ansible/inventory_initialization.yml | 8 - .../Ansible/playbooks/compliance.yml | 29 --- .../Ansible/playbooks/initialization.yml | 87 ------- .../Ansible/playbooks/provisioning.yml | 29 --- .../iac/old-content/Ansible/requirements.yml | 9 - .../bootstrap_roles/base_users/tasks/main.yml | 15 -- .../disk_resize/tasks/main.yml | 28 --- .../docker_gitlab_setup/defaults/main.yml | 23 -- .../docker_gitlab_setup/handlers/main.yml | 5 - .../docker_gitlab_setup/tasks/main.yml | 75 ------ .../endlessh/defaults/main.yml | 4 - .../bootstrap_roles/endlessh/tasks/main.yml | 67 ----- .../endlessh/templates/endlessh.service.j2 | 20 -- .../endlessh/templates/endlessh_config.j2 | 5 - .../firewall_ssh/defaults/main.yml | 4 - .../firewall_ssh/tasks/main.yml | 69 ------ .../hostname_network/tasks/main.yml | 29 --- .../packages/defaults/main.yml | 10 - .../bootstrap_roles/packages/tasks/main.yml | 32 --- .../portainer_agent/tasks/main.yml | 39 --- .../root_password/defaults/main.yml | 2 - .../root_password/tasks/main.yml | 16 -- .../bootstrap_roles/zsh_custom/tasks/main.yml | 82 ------- .../zsh_custom/templates/zshrc.j2 | 21 -- .../cis_hardening/banners/defaults/main.yml | 11 - .../cis_hardening/banners/tasks/main.yml | 26 -- .../roles/cis_hardening/defaults/main.yml | 6 - .../file_permissions/defaults/main.yml | 16 -- .../file_permissions/tasks/main.yml | 11 - .../filesystem_hardening/defaults/main.yml | 4 - .../filesystem_hardening/tasks/main.yml | 34 --- .../roles/cis_hardening/handlers/main.yml | 17 -- .../kernel_hardening/defaults/main.yml | 7 - .../tasks/blacklist_module.yml | 18 -- .../kernel_hardening/tasks/main.yml | 78 ------ .../password_policy/defaults/main.yml | 9 - .../password_policy/tasks/main.yml | 60 ----- .../service_disable/defaults/main.yml | 10 - .../service_disable/tasks/main.yml | 10 - .../ssh_hardening/defaults/main.yml | 32 --- .../ssh_hardening/tasks/main.yml | 82 ------- .../roles/cis_hardening/tasks/main.yml | 29 --- .../secure_vault/haproxy/defaults/main.yml | 55 ----- .../secure_vault/haproxy/handlers/main.yml | 5 - .../roles/secure_vault/haproxy/tasks/main.yml | 107 -------- .../haproxy/templates/haproxy.cfg.j2 | 86 ------- .../secure_vault/technitium/defaults/main.yml | 28 --- .../secure_vault/technitium/handlers/main.yml | 8 - .../secure_vault/technitium/tasks/main.yml | 125 ---------- .../templates/technitium.service.j2 | 16 -- .../secure_vault/technitium/vars/main.yml | 4 - .../vault_agent/defaults/main.yml | 41 ---- .../vault_agent/files/generic_ca.ctmpl | 3 - .../vault_agent/files/generic_cert.ctmpl | 7 - .../vault_agent/files/haproxy.pem.ctmpl | 6 - .../vault_agent/files/haproxy_ca.ctmpl | 3 - .../vault_agent/files/technitium_ca.ctmpl | 3 - .../vault_agent/files/technitium_cert.ctmpl | 3 - .../vault_agent/files/technitium_key.ctmpl | 3 - .../vault_agent/files/thesabear-client.ctmpl | 6 - .../vault_agent/handlers/main.yml | 3 - .../secure_vault/vault_agent/tasks/main.yml | 230 ------------------ .../templates/vault-agent-config.hcl.j2 | 30 --- .../templates/vault-agent.service.j2 | 13 - .../old-content/Ansible/roles_metadata.yml | 123 ---------- automation/iac/old-content/Packer/README.md | 20 -- .../rocky10-proxmox-template/.vault_pass.txt | 1 - .../rocky10-proxmox-template/http/ks.cfg | 82 ------- .../rocky10-proxmox-template/packer.pkr.hcl | 105 -------- .../scripts/setup-admin-user.sh | 108 -------- .../scripts/setup-ansible-user.sh | 33 --- .../secure-packer-build.sh | 27 -- .../terraform.pkrvar.hcl | 27 -- .../variables.pkr.hcl | 15 -- automation/iac/old-content/README.md | 176 -------------- automation/iac/old-content/SSO/README.md | 7 - .../iac/old-content/Terraform/README.md | 3 - .../old-content/Terraform/host_tags.yml.tpl | 20 -- automation/iac/old-content/Terraform/main.tf | 108 -------- .../iac/old-content/Terraform/providers.tf | 16 -- .../old-content/Terraform/terraform.tfvars | 78 ------ .../iac/old-content/Terraform/variables.tf | 32 --- caddy-vm/Caddy/Caddyfile | 68 ------ caddy-vm/Hawser/docker-compose.yaml | 19 -- monitoring-vm/Hawser/docker-compose.yaml | 19 -- .../Kodi-MariaDB/docker-compose.yaml | 32 --- .../cloudcommander}/docker-compose.yaml | 0 .../dev-tools/it-tools}/docker-compose.yaml | 0 .../dev-tools/ollama}/docker-compose.yaml | 0 .../authentik}/docker-compose.yaml | 0 .../vaultwarden}/docker-compose.yaml | 0 .../wazuh/docker-compose.yaml | 106 ++++++++ .../media/audiobookshelf}/docker-compose.yaml | 0 .../media/bazarr}/docker-compose.yaml | 0 .../media/beets}/docker-compose.yaml | 0 .../docker-compose.yaml | 6 +- .../media/calibre}/docker-compose.yaml | 0 .../media/emby}/docker-compose.yaml | 0 .../media/immich}/docker-compose.yaml | 0 .../media/jellyfin}/docker-compose.yaml | 0 stacks/media/kodi/docker-compose.yaml | 56 +++++ .../media/lidarr}/docker-compose.yaml | 0 .../music-assistant}/docker-compose.yaml | 0 .../media/prowlarr}/docker-compose.yaml | 0 .../media/qbittorrent}/docker-compose.yaml | 0 .../media/radarr}/docker-compose.yaml | 0 .../media/seerr}/docker-compose.yaml | 0 .../media/sonarr}/docker-compose.yaml | 0 .../media/tdarr}/docker-compose.yaml | 0 .../tinymediamanager}/docker-compose.yaml | 0 .../caddy-internal/docker-compose.yaml | 19 ++ .../platform/caddy}/docker-compose.yaml | 0 .../platform/dashy}/docker-compose.yaml | 0 .../docker-compose.yaml | 9 + .../docker-socket-proxy}/docker-compose.yaml | 0 .../platform/dockhand}/docker-compose.yaml | 0 .../platform/gitea}/docker-compose.yaml | 0 .../grafana-stack}/docker-compose.yaml | 0 .../platform/hawser}/docker-compose.yaml | 0 .../platform/kestra}/docker-compose.yaml | 0 .../platform/kopia}/docker-compose.yaml | 0 .../mariadb-latest/docker-compose.yaml | 16 ++ .../platform/mosquitto}/docker-compose.yaml | 0 stacks/platform/mysql-8/docker-compose.yaml | 15 ++ .../platform/nocodb}/docker-compose.yaml | 0 .../platform/node-red}/docker-compose.yaml | 0 .../postgres-18-alpine/docker-compose.yaml | 17 ++ .../speedtest-tracker}/docker-compose.yaml | 0 .../valkey-9.0-alpine/docker-compose.yaml | 11 + .../productivity/actual}/docker-compose.yaml | 0 .../bookstack}/docker-compose.yaml | 0 .../firefly-iii/docker-compose.yaml | 49 ++++ .../productivity/ghost}/docker-compose.yaml | 0 .../home-assistant}/docker-compose.yaml | 0 .../productivity/joplin}/docker-compose.yaml | 0 .../productivity/n8n}/docker-compose.yaml | 0 .../nextcloud}/docker-compose.yaml | 0 .../nocodb-content/docker-compose.yaml | 41 ++++ .../paperless-ngx}/docker-compose.yaml | 0 .../productivity/postiz/docker-compose.yaml | 157 ++++++++++++ .../productivity/trilium}/docker-compose.yaml | 0 155 files changed, 500 insertions(+), 3519 deletions(-) delete mode 100644 automation/ansible/old-playbooks/playbooks/clean-docker.yml delete mode 100644 automation/ansible/old-playbooks/playbooks/ping.yml delete mode 100644 automation/ansible/old-playbooks/playbooks/remove_apps.yml delete mode 100644 automation/ansible/old-playbooks/playbooks/remove_repo.yml delete mode 100644 automation/ansible/old-playbooks/playbooks/upgrade-packages.yml delete mode 100644 automation/automation-vm/NetBox/docker-compose.yaml delete mode 100644 automation/iac/old-content/Ansible/.vault_pass.txt delete mode 100644 automation/iac/old-content/Ansible/README.md delete mode 100644 automation/iac/old-content/Ansible/ansible.cfg delete mode 100644 automation/iac/old-content/Ansible/group_vars/all.yml delete mode 100644 automation/iac/old-content/Ansible/group_vars/all/vault_token.yml delete mode 100755 automation/iac/old-content/Ansible/host_vars/docker-host/host_tags.yml delete mode 100755 automation/iac/old-content/Ansible/host_vars/haproxy-vm/host_tags.yml delete mode 100644 automation/iac/old-content/Ansible/inventory.yml delete mode 100644 automation/iac/old-content/Ansible/inventory_initialization.yml delete mode 100644 automation/iac/old-content/Ansible/playbooks/compliance.yml delete mode 100644 automation/iac/old-content/Ansible/playbooks/initialization.yml delete mode 100644 automation/iac/old-content/Ansible/playbooks/provisioning.yml delete mode 100644 automation/iac/old-content/Ansible/requirements.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/base_users/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/disk_resize/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/handlers/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/templates/endlessh.service.j2 delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/templates/endlessh_config.j2 delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/firewall_ssh/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/firewall_ssh/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/hostname_network/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/packages/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/packages/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/portainer_agent/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/root_password/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/root_password/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/zsh_custom/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/bootstrap_roles/zsh_custom/templates/zshrc.j2 delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/banners/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/banners/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/file_permissions/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/file_permissions/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/filesystem_hardening/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/filesystem_hardening/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/handlers/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/tasks/blacklist_module.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/password_policy/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/password_policy/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/service_disable/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/service_disable/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/ssh_hardening/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/ssh_hardening/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/cis_hardening/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/haproxy/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/haproxy/handlers/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/haproxy/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/haproxy/templates/haproxy.cfg.j2 delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/technitium/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/technitium/handlers/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/technitium/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/technitium/templates/technitium.service.j2 delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/technitium/vars/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/defaults/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/generic_ca.ctmpl delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/generic_cert.ctmpl delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/haproxy.pem.ctmpl delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/haproxy_ca.ctmpl delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_ca.ctmpl delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_cert.ctmpl delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_key.ctmpl delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/thesabear-client.ctmpl delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/handlers/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/tasks/main.yml delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/templates/vault-agent-config.hcl.j2 delete mode 100644 automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/templates/vault-agent.service.j2 delete mode 100644 automation/iac/old-content/Ansible/roles_metadata.yml delete mode 100644 automation/iac/old-content/Packer/README.md delete mode 100644 automation/iac/old-content/Packer/rocky10-proxmox-template/.vault_pass.txt delete mode 100644 automation/iac/old-content/Packer/rocky10-proxmox-template/http/ks.cfg delete mode 100644 automation/iac/old-content/Packer/rocky10-proxmox-template/packer.pkr.hcl delete mode 100755 automation/iac/old-content/Packer/rocky10-proxmox-template/scripts/setup-admin-user.sh delete mode 100644 automation/iac/old-content/Packer/rocky10-proxmox-template/scripts/setup-ansible-user.sh delete mode 100755 automation/iac/old-content/Packer/rocky10-proxmox-template/secure-packer-build.sh delete mode 100644 automation/iac/old-content/Packer/rocky10-proxmox-template/terraform.pkrvar.hcl delete mode 100644 automation/iac/old-content/Packer/rocky10-proxmox-template/variables.pkr.hcl delete mode 100644 automation/iac/old-content/README.md delete mode 100644 automation/iac/old-content/SSO/README.md delete mode 100644 automation/iac/old-content/Terraform/README.md delete mode 100644 automation/iac/old-content/Terraform/host_tags.yml.tpl delete mode 100644 automation/iac/old-content/Terraform/main.tf delete mode 100644 automation/iac/old-content/Terraform/providers.tf delete mode 100644 automation/iac/old-content/Terraform/terraform.tfvars delete mode 100644 automation/iac/old-content/Terraform/variables.tf delete mode 100644 caddy-vm/Caddy/Caddyfile delete mode 100644 caddy-vm/Hawser/docker-compose.yaml delete mode 100644 monitoring-vm/Hawser/docker-compose.yaml delete mode 100644 rocky-docker-lxc/Kodi-MariaDB/docker-compose.yaml rename {rocky-docker-lxc/CloudCommander => stacks/dev-tools/cloudcommander}/docker-compose.yaml (100%) rename {rocky-docker-lxc/IT-Tools => stacks/dev-tools/it-tools}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Ollama => stacks/dev-tools/ollama}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Authentik => stacks/identity-and-security/authentik}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Vaultwarden => stacks/identity-and-security/vaultwarden}/docker-compose.yaml (100%) create mode 100644 stacks/identity-and-security/wazuh/docker-compose.yaml rename {rocky-docker-lxc/Audiobookshelf => stacks/media/audiobookshelf}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Bazarr => stacks/media/bazarr}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Beets => stacks/media/beets}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Calibre-Web => stacks/media/calibre-web-automated}/docker-compose.yaml (72%) rename {rocky-docker-lxc/Calibre => stacks/media/calibre}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Emby => stacks/media/emby}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Immich => stacks/media/immich}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Jellyfin => stacks/media/jellyfin}/docker-compose.yaml (100%) create mode 100644 stacks/media/kodi/docker-compose.yaml rename {rocky-docker-lxc/Lidarr => stacks/media/lidarr}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Music-Assistant => stacks/media/music-assistant}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Prowlarr => stacks/media/prowlarr}/docker-compose.yaml (100%) rename {rocky-docker-lxc/qBittorrent => stacks/media/qbittorrent}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Radarr => stacks/media/radarr}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Seerr => stacks/media/seerr}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Sonarr => stacks/media/sonarr}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Tdarr => stacks/media/tdarr}/docker-compose.yaml (100%) rename {rocky-docker-lxc/TinyMediaManager => stacks/media/tinymediamanager}/docker-compose.yaml (100%) create mode 100644 stacks/platform/caddy-internal/docker-compose.yaml rename {caddy-vm/Caddy => stacks/platform/caddy}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Dashy => stacks/platform/dashy}/docker-compose.yaml (100%) create mode 100644 stacks/platform/docker-socket-proxy-mirror/docker-compose.yaml rename {rocky-docker-lxc/Docker-Socket-Proxy => stacks/platform/docker-socket-proxy}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Dockhand => stacks/platform/dockhand}/docker-compose.yaml (100%) rename {automation/automation-vm/Gitea => stacks/platform/gitea}/docker-compose.yaml (100%) rename {monitoring-vm/Grafana-Stack => stacks/platform/grafana-stack}/docker-compose.yaml (100%) rename {automation/automation-vm/Hawser => stacks/platform/hawser}/docker-compose.yaml (100%) rename {automation/automation-vm/Kestra => stacks/platform/kestra}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Kopia => stacks/platform/kopia}/docker-compose.yaml (100%) create mode 100644 stacks/platform/mariadb-latest/docker-compose.yaml rename {automation/automation-vm/Mosquitto => stacks/platform/mosquitto}/docker-compose.yaml (100%) create mode 100644 stacks/platform/mysql-8/docker-compose.yaml rename {rocky-docker-lxc/NocoDB => stacks/platform/nocodb}/docker-compose.yaml (100%) rename {automation/automation-vm/Node-RED => stacks/platform/node-red}/docker-compose.yaml (100%) create mode 100644 stacks/platform/postgres-18-alpine/docker-compose.yaml rename {rocky-docker-lxc/Speedtest-Tracker => stacks/platform/speedtest-tracker}/docker-compose.yaml (100%) create mode 100644 stacks/platform/valkey-9.0-alpine/docker-compose.yaml rename {rocky-docker-lxc/Actual => stacks/productivity/actual}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Bookstack => stacks/productivity/bookstack}/docker-compose.yaml (100%) create mode 100644 stacks/productivity/firefly-iii/docker-compose.yaml rename {rocky-docker-lxc/Ghost => stacks/productivity/ghost}/docker-compose.yaml (100%) rename {automation/automation-vm/Home-Assistant => stacks/productivity/home-assistant}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Joplin => stacks/productivity/joplin}/docker-compose.yaml (100%) rename {automation/automation-vm/N8n => stacks/productivity/n8n}/docker-compose.yaml (100%) rename {rocky-docker-lxc/Nextcloud => stacks/productivity/nextcloud}/docker-compose.yaml (100%) create mode 100644 stacks/productivity/nocodb-content/docker-compose.yaml rename {rocky-docker-lxc/Paperless-NGX => stacks/productivity/paperless-ngx}/docker-compose.yaml (100%) create mode 100644 stacks/productivity/postiz/docker-compose.yaml rename {rocky-docker-lxc/Trilium => stacks/productivity/trilium}/docker-compose.yaml (100%) diff --git a/automation/ansible/old-playbooks/playbooks/clean-docker.yml b/automation/ansible/old-playbooks/playbooks/clean-docker.yml deleted file mode 100644 index 26b074b..0000000 --- a/automation/ansible/old-playbooks/playbooks/clean-docker.yml +++ /dev/null @@ -1,57 +0,0 @@ ---- -- hosts: Docker - become: true - become_method: sudo - become_user: root - vars: - GOTIFY_IP: xxx #[Your gotify host IP goes here] - GOTIFY_PORT: xxx #[Your gotify port goes here] - GOTIFY_TOKEN: xxx #[Your app token goes here] - ansible_python_interpreter: /usr/bin/python3 - - tasks: - - - name: prune non-dangling images - community.docker.docker_prune: - containers: false - images: true - images_filters: - dangling: false - networks: false - volumes: false - builder_cache: false - - - name: Check if reboot is required - stat: - path: /var/run/reboot-required - register: reboot_required_file - - - name: Show Output of required reboots - debug: msg="{{ reboot_required_file.stat.exists == true }}" - - - name: Rebooting machine - shell: sleep 2 && shutdown -r now "Ansible updates triggered" - async: 1 - poll: 0 - ignore_errors: true - when: reboot_required_file.stat.exists - - - name: Waiting for the machine to come back - local_action: wait_for host={{ ansible_host }} state=started port=22 delay=30 - become: false - when: reboot_required_file.stat.exists - - - name: notify via Gotify - uri: - url: 'http://{{ GOTIFY_IP }}:{{ GOTIFY_PORT }}/message?token={{ GOTIFY_TOKEN }}' - method: POST - body: - title: - content: clean docker hosts - message: - content: The clean docker playbook has completed for {{ ansible_host }} and is now updated. A required reboot is {{ reboot_required_file.stat.exists == true }}. - priority: - content: '5' - body_format: form-multipart - register: result -... \ No newline at end of file diff --git a/automation/ansible/old-playbooks/playbooks/ping.yml b/automation/ansible/old-playbooks/playbooks/ping.yml deleted file mode 100644 index 24c3ec3..0000000 --- a/automation/ansible/old-playbooks/playbooks/ping.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: ping test - hosts: all - become: true - vars: - ansible_python_interpreter: /usr/bin/python3 - tasks: - - name: test ping - ansible.builtin.ping: \ No newline at end of file diff --git a/automation/ansible/old-playbooks/playbooks/remove_apps.yml b/automation/ansible/old-playbooks/playbooks/remove_apps.yml deleted file mode 100644 index 67ebe8c..0000000 --- a/automation/ansible/old-playbooks/playbooks/remove_apps.yml +++ /dev/null @@ -1,65 +0,0 @@ -### This is just a sample showing the way of removing apps from a VM using Ansible ---- -- hosts: all - become: yes - vars: - GOTIFY_IP: xxx #[Your gotify host IP goes here] - GOTIFY_PORT: xxx #[Your gotify port goes here] - GOTIFY_TOKEN: xxx #[Your app token goes here] - - tasks: - - - name: Ansible apt remove crowdsec - apt: - name: crowdsec - state: absent - - - name: Ansible apt remove zabbix - apt: - name: zabbix - state: absent - - - name: Ansible apt remove zabbix-agent - apt: - name: zabbix-agent - state: absent - - - name: Remove dependencies that are no longer required and purge their configuration files - ansible.builtin.apt: - autoremove: yes - purge: true - - - name: Check if reboot is required - stat: - path: /var/run/reboot-required - register: reboot_required_file - - - name: Show Output of required reboots - debug: msg="{{ reboot_required_file.stat.exists == true }}" - - - name: Rebooting machine - shell: sleep 2 && shutdown -r now "Ansible updates triggered" - async: 1 - poll: 0 - ignore_errors: true - when: reboot_required_file.stat.exists - - - name: Waiting for the machine to come back - local_action: wait_for host={{ ansible_host }} state=started port=22 delay=30 - become: no - when: reboot_required_file.stat.exists - - - name: notify via Gotify - uri: - url: 'http://{{ GOTIFY_IP }}:{{ GOTIFY_PORT }}/message?token={{ GOTIFY_TOKEN }}' - method: POST - body: - title: - content: APT Packages Update - message: - content: The remove apps playbook has completed for {{ ansible_host }} and is now updated. A required reboot is {{ reboot_required_file.stat.exists == true }}. - priority: - content: '5' - body_format: form-multipart - register: result -... \ No newline at end of file diff --git a/automation/ansible/old-playbooks/playbooks/remove_repo.yml b/automation/ansible/old-playbooks/playbooks/remove_repo.yml deleted file mode 100644 index 1af26bd..0000000 --- a/automation/ansible/old-playbooks/playbooks/remove_repo.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -- hosts: all - become: true - tasks: - - name: Remove specified repository from sources list - ansible.builtin.apt_repository: - repo: xxx #put the reponame of the repo you no longer want here - state: absent diff --git a/automation/ansible/old-playbooks/playbooks/upgrade-packages.yml b/automation/ansible/old-playbooks/playbooks/upgrade-packages.yml deleted file mode 100644 index 035ab11..0000000 --- a/automation/ansible/old-playbooks/playbooks/upgrade-packages.yml +++ /dev/null @@ -1,89 +0,0 @@ ---- -- name: Patching and Updating Linux Systems - hosts: all - become: true - vars: - GOTIFY_IP: xxx #[Your gotify host IP goes here] - GOTIFY_PORT: xxx #[Your gotify port goes here] - GOTIFY_TOKEN: xxx #[Your app token goes here] - ansible_python_interpreter: /usr/bin/python3 - - tasks: - - name: Update Debian-based Systems - when: ansible_os_family == 'Debian' or ansible_os_family == 'Ubuntu' - apt: - update_cache: yes - upgrade: dist - - - name: Update RHEL-based Systems - when: ansible_os_family == 'RedHat' - yum: - name: '*' - state: latest - - - name: List installed and updated packages - shell: grep -E "^$(date +%Y-%m-%d).+ (install|upgrade) " /var/log/dpkg.log |cut -d " " -f 3-5 - register: result - - - name: Check if Docker is installed - command: which docker - register: docker_installed - ignore_errors: true - changed_when: false - - - name: Upgrade Python pip modules for Docker support (only if Docker is installed) - when: docker_installed.rc == 0 and ansible_os_family == 'RedHat' - pip: - name: - - docker - - requests - state: latest - executable: pip3 - - - name: Show Output of updated files - debug: msg="{{ result.stdout_lines }}" - - - name: Check if reboot is required - stat: - path: /var/run/reboot-required - register: reboot_required_file - - - name: Show Output of required reboots - debug: msg="{{ reboot_required_file.stat.exists == true }}" - - - name: Rebooting machine - shell: sleep 2 && shutdown -r now "Ansible updates triggered" - async: 1 - poll: 0 - ignore_errors: true - when: reboot_required_file.stat.exists - - - name: Waiting for the machine to come back - local_action: wait_for host={{ ansible_host }} state=started port=22 delay=30 - become: false - when: reboot_required_file.stat.exists -### - - name: Remove DNF dependencies that are no longer required. - when: ansible_os_family == 'RedHat' - ansible.builtin.dnf: - autoremove: yes - - - name: Remove APT dependencies that are no longer required. - when: ansible_os_family == 'Debian' or ansible_os_family == 'Ubuntu' - ansible.builtin.apt: - autoremove: yes - - - name: notify via Gotify - uri: - url: 'http://{{ GOTIFY_IP }}:{{ GOTIFY_PORT }}/message?token={{ GOTIFY_TOKEN }}' - method: POST - body: - title: - content: All Packages Update - message: - content: The upgrade-packages playbook has completed for {{ ansible_host }} and is now updated. A required reboot is {{ reboot_required_file.stat.exists == true }}. - priority: - content: '5' - body_format: form-multipart - register: result -... \ No newline at end of file diff --git a/automation/automation-vm/NetBox/docker-compose.yaml b/automation/automation-vm/NetBox/docker-compose.yaml deleted file mode 100644 index e61b261..0000000 --- a/automation/automation-vm/NetBox/docker-compose.yaml +++ /dev/null @@ -1,112 +0,0 @@ -services: - postgres: - image: postgres:17-alpine - container_name: netbox-postgres - restart: unless-stopped - environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - volumes: - - /path/to/netbox/postgres_data:/var/lib/postgresql/data - healthcheck: - test: pg_isready -q -t 2 -d $$POSTGRES_DB -U $$POSTGRES_USER - start_period: 20s - timeout: 30s - interval: 10s - retries: 5 - networks: - - netbox-net - - redis: - image: valkey/valkey:9.0-alpine - container_name: netbox-redis - restart: unless-stopped - command: - - sh - - -c - - valkey-server --appendonly yes --requirepass $$REDIS_PASSWORD - environment: - REDIS_PASSWORD: ${REDIS_PASSWORD} - volumes: - - /path/to/netbox/redis_data:/data - networks: - - netbox-net - - redis-cache: - image: valkey/valkey:9.0-alpine - container_name: netbox-redis-cache - restart: unless-stopped - command: - - sh - - -c - - valkey-server --requirepass $$REDIS_PASSWORD - environment: - REDIS_PASSWORD: ${REDIS_CACHE_PASSWORD} - volumes: - - /path/to/netbox/redis_cache:/data - networks: - - netbox-net - - netbox: &netbox - image: netboxcommunity/netbox:latest - container_name: netbox - user: "netbox:root" - restart: unless-stopped - depends_on: - - postgres - - redis - - redis-cache - env_file: .env - ports: - - ${HTTP_PORT}:8080 - environment: - SECRET_KEY: ${NETBOX_SECRET_KEY} - DB_NAME: ${POSTGRES_DB} - DB_USER: ${POSTGRES_USER} - DB_PASSWORD: ${POSTGRES_PASSWORD} - DB_HOST: postgres - REDIS_HOST: redis - REDIS_PORT: 6379 - REDIS_PASSWORD: ${REDIS_PASSWORD} - REDIS_DATABASE: 0 - REDIS_CACHE_HOST: redis-cache - REDIS_CACHE_PORT: 6379 - REDIS_CACHE_PASSWORD: ${REDIS_CACHE_PASSWORD} - REDIS_CACHE_DATABASE: 1 - SUPERUSER_NAME: ${SUPERUSER_NAME} - SUPERUSER_PASSWORD: ${SUPERUSER_PASSWORD} - SUPERUSER_EMAIL: ${SUPERUSER_EMAIL} - volumes: - - /path/to/netbox/netbox_media:/opt/netbox/netbox/media - - /path/to/netbox/netbox_reports:/opt/netbox/netbox/reports - - /path/to/netbox/netbox_scripts:/opt/netbox/netbox/scripts - - ./configuration/extra.py:/etc/netbox/config/extra.py:ro - healthcheck: - test: curl -f http://localhost:8080/login/ || exit 1 - start_period: 90s - timeout: 3s - interval: 15s - networks: - - netbox-net - - netbox-worker: - <<: *netbox - container_name: netbox-worker - ports: [] - depends_on: - netbox: - condition: service_healthy - command: - - /opt/netbox/venv/bin/python - - /opt/netbox/netbox/manage.py - - rqworker - healthcheck: - test: ps -aux | grep -v grep | grep -q rqworker || exit 1 - start_period: 20s - timeout: 3s - interval: 15s - -networks: - netbox-net: - external: true diff --git a/automation/iac/old-content/Ansible/.vault_pass.txt b/automation/iac/old-content/Ansible/.vault_pass.txt deleted file mode 100644 index fd52cd4..0000000 --- a/automation/iac/old-content/Ansible/.vault_pass.txt +++ /dev/null @@ -1 +0,0 @@ -asupersecretpasswordfor ansiblevaultunlock \ No newline at end of file diff --git a/automation/iac/old-content/Ansible/README.md b/automation/iac/old-content/Ansible/README.md deleted file mode 100644 index ce6de4b..0000000 --- a/automation/iac/old-content/Ansible/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Coming Soon... - -There will soon be a full write-up of the way that the Ansible Roles and Tags laid out during the VM creation via Terraform, is used to configure a VM based on very specific use cases and criteria. The way I have designed the entire workflow is condusive to having a secure Packer built ISO expanded in its capabilites simply by the addition of a new Ansible Role and Tag. \ No newline at end of file diff --git a/automation/iac/old-content/Ansible/ansible.cfg b/automation/iac/old-content/Ansible/ansible.cfg deleted file mode 100644 index ac11fb9..0000000 --- a/automation/iac/old-content/Ansible/ansible.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[defaults] -inventory = ./inventory.ini -roles_path = ./roles:./roles/bootstrap_roles:./roles/cis_hardening:./roles/kestra:./roles/monitoring:./roles/secure_vault:./roles/wazuh_docker -ansible_python_interpreter = /path/to/ansible-modern/bin/python3 -collections_paths = /path/to/ansible-modern/lib64/python3.11/site-packages/ansible_collections:/path/to/ansible_collections:/usr/share/ansible/collections -remote_user = ansible -private_key_file = /path/to/.ssh/key_file -host_key_checking = False diff --git a/automation/iac/old-content/Ansible/group_vars/all.yml b/automation/iac/old-content/Ansible/group_vars/all.yml deleted file mode 100644 index 2ed8038..0000000 --- a/automation/iac/old-content/Ansible/group_vars/all.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -roles_metadata: "{{ lookup('file', 'roles_metadata.yml') | from_yaml }}" diff --git a/automation/iac/old-content/Ansible/group_vars/all/vault_token.yml b/automation/iac/old-content/Ansible/group_vars/all/vault_token.yml deleted file mode 100644 index 3c8ab10..0000000 --- a/automation/iac/old-content/Ansible/group_vars/all/vault_token.yml +++ /dev/null @@ -1,14 +0,0 @@ -$ANSIBLE_VAULT;1.1;AES256 -64373439343462336430396135326665346633343564656532636363356339326561643161353635 -3636363336663638373932643830646634366336366363370a616235646239386166343964636336 -66303364663462396235626566613266313561376466646631346464653564623630333137383536 -3630363935333333390a633633333264323834323863623035626662326639663731323938633534 -65303062303837636430346435316538336434386464373836336538633933633465376162333138 -63626433643734633634363433666139653736306630393031653566666362343833363936383265 -38656136636434653135633561323839656337623963393731663762333836343665323239356536 -35663433316535313063323264316338353761323537393035373338376634656265363361623037 -32323935333262373437373662646538613665626265626534333862616138373361666639376437 -36613238336332313734316235363265636164363566326636646534646561363666333637323737 -63313336623130306636383362646138656130383661633738623365663762393761306164333536 -39356564636164306332333763663461343462653562343330623862363131653863333363333332 -3162 diff --git a/automation/iac/old-content/Ansible/host_vars/docker-host/host_tags.yml b/automation/iac/old-content/Ansible/host_vars/docker-host/host_tags.yml deleted file mode 100755 index 54a3526..0000000 --- a/automation/iac/old-content/Ansible/host_vars/docker-host/host_tags.yml +++ /dev/null @@ -1,31 +0,0 @@ -# VM metadata from Terraform provisioning -vmid: id number here -vm_name: "vm name" -target_node: "hypervisor node name" -template: "template-name" -cores: 4 -sockets: 1 -memory: 57344 -bridge: vmbr0 -macaddr: "xx:x:x:x:x:x" -disk_size: 250GB -disk_storage: "storage name here" -ip: xx.xx.xx.xx -vlan: 0 -vm_tags: - - packages - - hostname_network - - root_password - - disk_resize - - base_users - - firewall_ssh - - endlessh - - zsh_custom - - ssh_hardening - - banners - - file_permissions - - service_disable - - kernel_hardening - - docker_gitlab_setup - - diff --git a/automation/iac/old-content/Ansible/host_vars/haproxy-vm/host_tags.yml b/automation/iac/old-content/Ansible/host_vars/haproxy-vm/host_tags.yml deleted file mode 100755 index e7fe77d..0000000 --- a/automation/iac/old-content/Ansible/host_vars/haproxy-vm/host_tags.yml +++ /dev/null @@ -1,32 +0,0 @@ -# VM metadata from Terraform provisioning -vmid: id number here -vm_name: "vm name" -target_node: "hypervisor node name" -template: "template-name" -cores: 1 -sockets: 1 -memory: 4096 -bridge: vmbr0 -macaddr: "xx:x:x:x:x:x" -disk_size: 20GB -disk_storage: "storage name here" -ip: xx.xx.xx.xx -vlan: 0 -vm_tags: - - packages - - hostname_network - - root_password - - disk_resize - - base_users - - firewall_ssh - - endlessh - - zsh_custom - - vault_agent - - haproxy - - ssh_hardening - - banners - - file_permissions - - service_disable - - kernel_hardening - - diff --git a/automation/iac/old-content/Ansible/inventory.yml b/automation/iac/old-content/Ansible/inventory.yml deleted file mode 100644 index 6c0c5d8..0000000 --- a/automation/iac/old-content/Ansible/inventory.yml +++ /dev/null @@ -1,14 +0,0 @@ -all: - hosts: - haproxy: - ansible_host: xx.xx.xx.xx - ansible_port: xxxx - initialized: true - service: haproxy - docker: - ansible_host: xx.xx.xx.xx - ansible_port: xxxx - initialized: true - service: docker - vars: - ansible_python_interpreter: /usr/bin/python3 diff --git a/automation/iac/old-content/Ansible/inventory_initialization.yml b/automation/iac/old-content/Ansible/inventory_initialization.yml deleted file mode 100644 index f5c71cc..0000000 --- a/automation/iac/old-content/Ansible/inventory_initialization.yml +++ /dev/null @@ -1,8 +0,0 @@ -all: - vars: - ansible_python_interpreter: /usr/bin/python3 - hosts: - haproxy: - ansible_host: xx.xx.xx.xx - ansible_port: 22 - service: haproxy diff --git a/automation/iac/old-content/Ansible/playbooks/compliance.yml b/automation/iac/old-content/Ansible/playbooks/compliance.yml deleted file mode 100644 index fd8bda2..0000000 --- a/automation/iac/old-content/Ansible/playbooks/compliance.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -- name: Compliance stage - hosts: all - become: true - gather_facts: true - - vars: - stage_name: compliance - - vars_files: - - /path/to/Infrastrucutre as Code/ansible/roles_metadata.yml - - tasks: - - name: Run roles for this stage - ansible.builtin.include_role: - name: "{{ item }}" - loop: >- - {{ - vm_tags - | select('in', - roles_metadata - | dict2items - | selectattr('value.' ~ stage_name, 'defined') - | selectattr('value.' ~ stage_name) - | map(attribute='key') - | list - ) - | list - }} diff --git a/automation/iac/old-content/Ansible/playbooks/initialization.yml b/automation/iac/old-content/Ansible/playbooks/initialization.yml deleted file mode 100644 index 3cdd4e1..0000000 --- a/automation/iac/old-content/Ansible/playbooks/initialization.yml +++ /dev/null @@ -1,87 +0,0 @@ ---- -- name: Initialization stage - hosts: all - become: true - gather_facts: true - - vars: - stage_name: initialization - inventory_init: "/path/to/Infrastrucutre as Code/ansible/inventory_initialization.yml" - inventory_active: "/path/to/Infrastrucutre as Code/ansible/inventory.yml" - - vars_files: - - /path/to/Infrastrucutre as Code/ansible/roles_metadata.yml - - /path/to/Infrastrucutre as Code/ansible/group_vars/all/vault_token.yml - - pre_tasks: - - name: Ensure active inventory exists - ansible.builtin.file: - path: "{{ inventory_active }}" - state: touch - delegate_to: localhost - run_once: true - - - name: Load existing active inventory - ansible.builtin.slurp: - src: "{{ inventory_active }}" - register: active_inv_raw - delegate_to: localhost - run_once: true - - - name: Parse active inventory YAML (or initialize empty) - ansible.builtin.set_fact: - active_inventory: >- - {{ - (active_inv_raw.content | b64decode | from_yaml) - if (active_inv_raw.content | b64decode | from_yaml is mapping) - else {'all': {'hosts': {}}} - }} - run_once: true - - tasks: - - name: Run initialization roles for uninitialized hosts - ansible.builtin.include_role: - name: "{{ item }}" - loop: >- - {{ - vm_tags - | select('in', - roles_metadata - | dict2items - | selectattr('value.' ~ stage_name, 'defined') - | selectattr('value.' ~ stage_name) - | map(attribute='key') - | list - ) - | list - }} - - post_tasks: - - name: Append or update host in active inventory - ansible.builtin.set_fact: - active_inventory: >- - {{ - active_inventory | - combine({ - 'all': { - 'hosts': ( - active_inventory.all.hosts | - combine({ - inventory_hostname: { - 'ansible_host': hostvars[inventory_hostname]['ansible_host'], - 'ansible_port': hostvars[inventory_hostname]['ssh_port'] | default(22), - 'initialized': true - } - }) - ) - } - }, recursive=True) - }} - delegate_to: localhost - - - name: Write updated active inventory back to file - ansible.builtin.copy: - dest: "{{ inventory_active }}" - content: "{{ active_inventory | to_nice_yaml }}" - delegate_to: localhost - run_once: true diff --git a/automation/iac/old-content/Ansible/playbooks/provisioning.yml b/automation/iac/old-content/Ansible/playbooks/provisioning.yml deleted file mode 100644 index bfa899d..0000000 --- a/automation/iac/old-content/Ansible/playbooks/provisioning.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -- name: Provisioning stage - hosts: all - become: true - gather_facts: true - - vars: - stage_name: provisioning - - vars_files: - - /path/to/Infrastrucutre as Code/ansible/roles_metadata.yml - - tasks: - - name: Run roles for this stage - ansible.builtin.include_role: - name: "{{ item }}" - loop: >- - {{ - vm_tags - | select('in', - roles_metadata - | dict2items - | selectattr('value.' ~ stage_name, 'defined') - | selectattr('value.' ~ stage_name) - | map(attribute='key') - | list - ) - | list - }} diff --git a/automation/iac/old-content/Ansible/requirements.yml b/automation/iac/old-content/Ansible/requirements.yml deleted file mode 100644 index d461551..0000000 --- a/automation/iac/old-content/Ansible/requirements.yml +++ /dev/null @@ -1,9 +0,0 @@ -collections: - - name: community.hashi_vault - - name: community.general - - name: ansible.posix - - name: community.crypto - - name: community.dns - - name: middleware_automation.keycloak - - name: community.network - - name: community.docker diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/base_users/tasks/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/base_users/tasks/main.yml deleted file mode 100644 index 8b40659..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/base_users/tasks/main.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Configure default home directory and shell for system users - block: - - name: Set default home directory and shell for system users - ansible.builtin.lineinfile: - path: /etc/default/useradd - regexp: "^{{ setting.key }}=" - line: "{{ setting.key }}={{ setting.value }}" - create: yes - backup: yes - loop: - - { key: "HOME", value: "/nonexistent" } - - { key: "SHELL", value: "/sbin/nologin" } - loop_control: - loop_var: setting diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/disk_resize/tasks/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/disk_resize/tasks/main.yml deleted file mode 100644 index 50348e0..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/disk_resize/tasks/main.yml +++ /dev/null @@ -1,28 +0,0 @@ -- name: Expand disk and root filesystem - block: - - name: Attempt to grow partition (safe if already full) - command: growpart /dev/sda 2 - register: growpart_result - ignore_errors: true - - - name: Determine if partition actually grew - set_fact: - partition_grew: >- - {{ growpart_result.rc == 0 and - (growpart_result.stdout is defined and 'NOCHANGE' not in growpart_result.stdout) }} - - - name: Resize LVM physical volume if needed - command: pvresize /dev/sda2 - when: partition_grew - register: pvresize_result - changed_when: "'Physical volume' in pvresize_result.stdout and 'resized' in pvresize_result.stdout" - - - name: Extend logical volume if needed - command: lvextend -l +100%FREE /dev/mapper/rocky-lv_root - when: partition_grew - register: lvextend_result - changed_when: lvextend_result.rc == 0 and "'0 extents found" not in lvextend_result.stderr - - - name: Grow the XFS filesystem if needed - command: xfs_growfs / - when: partition_grew and (lvextend_result is changed or lvextend_result is not defined) diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/defaults/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/defaults/main.yml deleted file mode 100644 index 1c7be9b..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/defaults/main.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- -docker_old_root: "/var/lib/docker" -docker_new_root_base: "/opt/docker/docker_data" -docker_new_root: "{{ docker_new_root_base }}/docker" - -docker_volumes_dir: "/opt/docker/docker_volumes" -docker_homelab_dir: "/opt/docker/homelab" - -docker_volumes_owner: "user" -docker_volumes_group: "group" - -git_repo_url: "git@git.example.com:USER/REPO.git" -git_repo_version: "main" - -ssh_key_path: "/home/USER/.ssh/id_rsa" -git_repo_owner: "user" -git_repo_group: "group" - -docker_daemon_conf: "/etc/docker/daemon.json" -daemon_json_template: | - { - "data-root": "{{ docker_new_root }}" - } diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/handlers/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/handlers/main.yml deleted file mode 100644 index 3627303..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: restart docker - service: - name: docker - state: restarted diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/tasks/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/tasks/main.yml deleted file mode 100644 index 4c4c490..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/docker_gitlab_setup/tasks/main.yml +++ /dev/null @@ -1,75 +0,0 @@ ---- -# 1. Ensure SSH key exists so git clone works -- name: Ensure .ssh directory exists - file: - path: "{{ ssh_key_path | dirname }}" - state: directory - owner: "user" - group: "user" - mode: "0700" - -- name: Ensure SSH key exists (don't overwrite) - copy: - src: "{{ ssh_key_path }}" - dest: "{{ ssh_key_path }}" - owner: "user" - group: "user" - mode: "0600" - -# 2. Ensure docker_data directory exists -- name: Ensure new Docker data root base exists - file: - path: "{{ docker_new_root_base }}" - state: directory - owner: root - group: root - mode: "0755" - -# 3. Stop Docker ONLY if /var/lib/docker still exists -- name: Stop Docker if old root exists - service: - name: docker - state: stopped - when: docker_old_root is exists - -# 4. Move /var/lib/docker → new location (idempotent) -- name: Move Docker data root to new location - command: "mv {{ docker_old_root }} {{ docker_new_root }}" - args: - creates: "{{ docker_new_root }}" - when: docker_old_root is exists - -# 5. Ensure daemon.json points to new data-root -- name: Configure Docker daemon.json - copy: - dest: "{{ docker_daemon_conf }}" - content: "{{ daemon_json_template }}" - owner: root - group: root - mode: "0644" - notify: restart docker - -# 6. Ensure docker_volumes exists -- name: Ensure docker_volumes directory exists - file: - path: "{{ docker_volumes_dir }}" - state: directory - owner: "{{ docker_volumes_owner }}" - group: "{{ docker_volumes_group }}" - mode: "0755" - -# 7. Ensure homelab directory exists -- name: Ensure homelab directory exists - file: - path: "{{ docker_homelab_dir }}" - state: directory - owner: "{{ git_repo_owner }}" - group: "{{ git_repo_group }}" - mode: "0755" - -# 8. Start Docker if it was stopped -- name: Start Docker - service: - name: docker - state: started - when: docker_new_root is exists diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/defaults/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/defaults/main.yml deleted file mode 100644 index 4ee19bf..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -endlessh_port: 22 -endlessh_repo: https://github.com/skeeto/endlessh.git -endlessh_clone_path: /usr/local/src/endlessh diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/tasks/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/tasks/main.yml deleted file mode 100644 index 98fb869..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/tasks/main.yml +++ /dev/null @@ -1,67 +0,0 @@ ---- -- name: Ensure endlessh group exists - ansible.builtin.group: - name: endlessh - system: true - -- name: Ensure endlessh user exists - ansible.builtin.user: - name: endlessh - group: endlessh - system: true - shell: /usr/sbin/nologin - create_home: false - -- name: Ensure Endlessh repo is cloned and updated - ansible.builtin.git: - repo: "{{ endlessh_repo }}" - dest: "{{ endlessh_clone_path }}" - version: master - update: yes - register: git_result - -- name: Build Endlessh if repo was updated - ansible.builtin.command: make - args: - chdir: "{{ endlessh_clone_path }}" - when: git_result.after != git_result.before - register: make_result - # no changed_when needed; we'll rely on the copy step to track changes - -- name: Copy Endlessh binary to /usr/local/bin if updated - ansible.builtin.copy: - src: "{{ endlessh_clone_path }}/endlessh" - dest: /usr/local/bin/endlessh - mode: "0755" - remote_src: true - when: git_result.after != git_result.before - register: copy_result - -- name: Create Endlessh config directory - ansible.builtin.file: - path: /etc/endlessh - state: directory - mode: "0755" - -- name: Deploy Endlessh config - ansible.builtin.template: - src: endlessh_config.j2 - dest: /etc/endlessh/config - mode: "0644" - -- name: Deploy Endlessh systemd service - ansible.builtin.template: - src: endlessh.service.j2 - dest: /etc/systemd/system/endlessh.service - mode: "0644" - -- name: Reload systemd daemon - ansible.builtin.systemd: - daemon_reload: true - -- name: Restart Endlessh if binary updated - ansible.builtin.systemd: - name: endlessh - enabled: true - state: restarted - when: copy_result is changed diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/templates/endlessh.service.j2 b/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/templates/endlessh.service.j2 deleted file mode 100644 index 1ffecc1..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/templates/endlessh.service.j2 +++ /dev/null @@ -1,20 +0,0 @@ -[Unit] -Description=Endlessh SSH Tarpit -After=network.target - -[Service] -ExecStart=/usr/local/bin/endlessh -f /etc/endlessh/config -Restart=always -User=endlessh -Group=endlessh -AmbientCapabilities=CAP_NET_BIND_SERVICE -NoNewPrivileges=true -ProtectSystem=full -ProtectHome=true -PrivateTmp=true -RestrictAddressFamilies=AF_INET AF_INET6 -ReadWritePaths=/etc/endlessh -LockPersonality=true - -[Install] -WantedBy=multi-user.target diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/templates/endlessh_config.j2 b/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/templates/endlessh_config.j2 deleted file mode 100644 index 948322b..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/endlessh/templates/endlessh_config.j2 +++ /dev/null @@ -1,5 +0,0 @@ -Port {{ endlessh_port }} -Delay 10000 -MaxLineLength 32 -MaxClients 4096 -LogLevel 1 diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/firewall_ssh/defaults/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/firewall_ssh/defaults/main.yml deleted file mode 100644 index f0de0ba..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/firewall_ssh/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -# Customize if needed; this defaults to port 22 for endlessh -endlessh_port: 22 -# The SSH port will be dynamically computed as: 10000 + (vmid % 100) diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/firewall_ssh/tasks/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/firewall_ssh/tasks/main.yml deleted file mode 100644 index 21f3336..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/firewall_ssh/tasks/main.yml +++ /dev/null @@ -1,69 +0,0 @@ ---- -- name: Configure firewall and SSH port - block: - - name: Fail if vmid is not defined - ansible.builtin.fail: - msg: "'vmid' must be defined to calculate dynamic SSH port" - when: vmid is not defined - - - name: Calculate SSH port from vmid - ansible.builtin.set_fact: - ssh_port: "{{ 10000 + (vmid | int % 100) }}" - - - name: Enable and start firewalld - ansible.builtin.service: - name: firewalld - state: started - enabled: true - - - name: Set firewalld default zone to drop - ansible.posix.firewalld: - zone: public - state: enabled - permanent: yes - target: DROP - - - name: Reload firewalld to apply permanent changes - ansible.builtin.command: firewall-cmd --reload - - - name: Allow custom SSH port in firewalld - ansible.posix.firewalld: - port: "{{ ssh_port }}/tcp" - permanent: true - state: enabled - immediate: true - - - name: Allow Endlessh port in firewalld - ansible.posix.firewalld: - port: "{{ endlessh_port }}/tcp" - permanent: true - state: enabled - immediate: true - - - name: Ensure custom SSH port is set in sshd_config - ansible.builtin.lineinfile: - path: /etc/ssh/sshd_config - regexp: '^#?Port\s+' - line: "Port {{ ssh_port }}" - backup: yes - validate: "/usr/sbin/sshd -T -f %s" - register: sshd_config_changed - - - name: Gather SELinux facts - ansible.builtin.setup: - filter: ansible_selinux - - - name: Allow SSH to use custom port in SELinux - ansible.builtin.command: > - semanage port -a -t ssh_port_t -p tcp {{ ssh_port }} - register: semanage_result - failed_when: semanage_result.rc not in [0, 1] - changed_when: semanage_result.rc == 0 - when: ansible_selinux.status == "enabled" - - - name: Restart and enable sshd service if needed - ansible.builtin.service: - name: sshd - state: restarted - enabled: true - when: sshd_config_changed is changed diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/hostname_network/tasks/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/hostname_network/tasks/main.yml deleted file mode 100644 index 7a35314..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/hostname_network/tasks/main.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -- name: Set hostname and update /etc/hosts - vars: - default_domain: subdomain.domain - block: - - name: Set hostname fact - ansible.builtin.set_fact: - short_hostname: "{{ vm_name }}" - custom_hostname: "{{ vm_name }}.{{ default_domain }}" - - - name: Set system hostname - ansible.builtin.hostname: - name: "{{ custom_hostname }}" - - - name: Ensure /etc/hosts contains loopback entry for hostname - ansible.builtin.lineinfile: - path: /etc/hosts - regexp: '^127\.0\.1\.1\s+' - line: "127.0.1.1 {{ custom_hostname }} {{ short_hostname }}" - state: present - create: yes - - - name: Ensure /etc/hosts contains primary network IP entry - ansible.builtin.lineinfile: - path: /etc/hosts - regexp: '^{{ ip }}\s+' - line: "{{ ip }} {{ custom_hostname }} {{ short_hostname }}" - state: present - create: yes diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/packages/defaults/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/packages/defaults/main.yml deleted file mode 100644 index 27d2e39..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/packages/defaults/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -base_packages: - - firewalld - - policycoreutils-python-utils - - git - - make - - gcc - - cloud-utils-growpart - - lvm2 - - xfsprogs diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/packages/tasks/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/packages/tasks/main.yml deleted file mode 100644 index 9a06a50..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/packages/tasks/main.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -- name: Package management tasks - tags: [packages] - block: - - name: Clean all cached metadata - ansible.builtin.command: dnf clean all - become: true - - - name: Rebuild the DNF cache - ansible.builtin.command: dnf makecache - become: true - - - name: Update all packages to latest - ansible.builtin.dnf: - name: "*" - state: latest - update_cache: true - become: true - - - name: Reboot if kernel was upgraded - ansible.builtin.reboot: - reboot_timeout: 120 - pre_reboot_delay: 10 - when: ansible_facts.packages['kernel'] is defined - become: true - - - name: Install base system packages - ansible.builtin.package: - name: "{{ base_packages }}" - state: present - update_cache: true - become: true diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/portainer_agent/tasks/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/portainer_agent/tasks/main.yml deleted file mode 100644 index 4e60eed..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/portainer_agent/tasks/main.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -- name: Set Portainer Agent installation directory - vars: - portainer_agent_dir: /opt/portainer-agent - block: - - name: Create Portainer Agent directory - become: true - ansible.builtin.file: - path: "{{ portainer_agent_dir }}" - state: directory - owner: user - group: user - mode: "0755" - - - name: Create Portainer Agent docker-compose file - become: true - ansible.builtin.copy: - dest: "{{ portainer_agent_dir }}/docker-compose.yml" - owner: user - group: user - mode: "0644" - content: | - services: - agent: - image: portainer/agent:latest - container_name: portainer_agent - restart: always - ports: - - "9001:9001" - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - /var/lib/docker/volumes:/var/lib/docker/volumes - - - name: Ensure Portainer Agent is running - become: true - community.docker.docker_compose_v2: - project_src: "{{ portainer_agent_dir }}" - state: present # ensures containers exist - recreate: always # recreates if the definition changed diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/root_password/defaults/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/root_password/defaults/main.yml deleted file mode 100644 index 9f7201a..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/root_password/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -root_password_plain: "{{ lookup('env', 'ROOT_PASSWORD') }}" diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/root_password/tasks/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/root_password/tasks/main.yml deleted file mode 100644 index 95083ae..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/root_password/tasks/main.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -- name: Set root password - block: - - name: Fail if root password is not defined - fail: - msg: "The variable 'root_password_plain' must be provided (e.g., via GitLab CI/CD Variable)" - when: root_password_plain is not defined - - - name: Generate root password hash - set_fact: - root_password_hash: "{{ root_password_plain | password_hash('sha512') }}" - - - name: Set root user password - user: - name: root - password: "{{ root_password_hash }}" diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/zsh_custom/tasks/main.yml b/automation/iac/old-content/Ansible/roles/bootstrap_roles/zsh_custom/tasks/main.yml deleted file mode 100644 index bb7765a..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/zsh_custom/tasks/main.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- -- name: Customize Zsh for users - vars: - zsh_users: - - user - - block: - - name: Ensure parent home directory exists (safety) - ansible.builtin.file: - path: "/home/{{ user }}" - state: directory - owner: "{{ user }}" - group: "{{ user }}" - mode: "0755" - loop: "{{ zsh_users }}" - loop_control: - loop_var: user - become: true - - - name: Remove any old oh-my-zsh - ansible.builtin.file: - path: "/home/{{ user }}/.oh-my-zsh" - state: absent - loop: "{{ zsh_users }}" - loop_control: - loop_var: user - become: true - - - name: Clone Oh My Zsh as root - ansible.builtin.git: - repo: "https://github.com/ohmyzsh/ohmyzsh.git" - dest: "/home/{{ user }}/.oh-my-zsh" - version: master - update: yes - force: yes - loop: "{{ zsh_users }}" - loop_control: - loop_var: user - become: true - - - name: Add trusted safe.directory system-wide for Oh My Zsh - ansible.builtin.command: - cmd: git config --system --add safe.directory /home/{{ user }}/.oh-my-zsh - loop: "{{ zsh_users }}" - loop_control: - loop_var: user - become: true - - - name: Install syntax-highlighting plugin - ansible.builtin.git: - repo: "https://github.com/zsh-users/zsh-syntax-highlighting.git" - dest: "/home/{{ user }}/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting" - version: master - update: yes - force: yes - loop: "{{ zsh_users }}" - loop_control: - loop_var: user - become: true - - - name: Deploy customized .zshrc - ansible.builtin.template: - src: zshrc.j2 - dest: "/home/{{ user }}/.zshrc" - owner: "{{ user }}" - group: "{{ user }}" - mode: "0644" - loop: "{{ zsh_users }}" - loop_control: - loop_var: user - become: true - - - name: Fix ownership recursively for Oh My Zsh directory - ansible.builtin.file: - path: "/home/{{ user }}/.oh-my-zsh" - owner: "{{ user }}" - group: "{{ user }}" - recurse: yes - loop: "{{ zsh_users }}" - loop_control: - loop_var: user - become: true diff --git a/automation/iac/old-content/Ansible/roles/bootstrap_roles/zsh_custom/templates/zshrc.j2 b/automation/iac/old-content/Ansible/roles/bootstrap_roles/zsh_custom/templates/zshrc.j2 deleted file mode 100644 index bcf7b7f..0000000 --- a/automation/iac/old-content/Ansible/roles/bootstrap_roles/zsh_custom/templates/zshrc.j2 +++ /dev/null @@ -1,21 +0,0 @@ -export ZSH="\$HOME/.oh-my-zsh" -ZSH_THEME="robbyrussell" -plugins=(git zsh-autosuggestions zsh-syntax-highlighting) -source \$ZSH/oh-my-zsh.sh - -# Where to save history and how much to keep -HISTFILE=~/.zsh_history -HISTSIZE=10000 # In-memory history -SAVEHIST=10000 # Lines to save to file - -# Recommended options -setopt APPEND_HISTORY # Don’t overwrite history file; append to it -setopt SHARE_HISTORY # Share history across all sessions -setopt HIST_IGNORE_DUPS # Don’t record duplicate commands -setopt HIST_IGNORE_SPACE # Ignore commands starting with a space -setopt HIST_VERIFY # Edit a command before running from history -setopt INC_APPEND_HISTORY # Write history incrementally as commands are run - - -PS1='%F{51}%n%F{255}@%F{227}%m %F{84}%~%f %F{15}$ ' -fastfetch \ No newline at end of file diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/banners/defaults/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/banners/defaults/main.yml deleted file mode 100644 index 94cd1fa..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/banners/defaults/main.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -cis_banner: | - ********************************************************************* - * WARNING: Unauthorized access to this system is prohibited. * - * All activities are monitored and recorded. * - ********************************************************************* - -cis_motd_banner: | - ********************************************************************* - * Welcome to the system. Access is restricted to authorized users. * - ********************************************************************* diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/banners/tasks/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/banners/tasks/main.yml deleted file mode 100644 index a1606d3..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/banners/tasks/main.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- -# Login banners for /etc/motd, /etc/issue, /etc/issue.net - -- name: Ensure /etc/motd contains standard CIS banner - ansible.builtin.copy: - dest: /etc/motd - owner: root - group: root - mode: "0644" - content: "{{ cis_motd_banner }}" - -- name: Ensure /etc/issue contains standard CIS banner - ansible.builtin.copy: - dest: /etc/issue - owner: root - group: root - mode: "0644" - content: "{{ cis_motd_banner }}" - -- name: Ensure /etc/issue.net contains standard CIS banner - ansible.builtin.copy: - dest: /etc/issue.net - owner: root - group: root - mode: "0644" - content: "{{ cis_banner }}" diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/defaults/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/defaults/main.yml deleted file mode 100644 index 22644cf..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/defaults/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -# Parent-level defaults -cis_tag: cis_hardening -audit_rules_file: /etc/audit/rules.d/cis.rules -rsyslog_remote: "" # set to "logserver.example.com:514" to forward logs -txt_grub_args: "" # additional kernel args if needed, e.g. "audit=1" diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/file_permissions/defaults/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/file_permissions/defaults/main.yml deleted file mode 100644 index 87f5dd6..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/file_permissions/defaults/main.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -# Default ownership and permissions for critical files and directories - -file_permissions_list: - - { path: "/root", mode: "0700", state: "directory" } - - { path: "/etc/passwd", mode: "0644", state: "file" } - - { path: "/etc/shadow", mode: "0400", state: "file" } - - { path: "/etc/group", mode: "0644", state: "file" } - - { path: "/etc/gshadow", mode: "0400", state: "file" } - - { path: "/etc/crontab", mode: "0600", state: "file" } - - { path: "/etc/cron.hourly", mode: "0700", state: "directory" } - - { path: "/etc/cron.daily", mode: "0700", state: "directory" } - - { path: "/etc/cron.weekly", mode: "0700", state: "directory" } - - { path: "/etc/cron.monthly", mode: "0700", state: "directory" } - - { path: "/etc/cron.d", mode: "0700", state: "directory" } - - { path: "/etc/rsyslog.conf", mode: "0640", state: "file" } diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/file_permissions/tasks/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/file_permissions/tasks/main.yml deleted file mode 100644 index 86a8483..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/file_permissions/tasks/main.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- name: Ensure system files and directories have correct ownership and permissions - ansible.builtin.file: - path: "{{ file_item.path }}" - owner: root - group: root - mode: "{{ file_item.mode }}" - state: "{{ file_item.state }}" - loop: "{{ file_permissions_list }}" - loop_control: - loop_var: file_item diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/filesystem_hardening/defaults/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/filesystem_hardening/defaults/main.yml deleted file mode 100644 index 0d890e3..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/filesystem_hardening/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -tmp_mount_options: "defaults,nosuid,nodev,noexec,relatime" -var_tmp_mount_options: "defaults,nosuid,nodev,noexec,relatime" -home_mount_options: "defaults,nosuid,nodev,relatime" -dev_shm_mount_options: "defaults,nosuid,nodev,noexec,relatime" diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/filesystem_hardening/tasks/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/filesystem_hardening/tasks/main.yml deleted file mode 100644 index f39e8b1..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/filesystem_hardening/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -# Remount and persist secure options using defaults variables - -- name: Gather mount facts - ansible.builtin.setup: - filter: ansible_mounts - -- name: Ensure /tmp has secure mount options - ansible.builtin.mount: - path: /tmp - fstype: "{{ ansible_mounts | selectattr('mount','equalto','/tmp') | map(attribute='fstype') | first }}" - opts: "{{ tmp_mount_options }}" - state: mounted - -- name: Ensure /var/tmp has secure mount options - ansible.builtin.mount: - path: /var/tmp - fstype: "{{ ansible_mounts | selectattr('mount','equalto','/var/tmp') | map(attribute='fstype') | first }}" - opts: "{{ var_tmp_mount_options }}" - state: mounted - -- name: Ensure /home has secure mount options - ansible.builtin.mount: - path: /home - fstype: "{{ ansible_mounts | selectattr('mount','equalto','/home') | map(attribute='fstype') | first }}" - opts: "{{ home_mount_options }}" - state: mounted - -- name: Ensure /dev/shm has secure mount options - ansible.builtin.mount: - path: /dev/shm - fstype: tmpfs - opts: "{{ dev_shm_mount_options }}" - state: mounted diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/handlers/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/handlers/main.yml deleted file mode 100644 index 4f69f71..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/handlers/main.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: restart rsyslog - ansible.builtin.service: - name: rsyslog - state: restarted - -- name: restart auditd - ansible.builtin.service: - name: auditd - state: restarted - -- name: reload systemd - ansible.builtin.command: systemctl daemon-reexec - -- name: update initramfs - ansible.builtin.command: dracut -f - when: ansible_facts['os_family'] == 'RedHat' or ansible_facts['distribution'] in ['Rocky','RedHat','CentOS'] diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/defaults/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/defaults/main.yml deleted file mode 100644 index 96dc2bf..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/defaults/main.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# Kernel defaults (override per host if needed) -modprobe_blacklist_file: /etc/modprobe.d/cis_blacklist.conf - -# Additional kernel modules to disable -blacklist_modules: - - tipc diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/tasks/blacklist_module.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/tasks/blacklist_module.yml deleted file mode 100644 index 51d22b6..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/tasks/blacklist_module.yml +++ /dev/null @@ -1,18 +0,0 @@ -# blacklist_module.yml -- name: Check if module {{ mod }} exists on system - ansible.builtin.shell: "modprobe -n -v {{ mod }}" - register: modprobe_check - ignore_errors: true - -- name: Blacklist module {{ mod }} in {{ modprobe_blacklist_file }} - ansible.builtin.lineinfile: - path: "{{ modprobe_blacklist_file }}" - line: "install {{ mod }} /bin/false" - create: yes - state: present - when: modprobe_check.rc == 0 - -- name: Unload module {{ mod }} if currently loaded - ansible.builtin.shell: "modprobe -r {{ mod }}" - ignore_errors: true - when: modprobe_check.rc == 0 diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/tasks/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/tasks/main.yml deleted file mode 100644 index 8e71898..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/kernel_hardening/tasks/main.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- -# Kernel & sysctl hardening (CIS network/kernel items) - -- name: Ensure IPv4 forwarding is disabled - ansible.builtin.sysctl: - name: net.ipv4.ip_forward - value: "0" - state: present - reload: yes - -- name: Ensure IPv6 forwarding is disabled - ansible.builtin.sysctl: - name: net.ipv6.conf.all.forwarding - value: "0" - state: present - reload: yes - -- name: Ensure source routed packets are not accepted - ansible.builtin.sysctl: - name: net.ipv4.conf.all.accept_source_route - value: "0" - state: present - reload: yes - -- name: Ensure ICMP redirects are not accepted - ansible.builtin.sysctl: - name: net.ipv4.conf.all.accept_redirects - value: "0" - state: present - reload: yes - -- name: Ensure secure ICMP redirects are not accepted - ansible.builtin.sysctl: - name: net.ipv4.conf.all.secure_redirects - value: "0" - state: present - reload: yes - -- name: Ensure Address Space Layout Randomization (ASLR) is enabled - ansible.builtin.sysctl: - name: kernel.randomize_va_space - value: "2" - state: present - reload: yes - -- name: Ensure fs.suid_dumpable is 0 (disable core dumps) - ansible.builtin.sysctl: - name: fs.suid_dumpable - value: "0" - state: present - reload: yes - -- name: Create /etc/modprobe.d/cis_blacklist.conf with common blacklists - ansible.builtin.copy: - dest: /etc/modprobe.d/cis_blacklist.conf - owner: root - group: root - mode: "0644" - content: | - # CIS blacklist - install cramfs /bin/true - install freevxfs /bin/true - install jffs2 /bin/true - install hfs /bin/true - install hfsplus /bin/true - install squashfs /bin/true - install udf /bin/true - -- name: Regenerate initramfs if modprobe blacklist changed - ansible.builtin.command: dracut -f - changed_when: false - when: ansible_facts.get('os_family') == 'RedHat' or ansible_facts.get('distribution') in ['Rocky', 'RedHat', 'CentOS'] - -- name: Blacklist all modules - include_tasks: blacklist_module.yml - loop: "{{ blacklist_modules }}" - loop_control: - loop_var: mod diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/password_policy/defaults/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/password_policy/defaults/main.yml deleted file mode 100644 index 3672cd3..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/password_policy/defaults/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -# Password policy defaults -pw_minlen: 14 -pw_minclass: 4 -pw_max_days: 365 -pw_min_days: 7 -pw_warn_age: 7 -faillock_deny: 5 -faillock_unlock_time: 900 diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/password_policy/tasks/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/password_policy/tasks/main.yml deleted file mode 100644 index 820964c..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/password_policy/tasks/main.yml +++ /dev/null @@ -1,60 +0,0 @@ ---- -# Password and PAM related hardening - -- name: Ensure password hashing algorithm is SHA512 - ansible.builtin.lineinfile: - path: /etc/login.defs - regexp: "^ENCRYPT_METHOD" - line: "ENCRYPT_METHOD SHA512" - create: yes - -- name: Ensure PASS_MAX_DAYS is 365 - ansible.builtin.lineinfile: - path: /etc/login.defs - regexp: "^PASS_MAX_DAYS" - line: "PASS_MAX_DAYS 365" - create: yes - -- name: Ensure PASS_MIN_DAYS is 7 - ansible.builtin.lineinfile: - path: /etc/login.defs - regexp: "^PASS_MIN_DAYS" - line: "PASS_MIN_DAYS 7" - create: yes - -- name: Ensure PASS_WARN_AGE is 7 - ansible.builtin.lineinfile: - path: /etc/login.defs - regexp: "^PASS_WARN_AGE" - line: "PASS_WARN_AGE 7" - create: yes - -- name: Ensure pwquality minlen and requirements - ansible.builtin.lineinfile: - path: /etc/security/pwquality.conf - regexp: "^minlen" - line: "minlen = 14" - create: yes - -- name: Ensure pwquality minclass (character classes) is 4 - ansible.builtin.lineinfile: - path: /etc/security/pwquality.conf - regexp: "^minclass" - line: "minclass = 4" - create: yes - -- name: Ensure pam_faillock preauth is configured - ansible.builtin.lineinfile: - path: /etc/pam.d/system-auth - insertafter: "^auth.*required.*pam_unix.so" - line: "auth required pam_faillock.so preauth silent audit deny=5 unlock_time=900" - state: present - backrefs: no - -- name: Ensure pam_faillock authfail/account lines exist - ansible.builtin.blockinfile: - path: /etc/pam.d/system-auth - insertafter: "^auth.*required.*pam_unix.so" - block: | - auth [default=die] pam_faillock.so authfail deny=5 unlock_time=900 audit - account required pam_faillock.so diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/service_disable/defaults/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/service_disable/defaults/main.yml deleted file mode 100644 index 1efe812..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/service_disable/defaults/main.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -unused_services: - - avahi-daemon - - bluetooth - - cups - - rpcbind - - nfslock - - rsh.socket - - telnet.socket - - rsyncd diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/service_disable/tasks/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/service_disable/tasks/main.yml deleted file mode 100644 index 65d4c18..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/service_disable/tasks/main.yml +++ /dev/null @@ -1,10 +0,0 @@ -- name: Ensure list of unnecessary services are stopped and masked - ansible.builtin.service: - name: "{{ svc }}" - enabled: no - state: stopped - masked: yes - loop: "{{ unused_services }}" - loop_control: - loop_var: svc - ignore_errors: true diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/ssh_hardening/defaults/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/ssh_hardening/defaults/main.yml deleted file mode 100644 index 3da2d50..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/ssh_hardening/defaults/main.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -# General settings -ssh_protocol: 2 -ssh_permit_root_login: "no" -ssh_password_authentication: "no" -ssh_challenge_response_authentication: "no" -ssh_kerberos_authentication: "no" -ssh_gssapi_authentication: "no" -ssh_use_pam: "yes" -PrintLastLog: "yes" - -# Session security -ssh_x11_forwarding: "no" -ssh_allow_tcp_forwarding: "yes" -ssh_permit_tunnel: "no" -ssh_allow_agent_forwarding: "no" - -# Idle timeout / login attempts -ssh_client_alive_interval: 300 -ssh_client_alive_count_max: 3 -ssh_login_grace_time: 60 -ssh_max_auth_tries: 3 -ssh_max_sessions: 2 -ssh_max_startups: "10:30:60" - -# SSH access restrictions -ssh_allow_users: "adminuser ansibleuser" - -# Strong encryption -ssh_ciphers: "aes256-ctr,aes192-ctr,aes128-ctr" -ssh_macs: "hmac-sha2-512,hmac-sha2-256" -ssh_kex_algorithms: "curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256" diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/ssh_hardening/tasks/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/ssh_hardening/tasks/main.yml deleted file mode 100644 index 2132f18..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/ssh_hardening/tasks/main.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- -- name: Ensure OpenSSH server is installed - ansible.builtin.package: - name: openssh-server - state: present - -- name: Ensure SSH daemon is enabled and running - ansible.builtin.service: - name: sshd - enabled: true - state: started - -- name: Backup current sshd_config - ansible.builtin.copy: - src: /etc/ssh/sshd_config - dest: /etc/ssh/sshd_config.bak - owner: root - group: root - mode: "0600" - remote_src: true - -- name: Harden SSH configuration - ansible.builtin.lineinfile: - path: /etc/ssh/sshd_config - regexp: "{{ ssh_item.regexp }}" - line: "{{ ssh_item.line }}" - state: present - backrefs: yes - loop: - - regexp: "^#?Protocol" - line: "Protocol {{ ssh_protocol }}" - - regexp: "^#?PermitRootLogin" - line: "PermitRootLogin {{ ssh_permit_root_login }}" - - regexp: "^#?PasswordAuthentication" - line: "PasswordAuthentication {{ ssh_password_authentication }}" - - regexp: "^#?ChallengeResponseAuthentication" - line: "ChallengeResponseAuthentication {{ ssh_challenge_response_authentication }}" - - regexp: "^#?KerberosAuthentication" - line: "KerberosAuthentication {{ ssh_kerberos_authentication }}" - - regexp: "^#?GSSAPIAuthentication" - line: "GSSAPIAuthentication {{ ssh_gssapi_authentication }}" - - regexp: "^#?UsePAM" - line: "UsePAM {{ ssh_use_pam }}" - - regexp: "^#?X11Forwarding" - line: "X11Forwarding {{ ssh_x11_forwarding }}" - - regexp: "^#?AllowTcpForwarding" - line: "AllowTcpForwarding {{ ssh_allow_tcp_forwarding }}" - - regexp: "^#?PermitTunnel" - line: "PermitTunnel {{ ssh_permit_tunnel }}" - - regexp: "^#?AllowAgentForwarding" - line: "AllowAgentForwarding {{ ssh_allow_agent_forwarding }}" - - regexp: "^#?ClientAliveInterval" - line: "ClientAliveInterval {{ ssh_client_alive_interval }}" - - regexp: "^#?ClientAliveCountMax" - line: "ClientAliveCountMax {{ ssh_client_alive_count_max }}" - - regexp: "^#?LoginGraceTime" - line: "LoginGraceTime {{ ssh_login_grace_time }}" - - regexp: "^#?MaxAuthTries" - line: "MaxAuthTries {{ ssh_max_auth_tries }}" - - regexp: "^#?MaxSessions" - line: "MaxSessions {{ ssh_max_sessions }}" - - regexp: "^#?MaxStartups" - line: "MaxStartups {{ ssh_max_startups }}" - - regexp: "^#?Ciphers" - line: "Ciphers {{ ssh_ciphers }}" - - regexp: "^#?MACs" - line: "MACs {{ ssh_macs }}" - - regexp: "^#?KexAlgorithms" - line: "KexAlgorithms {{ ssh_kex_algorithms }}" - - regexp: "^#?PrintLastLog" - line: "PrintLastLog {{ PrintLastLog }}" - - regexp: '^\s*#?\s*AllowUsers' - line: "AllowUsers {{ ssh_allow_users }}" - - regexp: "^#?Banner" - line: "Banner /etc/issue.net" - loop_control: - loop_var: ssh_item - -- name: Restart SSH service to apply changes - ansible.builtin.service: - name: sshd - state: restarted diff --git a/automation/iac/old-content/Ansible/roles/cis_hardening/tasks/main.yml b/automation/iac/old-content/Ansible/roles/cis_hardening/tasks/main.yml deleted file mode 100644 index cdafb66..0000000 --- a/automation/iac/old-content/Ansible/roles/cis_hardening/tasks/main.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -# Parent CIS hardening role: import each subrole with single tag -- import_role: - name: cis_hardening/kernel_hardening - tags: [cis_hardening] - -- import_role: - name: cis_hardening/password_policy - tags: [cis_hardening] - -- import_role: - name: cis_hardening/file_permissions - tags: [cis_hardening] - -- import_role: - name: cis_hardening/service_disable - tags: [cis_hardening] - -- import_role: - name: cis_hardening/banners - tags: [cis_hardening] - -- import_role: - name: cis_hardening/ssh_hardening - tags: [cis_hardening] - -- import_role: - name: cis_hardening/filesystem_hardening - tags: [cis_hardening] diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/defaults/main.yml b/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/defaults/main.yml deleted file mode 100644 index 0b362b3..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/defaults/main.yml +++ /dev/null @@ -1,55 +0,0 @@ -# Vault connection -vault_addr: "http://VAULT_IP:VAULT_PORT" - -# Directory paths -haproxy_certs_dir: "/etc/haproxy/certs" -haproxy_cert_path: "{{ haproxy_pem_path }}" -haproxy_pem_path: "{{ haproxy_certs_dir }}/haproxy.pem" -haproxy_ca_path: "{{ haproxy_certs_dir }}/haproxy_ca.crt" - -# Systemd service names -haproxy_service: "haproxy" - -# HAProxy tuning -haproxy_global_maxconn: 4096 -haproxy_timeout_connect_ms: 5000 -haproxy_timeout_client_ms: 60000 -haproxy_timeout_server_ms: 60000 -haproxy_enable_hsts: true - -vault_agent_templates: - - src: "haproxy.pem.ctmpl" - dest: "{{ haproxy_pem_path }}" - service: "haproxy" - - src: "haproxy_ca.ctmpl" - dest: "{{ haproxy_ca_path }}" - service: "haproxy" - -# === Services routed internally through HAProxy === -securemtls_services: - vault: - hostname: vault.local.DOMAIN_PLACEHOLDER - balance: roundrobin - mode: http - timeout_connect: 5s - timeout_server: 30s - default_server_inter: 3s - default_server_rise: 2 - default_server_fall: 3 - backend_servers: - - address: VAULT_IP - port: VAULT_PORT - proto: http - headers: - - "http-request set-header Host vault.local.DOMAIN_PLACEHOLDER" - - "http-request set-header X-Forwarded-Proto https" - rewrites: - - "http-response replace-header Location ^http://VAULT_IP:VAULT_PORT/(.*) https://vault.local.DOMAIN_PLACEHOLDER/\\1" - - technitium: - hostname: "technitium.local.DOMAIN_PLACEHOLDER" - backend_mode: http - backend_servers: - - address: TECHNITIUM_IP - port: TECHNITIUM_PORT - proto: "http" diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/handlers/main.yml b/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/handlers/main.yml deleted file mode 100644 index 6d501e4..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: Reload HAProxy - systemd: - name: haproxy - state: reloaded diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/tasks/main.yml b/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/tasks/main.yml deleted file mode 100644 index a6884c2..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/tasks/main.yml +++ /dev/null @@ -1,107 +0,0 @@ ---- -- name: Install HAProxy - dnf: - name: haproxy - state: present - -- name: Ensure firewalld is running and enabled - systemd: - name: firewalld - enabled: true - state: started - -- name: Allow inbound HTTPS (443/tcp) - ansible.posix.firewalld: - service: https - permanent: true - state: enabled - immediate: true - -- name: Ensure HAProxy certificate directories exist - file: - path: "{{ cert_dir }}" - state: directory - owner: haproxy - group: haproxy - mode: "0750" - loop: - - "{{ haproxy_certs_dir }}" - - "{{ haproxy_certs_dir }}/clients" - loop_control: - loop_var: cert_dir - -- name: Apply SELinux context for HAProxy certs - command: semanage fcontext -a -t etc_t "{{ haproxy_certs_dir }}(/.*)?" - become: true - register: semanage_fcontext_result - failed_when: false - changed_when: semanage_fcontext_result.rc == 0 - -- name: Restore SELinux context for HAProxy certs - command: restorecon -Rv "{{ haproxy_certs_dir }}" - become: true - changed_when: false - -- name: Allow HAProxy to connect to any port (SELinux) - ansible.posix.seboolean: - name: haproxy_connect_any - state: true - persistent: true - -- name: Wait for HAProxy PEM and CA files - wait_for: - path: "{{ pem_item }}" - state: present - timeout: 120 - loop: - - "{{ haproxy_pem_path }}" - - "{{ haproxy_ca_path }}" - loop_control: - loop_var: pem_item - -- name: Ensure permissions for HAProxy certs - file: - path: "{{ cert_item }}" - owner: haproxy - group: haproxy - mode: "0644" - loop: - - "{{ haproxy_pem_path }}" - - "{{ haproxy_ca_path }}" - loop_control: - loop_var: cert_item - -- name: Deploy HAProxy configuration - template: - src: haproxy.cfg.j2 - dest: /etc/haproxy/haproxy.cfg - owner: root - group: root - mode: "0644" - notify: Reload HAProxy - -- name: Ensure HAProxy service starts after vault-agent - lineinfile: - path: /usr/lib/systemd/system/haproxy.service - regexp: "^After=" - line: "After=network-online.target vault-agent.service" - backup: yes - -- name: Reload systemd daemon - command: systemctl daemon-reload - -- name: Enable and start HAProxy - systemd: - name: haproxy - enabled: yes - state: started - -- name: Check SELinux mode - command: getenforce - register: selinux_state - changed_when: false - -- name: Warn if SELinux is not enforcing - debug: - msg: "⚠️ SELinux is not enforcing — HAProxy cert contexts may not be correctly applied." - when: selinux_state.stdout != "Enforcing" diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/templates/haproxy.cfg.j2 b/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/templates/haproxy.cfg.j2 deleted file mode 100644 index e4b32a7..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/haproxy/templates/haproxy.cfg.j2 +++ /dev/null @@ -1,86 +0,0 @@ -# ========================================== -# HAProxy global settings -# ========================================== -global - log /dev/log local0 - log /dev/log local1 notice - chroot /var/lib/haproxy - pidfile /run/haproxy.pid - maxconn {{ haproxy_global_maxconn | default(4096) }} - user haproxy - group haproxy - daemon - -defaults - log global - option httplog - option dontlognull - timeout connect {{ haproxy_timeout_connect_ms | default('5000') }} - timeout client {{ haproxy_timeout_client_ms | default('60000') }} - timeout server {{ haproxy_timeout_server_ms | default('60000') }} - option http-server-close - option forwardfor - retries 3 - maxconn 2000 - -# ========================================== -# HAProxy frontends and backends template -# ========================================== - -frontend https-in - mode http - bind *:443 ssl crt {{ haproxy_pem_path }} ca-file {{ haproxy_ca_path }} verify required alpn h2,http/1.1 - option httplog - option forwardfor - timeout client 30s - - http-request set-header X-Client-Cert %[ssl_c_der,base64] - -{% for service_name, service in securemtls_services.items() %} - acl host_{{ service_name }} hdr(host) -i {{ service.hostname }} - use_backend {{ service_name }} if host_{{ service_name }} -{% endfor %} - -# ========================================== -# Backends -# ========================================== -{% for service_name, service in securemtls_services.items() %} -backend {{ service_name }} - balance {{ service.balance | default('roundrobin') }} - mode {{ service.mode | default('http') }} - timeout connect {{ service.timeout_connect | default('5s') }} - timeout server {{ service.timeout_server | default('30s') }} - option {{ service.options | default('http-server-close') }} - default-server inter {{ service.default_server_inter | default('3s') }} - default-server rise {{ service.default_server_rise | default('2') }} - default-server fall {{ service.default_server_fall | default('3') }} - -{% for server in service.backend_servers %} - {% if server.proto == "https" %} - server {{ service_name }}-{{ loop.index }} {{ server.address }}:{{ server.port }} ssl verify none check - {% else %} - server {{ service_name }}-{{ loop.index }} {{ server.address }}:{{ server.port }} check - {% endif %} -{% endfor %} - -{% if service.headers is defined %} -{% for hdr in service.headers %} - {{ hdr }} -{% endfor %} -{% endif %} - -{% if service.rewrites is defined %} -{% for rewrite in service.rewrites %} - {{ rewrite }} -{% endfor %} -{% endif %} - -{% endfor %} - -# ========================================== -# Vault backend for HAProxy -# ========================================== -backend vault_backend - mode tcp - option ssl-hello-chk - server vault1 VAULT_IP:VAULT_PORT ssl verify required ca-file {{ haproxy_ca_path }} crt {{ haproxy_cert_path }} diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/technitium/defaults/main.yml b/automation/iac/old-content/Ansible/roles/secure_vault/technitium/defaults/main.yml deleted file mode 100644 index 216ff2f..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/technitium/defaults/main.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Networking -technitium_port: 53 -technitium_tls_port: 853 -technitium_admin_port: TECHNITIUM_PORT -technitium_bind_address: "0.0.0.0" - -# ========================================================== -# Directory paths -# ========================================================== -technitium_certs_dir: "/etc/technitium/certs" -technitium_crt_path: "{{ technitium_certs_dir }}/technitium.crt" -technitium_key_path: "{{ technitium_certs_dir }}/technitium.key" -technitium_ca_path: "{{ technitium_certs_dir }}/technitium_ca.crt" - -# Install paths -technitium_install_dir: "/opt/technitium/dns" -technitium_data_dir: "{{ technitium_install_dir }}/data" - -vault_agent_templates: - - src: "technitium_cert.ctmpl" - dest: "{{ technitium_crt_path }}" - service: "technitium" - - src: "technitium_key.ctmpl" - dest: "{{ technitium_key_path }}" - service: "technitium" - - src: "technitium_ca.ctmpl" - dest: "{{ technitium_ca_path }}" - service: "technitium" diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/technitium/handlers/main.yml b/automation/iac/old-content/Ansible/roles/secure_vault/technitium/handlers/main.yml deleted file mode 100644 index 6bcc4fc..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/technitium/handlers/main.yml +++ /dev/null @@ -1,8 +0,0 @@ -- name: Reload systemd - ansible.builtin.systemd: - daemon_reload: yes - -- name: Restart technitium - ansible.builtin.systemd: - name: technitium - state: restarted diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/technitium/tasks/main.yml b/automation/iac/old-content/Ansible/roles/secure_vault/technitium/tasks/main.yml deleted file mode 100644 index b96dd10..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/technitium/tasks/main.yml +++ /dev/null @@ -1,125 +0,0 @@ ---- -# ========================================================== -# Install and configure Technitium DNS Server -# ========================================================== - -- name: Ensure Technitium install directory exists - ansible.builtin.file: - path: "{{ technitium_install_dir }}" - state: directory - owner: root - group: root - mode: "0755" - -- name: Ensure Technitium data directory exists - ansible.builtin.file: - path: "{{ technitium_data_dir }}" - state: directory - owner: root - group: root - mode: "0755" - -- name: Ensure Technitium TLS directory exists - ansible.builtin.file: - path: "{{ technitium_certs_dir }}" - state: directory - owner: vault - group: vault - mode: "0700" - -# ========================================================== -# Install Technitium if not already installed -# ========================================================== -- name: Install Technitium DNS Server - ansible.builtin.command: bash install.sh - args: - chdir: /tmp - creates: "{{ technitium_install_dir }}/start.sh" - environment: - INSTALL_URL: "https://download.technitium.com/dns/install.sh" - register: technitium_install_result - ignore_errors: true - changed_when: technitium_install_result.rc == 0 - -# ========================================================== -# SELinux setup (idempotent) -# ========================================================== -- name: Apply SELinux context for Technitium certs - ansible.builtin.command: semanage fcontext -a -t etc_t '{{ technitium_certs_dir }}(/.*)?' - register: selinux_ctx - changed_when: selinux_ctx.rc == 0 - ignore_errors: true - -- name: Restore SELinux context for Technitium certs - ansible.builtin.command: restorecon -Rv "{{ technitium_certs_dir }}" - changed_when: false - -# ========================================================== -# Firewalld setup -# ========================================================== -- name: Ensure firewalld is running - ansible.builtin.systemd: - name: firewalld - enabled: true - state: started - -- name: Open Technitium DNS and admin ports - ansible.posix.firewalld: - port: "{{ item.port }}/{{ item.proto }}" - permanent: true - state: enabled - immediate: true - loop: - - { port: 53, proto: "udp" } - - { port: 53, proto: "tcp" } - - { port: 853, proto: "tcp" } - - { port: 443, proto: "tcp" } - - { port: 5380, proto: "tcp" } - -# ========================================================== -# Systemd service deployment -# ========================================================== -- name: Deploy Technitium systemd unit - ansible.builtin.template: - src: "technitium.service.j2" - dest: "/etc/systemd/system/technitium.service" - owner: root - group: root - mode: "0644" - notify: - - Reload systemd - - Restart technitium - -- name: Wait for Vault-Agent to render certificates - ansible.builtin.wait_for: - path: "{{ cert_path }}" - state: present - timeout: 60 - loop: - - "{{ technitium_crt_path }}" - - "{{ technitium_key_path }}" - - "{{ technitium_ca_path }}" - loop_control: - loop_var: cert_path - -- name: Fix ownership and permissions for Technitium certs - ansible.builtin.file: - path: "{{ cert.path }}" - owner: vault - group: vault - mode: "{{ cert.mode }}" - loop: - - { path: "{{ technitium_crt_path }}", mode: "0644" } - - { path: "{{ technitium_key_path }}", mode: "0600" } - - { path: "{{ technitium_ca_path }}", mode: "0644" } - loop_control: - loop_var: cert - -# ========================================================== -# Start and enable service -# ========================================================== -- name: Ensure Technitium DNS service is running - ansible.builtin.systemd: - name: technitium - enabled: true - state: started diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/technitium/templates/technitium.service.j2 b/automation/iac/old-content/Ansible/roles/secure_vault/technitium/templates/technitium.service.j2 deleted file mode 100644 index 2664bbb..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/technitium/templates/technitium.service.j2 +++ /dev/null @@ -1,16 +0,0 @@ -[Unit] -Description=Technitium DNS Server -After=network.target - -[Service] -Type=simple -WorkingDirectory={{ technitium_install_dir }} -#ExecStart={{ technitium_install_dir }}/start.sh -ExecStart={{ technitium_install_dir }}/start.sh --tls-cert /etc/technitium/certs/technitium.crt --tls-key /etc/technitium/certs/technitium.key -Restart=always -RestartSec=5 -User=root -Group=root - -[Install] -WantedBy=multi-user.target diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/technitium/vars/main.yml b/automation/iac/old-content/Ansible/roles/secure_vault/technitium/vars/main.yml deleted file mode 100644 index ffce5d9..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/technitium/vars/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -technitium_service_name: "technitium" -technitium_binary_url: "https://download.technitium.com/dns/DnsServerPortable.tar.gz" -technitium_data_dir: "{{ technitium_install_dir }}/data" -technitium_conf_file: "{{ technitium_install_dir }}/Technitium.Dns.Server.json" diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/defaults/main.yml b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/defaults/main.yml deleted file mode 100644 index cfcd822..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/defaults/main.yml +++ /dev/null @@ -1,41 +0,0 @@ ---- -vault_addr: "http://VAULT_IP:VAULT_PORT" - -vault_agent_config_path: "/etc/vault-agent-config.hcl" -vault_agent_pid_file: "/var/run/vault-agent.pid" -vault_agent_user: "root" -vault_agent_service: "vault-agent" -vault_agent_systemd_unit: "/etc/systemd/system/vault-agent.service" - -# Paths to role_id / secret_id files (written by bootstrap process) -vault_role_id_file: "/etc/vault-agent/role_id" -vault_secret_id_file: "/etc/vault-agent/secret_id" - -# Templates -vault_templates_dir: "/etc/vault-agent-templates" - -vault_agent_templates: - # HAProxy - - src: "haproxy.pem.ctmpl" - dest: "/etc/haproxy/certs/haproxy.pem" - service: haproxy - - src: "haproxy_ca.ctmpl" - dest: "/etc/haproxy/certs/haproxy_ca.crt" - service: haproxy - - src: "thesabear-client.ctmpl" - dest: "/etc/haproxy/certs/clients/thesabear-client.pem" - service: "haproxy" - - # Technitium - - src: "technitium_cert.ctmpl" - dest: "/etc/technitium/certs/technitium.crt" - service: technitium - - src: "technitium_key.ctmpl" - dest: "/etc/technitium/certs/technitium.key" - service: technitium - - src: "technitium_ca.ctmpl" - dest: "/etc/technitium/certs/technitium_ca.crt" - service: technitium - -# Default Vault PKI options (can remain) -pki_mount_path: "pki" diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/generic_ca.ctmpl b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/generic_ca.ctmpl deleted file mode 100644 index 27d7de5..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/generic_ca.ctmpl +++ /dev/null @@ -1,3 +0,0 @@ -{{- with secret "pki/cert/ca" -}} -{{ trim .Data.certificate "\n" }} -{{- end }} diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/generic_cert.ctmpl b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/generic_cert.ctmpl deleted file mode 100644 index d492aca..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/generic_cert.ctmpl +++ /dev/null @@ -1,7 +0,0 @@ -{% raw %} -{{- with secret "pki/issue/{{ wildcard_role_name }}" "common_name={{ common_name }}" -}} -{{ .Data.certificate }} -{{ .Data.private_key }} -{{ .Data.issuing_ca }} -{{- end }} -{% endraw %} diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/haproxy.pem.ctmpl b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/haproxy.pem.ctmpl deleted file mode 100644 index 29081da..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/haproxy.pem.ctmpl +++ /dev/null @@ -1,6 +0,0 @@ -{{ with secret "pki/issue/securevault-wildcard" "common_name=*.local.DOMAIN_PLACEHOLDER" "ttl=8760h" }} -{{ .Data.certificate }} -{{ .Data.issuing_ca }} -{{ .Data.private_key }} -{{ end }} - diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/haproxy_ca.ctmpl b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/haproxy_ca.ctmpl deleted file mode 100644 index 19b5278..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/haproxy_ca.ctmpl +++ /dev/null @@ -1,3 +0,0 @@ -{{- with secret "pki/issue/securevault-wildcard" "common_name=*.local.DOMAIN_PLACEHOLDER" -}} -{{ .Data.issuing_ca }} -{{- end }} diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_ca.ctmpl b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_ca.ctmpl deleted file mode 100644 index 0beda22..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_ca.ctmpl +++ /dev/null @@ -1,3 +0,0 @@ -{{- with secret "pki_int/issue/securevault-wildcard" "common_name=technitium.local.DOMAIN_PLACEHOLDER" -}} -{{ .Data.issuing_ca }} -{{- end }} diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_cert.ctmpl b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_cert.ctmpl deleted file mode 100644 index 0bb85c1..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_cert.ctmpl +++ /dev/null @@ -1,3 +0,0 @@ -{{- with secret "pki_int/issue/securevault-wildcard" "common_name=technitium.local.DOMAIN_PLACEHOLDER" -}} -{{ .Data.certificate }} -{{- end }} diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_key.ctmpl b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_key.ctmpl deleted file mode 100644 index a0b20b4..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/technitium_key.ctmpl +++ /dev/null @@ -1,3 +0,0 @@ -{{- with secret "pki_int/issue/securevault-wildcard" "common_name=technitium.local.DOMAIN_PLACEHOLDER" -}} -{{ .Data.private_key }} -{{- end }} diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/thesabear-client.ctmpl b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/thesabear-client.ctmpl deleted file mode 100644 index d0a0b41..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/files/thesabear-client.ctmpl +++ /dev/null @@ -1,6 +0,0 @@ -{{ with secret "pki_int/issue/mtls-client-cert" "common_name=clientname.local.DOMAIN_PLACEHOLDER" "ttl=8760h" }} -{{ .Data.certificate }} -{{ .Data.private_key }} -{{ .Data.issuing_ca }} -{{ end }} - diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/handlers/main.yml b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/handlers/main.yml deleted file mode 100644 index c942a47..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/handlers/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -- name: Reload systemd - command: systemctl daemon-reload diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/tasks/main.yml b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/tasks/main.yml deleted file mode 100644 index eebdafc..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/tasks/main.yml +++ /dev/null @@ -1,230 +0,0 @@ ---- -# ========================================================== -# 1️⃣ Install Vault and Dependencies -# ========================================================== -- name: Ensure HashiCorp repository (RHEL9) - ansible.builtin.copy: - dest: /etc/yum.repos.d/hashicorp.repo - mode: "0644" - content: | - [hashicorp] - name=HashiCorp Stable Repository - baseurl=https://rpm.releases.hashicorp.com/RHEL/9/x86_64/stable/ - enabled=1 - gpgcheck=1 - gpgkey=https://rpm.releases.hashicorp.com/gpg - -- name: Install Vault (includes vault-agent) - ansible.builtin.dnf: - name: vault - state: present - -# ========================================================== -# 2️⃣ Firewall Configuration -# ========================================================== -- name: Ensure firewalld is running and enabled - ansible.builtin.systemd: - name: firewalld - enabled: true - state: started - -- name: Allow outbound access to Vault (VAULT_PORT/tcp) - ansible.posix.firewalld: - rich_rule: > - rule family="ipv4" - destination address="VAULT_IP" - port port="VAULT_PORT" protocol="tcp" accept - permanent: true - state: enabled - immediate: true - -# ========================================================== -# 3️⃣ Vault-Agent Directories and Configs -# ========================================================== -- name: Ensure Vault-Agent directories exist - ansible.builtin.file: - path: "{{ vault_dir.path }}" - state: directory - owner: root - group: root - mode: "{{ vault_dir.mode | default('0750') }}" - loop: - - { path: "{{ vault_templates_dir }}" } - - { path: "/etc/vault-agent", mode: "0700" } - loop_control: - loop_var: vault_dir - -- name: Deploy Vault-Agent configuration - ansible.builtin.template: - src: vault-agent-config.hcl.j2 - dest: "{{ vault_agent_config_path }}" - owner: root - group: root - mode: "0600" - -- name: Install Vault-Agent systemd unit - ansible.builtin.template: - src: vault-agent.service.j2 - dest: "{{ vault_agent_systemd_unit }}" - owner: root - group: root - mode: "0644" - notify: Reload systemd - -- name: Enable Vault-Agent but do not start yet - ansible.builtin.systemd: - name: "{{ vault_agent_service }}" - enabled: true - state: stopped - -# ========================================================== -# 4️⃣ Vault-Agent Templates and Cert Paths -# ========================================================== -- name: Copy Vault-Agent templates - ansible.builtin.copy: - src: "{{ vault_item.src }}" - dest: "{{ vault_templates_dir }}/{{ vault_item.src | basename }}" - owner: root - group: root - mode: "0600" - loop: "{{ vault_agent_templates }}" - loop_control: - loop_var: vault_item - -- name: Ensure directories for Vault-rendered files exist - ansible.builtin.file: - path: "{{ vault_template.dest | dirname }}" - state: directory - owner: root - group: root - mode: "0755" - loop: "{{ vault_agent_templates }}" - loop_control: - loop_var: vault_template - -- name: Start Vault-Agent (now that templates exist) - ansible.builtin.systemd: - name: "{{ vault_agent_service }}" - state: started - -# ========================================================== -# 5️⃣ AppRole Authentication Setup -# ========================================================== -- name: Fetch AppRole credentials for this host - delegate_to: localhost - block: - - name: Get role_id - ansible.builtin.command: - cmd: > - vault read -field=role_id auth/approle/role/{{ inventory_hostname }}-role/role-id - register: role_id_raw - changed_when: false - failed_when: role_id_raw.stdout | trim == "" - environment: - VAULT_ADDR: "http://VAULT_IP:VAULT_PORT" - VAULT_TOKEN: "{{ vault_token }}" - - - name: Get secret_id - ansible.builtin.command: - cmd: > - vault write -f -field=secret_id auth/approle/role/{{ inventory_hostname }}-role/secret-id - register: secret_id_raw - changed_when: false - failed_when: secret_id_raw.stdout | trim == "" - environment: - VAULT_ADDR: "http://VAULT_IP:VAULT_PORT" - VAULT_TOKEN: "{{ vault_token }}" - -- name: Write AppRole credentials to Vault-Agent directory - ansible.builtin.copy: - dest: "/etc/vault-agent/{{ cred.name }}" - content: "{{ cred.content }}" - owner: root - group: root - mode: "0600" - loop: - - { name: "role_id", content: "{{ role_id_raw.stdout | trim }}" } - - { name: "secret_id", content: "{{ secret_id_raw.stdout | trim }}" } - loop_control: - loop_var: cred - label: "{{ cred.name }}" - -# ========================================================== -# 6️⃣ Register Service in Vault -# ========================================================== -- name: Login to Vault with AppRole and register VM - delegate_to: localhost - block: - - name: Login to Vault with AppRole - ansible.builtin.command: - cmd: > - vault write -field=token auth/approle/login - role_id={{ role_id_raw.stdout | trim }} - secret_id={{ secret_id_raw.stdout | trim }} - register: vault_login - changed_when: false - environment: - VAULT_ADDR: "http://VAULT_IP:VAULT_PORT" - - - name: Register VM IP in Vault KV - ansible.builtin.uri: - url: "http://VAULT_IP:VAULT_PORT/v1/kv/data/services/{{ inventory_hostname }}" - method: POST - headers: - X-Vault-Token: "{{ vault_login.stdout }}" - body: - data: - ip: "{{ ansible_default_ipv4.address }}" - body_format: json - status_code: [200, 204] - -# ========================================================== -# 7️⃣ SELinux Context for Vault Rendered Paths -# ========================================================== -- name: Check if SELinux is enforcing - ansible.builtin.command: getenforce - register: selinux_status - changed_when: false - failed_when: false - -- name: Gather all Vault-Agent template and rendered paths - ansible.builtin.set_fact: - all_vault_paths: >- - {{ - ( - (vault_agent_templates | default([]) | map(attribute='dest') | map('dirname') | list) - + - (vault_agent_templates | default([]) | map(attribute='dest') | list) - ) | unique - }} - when: vault_agent_templates is defined and vault_agent_templates | length > 0 - -- name: Filter only paths that exist on the host - ansible.builtin.find: - paths: "{{ all_vault_paths }}" - file_type: directory - register: existing_selinux_paths - when: all_vault_paths is defined and all_vault_paths | length > 0 - -- name: Apply SELinux fcontext to all existing Vault paths - ansible.builtin.command: - cmd: semanage fcontext -a -t etc_t '{{ selinux_path_item.path }}(/.*)?' - loop: "{{ existing_selinux_paths.files | default([]) }}" - loop_control: - loop_var: selinux_path_item - ignore_errors: true - when: selinux_status.stdout == "Enforcing" - -- name: Restore SELinux context for all existing Vault paths - ansible.builtin.command: - cmd: restorecon -Rv "{{ selinux_path_item.path }}" - loop: "{{ existing_selinux_paths.files | default([]) }}" - loop_control: - loop_var: selinux_path_item - ignore_errors: true - when: selinux_status.stdout == "Enforcing" - -- name: Warn if SELinux is not enforcing - ansible.builtin.debug: - msg: "⚠️ SELinux is not enforcing — Vault-Agent directories may not be properly confined." - when: selinux_status.stdout != "Enforcing" diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/templates/vault-agent-config.hcl.j2 b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/templates/vault-agent-config.hcl.j2 deleted file mode 100644 index 4226630..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/templates/vault-agent-config.hcl.j2 +++ /dev/null @@ -1,30 +0,0 @@ -pid_file = "{{ vault_agent_pid_file }}" - -auto_auth { - method { - type = "approle" - config = { - role_id_file_path = "{{ vault_role_id_file }}" - secret_id_file_path = "{{ vault_secret_id_file }}" - remove_secret_id_file_after_reading = false - } - } - sink { - type = "file" - config = { - path = "/etc/vault-token" - } - } -} - -{% for tpl in vault_agent_templates if tpl.service == hostvars[inventory_hostname].service %} -template { - source = "{{ vault_templates_dir }}/{{ tpl.src }}" - destination = "{{ tpl.dest }}" - perms = "0644" -} -{% endfor %} - -vault { - address = "{{ vault_addr }}" -} diff --git a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/templates/vault-agent.service.j2 b/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/templates/vault-agent.service.j2 deleted file mode 100644 index ca25f6a..0000000 --- a/automation/iac/old-content/Ansible/roles/secure_vault/vault_agent/templates/vault-agent.service.j2 +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Vault Agent -After=network-online.target -Wants=network-online.target - -[Service] -ExecStart=/usr/bin/vault agent -config={{ vault_agent_config_path }} -Restart=always -RestartSec=5 -User={{ vault_agent_user }} - -[Install] -WantedBy=multi-user.target diff --git a/automation/iac/old-content/Ansible/roles_metadata.yml b/automation/iac/old-content/Ansible/roles_metadata.yml deleted file mode 100644 index ae1a444..0000000 --- a/automation/iac/old-content/Ansible/roles_metadata.yml +++ /dev/null @@ -1,123 +0,0 @@ -roles_metadata: - # Bootstrap roles - base_users: - initialization: true - provisioning: false - compliance: false - description: "Base user creation tasks" - - disk_resize: - initialization: true - provisioning: false - compliance: true - description: "Disk resizing tasks" - - docker_gitlab_setup: - initialization: true - provisioning: false - compliance: false - description: "Docker runtime files moving and homelab repo copy" - - endlessh: - initialization: true - provisioning: false - compliance: false - description: "Endlessh setup" - - firewall_ssh: - initialization: true - provisioning: false - compliance: true - description: "Firewall and SSH configuration" - - hostname_network: - initialization: true - provisioning: false - compliance: false - description: "Set hostname and networking" - - packages: - initialization: true - provisioning: false - compliance: true - description: "base packages and update tasks" - - portainer_agent: - initialization: true - provisioning: false - compliance: true - description: "Portainer agent setup" - - root_password: - initialization: true - provisioning: false - compliance: false - description: "Root password setup" - - zsh_custom: - initialization: true - provisioning: false - compliance: false - description: "Custom Zsh setup" - - # CIS Hardening roles - banners: - initialization: false - provisioning: false - compliance: true - description: "Login banners setup" - - file_permissions: - initialization: false - provisioning: false - compliance: true - description: "File permissions hardening" - - filesystem_hardening: - initialization: false - provisioning: false - compliance: true - description: "filesystems hardening" - - kernel_hardening: - initialization: false - provisioning: false - compliance: true - description: "Kernel hardening tasks" - - password_policy: - initialization: false - provisioning: false - compliance: true - description: "Password policy enforcement" - - service_disable: - initialization: false - provisioning: false - compliance: true - description: "Disable unnecessary services" - - ssh_hardening: - initialization: false - provisioning: false - compliance: true - description: "SSH hardening" - - # SecureVault roles - haproxy: - initialization: false - provisioning: true - compliance: true - description: "haproxy deployment" - - vault_agent: - initialization: true - provisioning: false - compliance: false - description: "vault_agent deployment" - - technitium: - initialization: false - provisioning: true - compliance: false - description: "technitium deployment" diff --git a/automation/iac/old-content/Packer/README.md b/automation/iac/old-content/Packer/README.md deleted file mode 100644 index 98d26bd..0000000 --- a/automation/iac/old-content/Packer/README.md +++ /dev/null @@ -1,20 +0,0 @@ -Coming Soon... - -A description of how I use a minimal ISO to built out create a base image with defaults configurations which is perfect for its use as a base for creating Proxmox templates from. - - - - -#ROCKY10-CIS -cd /mnt/storage/template/iso -qm create 5000 --memory 2048 --core 2 --name rocky10-cis --net0 virtio,bridge=vmbr0 -qm importdisk 5000 packer-rocky10.iso storage --format qcow2 -qm set 5000 \ - --scsihw virtio-scsi-pci \ - --scsi0 storage:5000/vm-5000-disk-0.qcow2,discard=on,ssd=1 \ - --cpu host \ - --numa 1 \ - --balloon 0 -qm set 5000 --agent enabled=1,freeze-fs-on-backup=1,fstrim_cloned_disks=1 -qm set 5000 --boot c --bootdisk scsi0 -qm set 5000 --serial0 socket --vga serial0 diff --git a/automation/iac/old-content/Packer/rocky10-proxmox-template/.vault_pass.txt b/automation/iac/old-content/Packer/rocky10-proxmox-template/.vault_pass.txt deleted file mode 100644 index 9e4681f..0000000 --- a/automation/iac/old-content/Packer/rocky10-proxmox-template/.vault_pass.txt +++ /dev/null @@ -1 +0,0 @@ -SuperSecretPasswordToUnlock.vault_pass.txtFile diff --git a/automation/iac/old-content/Packer/rocky10-proxmox-template/http/ks.cfg b/automation/iac/old-content/Packer/rocky10-proxmox-template/http/ks.cfg deleted file mode 100644 index 8475af6..0000000 --- a/automation/iac/old-content/Packer/rocky10-proxmox-template/http/ks.cfg +++ /dev/null @@ -1,82 +0,0 @@ -#version=RHEL10 -lang en_US.UTF-8 -keyboard us -timezone Europe/Sofia --utc -authselect --enablefeatures=with-faillock -selinux --enforcing -firewall --disabled -services --enabled=sshd,qemu-guest-agent -firstboot --disable -network --bootproto=dhcp --device=link --onboot=on --hostname=rocky10 --activate -ignoredisk --only-use=vda -rootpw --plaintext thisisatemporarypassword -reboot - -# Clear all partitions and create new MBR label -clearpart --all --initlabel --drives=vda --disklabel=msdos - -# /boot with ext4 -part /boot --fstype="ext4" --size=1024 --ondisk=vda --label=BOOT - -# LVM physical volume on rest of disk -part pv.01 --fstype="lvmpv" --ondisk=vda --grow --size=1 --label=PV01 -volgroup rocky pv.01 - -# Logical volumes -logvol /tmp --fstype=xfs --size=2048 --name=lv_tmp --vgname=rocky --fsoptions="defaults,nodev,nosuid" -logvol /home --fstype=xfs --size=2048 --name=lv_home --vgname=rocky --fsoptions="defaults,nodev" -logvol /var --fstype=xfs --size=4096 --name=lv_var --vgname=rocky --fsoptions="defaults,nodev" -logvol /var/tmp --fstype=xfs --size=1024 --name=lv_vartmp --vgname=rocky --fsoptions="defaults,nodev,nosuid,noexec" -logvol /var/log --fstype=xfs --size=2048 --name=lv_varlog --vgname=rocky --fsoptions="defaults,nodev,noexec,nosuid" -logvol /var/log/audit --fstype=xfs --size=2048 --name=lv_audit --vgname=rocky --fsoptions="defaults,nodev,noexec,nosuid" -logvol / --fstype=xfs --name=lv_root --vgname=rocky --grow --size=512 --fsoptions="defaults" - -# BIOS-compatible bootloader -bootloader --location=mbr --boot-drive=vda - -# Repositories -repo --name="base" --baseurl=https://download.rockylinux.org/pub/rocky/10/BaseOS/x86_64/os/ -repo --name="appstream" --baseurl=https://download.rockylinux.org/pub/rocky/10/AppStream/x86_64/os/ - -%packages -@^minimal-environment -openssh-server -openssh-clients -qemu-guest-agent -nano -zsh -git -curl -sudo -util-linux-user -rsync -tree -nmap-ncat -%end - -%post --erroronfail - -# Enable Docker repository -dnf install -y epel-release dnf-plugins-core -dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo - -# Install Docker fastfetch jq -dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin fastfetch jq - -# Enable services -systemctl enable sshd -systemctl enable docker -systemctl restart docker -systemctl restart sshd - -# Enable password authentication for SSH -cat > /etc/ssh/sshd_config.d/99-password-login.conf <", - "e", # edit boot entry - "", # go to linux line end - " inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg", - " console=tty0 console=ttyS0,115200n8", - " ip=dhcp", - "" # boot with edited entry - ] - - headless = true - qemu_binary = "/usr/bin/qemu-system-x86_64" - accelerator = "kvm" - cpus = 2 - memory = 2048 - - qemuargs = [ - ["-serial", "file:serial.log"], - ["-cpu", "host"], - ["-display", "none"] - ] -} - - -build { - sources = ["source.qemu.rocky10"] - - provisioner "file" { - source = "scripts/setup-admin-user.sh" - destination = "/tmp/setup-admin-user.sh" - } - - provisioner "file" { - source = "scripts/setup-ansible-user.sh" - destination = "/tmp/setup-ansible-user.sh" - } - -# Run setup-admin-user.sh - provisioner "shell" { - inline = [ - "chmod +x /tmp/setup-admin-user.sh", - "/tmp/setup-admin-user.sh \"${var.admin_username}\" \"${var.admin_password_hash}\" \"${var.admin_ssh_key}\"" - ] - } - - provisioner "shell" { - inline = [ - "chmod +x /tmp/setup-ansible-user.sh", - "/tmp/setup-ansible-user.sh \"${var.ansible_username}\" \"${var.ansible_ssh_key}\"" - ] - } -} diff --git a/automation/iac/old-content/Packer/rocky10-proxmox-template/scripts/setup-admin-user.sh b/automation/iac/old-content/Packer/rocky10-proxmox-template/scripts/setup-admin-user.sh deleted file mode 100755 index 12dbe42..0000000 --- a/automation/iac/old-content/Packer/rocky10-proxmox-template/scripts/setup-admin-user.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash -set -euo pipefail - -USERNAME="$1" -HASHED_PASSWORD="$2" -SSH_KEY="$3" - -echo "Creating admin user: $USERNAME" - -# --- Install dependencies early -if command -v dnf &>/dev/null; then - dnf install -y zsh git curl sudo util-linux-user -elif command -v apt-get &>/dev/null; then - apt-get update - apt-get install -y zsh git curl sudo -else - echo "Unsupported package manager" - exit 1 -fi - -# --- Create user if not exists -if ! id "$USERNAME" &>/dev/null; then - useradd -m -s /bin/zsh "$USERNAME" - echo "${USERNAME}:${HASHED_PASSWORD}" | chpasswd -e -# Disable forced password change and expiration -chage -M 99999 -I -1 -E -1 "$USERNAME" -else - echo "User $USERNAME already exists, skipping creation" -fi - -USER_HOME=$(eval echo "~$USERNAME") - -# --- Create fastfetch config -mkdir -p "$USER_HOME/.config/fastfetch" -cat <<'EOF' > "$USER_HOME/.config/fastfetch/config.jsonc" -{ - "displayMode": "default", - "modules": [ - "os", "host", "kernel", "uptime", "packages", "shell", - "cpu", "memory", - { - "type": "disk", - "folders": ["/", "/home", "/tmp", "/var", "/var/log", "/var/log/audit", "/var/tmp"] - }, - "locale" - ] -} -EOF - -chown -R "$USERNAME:$USERNAME" "$USER_HOME/.config" -chmod -R 700 "$USER_HOME/.config" - -# --- SSH Setup -mkdir -p "$USER_HOME/.ssh" -echo "$SSH_KEY" > "$USER_HOME/.ssh/authorized_keys" -chmod 700 "$USER_HOME/.ssh" -chmod 600 "$USER_HOME/.ssh/authorized_keys" -chown -R "$USERNAME:$USERNAME" "$USER_HOME/.ssh" - -# --- Groups and Sudo -if ! getent group docker >/dev/null; then - groupadd docker -fi - -if getent group sudo >/dev/null; then - usermod -aG sudo,docker "$USERNAME" -elif getent group wheel >/dev/null; then - usermod -aG wheel,docker "$USERNAME" -else - echo "No sudo-equivalent group found, skipping" -fi - -echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" > "/etc/sudoers.d/99_$USERNAME" -chmod 440 "/etc/sudoers.d/99_$USERNAME" - -# --- Install Oh My Zsh and config as the user -runuser -l "$USERNAME" -c 'export RUNZSH=no CHSH=no KEEP_ZSHRC=yes && \ - sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" --unattended' - -# --- Install autosuggestions plugin -runuser -l "$USERNAME" -c "git clone https://github.com/zsh-users/zsh-autosuggestions \ - ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions" - -# --- Generate custom .zshrc -cat << 'EOF' > "$USER_HOME/.zshrc" -export ZSH="\$HOME/.oh-my-zsh" -ZSH_THEME="robbyrussell" -plugins=(git zsh-autosuggestions) -source \$ZSH/oh-my-zsh.sh - -PS1='%F{51}%n%F{255}@%F{227}%m %F{84}%~%f %F{15}$ ' -fastfetch -EOF - -chown "$USERNAME:$USERNAME" "$USER_HOME/.zshrc" -chmod 644 "$USER_HOME/.zshrc" - -# --- Set shell (do this last to avoid breaking script if user shell changes mid-run) -chsh -s "$(command -v zsh)" "$USERNAME" - -# --- Deny admin from using Ansible -cat < /etc/sudoers.d/99_no_ansible_for_admin -$USERNAME ALL=(ALL) !/usr/bin/ansible, !/usr/bin/ansible-playbook -EOF - -chmod 440 /etc/sudoers.d/99_no_ansible_for_admin - -echo "✅ User $USERNAME configured successfully" diff --git a/automation/iac/old-content/Packer/rocky10-proxmox-template/scripts/setup-ansible-user.sh b/automation/iac/old-content/Packer/rocky10-proxmox-template/scripts/setup-ansible-user.sh deleted file mode 100644 index 0804ff2..0000000 --- a/automation/iac/old-content/Packer/rocky10-proxmox-template/scripts/setup-ansible-user.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -set -euo pipefail - -USERNAME="$1" -SSH_KEY="$2" - -echo "Creating ansible user: $USERNAME" - -# --- Create user if not exists -if ! id "$USERNAME" &>/dev/null; then - useradd -m "$USERNAME" - mkdir -p "/home/$USERNAME/.ssh" - echo "$SSH_KEY" > "/home/$USERNAME/.ssh/authorized_keys" - chmod 700 "/home/$USERNAME/.ssh" - chmod 600 "/home/$USERNAME/.ssh/authorized_keys" - chown -R "$USERNAME:$USERNAME" "/home/$USERNAME/.ssh" -else - echo "User $USERNAME already exists, skipping creation" -fi - -# --- Harden the ansible user - -# Disable password (no password login) -passwd -d "$USERNAME" -passwd -l "$USERNAME" - -# Allow full passwordless sudo (needed for playbook tasks) -cat < "/etc/sudoers.d/99_${USERNAME}" -${USERNAME} ALL=(ALL) NOPASSWD: ALL -EOF -chmod 0440 "/etc/sudoers.d/99_${USERNAME}" - -echo "✅ User $USERNAME hardened for automation-only access" diff --git a/automation/iac/old-content/Packer/rocky10-proxmox-template/secure-packer-build.sh b/automation/iac/old-content/Packer/rocky10-proxmox-template/secure-packer-build.sh deleted file mode 100755 index bdcdd21..0000000 --- a/automation/iac/old-content/Packer/rocky10-proxmox-template/secure-packer-build.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -VAULT_FILE=".vault_pass.txt" -VARS_FILE="terraform.pkrvar.hcl" -PACKER_TEMPLATE="packer.pkr.hcl" - -# Check if vault password file exists -if [[ ! -f "$VAULT_FILE" ]]; then - echo "❌ Vault password file '$VAULT_FILE' not found." - exit 1 -fi - -# Decrypt the vars file temporarily -echo "🔓 Decrypting $VARS_FILE..." -ansible-vault decrypt "$VARS_FILE" --vault-password-file "$VAULT_FILE" - -# Run packer build -echo "🏗️ Running Packer build..." -packer build -var-file="$VARS_FILE" "$PACKER_TEMPLATE" - -# Re-encrypt the vars file -echo "🔒 Re-encrypting $VARS_FILE..." -ansible-vault encrypt "$VARS_FILE" --vault-password-file "$VAULT_FILE" - -echo "✅ Done!" diff --git a/automation/iac/old-content/Packer/rocky10-proxmox-template/terraform.pkrvar.hcl b/automation/iac/old-content/Packer/rocky10-proxmox-template/terraform.pkrvar.hcl deleted file mode 100644 index a173902..0000000 --- a/automation/iac/old-content/Packer/rocky10-proxmox-template/terraform.pkrvar.hcl +++ /dev/null @@ -1,27 +0,0 @@ -$ANSIBLE_VAULT;1.1;AES256 -37323332646365326338303234343138326439366364323631663634653136363935363865636334 -6534666264666666326235393861356362353932633630390a366334646166623237623233663763 -32323438646339353263366361323632646433643134663666616631316262363539373330633536 -3966623765323965650a613664306466353931643234333837376237303131643932306563346532 -65363634643964613936376661386639303431623534373464636638333238626130316664663666 -33356661313632366531646564366465366530663366326135326133313662323939393566653333 -62393839316330303164646131393162373138613764303864616562666130663035323864383031 -31303536346332393164306162343062616436303138643138653734633630666462633565326234 -66636562663165333863373563373535666533396334363865303237373331633761633838653961 -38383634326530333531656438346238336133613636356238653264303137333839313233656339 -38323730626234643963636662326663353737346332366263373139353962663239663363623736 -38656434386261316136323130646235666139643131313132396536393234373263323735336631 -37623537613164346663363138343238386362646533343837363165353539636539323434393839 -32323633636534623738356338336561653033633939366537653662643430396364383033343663 -37306666353432643636353464333362343162306435363236623866366639663339363339353736 -64663332386662353864303634653539323831396136383565363462316638613530623236623038 -63613262393035303730376164656239646336343133363931613136393362383734363235336637 -34613830633136636130303737636339306332393062656538616133393638613564326534336233 -35623764366232366538363464383334386539333963373066373065323466313033663735626466 -30366430323565333365343036343566663133316236663431393335353930323731633934346636 -38653039653930356633666336333365663833316635353866313965653632363365303165393538 -30666431663838633434363637656365613133323834343630383133396435333061373832633361 -30393730653963303933303934626562373663623265356562376633366238323563623462343162 -32626164663630393831316136303835613362663534383938353965366538653838343539663263 -65663833343834356137366263623331373236323065376536633237613030346135663563333763 -6539613565366337613162366434373430643634393665326666 diff --git a/automation/iac/old-content/Packer/rocky10-proxmox-template/variables.pkr.hcl b/automation/iac/old-content/Packer/rocky10-proxmox-template/variables.pkr.hcl deleted file mode 100644 index 48d1f5a..0000000 --- a/automation/iac/old-content/Packer/rocky10-proxmox-template/variables.pkr.hcl +++ /dev/null @@ -1,15 +0,0 @@ -variable "admin_username" { - default = "admin" -} - -variable "admin_password_hash" { - type = string - sensitive = true -} - -variable "admin_ssh_key" { - type = string -} - -variable "ansible_username" {} -variable "ansible_ssh_key" {} diff --git a/automation/iac/old-content/README.md b/automation/iac/old-content/README.md deleted file mode 100644 index 4439aa7..0000000 --- a/automation/iac/old-content/README.md +++ /dev/null @@ -1,176 +0,0 @@ -# Infrastructure as Code - -This repository contains the full Infrastructure-as-Code stack that builds, configures, and manages my homelab environment. It brings together **Packer**, **Terraform**, and **Ansible** into a single, structured workflow that provisions VM templates, deploys infrastructure on Proxmox, and configures each service automatically. - -[![GitLab repo](https://img.shields.io/badge/GitLab-Public-blue)](https://gitlab.com/) -[![Terraform](https://img.shields.io/badge/Terraform-Blue?logo=terraform&logoColor=white)](https://www.terraform.io/) -[![Packer](https://img.shields.io/badge/Packer-6C9BFF?logo=hashicorp&logoColor=white)](https://www.packer.io/) -[![Ansible](https://img.shields.io/badge/Ansible-Red?logo=ansible&logoColor=white)](https://www.ansible.com/) - -The goal is to maintain everything as code: reproducible, version-controlled, and modular. - ---- - -## 🧱 Repository Structure - -``` -Infrastrucutre-as-Code/ -├── Packer -├── Terraform -├── Ansible -├── SSO -└── README.md -``` - ---- - -## ![Packer badge](https://img.shields.io/badge/Packer-6C9BFF?logo=hashicorp&logoColor=white) **Packer** -Packer -├── rocky10-proxmox-template -│ ├── http -│ │ └── ks.cfg -│ ├── scripts -│ │ ├── setup-admin-user.sh -│ │ └── setup-ansible-user.sh -│ ├── packer.pkr.hcl -│ ├── secure-packer-build.sh -│ ├── terraform.pkrvar.hcl -│ └── variables.pkr.hcl -└── README.md - -Packer is used to create the base OS templates that all my virtual machines are built from. -This includes: - -- Automated OS installation (using a minimal Rocky10 base image) -- Hardening steps during image creation -- Preconfigured admin and automation users and passwordless SSH access for them -- Preparation for provisioning tools such as Ansible - -Each Packer build lives in its own directory containing: - -- `packer.pkr.hcl` build files -- Kickstart / cloud-init automation -- Hardening & configuration scripts - -These ISO's are uploaded to Proxmox as templates to be used by Terraform and form the baseline for the rest of the IaC pipeline. - ---- - -## ![Terraform badge](https://img.shields.io/badge/Terraform-4C9BFF?logo=terraform&logoColor=white) **Terraform** -Terraform -├── host_tags.yml.tpl -├── main.tf -├── providers.tf -├── README.md -├── terraform.tfvars -└── variables.tf - -Terraform handles the infrastructure provisioning layer. -It manages all Proxmox-related resources, including: - -- VM creation from Packer templates -- Network, firewall, and storage definitions -- Infrastructure for identity and trust components -- Modular, reusable Terraform modules - -Terraform defines **what the homelab *is***. - ---- - -## ![Ansible badge](https://img.shields.io/badge/Ansible-FF5A5A?logo=ansible&logoColor=white) **Ansible** -Ansible -├── group_vars -│ ├── all -│ │ └── vault_token.yml -│ └── all.yml -├── host_vars -│ ├── docker-host -│ │ └── host_tags.yml -│ └── haproxy-vm -│ └── host_tags.yml -├── playbooks -│ ├── compliance.yml -│ ├── initialization.yml -│ └── provisioning.yml -├── roles -│ ├── bootstrap_roles -│ │ ├── base_users -│ │ ├── disk_resize -│ │ ├── docker_gitlab_setup -│ │ ├── endlessh -│ │ ├── firewall_ssh -│ │ ├── hostname_network -│ │ ├── packages -│ │ ├── portainer_agent -│ │ ├── root_password -│ │ └── zsh_custom -│ ├── cis_hardening -│ │ ├── banners -│ │ ├── defaults -│ │ ├── file_permissions -│ │ ├── filesystem_hardening -│ │ ├── handlers -│ │ ├── kernel_hardening -│ │ ├── password_policy -│ │ ├── service_disable -│ │ ├── ssh_hardening -│ │ └── tasks -│ └── secure_vault -│ ├── haproxy -│ ├── technitium -│ └── vault_agent -├── ansible.cfg -├── inventory_initialization.yml -├── inventory.yml -├── README.md -├── requirements.yml -└── roles_metadata.yml - -Ansible configures the systems after Terraform brings them online. - -Roles and playbooks in this layer include: - -- Service installation and configuration -- Certificate lifecycle management using Hashicrp Vault -- mTLS enforcement for internal services -- Service deployment and automation -- Modular, reusable roles - -Ansible defines **how the homelab *behaves***. - ---- - -## ![SSO badge](https://img.shields.io/badge/SSO-00C2A2?logo=keycloak&logoColor=white) **SSO** - -This directory contains everything related to the Single Sign-On stack. - -This includes: - -- Identity provider access to all locally routed applications and services behind HAProxy -- Integrations with Vault, HAProxy and mTLS layers for true SSO once mTLS trust is verified - -The goal is to centralize and standardize authentication across the environment. - ---- - -## 🔧 Workflow Overview - -The full workflow follows a simple, layered model: - -1. **Packer** → build secure, repeatable VM templates -2. **Terraform** → instantiate infrastructure from those templates -3. **Ansible** → configure, secure, and deploy services - -Each layer owns a specific responsibility, keeping the stack clean, modular, and easy to reason about. - ---- - -## 📌 Notes - -- Everything here is designed to be reproducible. -- No secrets live in this repository — Vault injects them during provisioning. -- Each component stands alone while participating in the overall pipeline. - ---- - -If you're exploring, a good path is **Packer → Terraform → Ansible** to see how everything connects. diff --git a/automation/iac/old-content/SSO/README.md b/automation/iac/old-content/SSO/README.md deleted file mode 100644 index c3aa823..0000000 --- a/automation/iac/old-content/SSO/README.md +++ /dev/null @@ -1,7 +0,0 @@ -Coming Soon... - -This is the final piece of the IaC pipeline I need to construct. I have tried and tested Authelia, Authentik and Keycloak and none of them can do or fit in with my needs, which are automatically logging in once the mTLS layer provided via HAproxy is verified and access to the local domain granted, for the sign-in to be done. - -I have done some research and it looks like a small python script can be made which will allow for a pre-auth proxy service that sits between HAProxy and the backend apps. - -I have yet to get this fully working and in production. Once it is tested and working this readme and folder will be updated with all the relevant code and information for deployment. \ No newline at end of file diff --git a/automation/iac/old-content/Terraform/README.md b/automation/iac/old-content/Terraform/README.md deleted file mode 100644 index 6ab4b8f..0000000 --- a/automation/iac/old-content/Terraform/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Coming Soon... - -A full explanation of the files in the Terraform folder and how they are laid out in order to consume the Packer built ISO, which has been uploaded into a Proxmox template, for the construction of a VM with specific parameters. \ No newline at end of file diff --git a/automation/iac/old-content/Terraform/host_tags.yml.tpl b/automation/iac/old-content/Terraform/host_tags.yml.tpl deleted file mode 100644 index b658cc3..0000000 --- a/automation/iac/old-content/Terraform/host_tags.yml.tpl +++ /dev/null @@ -1,20 +0,0 @@ -# VM metadata from Terraform provisioning -vmid: ${vmid} -vm_name: ${name} -target_node: ${target_node} -template: ${template} -cores: ${cores} -sockets: ${sockets} -memory: ${memory} -bridge: ${bridge} -macaddr: ${macaddr} -disk_size: ${disk_size}GB -disk_storage: ${disk_storage} -ip: ${ip} -vlan: ${vlan} -vm_tags: -%{ for tag in tags ~} - - ${tag} -%{ endfor ~} - - diff --git a/automation/iac/old-content/Terraform/main.tf b/automation/iac/old-content/Terraform/main.tf deleted file mode 100644 index 0a9bf99..0000000 --- a/automation/iac/old-content/Terraform/main.tf +++ /dev/null @@ -1,108 +0,0 @@ -locals { - ansible_repo_path = var.ansible_repo_path != "" ? var.ansible_repo_path : "${path.module}/../ansible" -} - -resource "proxmox_vm_qemu" "vm" { - for_each = var.vms - agent = 1 - skip_ipv6 = true - vmid = each.value.vmid - name = each.value.name - target_node = each.value.target_node - clone = each.value.template - onboot = each.value.onboot - os_type = "other" - - cpu { - type = "host" - numa = true - cores = each.value.cores - sockets = each.value.sockets - } - - memory = each.value.memory - balloon = 0 - scsihw = "virtio-scsi-pci" - bootdisk = "scsi0" - - disk { - slot = "scsi0" - type = "disk" - storage = each.value.disk_storage - size = each.value.disk_size - format = "qcow2" - discard = true - } - - network { - id = 0 - bridge = each.value.bridge - model = "virtio" - macaddr = each.value.macaddr - tag = each.value.vlan != 0 ? each.value.vlan : null - } - - lifecycle { - ignore_changes = [ - usb, - ] - } - - serial { - id = 0 - } - - tags = length(each.value.tags) > 0 ? join(",", each.value.tags) : null -} - -resource "null_resource" "wait_for_ssh" { - for_each = var.vms - depends_on = [proxmox_vm_qemu.vm] - - connection { - type = "ssh" - host = each.value.ip - user = "ansible" - private_key = file("~/.ssh/auto") - timeout = "5m" - } - - provisioner "local-exec" { - command = </dev/null 2>&1; then - echo "✅ SSH is up!" - exit 0 - fi - echo "Retry $i: SSH not ready yet..." - sleep 10 - done - echo "❌ SSH did not become available on ${each.value.ip} after timeout." - exit 1 - EOT - } -} - -resource "local_file" "host_tags" { - for_each = var.vms - - content = templatefile("${path.module}/host_tags.yml.tpl", { - vmid = each.value.vmid - name = each.value.name - target_node = each.value.target_node - template = each.value.template - cores = each.value.cores - sockets = each.value.sockets - memory = each.value.memory - bridge = each.value.bridge - macaddr = each.value.macaddr - disk_size = each.value.disk_size - disk_storage = each.value.disk_storage - ip = each.value.ip - vlan = each.value.vlan - tags = each.value.tags - }) - - filename = "${local.ansible_repo_path}/host_vars/${each.value.name}/host_tags.yml" -} diff --git a/automation/iac/old-content/Terraform/providers.tf b/automation/iac/old-content/Terraform/providers.tf deleted file mode 100644 index 01de8ce..0000000 --- a/automation/iac/old-content/Terraform/providers.tf +++ /dev/null @@ -1,16 +0,0 @@ -terraform { - required_version = ">= 0.14" - required_providers { - proxmox = { - source = "telmate/proxmox" - version = "3.0.2-rc03" - } - } -} - -provider "proxmox" { - pm_tls_insecure = true - pm_api_url = "https://host:port/api2/json" - pm_api_token_secret = "pm_api_token_secret" - pm_api_token_id = "pm_api_token_id" -} \ No newline at end of file diff --git a/automation/iac/old-content/Terraform/terraform.tfvars b/automation/iac/old-content/Terraform/terraform.tfvars deleted file mode 100644 index c51a405..0000000 --- a/automation/iac/old-content/Terraform/terraform.tfvars +++ /dev/null @@ -1,78 +0,0 @@ -vms = { - haproxy = { - vmid = id number here - name = "vm name" - target_node = "hypervisor node name" - template = "template-name" - onboot = true - cores = 2 - sockets = 1 - memory = 2048 - bridge = "vmbr0" - macaddr = "xx:x:x:x:x:x" - disk_size = 20 - disk_storage = "storage name here" - ip = "xx.xx.xx.x" - gateway = "x.x.x.x" - netmask = "24" - vlan = "0" - startup = { - order = 3 - up = 10 - down = 10 - } - tags = [ - "packages", - "hostname_network", - "root_password", - "disk_resize", - "base_users", - "firewall_ssh", - "endlessh", - "portainer_agent", - "zsh_custom", - "cis_hardening" - ] - } - docker = { - vmid = id number here - name = "vm name" - target_node = "hypervisor node name" - template = "template-name" - onboot = true - cores = 2 - sockets = 1 - memory = 8192 - bridge = "vmbr0" - macaddr = "xx:x:x:x:x:x" - disk_size = 20 - disk_storage = "storage name here" - ip = "xx.xx.xx.x" - gateway = "x.x.x.x" - netmask = "24" - vlan = "0" - startup = { - order = 3 - up = 10 - down = 20 - } - tags = [ - "packages", - "hostname_network", - "root_password", - "disk_resize", - "base_users", - "firewall_ssh", - "endlessh", - "portainer_agent", - "zsh_custom", - "vault_agent", - "cis_hardening", - "docker_gitlab_setup" - "s_nail", - "lynis" - ] - } -} - -ansible_repo_path = "" diff --git a/automation/iac/old-content/Terraform/variables.tf b/automation/iac/old-content/Terraform/variables.tf deleted file mode 100644 index ff93f29..0000000 --- a/automation/iac/old-content/Terraform/variables.tf +++ /dev/null @@ -1,32 +0,0 @@ -variable "vms" { - description = "Map of VMs to create" - type = map(object({ - vmid = number - name = string - target_node = string - template = string - onboot = bool - cores = number - sockets = number - memory = number - bridge = string - macaddr = string - disk_size = number - disk_storage = string - ip = string - gateway = string - netmask = string - vlan = string - startup = object({ - order = number - up = number - down = number - }) - tags = list(string) - })) -} - -variable "ansible_repo_path" { - description = "Path to the ansible repo" - type = string -} diff --git a/caddy-vm/Caddy/Caddyfile b/caddy-vm/Caddy/Caddyfile deleted file mode 100644 index 9e5ae38..0000000 --- a/caddy-vm/Caddy/Caddyfile +++ /dev/null @@ -1,68 +0,0 @@ -# Truncated, sanitized example - real Caddyfile has one block per app. -# Shows the pattern: mTLS + Authentik forward-auth in front of every -# reverse-proxied service. - -{ - servers { - protocols h1 h2 - } -} - -# ------------------------- -# mTLS -# ------------------------- -(local_mtls) { - tls /etc/caddy/certs/example.com.crt /etc/caddy/certs/example.com.key { - client_auth { - mode require_and_verify - - trust_pool file { - pem_file /etc/caddy/certs/example.com.ca.crt - } - } - } -} - -# ------------------------- -# Authentik forward auth -# ------------------------- -(authentik_forward_auth) { - forward_auth http://authentik.internal:9054 { - uri /outpost.goauthentik.io/auth/caddy - - trusted_proxies private_ranges - - header_up Host {host} - header_up X-Forwarded-Host {host} - header_up X-Forwarded-Proto {scheme} - header_up X-Forwarded-For {remote_host} - header_up X-Real-IP {remote_host} - - copy_headers { - X-Authentik-Username - X-Authentik-Email - X-Authentik-Groups - X-Authentik-Uid - } - } -} - -# ------------------------- -# Example app entries -# ------------------------- -app1.example.com { - import local_mtls - import authentik_forward_auth - reverse_proxy http://app1.internal:8080 -} - -app2.example.com { - import local_mtls - reverse_proxy http://app2.internal:9000 { - header_up Host {host} - header_up X-Forwarded-Host {host} - header_up X-Forwarded-Proto {scheme} - header_up X-Forwarded-For {remote_host} - header_up X-Real-IP {remote_host} - } -} diff --git a/caddy-vm/Hawser/docker-compose.yaml b/caddy-vm/Hawser/docker-compose.yaml deleted file mode 100644 index 44f135b..0000000 --- a/caddy-vm/Hawser/docker-compose.yaml +++ /dev/null @@ -1,19 +0,0 @@ -services: - hawser: - image: ghcr.io/finsys/hawser:latest - container_name: hawser - restart: unless-stopped - ports: - - "${HTTP_PORT}:2376" - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - /path/to/hawser/hawser_stacks:/data/stacks - environment: - - TOKEN=${TOKEN} - - TZ=${TZ} - networks: - - hawser-net - -networks: - hawser-net: - external: true diff --git a/monitoring-vm/Hawser/docker-compose.yaml b/monitoring-vm/Hawser/docker-compose.yaml deleted file mode 100644 index 44f135b..0000000 --- a/monitoring-vm/Hawser/docker-compose.yaml +++ /dev/null @@ -1,19 +0,0 @@ -services: - hawser: - image: ghcr.io/finsys/hawser:latest - container_name: hawser - restart: unless-stopped - ports: - - "${HTTP_PORT}:2376" - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - /path/to/hawser/hawser_stacks:/data/stacks - environment: - - TOKEN=${TOKEN} - - TZ=${TZ} - networks: - - hawser-net - -networks: - hawser-net: - external: true diff --git a/rocky-docker-lxc/Kodi-MariaDB/docker-compose.yaml b/rocky-docker-lxc/Kodi-MariaDB/docker-compose.yaml deleted file mode 100644 index 3ef01f8..0000000 --- a/rocky-docker-lxc/Kodi-MariaDB/docker-compose.yaml +++ /dev/null @@ -1,32 +0,0 @@ -services: - mariadb: - image: lscr.io/linuxserver/mariadb:latest - container_name: kodi-mariadb - environment: - - PUID=${PUID} - - PGID=${PGID} - - TZ=${TZ} - - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - - MYSQL_USER=${MYSQL_USER} - - MYSQL_PASSWORD=${MYSQL_PASSWORD} - volumes: - - /path/to/kodi-mariadb:/config - ports: - - ${HTTP_PORT}:3306 - restart: unless-stopped - healthcheck: - test: - [ - "CMD-SHELL", - "mysqladmin ping -h 127.0.0.1 -u root -p${MYSQL_ROOT_PASSWORD} --silent", - ] - interval: 10s - timeout: 5s - retries: 5 - start_period: 30s - networks: - - media-net - -networks: - media-net: - external: true diff --git a/rocky-docker-lxc/CloudCommander/docker-compose.yaml b/stacks/dev-tools/cloudcommander/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/CloudCommander/docker-compose.yaml rename to stacks/dev-tools/cloudcommander/docker-compose.yaml diff --git a/rocky-docker-lxc/IT-Tools/docker-compose.yaml b/stacks/dev-tools/it-tools/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/IT-Tools/docker-compose.yaml rename to stacks/dev-tools/it-tools/docker-compose.yaml diff --git a/rocky-docker-lxc/Ollama/docker-compose.yaml b/stacks/dev-tools/ollama/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Ollama/docker-compose.yaml rename to stacks/dev-tools/ollama/docker-compose.yaml diff --git a/rocky-docker-lxc/Authentik/docker-compose.yaml b/stacks/identity-and-security/authentik/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Authentik/docker-compose.yaml rename to stacks/identity-and-security/authentik/docker-compose.yaml diff --git a/rocky-docker-lxc/Vaultwarden/docker-compose.yaml b/stacks/identity-and-security/vaultwarden/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Vaultwarden/docker-compose.yaml rename to stacks/identity-and-security/vaultwarden/docker-compose.yaml diff --git a/stacks/identity-and-security/wazuh/docker-compose.yaml b/stacks/identity-and-security/wazuh/docker-compose.yaml new file mode 100644 index 0000000..9e43764 --- /dev/null +++ b/stacks/identity-and-security/wazuh/docker-compose.yaml @@ -0,0 +1,106 @@ +name: single-node +# Wazuh App Copyright (C) 2017, Wazuh Inc. (License GPLv2) +services: + wazuh.manager: + image: wazuh/wazuh-manager:4.14.6 + hostname: wazuh.manager + restart: always + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: + soft: 655360 + hard: 655360 + ports: + - "1514:1514" + - "1515:1515" + - "514:514/udp" + - "55000:55000" + env_file: + - .env.secrets # INDEXER_PASSWORD, API_PASSWORD — never committed + environment: + - TZ=${TZ} + - INDEXER_URL=https://wazuh.indexer:9200 + - INDEXER_USERNAME=admin + - FILEBEAT_SSL_VERIFICATION_MODE=full + - SSL_CERTIFICATE_AUTHORITIES=/etc/ssl/root-ca.pem + - SSL_CERTIFICATE=/etc/ssl/filebeat.pem + - SSL_KEY=/etc/ssl/filebeat.key + - API_USERNAME=wazuh-wui + volumes: + - /path/to/wazuh/manager/api_configuration:/var/ossec/api/configuration + - /path/to/wazuh/manager/etc:/var/ossec/etc + - /path/to/wazuh/manager/logs:/var/ossec/logs + - /path/to/wazuh/manager/queue:/var/ossec/queue + - /path/to/wazuh/manager/var_multigroups:/var/ossec/var/multigroups + - /path/to/wazuh/manager/integrations:/var/ossec/integrations + - /path/to/wazuh/manager/active_response:/var/ossec/active-response/bin + - /path/to/wazuh/manager/agentless:/var/ossec/agentless + - /path/to/wazuh/manager/wodles:/var/ossec/wodles + - /path/to/wazuh/manager/filebeat_etc:/etc/filebeat + - /path/to/wazuh/manager/filebeat_var:/var/lib/filebeat + - ./config/wazuh_indexer_ssl_certs/root-ca-manager.pem:/etc/ssl/root-ca.pem + - ./config/wazuh_indexer_ssl_certs/wazuh.manager.pem:/etc/ssl/filebeat.pem + - ./config/wazuh_indexer_ssl_certs/wazuh.manager-key.pem:/etc/ssl/filebeat.key + - ./config/wazuh_cluster/wazuh_manager.conf:/wazuh-config-mount/etc/ossec.conf + + wazuh.indexer: + image: wazuh/wazuh-indexer:4.14.6 + hostname: wazuh.indexer + restart: always + ports: + - "9200:9200" + environment: + - TZ=${TZ} + - "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g" + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: + soft: 65536 + hard: 65536 + volumes: + - /path/to/wazuh/indexer/data:/var/lib/wazuh-indexer + - ./config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-indexer/config/certs/root-ca.pem + - ./config/wazuh_indexer_ssl_certs/wazuh.indexer-key.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.key + - ./config/wazuh_indexer_ssl_certs/wazuh.indexer.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.pem + - ./config/wazuh_indexer_ssl_certs/admin.pem:/usr/share/wazuh-indexer/config/certs/admin.pem + - ./config/wazuh_indexer_ssl_certs/admin-key.pem:/usr/share/wazuh-indexer/config/certs/admin-key.pem + - ./config/wazuh_indexer/wazuh.indexer.yml:/usr/share/wazuh-indexer/config/opensearch.yml + - ./config/wazuh_indexer/internal_users.yml:/usr/share/wazuh-indexer/config/opensearch-security/internal_users.yml + + wazuh.dashboard: + image: wazuh/wazuh-dashboard:4.14.6 + hostname: wazuh.dashboard + restart: always + ports: + - 443:5601 + env_file: + - .env.secrets # INDEXER_PASSWORD, DASHBOARD_PASSWORD, API_PASSWORD — never committed + environment: + - TZ=${TZ} + - INDEXER_USERNAME=admin + - WAZUH_API_URL=https://wazuh.manager + - DASHBOARD_USERNAME=kibanaserver + - API_USERNAME=wazuh-wui + entrypoint: + - /bin/sh + - -c + - | + sed "s/__API_USERNAME__/$$API_USERNAME/;s/__API_PASSWORD__/$$API_PASSWORD/" /wazuh-config-mount/wazuh.yml.tpl > /usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml + exec /entrypoint.sh + volumes: + - ./config/wazuh_indexer_ssl_certs/wazuh.dashboard.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem + - ./config/wazuh_indexer_ssl_certs/wazuh.dashboard-key.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem + - ./config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-dashboard/certs/root-ca.pem + - ./config/wazuh_dashboard/opensearch_dashboards.yml:/usr/share/wazuh-dashboard/config/opensearch_dashboards.yml + - ./config/wazuh_dashboard/wazuh.yml.tpl:/wazuh-config-mount/wazuh.yml.tpl:ro + - /path/to/wazuh/dashboard/config:/usr/share/wazuh-dashboard/data/wazuh/config + - /path/to/wazuh/dashboard/custom:/usr/share/wazuh-dashboard/plugins/wazuh/public/assets/custom + depends_on: + - wazuh.indexer + links: + - wazuh.indexer:wazuh.indexer + - wazuh.manager:wazuh.manager diff --git a/rocky-docker-lxc/Audiobookshelf/docker-compose.yaml b/stacks/media/audiobookshelf/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Audiobookshelf/docker-compose.yaml rename to stacks/media/audiobookshelf/docker-compose.yaml diff --git a/rocky-docker-lxc/Bazarr/docker-compose.yaml b/stacks/media/bazarr/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Bazarr/docker-compose.yaml rename to stacks/media/bazarr/docker-compose.yaml diff --git a/rocky-docker-lxc/Beets/docker-compose.yaml b/stacks/media/beets/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Beets/docker-compose.yaml rename to stacks/media/beets/docker-compose.yaml diff --git a/rocky-docker-lxc/Calibre-Web/docker-compose.yaml b/stacks/media/calibre-web-automated/docker-compose.yaml similarity index 72% rename from rocky-docker-lxc/Calibre-Web/docker-compose.yaml rename to stacks/media/calibre-web-automated/docker-compose.yaml index 2fd53e5..77e6524 100644 --- a/rocky-docker-lxc/Calibre-Web/docker-compose.yaml +++ b/stacks/media/calibre-web-automated/docker-compose.yaml @@ -6,10 +6,12 @@ services: - TZ=${TZ} - DOCKER_MODS=linuxserver/mods:universal-calibre volumes: - - /path/to/calibre-web:/config + - /path/to/calibre-web/config:/config - /path/to/media/calibre:/calibre-library - /path/to/calibre-web/ingest:/cwa-book-ingest - # This is an ingest dir, NOT a library one. Anything added here will be automatically added to your library according to the settings you have configured in CWA Settings page. All files placed here are REMOVED AFTER PROCESSING + # This is an ingest dir, NOT a library one. Anything added here is + # automatically added to the library per CWA's own settings, and + # removed after processing. ports: - ${HTTP_PORT}:8083 restart: unless-stopped diff --git a/rocky-docker-lxc/Calibre/docker-compose.yaml b/stacks/media/calibre/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Calibre/docker-compose.yaml rename to stacks/media/calibre/docker-compose.yaml diff --git a/rocky-docker-lxc/Emby/docker-compose.yaml b/stacks/media/emby/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Emby/docker-compose.yaml rename to stacks/media/emby/docker-compose.yaml diff --git a/rocky-docker-lxc/Immich/docker-compose.yaml b/stacks/media/immich/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Immich/docker-compose.yaml rename to stacks/media/immich/docker-compose.yaml diff --git a/rocky-docker-lxc/Jellyfin/docker-compose.yaml b/stacks/media/jellyfin/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Jellyfin/docker-compose.yaml rename to stacks/media/jellyfin/docker-compose.yaml diff --git a/stacks/media/kodi/docker-compose.yaml b/stacks/media/kodi/docker-compose.yaml new file mode 100644 index 0000000..c7ed6b7 --- /dev/null +++ b/stacks/media/kodi/docker-compose.yaml @@ -0,0 +1,56 @@ +services: + mariadb: + image: mariadb:latest + container_name: kodi-mariadb + env_file: + - .env.secrets # MYSQL_ROOT_PASSWORD, MYSQL_PASSWORD — never committed + environment: + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} + - MYSQL_USER=${MYSQL_USER} + volumes: + - /path/to/kodi-mariadb:/config + ports: + - ${HTTP_PORT}:3306 + restart: unless-stopped + healthcheck: + test: + [ + "CMD-SHELL", + "mysqladmin ping -h 127.0.0.1 -u root -p$$MYSQL_ROOT_PASSWORD --silent", + ] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + networks: + - media-net + + # A small custom bridge service, not an off-the-shelf image - polls Kodi's + # own API and keeps a separate media-library tool's watch-state in sync. + kodi-ma-bridge: + image: python:3.13-slim + container_name: kodi-ma-bridge + restart: unless-stopped + working_dir: /app + volumes: + - ./bridge.py:/app/bridge.py:ro + - ./requirements.txt:/app/requirements.txt:ro + command: sh -c "pip install --no-cache-dir -r requirements.txt && python bridge.py" + env_file: + - .env.secrets # KODI_PASSWORD, MA_API_TOKEN — never committed + environment: + - TZ=${TZ} + - MA_BASE_URL=${MA_BASE_URL} + - KODI_USER=${KODI_USER} + - KODI_INSTANCES=${KODI_INSTANCES} + - POLL_INTERVAL_SECONDS=${POLL_INTERVAL_SECONDS} + - REFILL_THRESHOLD=${REFILL_THRESHOLD} + - REFILL_COUNT=${REFILL_COUNT} + networks: + - media-net + +networks: + media-net: + external: true diff --git a/rocky-docker-lxc/Lidarr/docker-compose.yaml b/stacks/media/lidarr/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Lidarr/docker-compose.yaml rename to stacks/media/lidarr/docker-compose.yaml diff --git a/rocky-docker-lxc/Music-Assistant/docker-compose.yaml b/stacks/media/music-assistant/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Music-Assistant/docker-compose.yaml rename to stacks/media/music-assistant/docker-compose.yaml diff --git a/rocky-docker-lxc/Prowlarr/docker-compose.yaml b/stacks/media/prowlarr/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Prowlarr/docker-compose.yaml rename to stacks/media/prowlarr/docker-compose.yaml diff --git a/rocky-docker-lxc/qBittorrent/docker-compose.yaml b/stacks/media/qbittorrent/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/qBittorrent/docker-compose.yaml rename to stacks/media/qbittorrent/docker-compose.yaml diff --git a/rocky-docker-lxc/Radarr/docker-compose.yaml b/stacks/media/radarr/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Radarr/docker-compose.yaml rename to stacks/media/radarr/docker-compose.yaml diff --git a/rocky-docker-lxc/Seerr/docker-compose.yaml b/stacks/media/seerr/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Seerr/docker-compose.yaml rename to stacks/media/seerr/docker-compose.yaml diff --git a/rocky-docker-lxc/Sonarr/docker-compose.yaml b/stacks/media/sonarr/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Sonarr/docker-compose.yaml rename to stacks/media/sonarr/docker-compose.yaml diff --git a/rocky-docker-lxc/Tdarr/docker-compose.yaml b/stacks/media/tdarr/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Tdarr/docker-compose.yaml rename to stacks/media/tdarr/docker-compose.yaml diff --git a/rocky-docker-lxc/TinyMediaManager/docker-compose.yaml b/stacks/media/tinymediamanager/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/TinyMediaManager/docker-compose.yaml rename to stacks/media/tinymediamanager/docker-compose.yaml diff --git a/stacks/platform/caddy-internal/docker-compose.yaml b/stacks/platform/caddy-internal/docker-compose.yaml new file mode 100644 index 0000000..cb3bc84 --- /dev/null +++ b/stacks/platform/caddy-internal/docker-compose.yaml @@ -0,0 +1,19 @@ +services: + caddy: + image: caddy:latest + container_name: caddy-internal + restart: unless-stopped + ports: + - "${HTTPS_PORT}:443" + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile + - /path/to/caddy-internal/caddy_data:/data + - /path/to/caddy-internal/caddy_config:/config + - /path/to/caddy-internal/logs:/var/log/caddy + - ./certs/pki_int_ca.crt:/etc/caddy/certs/pki_int_ca.crt:ro + networks: + - caddy-net + +networks: + caddy-net: + external: true diff --git a/caddy-vm/Caddy/docker-compose.yaml b/stacks/platform/caddy/docker-compose.yaml similarity index 100% rename from caddy-vm/Caddy/docker-compose.yaml rename to stacks/platform/caddy/docker-compose.yaml diff --git a/rocky-docker-lxc/Dashy/docker-compose.yaml b/stacks/platform/dashy/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Dashy/docker-compose.yaml rename to stacks/platform/dashy/docker-compose.yaml diff --git a/stacks/platform/docker-socket-proxy-mirror/docker-compose.yaml b/stacks/platform/docker-socket-proxy-mirror/docker-compose.yaml new file mode 100644 index 0000000..704653d --- /dev/null +++ b/stacks/platform/docker-socket-proxy-mirror/docker-compose.yaml @@ -0,0 +1,9 @@ +services: + docker-socket-proxy-mirror: + container_name: docker-socket-proxy-mirror + image: tecnativa/docker-socket-proxy + restart: "no" + # No docker.sock mounted deliberately - this container never actually + # proxies anything, it only exists as a self-hosted-registry mirror + # build target. Real consumers mount their own socket with their own + # distinct permission sets. diff --git a/rocky-docker-lxc/Docker-Socket-Proxy/docker-compose.yaml b/stacks/platform/docker-socket-proxy/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Docker-Socket-Proxy/docker-compose.yaml rename to stacks/platform/docker-socket-proxy/docker-compose.yaml diff --git a/rocky-docker-lxc/Dockhand/docker-compose.yaml b/stacks/platform/dockhand/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Dockhand/docker-compose.yaml rename to stacks/platform/dockhand/docker-compose.yaml diff --git a/automation/automation-vm/Gitea/docker-compose.yaml b/stacks/platform/gitea/docker-compose.yaml similarity index 100% rename from automation/automation-vm/Gitea/docker-compose.yaml rename to stacks/platform/gitea/docker-compose.yaml diff --git a/monitoring-vm/Grafana-Stack/docker-compose.yaml b/stacks/platform/grafana-stack/docker-compose.yaml similarity index 100% rename from monitoring-vm/Grafana-Stack/docker-compose.yaml rename to stacks/platform/grafana-stack/docker-compose.yaml diff --git a/automation/automation-vm/Hawser/docker-compose.yaml b/stacks/platform/hawser/docker-compose.yaml similarity index 100% rename from automation/automation-vm/Hawser/docker-compose.yaml rename to stacks/platform/hawser/docker-compose.yaml diff --git a/automation/automation-vm/Kestra/docker-compose.yaml b/stacks/platform/kestra/docker-compose.yaml similarity index 100% rename from automation/automation-vm/Kestra/docker-compose.yaml rename to stacks/platform/kestra/docker-compose.yaml diff --git a/rocky-docker-lxc/Kopia/docker-compose.yaml b/stacks/platform/kopia/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Kopia/docker-compose.yaml rename to stacks/platform/kopia/docker-compose.yaml diff --git a/stacks/platform/mariadb-latest/docker-compose.yaml b/stacks/platform/mariadb-latest/docker-compose.yaml new file mode 100644 index 0000000..ac2bdb9 --- /dev/null +++ b/stacks/platform/mariadb-latest/docker-compose.yaml @@ -0,0 +1,16 @@ +services: + mariadb-latest: + container_name: mariadb-latest + image: mariadb:latest + restart: "no" + environment: + # No real data lives here - this is a thin self-hosted-registry mirror + # build target, not a running database. Random root password since + # the base image needs some root-auth setting to initialize at all. + - MYSQL_RANDOM_ROOT_PASSWORD=true + healthcheck: + test: ["CMD-SHELL", "mariadb-admin ping -h 127.0.0.1 -u root || exit 1"] + interval: 5s + timeout: 5s + retries: 10 + start_period: 15s diff --git a/automation/automation-vm/Mosquitto/docker-compose.yaml b/stacks/platform/mosquitto/docker-compose.yaml similarity index 100% rename from automation/automation-vm/Mosquitto/docker-compose.yaml rename to stacks/platform/mosquitto/docker-compose.yaml diff --git a/stacks/platform/mysql-8/docker-compose.yaml b/stacks/platform/mysql-8/docker-compose.yaml new file mode 100644 index 0000000..fbd8844 --- /dev/null +++ b/stacks/platform/mysql-8/docker-compose.yaml @@ -0,0 +1,15 @@ +services: + mysql-8: + container_name: mysql-8 + image: mysql:8 + restart: "no" + environment: + # No real data lives here - a thin self-hosted-registry mirror build + # target, not a running database. + - MYSQL_RANDOM_ROOT_PASSWORD=yes + healthcheck: + test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 || exit 1"] + interval: 5s + timeout: 5s + retries: 10 + start_period: 20s diff --git a/rocky-docker-lxc/NocoDB/docker-compose.yaml b/stacks/platform/nocodb/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/NocoDB/docker-compose.yaml rename to stacks/platform/nocodb/docker-compose.yaml diff --git a/automation/automation-vm/Node-RED/docker-compose.yaml b/stacks/platform/node-red/docker-compose.yaml similarity index 100% rename from automation/automation-vm/Node-RED/docker-compose.yaml rename to stacks/platform/node-red/docker-compose.yaml diff --git a/stacks/platform/postgres-18-alpine/docker-compose.yaml b/stacks/platform/postgres-18-alpine/docker-compose.yaml new file mode 100644 index 0000000..3c1d03c --- /dev/null +++ b/stacks/platform/postgres-18-alpine/docker-compose.yaml @@ -0,0 +1,17 @@ +services: + postgres-18-alpine: + container_name: postgres-18-alpine + image: postgres:18-alpine + restart: "no" + environment: + # No real data lives here - a thin self-hosted-registry mirror build + # target so other stacks can pull the result. trust auth is fine + # since nothing reaches it but the health check below - Postgres + # refuses to start at all without some password/auth method set. + - POSTGRES_HOST_AUTH_METHOD=trust + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + timeout: 5s + retries: 10 + start_period: 10s diff --git a/rocky-docker-lxc/Speedtest-Tracker/docker-compose.yaml b/stacks/platform/speedtest-tracker/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Speedtest-Tracker/docker-compose.yaml rename to stacks/platform/speedtest-tracker/docker-compose.yaml diff --git a/stacks/platform/valkey-9.0-alpine/docker-compose.yaml b/stacks/platform/valkey-9.0-alpine/docker-compose.yaml new file mode 100644 index 0000000..27ba3b0 --- /dev/null +++ b/stacks/platform/valkey-9.0-alpine/docker-compose.yaml @@ -0,0 +1,11 @@ +services: + valkey-9.0-alpine: + container_name: valkey-9.0-alpine + image: valkey/valkey:9.0-alpine + restart: "no" + healthcheck: + test: ["CMD", "valkey-cli", "ping"] + interval: 5s + timeout: 5s + retries: 10 + start_period: 10s diff --git a/rocky-docker-lxc/Actual/docker-compose.yaml b/stacks/productivity/actual/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Actual/docker-compose.yaml rename to stacks/productivity/actual/docker-compose.yaml diff --git a/rocky-docker-lxc/Bookstack/docker-compose.yaml b/stacks/productivity/bookstack/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Bookstack/docker-compose.yaml rename to stacks/productivity/bookstack/docker-compose.yaml diff --git a/stacks/productivity/firefly-iii/docker-compose.yaml b/stacks/productivity/firefly-iii/docker-compose.yaml new file mode 100644 index 0000000..c0fbf04 --- /dev/null +++ b/stacks/productivity/firefly-iii/docker-compose.yaml @@ -0,0 +1,49 @@ +services: + fireflyiii: + image: fireflyiii/core:latest + container_name: fireflyiii_app + restart: unless-stopped + depends_on: + - mariadb + env_file: + - .env.secrets # APP_KEY, DB_PASSWORD — never committed + environment: + - DB_CONNECTION=mysql + - DB_HOST=mariadb + - DB_PORT=3306 + - DB_DATABASE=fireflyiii + - DB_USERNAME=fireflyuser + - TZ=${TZ} + - TRUSTED_PROXIES=** + - APP_ENV=production + - AUTHENTICATION_GUARD=${AUTHENTICATION_GUARD} + - AUTHENTICATION_GUARD_HEADER=${AUTHENTICATION_GUARD_HEADER} + volumes: + - /path/to/fireflyiii/firefly_iii_upload:/var/www/html/storage/upload + ports: + - "${HTTP_PORT}:8080" + networks: + - firefly-net + + mariadb: + image: mariadb:latest + container_name: fireflyiii_db + restart: unless-stopped + env_file: + - .env.secrets # MYSQL_PASSWORD, MYSQL_ROOT_PASSWORD — never committed + environment: + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} + - MYSQL_DATABASE=fireflyiii + - MYSQL_USER=fireflyuser + volumes: + - /path/to/fireflyiii/firefly_iii_db:/config + ports: + - "${DB_PORT}:3306" + networks: + - firefly-net + +networks: + firefly-net: + external: true diff --git a/rocky-docker-lxc/Ghost/docker-compose.yaml b/stacks/productivity/ghost/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Ghost/docker-compose.yaml rename to stacks/productivity/ghost/docker-compose.yaml diff --git a/automation/automation-vm/Home-Assistant/docker-compose.yaml b/stacks/productivity/home-assistant/docker-compose.yaml similarity index 100% rename from automation/automation-vm/Home-Assistant/docker-compose.yaml rename to stacks/productivity/home-assistant/docker-compose.yaml diff --git a/rocky-docker-lxc/Joplin/docker-compose.yaml b/stacks/productivity/joplin/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Joplin/docker-compose.yaml rename to stacks/productivity/joplin/docker-compose.yaml diff --git a/automation/automation-vm/N8n/docker-compose.yaml b/stacks/productivity/n8n/docker-compose.yaml similarity index 100% rename from automation/automation-vm/N8n/docker-compose.yaml rename to stacks/productivity/n8n/docker-compose.yaml diff --git a/rocky-docker-lxc/Nextcloud/docker-compose.yaml b/stacks/productivity/nextcloud/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Nextcloud/docker-compose.yaml rename to stacks/productivity/nextcloud/docker-compose.yaml diff --git a/stacks/productivity/nocodb-content/docker-compose.yaml b/stacks/productivity/nocodb-content/docker-compose.yaml new file mode 100644 index 0000000..4fd249c --- /dev/null +++ b/stacks/productivity/nocodb-content/docker-compose.yaml @@ -0,0 +1,41 @@ +services: + nocodb: + image: nocodb/nocodb:latest + container_name: nocodb-content + restart: unless-stopped + ports: + - "${HTTP_PORT}:8080" + depends_on: + nocodb_db: + condition: service_healthy + env_file: + - .env.secrets # NC_DB, NC_AUTH_JWT_SECRET — never committed + volumes: + - /path/to/nocodb-content/nc_data:/usr/app/data + networks: + - nocodb-content-net + + nocodb_db: + image: postgres:18-alpine + container_name: nocodb-content-postgres + restart: unless-stopped + env_file: + - .env.secrets # POSTGRES_PASSWORD — never committed + environment: + TZ: ${TZ} + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + volumes: + - /path/to/nocodb-content/db_data:/var/lib/postgresql + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 10 + start_period: 20s + networks: + - nocodb-content-net + +networks: + nocodb-content-net: + external: true diff --git a/rocky-docker-lxc/Paperless-NGX/docker-compose.yaml b/stacks/productivity/paperless-ngx/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Paperless-NGX/docker-compose.yaml rename to stacks/productivity/paperless-ngx/docker-compose.yaml diff --git a/stacks/productivity/postiz/docker-compose.yaml b/stacks/productivity/postiz/docker-compose.yaml new file mode 100644 index 0000000..96eeee9 --- /dev/null +++ b/stacks/productivity/postiz/docker-compose.yaml @@ -0,0 +1,157 @@ +services: + postiz: + image: ghcr.io/gitroomhq/postiz-app:latest + container_name: postiz + restart: unless-stopped + env_file: + - .env.secrets # JWT_SECRET, DATABASE_URL, social-platform client IDs/secrets — never committed + environment: + TZ: ${TZ} + MAIN_URL: ${MAIN_URL} + FRONTEND_URL: ${FRONTEND_URL} + NEXT_PUBLIC_BACKEND_URL: ${NEXT_PUBLIC_BACKEND_URL} + BACKEND_INTERNAL_URL: ${BACKEND_INTERNAL_URL} + REDIS_URL: redis://postiz-redis:6379 + TEMPORAL_ADDRESS: temporal:7233 + IS_GENERAL: "true" + DISABLE_REGISTRATION: ${DISABLE_REGISTRATION} + STORAGE_PROVIDER: ${STORAGE_PROVIDER} + UPLOAD_DIRECTORY: ${UPLOAD_DIRECTORY} + NEXT_PUBLIC_UPLOAD_DIRECTORY: ${UPLOAD_DIRECTORY} + MASTODON_URL: ${MASTODON_URL} + volumes: + - /path/to/postiz/config:/config/ + - /path/to/postiz/uploads:/uploads/ + ports: + - "${HTTP_PORT}:5000" + depends_on: + postiz-postgres: + condition: service_healthy + postiz-redis: + condition: service_healthy + networks: + - postiz-net + + postiz-postgres: + image: postgres:18-alpine + container_name: postiz-postgres + restart: unless-stopped + env_file: + - .env.secrets # POSTGRES_PASSWORD — never committed + environment: + TZ: ${TZ} + POSTGRES_USER: ${POSTIZ_POSTGRES_USER} + POSTGRES_DB: ${POSTIZ_POSTGRES_DB} + volumes: + - /path/to/postiz/postgres_data:/var/lib/postgresql + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTIZ_POSTGRES_USER} -d ${POSTIZ_POSTGRES_DB}"] + interval: 10s + timeout: 3s + retries: 3 + networks: + - postiz-net + + postiz-redis: + image: valkey/valkey:9.0-alpine + container_name: postiz-redis + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "valkey-cli ping"] + interval: 10s + timeout: 3s + retries: 3 + volumes: + - /path/to/postiz/redis_data:/data + networks: + - postiz-net + + # Temporal stack: required since Postiz v2.12.0 for all background jobs + # (scheduled posting, OAuth token refresh, email digests) — not optional, + # a real surprise in this app's actual deployment footprint. + temporal-elasticsearch: + image: elasticsearch:7.17.27 + container_name: postiz-temporal-elasticsearch + restart: unless-stopped + environment: + - cluster.routing.allocation.disk.threshold_enabled=true + - cluster.routing.allocation.disk.watermark.low=512mb + - cluster.routing.allocation.disk.watermark.high=256mb + - cluster.routing.allocation.disk.watermark.flood_stage=128mb + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms256m -Xmx256m + - xpack.security.enabled=false + volumes: + - /path/to/postiz/temporal_elasticsearch_data:/usr/share/elasticsearch/data + networks: + - postiz-net + + temporal-postgres: + image: postgres:18-alpine + container_name: postiz-temporal-postgres + restart: unless-stopped + env_file: + - .env.secrets.temporal-postgres # POSTGRES_PASSWORD — never committed; separate file, avoids a collision with postiz-postgres + environment: + TZ: ${TZ} + POSTGRES_USER: ${TEMPORAL_POSTGRES_USER} + volumes: + - /path/to/postiz/temporal_postgres_data:/var/lib/postgresql + networks: + - postiz-net + + temporal: + image: temporalio/auto-setup:1.28.1 + container_name: postiz-temporal + restart: unless-stopped + depends_on: + - temporal-postgres + - temporal-elasticsearch + env_file: + - .env.secrets # POSTGRES_PWD — never committed + environment: + - DB=postgres12 + - DB_PORT=5432 + - POSTGRES_USER=${TEMPORAL_POSTGRES_USER} + - POSTGRES_SEEDS=temporal-postgres + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + - ENABLE_ES=true + - ES_SEEDS=temporal-elasticsearch + - ES_VERSION=v7 + - TEMPORAL_NAMESPACE=default + ports: + - "127.0.0.1:${TEMPORAL_PORT}:7233" # gRPC control plane, unauthenticated by default — localhost-only + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + networks: + - postiz-net + + temporal-admin-tools: + image: temporalio/admin-tools:1.28.1-tctl-1.18.4-cli-1.4.1 + container_name: postiz-temporal-admin-tools + restart: unless-stopped + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CLI_ADDRESS=temporal:7233 + depends_on: + - temporal + stdin_open: true + tty: true + networks: + - postiz-net + + temporal-ui: + image: temporalio/ui:2.34.0 + container_name: postiz-temporal-ui + restart: unless-stopped + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CORS_ORIGINS=http://127.0.0.1:${TEMPORAL_UI_PORT} + ports: + - "127.0.0.1:${TEMPORAL_UI_PORT}:8080" # unauthenticated by default — localhost-only, SSH-tunnel to debug + networks: + - postiz-net + +networks: + postiz-net: + external: true diff --git a/rocky-docker-lxc/Trilium/docker-compose.yaml b/stacks/productivity/trilium/docker-compose.yaml similarity index 100% rename from rocky-docker-lxc/Trilium/docker-compose.yaml rename to stacks/productivity/trilium/docker-compose.yaml