--- # Playbook: create-docker.yml # # But: # - Creer un conteneur LXC Proxmox pret pour Docker # - Activer les options necessaires pour Docker dans LXC # - Installer les paquets de base # - Creer un utilisateur ansible # - Ajouter la cle SSH de ansible-srv # - Ajouter automatiquement le nouveau LXC dans inventory/hosts.ini # # Exemple: # ansible-playbook -i inventory/hosts.ini playbooks/create-docker-lxc.yml \ # -e target_node=pve02 \ # -e lxc_ctid=102 \ # -e lxc_hostname=tracearr \ # -e lxc_ip=10.100.5.102/24 \ # -e lxc_gateway=10.100.5.1 \ # -e lxc_memory=2048 \ # -e lxc_swap=1024 \ # -e lxc_disk=20 \ # -e lxc_inventory_group=tracearr_servers - name: Creer un LXC pret hosts: "{{ target_node }}" become: false gather_facts: false vars: # Identite du conteneur LXC lxc_ctid: 111 lxc_hostname: immichprod # Configuration reseau du conteneur lxc_ip: 10.100.5.111/24 lxc_gateway: 10.100.5.1 lxc_bridge: vmbr0 # Stockages Proxmox # lxc_storage: stockage ou sera cree le disque du conteneur # lxc_template_storage: stockage ou se trouve le template LXC lxc_storage: proxmox-data-nfs lxc_template_storage: proxmox-data-nfs # Template Debian utilise pour creer le conteneur lxc_template: debian-13-standard_13.1-2_amd64.tar.zst # Ressources du conteneur lxc_cores: 2 lxc_memory: 2048 lxc_swap: 1024 lxc_disk: 250 # IP du serveur Ansible # Cette IP sera utilisee dans authorized_keys pour limiter la cle SSH ansible_controller_ip: 10.100.5.100 # Fichier inventaire a mettre a jour automatiquement lxc_inventory_file: "{{ playbook_dir }}/../inventory/hosts.ini" # Groupe Ansible ajoute dans inventory/hosts.ini # Exemple: # lxc_hostname=tracearr -> immich_servers lxc_inventory_group: "{{ lxc_hostname | replace('-', '_') }}_servers" # Parametres Ansible du futur conteneur lxc_ansible_user: ansible lxc_ansible_python_interpreter: /usr/bin/python3 # IP sans le /24 # Exemple: 10.100.5.102/24 -> 10.100.5.102 lxc_ip_address: "{{ lxc_ip.split('/')[0] }}" tasks: # On verifie que le CTID n'existe pas deja. # Le playbook s'arrete si le conteneur existe deja pour eviter # d'ecraser un service existant. - name: Verifier si le CT existe deja command: pct status {{ lxc_ctid }} register: ct_status changed_when: false failed_when: false - name: Arreter si le CT existe deja fail: msg: "CT {{ lxc_ctid }} already exists on this node. Stop to avoid overwrite." when: ct_status.rc == 0 # On copie la cle publique de ansible-srv sur le noeud Proxmox. # Elle sera injectee dans le compte root du LXC au moment du pct create. - name: Copier la cle publique Ansible sur le noeud Proxmox copy: content: "{{ lookup('file', '/root/.ssh/id_ed25519.pub') }}" dest: /tmp/ansible-srv.pub owner: root group: root mode: "0600" # Creation du conteneur LXC. # # --unprivileged 1: # conteneur non privilegie, plus securise # # --features nesting=1,keyctl=1: # options necessaires pour faire tourner Docker dans un LXC # # --ssh-public-keys: # ajoute la cle SSH dans le LXC lors de la creation # # --start 1: # demarre le conteneur directement apres creation - name: Creer le conteneur LXC command: > pct create {{ lxc_ctid }} {{ lxc_template_storage }}:vztmpl/{{ lxc_template }} --hostname {{ lxc_hostname }} --cores {{ lxc_cores }} --memory {{ lxc_memory }} --swap {{ lxc_swap }} --rootfs {{ lxc_storage }}:{{ lxc_disk }} --net0 name=eth0,bridge={{ lxc_bridge }},ip={{ lxc_ip }},gw={{ lxc_gateway }} --ostype debian --unprivileged 1 --features nesting=1,keyctl=1 --ssh-public-keys /tmp/ansible-srv.pub --start 1 register: create_result - name: Afficher le resultat de creation debug: var: create_result.stdout_lines # Petite pause pour laisser le conteneur terminer son premier demarrage. - name: Attendre le premier demarrage pause: seconds: 10 # Mise a jour du cache APT dans le conteneur. - name: Mettre a jour le cache APT dans le CT command: pct exec {{ lxc_ctid }} -- apt update changed_when: false # Installation des paquets minimums. # # openssh-server: acces SSH # sudo: elevation de privileges pour Ansible # python3: obligatoire pour les modules Ansible # curl/gnupg/ca-certificates: utiles pour installer Docker ensuite # nano: edition manuelle si besoin - name: Installer les paquets de base dans le CT command: > pct exec {{ lxc_ctid }} -- apt install -y openssh-server sudo python3 curl ca-certificates gnupg nano changed_when: true - name: Activer SSH dans le CT command: pct exec {{ lxc_ctid }} -- systemctl enable --now ssh changed_when: true # Creation de l'utilisateur ansible. # Cet utilisateur sera utilise pour piloter le LXC via SSH. - name: Creer l utilisateur ansible dans le CT command: pct exec {{ lxc_ctid }} -- bash -c "id ansible || useradd -m -s /bin/bash ansible" changed_when: true - name: Creer le dossier SSH de l utilisateur ansible command: pct exec {{ lxc_ctid }} -- mkdir -p /home/ansible/.ssh changed_when: true # Ajout de la cle publique Ansible dans authorized_keys. # # from="10.100.5.100": # la cle SSH ne peut etre utilisee que depuis ansible-srv # # no-agent-forwarding / no-X11-forwarding / no-port-forwarding: # limite les usages possibles de cette cle - name: Ajouter la cle publique Ansible dans le CT command: > pct exec {{ lxc_ctid }} -- bash -c 'echo "from=\"{{ ansible_controller_ip }}\",no-agent-forwarding,no-X11-forwarding,no-port-forwarding {{ lookup("file", "/root/.ssh/id_ed25519.pub") }}" > /home/ansible/.ssh/authorized_keys' changed_when: true # Permissions SSH strictes. # Sans ces permissions, SSH peut refuser la cle. - name: Corriger les permissions SSH dans le CT command: > pct exec {{ lxc_ctid }} -- bash -c "chown -R ansible:ansible /home/ansible/.ssh && chmod 700 /home/ansible/.ssh && chmod 600 /home/ansible/.ssh/authorized_keys" changed_when: true # Sudo sans mot de passe pour Ansible. # Necessaire pour que les playbooks puissent installer Docker, # copier des fichiers dans /opt/stacks et gerer les services. # # Plus tard, on pourra reduire ces droits. - name: Configurer sudo pour l utilisateur ansible command: > pct exec {{ lxc_ctid }} -- bash -c "echo 'ansible ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/ansible && chmod 440 /etc/sudoers.d/ansible" changed_when: true # Verification de la syntaxe sudoers. # Important: une erreur sudoers peut casser sudo. - name: Verifier le fichier sudoers dans le CT command: pct exec {{ lxc_ctid }} -- visudo -cf /etc/sudoers.d/ansible changed_when: false # On attend que le port SSH du nouveau LXC soit accessible # depuis ansible-srv. - name: Attendre SSH depuis ansible-srv wait_for: host: "{{ lxc_ip_address }}" port: 22 timeout: 120 delegate_to: localhost become: false # Ajout automatique du nouveau LXC dans inventory/hosts.ini. # # blockinfile evite les doublons: # si le bloc existe deja, il est mis a jour. - name: Ajouter le nouveau LXC dans l inventaire Ansible blockinfile: path: "{{ lxc_inventory_file }}" marker: "# {mark} ANSIBLE MANAGED {{ lxc_hostname }}" block: | [{{ lxc_inventory_group }}] {{ lxc_hostname }} ansible_host={{ lxc_ip_address }} ansible_user={{ lxc_ansible_user }} ansible_python_interpreter={{ lxc_ansible_python_interpreter }} delegate_to: localhost become: false - name: Verifier le statut final du CT command: pct status {{ lxc_ctid }} register: final_status changed_when: false - name: Afficher le statut final du CT debug: var: final_status.stdout