--- # Étape 12 : HTTPS par Let's Encrypt. certbot du dépôt Debian (2.1, mis à jour # avec le reste du système par unattended-upgrades), authentificateur nginx # en mode « certonly » : il ne modifie jamais nos fichiers de configuration, # Ansible reste seul maître du vhost. - name: installer Nginx et certbot ansible.builtin.apt: name: [nginx, certbot, python3-certbot-nginx] state: present - name: déployer les extraits TLS et en-têtes de sécurité ansible.builtin.template: src: "{{ item }}.j2" dest: "/etc/nginx/snippets/{{ item }}" mode: "0644" loop: - syllabus-tls.conf - syllabus-entetes.conf notify: recharger nginx # La page de statut n'est servie que si son nom pointe déjà vers ce serveur : # sinon Let's Encrypt refuserait tout le certificat. - name: vérifier le DNS du sous-domaine de statut ansible.builtin.command: getent ahostsv4 {{ portail_domaine_statut }} register: portail_dns_statut changed_when: false failed_when: false - name: noter si la page de statut peut être activée ansible.builtin.set_fact: portail_statut_actif: "{{ portail_ip_publique in portail_dns_statut.stdout }}" portail_noms_certificat: >- {{ [portail_domaine] + portail_domaines_alias + ([portail_domaine_statut] if portail_ip_publique in portail_dns_statut.stdout else []) }} - name: vérifier si le certificat existe déjà ansible.builtin.stat: path: "/etc/letsencrypt/live/{{ portail_domaine }}/fullchain.pem" register: portail_certificat_avant - name: déployer le vhost (HTTP seul tant qu'aucun certificat n'existe) ansible.builtin.template: src: nginx-portail.conf.j2 dest: /etc/nginx/sites-available/portail.conf mode: "0644" vars: portail_https_actif: "{{ portail_certificat_avant.stat.exists }}" notify: recharger nginx - name: activer le vhost ansible.builtin.file: src: /etc/nginx/sites-available/portail.conf dest: /etc/nginx/sites-enabled/portail.conf state: link notify: recharger nginx - name: désactiver le vhost par défaut de Nginx ansible.builtin.file: path: /etc/nginx/sites-enabled/default state: absent notify: recharger nginx - name: activer et démarrer php-fpm et nginx ansible.builtin.systemd: name: "{{ item }}" enabled: true state: started loop: - "php{{ portail_php_version }}-fpm" - nginx - name: appliquer la configuration Nginx avant le défi Let's Encrypt ansible.builtin.meta: flush_handlers # --keep-until-expiring : ne fait rien si le certificat est valide et couvre # déjà ces noms. --expand : ajoute un nom (ex. statut) au même certificat. # Pas d'e-mail : Let's Encrypt n'envoie plus d'avis d'expiration depuis 2025, # et le renouvellement est surveillé par Prometheus (voir supervision). - name: obtenir ou étendre le certificat Let's Encrypt ansible.builtin.command: cmd: >- certbot certonly --nginx --non-interactive --agree-tos --register-unsafely-without-email --cert-name {{ portail_domaine }} {% for nom in portail_noms_certificat %}-d {{ nom }} {% endfor %} --expand --keep-until-expiring --deploy-hook "systemctl reload nginx" register: portail_certbot changed_when: "'Successfully received certificate' in portail_certbot.stdout" - name: passer le vhost en HTTPS ansible.builtin.template: src: nginx-portail.conf.j2 dest: /etc/nginx/sites-available/portail.conf mode: "0644" vars: portail_https_actif: true notify: recharger nginx - name: vérifier que le renouvellement automatique est planifié ansible.builtin.systemd: name: certbot.timer enabled: true state: started # Pas d'e-mail Let's Encrypt : c'est Prometheus qui prévient si le # renouvellement ne se fait pas (règle CertificatExpireBientot). - name: déployer le script de mesure de l'expiration du certificat ansible.builtin.template: src: syllabus-expiration-certificat.sh.j2 dest: /usr/local/sbin/syllabus-expiration-certificat mode: "0755" - name: mesurer l'expiration chaque jour ansible.builtin.cron: name: "expiration du certificat HTTPS (métrique Prometheus)" user: root hour: "6" minute: "17" job: /usr/local/sbin/syllabus-expiration-certificat - name: mesurer l'expiration maintenant ansible.builtin.command: /usr/local/sbin/syllabus-expiration-certificat changed_when: false