Commit initial : infrastructure Ansible pour homeserver
- Playbooks Ansible avec rôles (common, cockpit, docker, services) - 30+ stacks Docker Compose avec reverse proxy Traefik - Ansible Vault pour gestion secrets - Intégration CrowdSec pour détection intrusions - Versions images Docker fixées pour reproductibilité
This commit is contained in:
commit
fd01ea59ee
125 changed files with 4768 additions and 0 deletions
4
roles/cockpit/handlers/main.yml
Normal file
4
roles/cockpit/handlers/main.yml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
- name: Redémarrer Cockpit
|
||||
service:
|
||||
name: cockpit
|
||||
state: restarted
|
||||
52
roles/cockpit/tasks/main.yml
Normal file
52
roles/cockpit/tasks/main.yml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
- name: Ajouter la source noble-backports
|
||||
copy:
|
||||
dest: /etc/apt/sources.list.d/noble-backports.sources
|
||||
content: |
|
||||
Types: deb
|
||||
URIs: http://archive.ubuntu.com/ubuntu
|
||||
Suites: noble-backports
|
||||
Components: main universe
|
||||
Architectures: amd64
|
||||
|
||||
- name: Installer les outils nécessaires à add-apt-repository
|
||||
apt:
|
||||
name: software-properties-common
|
||||
state: present
|
||||
update_cache: yes
|
||||
|
||||
- name: Ajouter le PPA pitti/cockpit-files
|
||||
apt_repository:
|
||||
repo: ppa:pitti/cockpit-files
|
||||
state: present
|
||||
|
||||
- name: Mettre à jour la liste des paquets après ajout des sources
|
||||
apt:
|
||||
update_cache: yes
|
||||
cache_valid_time: 3600
|
||||
|
||||
- name: Installer Cockpit depuis noble-backports
|
||||
apt:
|
||||
name: cockpit
|
||||
state: latest
|
||||
default_release: noble-backports
|
||||
|
||||
- name: Installer cockpit-files depuis le PPA
|
||||
apt:
|
||||
name: cockpit-files
|
||||
state: latest
|
||||
|
||||
- name: Activer Cockpit
|
||||
service:
|
||||
name: cockpit
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Créer le fichier cockpit.conf pour Traefik
|
||||
copy:
|
||||
dest: /etc/cockpit/cockpit.conf
|
||||
content: |
|
||||
[WebService]
|
||||
Origins = https://cockpit.local.tellserv.fr
|
||||
ProtocolHeader = X-Forwarded-Proto
|
||||
AllowUnencrypted = true
|
||||
notify: Redémarrer Cockpit
|
||||
4
roles/common/handlers/main.yml
Normal file
4
roles/common/handlers/main.yml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
- name: Restart dnsmasq
|
||||
service:
|
||||
name: dnsmasq
|
||||
state: restarted
|
||||
104
roles/common/tasks/main.yml
Normal file
104
roles/common/tasks/main.yml
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
- name: Installer paquets utilitaires
|
||||
apt:
|
||||
name:
|
||||
- git
|
||||
- curl
|
||||
- htop
|
||||
- firewalld
|
||||
- mergerfs
|
||||
- udev
|
||||
- util-linux
|
||||
- dnsmasq
|
||||
state: latest
|
||||
|
||||
- name: Désactiver systemd-resolved
|
||||
systemd:
|
||||
name: systemd-resolved
|
||||
enabled: no
|
||||
state: stopped
|
||||
|
||||
- name: Supprimer le lien symbolique resolv.conf géré par systemd-resolved
|
||||
file:
|
||||
path: /etc/resolv.conf
|
||||
state: absent
|
||||
|
||||
- name: Créer un nouveau resolv.conf classique pointant sur dnsmasq
|
||||
copy:
|
||||
dest: /etc/resolv.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
content: |
|
||||
nameserver 127.0.0.1
|
||||
|
||||
- name: Configurer dnsmasq pour résolution locale *.local.tellserv.fr et relay pour tellserv.fr (port 53)
|
||||
copy:
|
||||
dest: /etc/dnsmasq.d/tellserv.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
content: |
|
||||
# Résolution locale pour *.local.tellserv.fr
|
||||
address=/.local.tellserv.fr/{{ ansible_default_ipv4.address }}
|
||||
# Serveur DNS en amont par défaut (tout autre domaine)
|
||||
server=1.1.1.1
|
||||
# Écoute sur le port 53
|
||||
listen-address=127.0.0.1,{{ ansible_default_ipv4.address }},100.64.0.2
|
||||
port=53
|
||||
# Ne pas échouer si une interface manque
|
||||
bind-dynamic
|
||||
notify: Restart dnsmasq
|
||||
|
||||
- name: Démarrer et activer dnsmasq
|
||||
service:
|
||||
name: dnsmasq
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Configurer et démarrer firewalld
|
||||
service:
|
||||
name: firewalld
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Ouvrir SSH (22/tcp)
|
||||
firewalld:
|
||||
port: 22/tcp
|
||||
permanent: yes
|
||||
state: enabled
|
||||
|
||||
- name: Ouvrir HTTP (80/tcp) et HTTPS (443/tcp)
|
||||
firewalld:
|
||||
port: "{{ item }}"
|
||||
permanent: yes
|
||||
state: enabled
|
||||
loop:
|
||||
- 80/tcp
|
||||
- 443/tcp
|
||||
|
||||
- name: Ouvrir port DNSMasq (53/udp) pour la résolution locale
|
||||
firewalld:
|
||||
port: 53/udp
|
||||
permanent: yes
|
||||
state: enabled
|
||||
|
||||
- name: Ouvrir port DNSMasq (53/tcp) pour la résolution locale
|
||||
firewalld:
|
||||
port: 53/tcp
|
||||
permanent: yes
|
||||
state: enabled
|
||||
|
||||
- name: Ouvrir port Minecraft (25565/tcp)
|
||||
firewalld:
|
||||
port: 25565/tcp
|
||||
permanent: yes
|
||||
state: enabled
|
||||
|
||||
- name: Reload firewalld to apply changes
|
||||
command: firewall-cmd --reload
|
||||
|
||||
- name: Créer le répertoire de stockage MergerFS
|
||||
file:
|
||||
path: /mnt/storage
|
||||
state: directory
|
||||
mode: '0755'
|
||||
67
roles/docker/tasks/main.yml
Normal file
67
roles/docker/tasks/main.yml
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
- name: Mettre à jour cache apt
|
||||
apt:
|
||||
update_cache: yes
|
||||
- name: Installer les prérequis
|
||||
apt:
|
||||
name:
|
||||
- ca-certificates
|
||||
- curl
|
||||
state: present
|
||||
- name: Créer le répertoire keyrings
|
||||
file:
|
||||
path: /etc/apt/keyrings
|
||||
state: directory
|
||||
mode: '0755'
|
||||
- name: Télécharger la clé GPG Docker
|
||||
get_url:
|
||||
url: https://download.docker.com/linux/ubuntu/gpg
|
||||
dest: /etc/apt/keyrings/docker.asc
|
||||
mode: '0644'
|
||||
- name: Configurer le dépôt Docker
|
||||
shell: |
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
|
||||
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
|
||||
tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
args:
|
||||
executable: /bin/bash
|
||||
creates: /etc/apt/sources.list.d/docker.list
|
||||
- name: Mettre à jour cache apt après ajout du dépôt
|
||||
apt:
|
||||
update_cache: yes
|
||||
- name: Installer Docker Engine et plugins
|
||||
apt:
|
||||
name:
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
- containerd.io
|
||||
- docker-buildx-plugin
|
||||
- docker-compose-plugin
|
||||
state: latest
|
||||
- name: Activer et démarrer le service Docker
|
||||
systemd:
|
||||
name: docker
|
||||
enabled: true
|
||||
state: started
|
||||
- name: Ajouter l'utilisateur au groupe docker (optionnel)
|
||||
user:
|
||||
name: "{{ ansible_user }}"
|
||||
groups: docker
|
||||
append: yes
|
||||
|
||||
- name: Créer le réseau Docker pour Traefik
|
||||
shell: docker network create traefik_network || true
|
||||
become: yes
|
||||
|
||||
- name: Créer le répertoire pour les logs Traefik
|
||||
file:
|
||||
path: /var/log/traefik
|
||||
state: directory
|
||||
mode: '0755'
|
||||
become: yes
|
||||
|
||||
- name: Créer le répertoire pour les certificats Let's Encrypt
|
||||
file:
|
||||
path: /etc/letsencrypt/traefik
|
||||
state: directory
|
||||
mode: '0755'
|
||||
become: yes
|
||||
222
roles/services/tasks/main.yml
Normal file
222
roles/services/tasks/main.yml
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
# =============================================================================
|
||||
# Generate .env files from templates (secrets from Vault)
|
||||
# =============================================================================
|
||||
|
||||
- name: Générer les fichiers .env depuis les templates
|
||||
ansible.builtin.template:
|
||||
src: "{{ playbook_dir }}/templates/env/{{ item }}.env.j2"
|
||||
dest: "{{ playbook_dir }}/stacks/{{ item }}/.env"
|
||||
mode: '0600'
|
||||
loop:
|
||||
- traefik
|
||||
- tinyauth
|
||||
- vaultwarden
|
||||
- crowdsec
|
||||
- photoprism
|
||||
- vikunja
|
||||
- mobilizon
|
||||
- etesync
|
||||
- plex
|
||||
- yamtrack
|
||||
- joal
|
||||
- feedropolis
|
||||
- webdav
|
||||
- searxng
|
||||
- glance
|
||||
- watchtower
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
tags:
|
||||
- env
|
||||
- secrets
|
||||
|
||||
# =============================================================================
|
||||
# Sync stacks to server
|
||||
# =============================================================================
|
||||
|
||||
- name: Synchroniser le dossier stacks depuis la machine de gestion
|
||||
ansible.builtin.copy:
|
||||
src: "{{ playbook_dir }}/stacks/"
|
||||
dest: /opt/stacks/
|
||||
mode: preserve
|
||||
become: yes
|
||||
tags:
|
||||
- sync
|
||||
- deploy
|
||||
|
||||
# =============================================================================
|
||||
# Deploy all stacks
|
||||
# =============================================================================
|
||||
|
||||
- name: Chercher tous les fichiers compose.yml
|
||||
ansible.builtin.find:
|
||||
paths: /opt/stacks
|
||||
patterns: "compose.yml,compose.yaml"
|
||||
recurse: yes
|
||||
register: compose_files
|
||||
tags:
|
||||
- deploy
|
||||
|
||||
- name: Vérifier si les containers existent déjà
|
||||
ansible.builtin.shell: docker ps -a --format {% raw %}"{{.Names}}"{% endraw %}
|
||||
register: existing_containers
|
||||
changed_when: false
|
||||
tags:
|
||||
- deploy
|
||||
|
||||
- name: Arrêter et supprimer les conteneurs existants si nécessaire
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose down
|
||||
chdir: "{{ item.path | dirname }}"
|
||||
loop: "{{ compose_files.files }}"
|
||||
loop_control:
|
||||
label: "{{ item.path | dirname | basename }}"
|
||||
when: item.path | dirname | basename in existing_containers.stdout_lines
|
||||
ignore_errors: yes
|
||||
tags:
|
||||
- deploy
|
||||
|
||||
- name: Mettre à jour les images
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose pull
|
||||
chdir: "{{ item.path | dirname }}"
|
||||
loop: "{{ compose_files.files }}"
|
||||
loop_control:
|
||||
label: "{{ item.path | dirname | basename }}"
|
||||
tags:
|
||||
- deploy
|
||||
- pull
|
||||
|
||||
- name: Déployer chaque stack via docker compose
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d --build
|
||||
chdir: "{{ item.path | dirname }}"
|
||||
loop: "{{ compose_files.files }}"
|
||||
loop_control:
|
||||
label: "{{ item.path | dirname | basename }}"
|
||||
tags:
|
||||
- deploy
|
||||
|
||||
# =============================================================================
|
||||
# Individual stack deployment tasks (use with --tags <stack_name>)
|
||||
# =============================================================================
|
||||
|
||||
- name: Déployer Traefik
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/traefik
|
||||
tags: [traefik, never]
|
||||
|
||||
- name: Déployer CrowdSec
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/crowdsec
|
||||
tags: [crowdsec, never]
|
||||
|
||||
- name: Déployer Vaultwarden
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/vaultwarden
|
||||
tags: [vaultwarden, never]
|
||||
|
||||
- name: Déployer TinyAuth
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/tinyauth
|
||||
tags: [tinyauth, never]
|
||||
|
||||
- name: Déployer Photoprism
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/photoprism
|
||||
tags: [photoprism, never]
|
||||
|
||||
- name: Déployer Vikunja
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/vikunja
|
||||
tags: [vikunja, never]
|
||||
|
||||
- name: Déployer Mobilizon
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/mobilizon
|
||||
tags: [mobilizon, never]
|
||||
|
||||
- name: Déployer Plex
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/plex
|
||||
tags: [plex, never]
|
||||
|
||||
- name: Déployer Kavita
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/kavita
|
||||
tags: [kavita, never]
|
||||
|
||||
- name: Déployer Glance
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/glance
|
||||
tags: [glance, never]
|
||||
|
||||
- name: Déployer Uptime-Kuma
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/uptime-kuma
|
||||
tags: [uptime-kuma, never]
|
||||
|
||||
- name: Déployer Gotify
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/gotify
|
||||
tags: [gotify, never]
|
||||
|
||||
- name: Déployer Paperless
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/paperless
|
||||
tags: [paperless, never]
|
||||
|
||||
- name: Déployer FreshRSS
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/freshrss
|
||||
tags: [freshrss, never]
|
||||
|
||||
- name: Déployer SearXNG
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/searxng
|
||||
tags: [searxng, never]
|
||||
|
||||
- name: Déployer Headscale
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/headscale
|
||||
tags: [headscale, never]
|
||||
|
||||
- name: Déployer Kopia
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/kopia
|
||||
tags: [kopia, never]
|
||||
|
||||
- name: Déployer Blog
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/blog
|
||||
tags: [blog, never]
|
||||
|
||||
- name: Déployer Larabouillere
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/larabouillere
|
||||
tags: [larabouillere, never]
|
||||
|
||||
- name: Déployer Watchtower
|
||||
ansible.builtin.command:
|
||||
cmd: docker compose up -d
|
||||
chdir: /opt/stacks/watchtower
|
||||
tags: [watchtower, never]
|
||||
Loading…
Add table
Add a link
Reference in a new issue