diff --git a/docs/domaines.yml b/docs/domaines.yml index bbae793..a700a01 100644 --- a/docs/domaines.yml +++ b/docs/domaines.yml @@ -41,3 +41,4 @@ domaines_publics: - nom: forge # forge.alliance-boreale.ca cible: serveurs_forgejo type: web + port: 3000 # port interne de Forgejo (amont derive : http://:3000) diff --git a/roles/serveurs_nginx/defaults/main.yml b/roles/serveurs_nginx/defaults/main.yml index f319577..0b56e2c 100644 --- a/roles/serveurs_nginx/defaults/main.yml +++ b/roles/serveurs_nginx/defaults/main.yml @@ -19,10 +19,22 @@ serveurs_nginx_taille_max_corps: "16m" serveurs_nginx_redirection_http: true # 80 -> 443 serveurs_nginx_desactiver_defaut: false # retirer le site Debian par defaut -# Sites de reverse proxy. Vide par defaut : aucun site publie. +# Sites de reverse proxy declares a la main. Vide par defaut. +# S'AJOUTENT aux vhosts derives automatiquement de docs/domaines.yml. serveurs_nginx_sites: [] # - nom: forge # domaine: forge.chezlepro.internal # amont: "http://10.1.15.11:3000" # certificat: "/etc/ssl/.../forge.pem" # optionnel, sinon snakeoil # cle: "/etc/ssl/.../forge.key" + +# Groupe edge auquel ce role s'identifie (pour filtrer le champ "edge" de +# docs/domaines.yml). Permet plusieurs edges distincts a terme. +serveurs_nginx_groupe: "serveurs_nginx" + +# Deriver automatiquement des vhosts depuis docs/domaines.yml (bloc "exposition"). +# Pour chaque exposition de type "web" dont l'edge vise ce groupe, un vhost est +# genere : amont = entree "amont" explicite, sinon http://:. Une exposition non resolvable (cible sans hote actif, ou sans +# port) est ignoree (binding declare mais pas encore cablable). +serveurs_nginx_publier_expositions: true diff --git a/roles/serveurs_nginx/tasks/main.yml b/roles/serveurs_nginx/tasks/main.yml index 7f232bc..97a6a4c 100644 --- a/roles/serveurs_nginx/tasks/main.yml +++ b/roles/serveurs_nginx/tasks/main.yml @@ -22,7 +22,7 @@ when: serveurs_nginx_desactiver_defaut | bool notify: Valider et recharger nginx -- name: Deployer les sites reverse proxy +- name: Deployer les sites reverse proxy declares a la main ansible.builtin.template: src: site.conf.j2 dest: "/etc/nginx/sites-available/{{ item.nom }}.conf" @@ -34,7 +34,7 @@ label: "{{ item.nom }}" notify: Valider et recharger nginx -- name: Activer les sites reverse proxy +- name: Activer les sites reverse proxy declares a la main ansible.builtin.file: src: "/etc/nginx/sites-available/{{ item.nom }}.conf" dest: "/etc/nginx/sites-enabled/{{ item.nom }}.conf" @@ -44,6 +44,39 @@ label: "{{ item.nom }}" notify: Valider et recharger nginx +# --- Vhosts derives du registre partage docs/domaines.yml (bloc exposition) --- +- name: Charger le registre des domaines publics + ansible.builtin.include_vars: + file: "{{ role_path }}/../../docs/domaines.yml" + when: serveurs_nginx_publier_expositions | bool + +- name: Lister les expositions destinees a cet edge + ansible.builtin.set_fact: + serveurs_nginx_expositions: >- + {{ (domaines_publics | default({})) | dict2items + | selectattr('value.edge', 'defined') + | selectattr('value.edge', 'equalto', serveurs_nginx_groupe) + | subelements('value.exposition', skip_missing=true) | list }} + when: serveurs_nginx_publier_expositions | bool + +- name: Deployer les vhosts derives des expositions web + ansible.builtin.template: + src: expositions.conf.j2 + dest: /etc/nginx/sites-available/expositions.conf + owner: root + group: root + mode: "0644" + when: serveurs_nginx_publier_expositions | bool + notify: Valider et recharger nginx + +- name: Activer les vhosts derives des expositions web + ansible.builtin.file: + src: /etc/nginx/sites-available/expositions.conf + dest: /etc/nginx/sites-enabled/expositions.conf + state: link + when: serveurs_nginx_publier_expositions | bool + notify: Valider et recharger nginx + - name: Activer et demarrer nginx ansible.builtin.systemd: name: "{{ serveurs_nginx_service_name }}" diff --git a/roles/serveurs_nginx/templates/expositions.conf.j2 b/roles/serveurs_nginx/templates/expositions.conf.j2 new file mode 100644 index 0000000..86747ce --- /dev/null +++ b/roles/serveurs_nginx/templates/expositions.conf.j2 @@ -0,0 +1,50 @@ +# Vhosts derives de docs/domaines.yml (bloc exposition) — gere par Set-OPS +# (role serveurs_nginx). Ne pas editer a la main. +# +# Une exposition de type "web" produit un vhost si son amont est resolvable : +# entree "amont" explicite, sinon http://:. +# Une exposition sans amont resolvable (cible sans hote actif, ou sans port) +# est listee ci-dessous mais NON publiee (binding declare, pas encore cablable). +{% for paire in serveurs_nginx_expositions | default([]) %} +{% set dom = paire.0.key %} +{% set expo = paire.1 %} +{% if (expo.type | default('web')) == 'web' %} +{% set fqdn = dom if expo.nom in ['@', dom] else (expo.nom ~ '.' ~ dom) %} +{% set ns = namespace(amont=(expo.amont | default('', true))) %} +{% if not ns.amont and (groups[expo.cible] | default([]) | length > 0) and (expo.port is defined) and (hostvars[groups[expo.cible] | first].ansible_host is defined) %} +{% set ns.amont = 'http://' ~ hostvars[groups[expo.cible] | first].ansible_host ~ ':' ~ expo.port %} +{% endif %} +{% if ns.amont %} + +# {{ fqdn }} -> {{ expo.cible }} ({{ ns.amont }}) +{% if serveurs_nginx_redirection_http | bool %} +server { + listen 80; + listen [::]:80; + server_name {{ fqdn }}; + return 301 https://$host$request_uri; +} +{% endif %} +server { + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + server_name {{ fqdn }}; + + ssl_certificate {{ serveurs_nginx_certificat }}; + ssl_certificate_key {{ serveurs_nginx_cle }}; + + location / { + proxy_pass {{ ns.amont }}; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +{% else %} + +# (non publie) {{ fqdn }} -> {{ expo.cible }} : amont non resolvable (cible sans hote actif ou sans port). +{% endif %} +{% endif %} +{% endfor %}