diff --git a/roles/traefik/defaults/main.yml b/roles/traefik/defaults/main.yml index 3e43412..c896ae2 100644 --- a/roles/traefik/defaults/main.yml +++ b/roles/traefik/defaults/main.yml @@ -17,62 +17,54 @@ docker_volume_dir: "{{ docker_volume_base_dir }}/{{ service_name }}" traefik_mode: "backend" # SSL configuration -traefik_use_ssl: true -traefik_ssl_email: "admin@example.com" -traefik_ssl_cert_resolver: "dns" # Certificate resolver name +use_ssl: true +ssl_email: "admin@example.com" +ssl_cert_resolver: "dns" # Certificate resolver name # Certificate mode: 'acme' for Let's Encrypt with DNS challenge or 'selfsigned' for self-signed certs -traefik_cert_mode: "selfsigned" # Use selfsigned for vagrant, acme for production +cert_mode: "selfsigned" # Use selfsigned for vagrant, acme for production # ACME DNS Challenge with RFC2136 (TSIG) configuration -traefik_acme_dns_zone: "" # e.g., "digitalboard._acme.digitalboard.ch." -traefik_acme_dns_nameserver: "" # e.g., "192.168.1.1:53" -traefik_acme_tsig_algorithm: "hmac-sha256" -traefik_acme_tsig_key: "" # TSIG key name -traefik_acme_tsig_secret: "" # TSIG secret -traefik_acme_propagation_timeout: "120" -traefik_acme_polling_interval: "2" -traefik_acme_ttl: "60" +acme_dns_zone: "" # e.g., "digitalboard._acme.digitalboard.ch." +acme_dns_nameserver: "" # e.g., "192.168.1.1:53" +acme_tsig_algorithm: "hmac-sha256" +acme_tsig_key: "" # TSIG key name +acme_tsig_secret: "" # TSIG secret +acme_propagation_timeout: "120" +acme_polling_interval: "2" +acme_ttl: "60" # Self-signed certificate configuration (for vagrant/testing) -traefik_selfsigned_cert_dir: "{{ docker_volume_dir }}/certs" -traefik_selfsigned_cert_days: 365 -traefik_selfsigned_common_name: "*.local.test" +selfsigned_cert_dir: "{{ docker_volume_dir }}/certs" +selfsigned_cert_days: 365 +selfsigned_common_name: "*.local.test" # Dashboard -traefik_enable_dashboard: false -traefik_dashboard_domain: "" # e.g., "traefik.local.test" - if set, exposes dashboard via hostname instead of port 8080 +enable_dashboard: false +dashboard_domain: "" # e.g., "traefik.local.test" - if set, exposes dashboard via hostname instead of port 8080 # Access log configuration -traefik_enable_access_logs: true -traefik_access_log_format: "common" -traefik_log_level: "INFO" +enable_access_logs: true +access_log_format: "common" +log_level: "INFO" # Network name traefik_network: "proxy" -# Services to expose through DMZ (defined on backend servers via host_vars) -# The DMZ proxy aggregates these from all backend_servers and auto-populates backend_host -# traefik_dmz_exposed_services: +# Services to expose (defined by application roles via host_vars or group_vars) +# Each backend server should define this variable with their services +# traefik_services: # - name: httpbin # domain: httpbin.example.com # port: 8080 # protocol: http # http or https - -# Services to expose directly on the proxy (for hosts not managed by Ansible) -# Define on the DMZ host itself - requires explicit backend_host -# traefik_services: -# - name: external-api -# domain: api.example.com -# backend_host: 10.0.0.50 # required for direct definitions -# port: 8080 -# protocol: http +# entrypoints: [websecure] # optional, defaults based on SSL config # DMZ mode: Explicit backend server mapping # Define which backend servers this DMZ proxy should route to # If empty or undefined, routes to all servers in backend_servers group -traefik_backend_servers_to_proxy: [] +backend_servers_to_proxy: [] # Example: -# traefik_backend_servers_to_proxy: +# backend_servers_to_proxy: # - backend1 # - backend2 \ No newline at end of file diff --git a/roles/traefik/tasks/main.yml b/roles/traefik/tasks/main.yml index 159ba8f..d9253eb 100644 --- a/roles/traefik/tasks/main.yml +++ b/roles/traefik/tasks/main.yml @@ -4,20 +4,15 @@ - name: Determine which backend servers to proxy (DMZ mode) set_fact: - _backend_servers: "{{ traefik_backend_servers_to_proxy if traefik_backend_servers_to_proxy | length > 0 else groups['backend_servers'] | default([]) }}" + _backend_servers: "{{ backend_servers_to_proxy if backend_servers_to_proxy | length > 0 else groups['backend_servers'] | default([]) }}" when: traefik_mode == 'dmz' - name: Build service registry from backend servers (DMZ mode) set_fact: - proxied_services: "{{ proxied_services | default([]) + hostvars[item].traefik_dmz_exposed_services | default([]) | map('combine', {'backend_host': hostvars[item].ansible_host | default(item)}) | list }}" + proxied_services: "{{ proxied_services | default([]) + hostvars[item].traefik_services | default([]) | map('combine', {'backend_host': hostvars[item].ansible_host | default(item)}) | list }}" loop: "{{ _backend_servers | default([]) }}" when: traefik_mode == 'dmz' -- name: Add directly defined services to registry (DMZ mode) - set_fact: - proxied_services: "{{ proxied_services | default([]) + traefik_services | default([]) }}" - when: traefik_mode == 'dmz' - - name: Debug service registry debug: var: proxied_services @@ -48,7 +43,7 @@ path: "{{ docker_volume_dir }}/letsencrypt" state: directory mode: '0755' - when: traefik_cert_mode == 'acme' + when: cert_mode == 'acme' - name: Create traefik Docker network community.docker.docker_network: @@ -76,14 +71,14 @@ dest: "{{ docker_volume_dir }}/config/dashboard.yml" mode: '0644' notify: restart traefik - when: traefik_enable_dashboard | bool and traefik_dashboard_domain | length > 0 + when: enable_dashboard | bool and dashboard_domain | length > 0 - name: Remove dashboard routing configuration when not needed file: path: "{{ docker_volume_dir }}/config/dashboard.yml" state: absent notify: restart traefik - when: not (traefik_enable_dashboard | bool) or traefik_dashboard_domain | length == 0 + when: not (enable_dashboard | bool) or dashboard_domain | length == 0 - name: Create docker-compose file for traefik template: diff --git a/roles/traefik/templates/dashboard.yml.j2 b/roles/traefik/templates/dashboard.yml.j2 index 7f377b4..8d7e1bf 100644 --- a/roles/traefik/templates/dashboard.yml.j2 +++ b/roles/traefik/templates/dashboard.yml.j2 @@ -1,15 +1,15 @@ -{% set dashboard_ssl = traefik_use_ssl_dashboard | default(traefik_use_ssl) %} +{% set dashboard_ssl = use_ssl_dashboard | default(use_ssl) %} http: routers: dashboard: - rule: "Host(`{{ traefik_dashboard_domain }}`)" + rule: "Host(`{{ dashboard_domain }}`)" service: api@internal entryPoints: - {{ 'websecure' if dashboard_ssl else 'web' }} {% if dashboard_ssl %} tls: -{% if traefik_cert_mode == 'acme' %} - certResolver: {{ traefik_ssl_cert_resolver }} +{% if cert_mode == 'acme' %} + certResolver: {{ ssl_cert_resolver }} {% else %} {} {% endif %} diff --git a/roles/traefik/templates/docker-compose.yml.j2 b/roles/traefik/templates/docker-compose.yml.j2 index e45578b..d40a247 100644 --- a/roles/traefik/templates/docker-compose.yml.j2 +++ b/roles/traefik/templates/docker-compose.yml.j2 @@ -3,26 +3,26 @@ services: image: traefik:latest container_name: traefik restart: always -{% if traefik_cert_mode == 'acme' %} +{% if cert_mode == 'acme' %} environment: - RFC2136_NAMESERVER: "{{ traefik_acme_dns_nameserver }}" - RFC2136_TSIG_ALGORITHM: "{{ traefik_acme_tsig_algorithm }}" - RFC2136_TSIG_KEY: "{{ traefik_acme_tsig_key }}" - RFC2136_TSIG_SECRET: "{{ traefik_acme_tsig_secret }}" - RFC2136_PROPAGATION_TIMEOUT: "{{ traefik_acme_propagation_timeout }}" - RFC2136_POLLING_INTERVAL: "{{ traefik_acme_polling_interval }}" - RFC2136_TTL: "{{ traefik_acme_ttl }}" + RFC2136_NAMESERVER: "{{ acme_dns_nameserver }}" + RFC2136_TSIG_ALGORITHM: "{{ acme_tsig_algorithm }}" + RFC2136_TSIG_KEY: "{{ acme_tsig_key }}" + RFC2136_TSIG_SECRET: "{{ acme_tsig_secret }}" + RFC2136_PROPAGATION_TIMEOUT: "{{ acme_propagation_timeout }}" + RFC2136_POLLING_INTERVAL: "{{ acme_polling_interval }}" + RFC2136_TTL: "{{ acme_ttl }}" {% endif %} ports: - "80:80" - "443:443" -{% if traefik_enable_dashboard and not traefik_dashboard_domain %} +{% if enable_dashboard and not dashboard_domain %} - "8080:8080" {% endif %} volumes: - {{ docker_volume_dir }}/traefik.yml:/traefik.yml:ro - {{ docker_volume_dir }}/config:/config:ro -{% if traefik_cert_mode == 'acme' %} +{% if cert_mode == 'acme' %} - {{ docker_volume_dir }}/letsencrypt:/letsencrypt {% endif %} {% if traefik_mode == 'backend' %} diff --git a/roles/traefik/templates/middlewares.yml.j2 b/roles/traefik/templates/middlewares.yml.j2 index 6a8811d..ba022a4 100644 --- a/roles/traefik/templates/middlewares.yml.j2 +++ b/roles/traefik/templates/middlewares.yml.j2 @@ -1,18 +1,18 @@ -{% if traefik_enable_dashboard %} +{% if enable_dashboard %} api: dashboard: true insecure: true {% endif %} -{% if traefik_enable_access_logs %} +{% if enable_access_logs %} accessLog: - format: {{ traefik_access_log_format }} + format: {{ access_log_format }} {% endif %} entryPoints: web: address: ":80" -{% if traefik_use_ssl %} +{% if use_ssl %} http: redirections: entryPoint: diff --git a/roles/traefik/templates/services.yml.j2 b/roles/traefik/templates/services.yml.j2 index e7168f2..7b8c6dd 100644 --- a/roles/traefik/templates/services.yml.j2 +++ b/roles/traefik/templates/services.yml.j2 @@ -5,11 +5,11 @@ http: rule: "Host(`{{ service.domain }}`)" service: {{ service.name }}-service entryPoints: - - {{ 'websecure' if traefik_use_ssl else 'web' }} -{% if traefik_use_ssl %} + - {{ 'websecure' if use_ssl else 'web' }} +{% if use_ssl %} tls: -{% if traefik_cert_mode == 'acme' %} - certResolver: {{ traefik_ssl_cert_resolver }} +{% if cert_mode == 'acme' %} + certResolver: {{ ssl_cert_resolver }} {% else %} {} {% endif %} @@ -23,12 +23,12 @@ http: passHostHeader: true servers: - url: "{{ service.protocol }}://{{ service.backend_host }}:{{ service.port }}" -{% if service.protocol == 'https' and traefik_cert_mode == 'selfsigned' %} +{% if service.protocol == 'https' and cert_mode == 'selfsigned' %} serversTransport: insecure-transport {% endif %} {% endfor %} -{% if traefik_cert_mode == 'selfsigned' %} +{% if cert_mode == 'selfsigned' %} serversTransports: insecure-transport: insecureSkipVerify: true diff --git a/roles/traefik/templates/traefik.yml.j2 b/roles/traefik/templates/traefik.yml.j2 index 64bf351..92efd44 100644 --- a/roles/traefik/templates/traefik.yml.j2 +++ b/roles/traefik/templates/traefik.yml.j2 @@ -1,23 +1,23 @@ log: - level: {{ traefik_log_level }} + level: {{ log_level }} -{% if traefik_enable_dashboard %} +{% if enable_dashboard %} api: dashboard: true -{% if not traefik_dashboard_domain %} +{% if not dashboard_domain %} insecure: true {% endif %} {% endif %} -{% if traefik_enable_access_logs %} +{% if enable_access_logs %} accessLog: - format: {{ traefik_access_log_format }} + format: {{ access_log_format }} {% endif %} entryPoints: web: address: ":80" -{% if traefik_use_ssl %} +{% if use_ssl %} http: redirections: entryPoint: @@ -38,19 +38,19 @@ providers: exposedByDefault: false {% endif %} -{% if traefik_use_ssl and traefik_cert_mode == 'acme' %} +{% if use_ssl and cert_mode == 'acme' %} certificatesResolvers: - {{ traefik_ssl_cert_resolver }}: + {{ ssl_cert_resolver }}: acme: - email: {{ traefik_ssl_email }} + email: {{ ssl_email }} storage: /letsencrypt/acme.json dnsChallenge: provider: rfc2136 resolvers: - - "{{ traefik_acme_dns_nameserver }}" + - "{{ acme_dns_nameserver }}" {% endif %} -{% if traefik_use_ssl %} +{% if use_ssl %} tls: options: default: