Compare commits

..

4 commits

7 changed files with 79 additions and 66 deletions

View file

@ -17,54 +17,62 @@ docker_volume_dir: "{{ docker_volume_base_dir }}/{{ service_name }}"
traefik_mode: "backend" traefik_mode: "backend"
# SSL configuration # SSL configuration
use_ssl: true traefik_use_ssl: true
ssl_email: "admin@example.com" traefik_ssl_email: "admin@example.com"
ssl_cert_resolver: "dns" # Certificate resolver name traefik_ssl_cert_resolver: "dns" # Certificate resolver name
# Certificate mode: 'acme' for Let's Encrypt with DNS challenge or 'selfsigned' for self-signed certs # Certificate mode: 'acme' for Let's Encrypt with DNS challenge or 'selfsigned' for self-signed certs
cert_mode: "selfsigned" # Use selfsigned for vagrant, acme for production traefik_cert_mode: "selfsigned" # Use selfsigned for vagrant, acme for production
# ACME DNS Challenge with RFC2136 (TSIG) configuration # ACME DNS Challenge with RFC2136 (TSIG) configuration
acme_dns_zone: "" # e.g., "digitalboard._acme.digitalboard.ch." traefik_acme_dns_zone: "" # e.g., "digitalboard._acme.digitalboard.ch."
acme_dns_nameserver: "" # e.g., "192.168.1.1:53" traefik_acme_dns_nameserver: "" # e.g., "192.168.1.1:53"
acme_tsig_algorithm: "hmac-sha256" traefik_acme_tsig_algorithm: "hmac-sha256"
acme_tsig_key: "" # TSIG key name traefik_acme_tsig_key: "" # TSIG key name
acme_tsig_secret: "" # TSIG secret traefik_acme_tsig_secret: "" # TSIG secret
acme_propagation_timeout: "120" traefik_acme_propagation_timeout: "120"
acme_polling_interval: "2" traefik_acme_polling_interval: "2"
acme_ttl: "60" traefik_acme_ttl: "60"
# Self-signed certificate configuration (for vagrant/testing) # Self-signed certificate configuration (for vagrant/testing)
selfsigned_cert_dir: "{{ docker_volume_dir }}/certs" traefik_selfsigned_cert_dir: "{{ docker_volume_dir }}/certs"
selfsigned_cert_days: 365 traefik_selfsigned_cert_days: 365
selfsigned_common_name: "*.local.test" traefik_selfsigned_common_name: "*.local.test"
# Dashboard # Dashboard
enable_dashboard: false traefik_enable_dashboard: false
dashboard_domain: "" # e.g., "traefik.local.test" - if set, exposes dashboard via hostname instead of port 8080 traefik_dashboard_domain: "" # e.g., "traefik.local.test" - if set, exposes dashboard via hostname instead of port 8080
# Access log configuration # Access log configuration
enable_access_logs: true traefik_enable_access_logs: true
access_log_format: "common" traefik_access_log_format: "common"
log_level: "INFO" traefik_log_level: "INFO"
# Network name # Network name
traefik_network: "proxy" traefik_network: "proxy"
# Services to expose (defined by application roles via host_vars or group_vars) # Services to expose through DMZ (defined on backend servers via host_vars)
# Each backend server should define this variable with their services # The DMZ proxy aggregates these from all backend_servers and auto-populates backend_host
# traefik_services: # traefik_dmz_exposed_services:
# - name: httpbin # - name: httpbin
# domain: httpbin.example.com # domain: httpbin.example.com
# port: 8080 # port: 8080
# protocol: http # http or https # protocol: http # http or https
# entrypoints: [websecure] # optional, defaults based on SSL config
# 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
# DMZ mode: Explicit backend server mapping # DMZ mode: Explicit backend server mapping
# Define which backend servers this DMZ proxy should route to # Define which backend servers this DMZ proxy should route to
# If empty or undefined, routes to all servers in backend_servers group # If empty or undefined, routes to all servers in backend_servers group
backend_servers_to_proxy: [] traefik_backend_servers_to_proxy: []
# Example: # Example:
# backend_servers_to_proxy: # traefik_backend_servers_to_proxy:
# - backend1 # - backend1
# - backend2 # - backend2

View file

@ -4,15 +4,20 @@
- name: Determine which backend servers to proxy (DMZ mode) - name: Determine which backend servers to proxy (DMZ mode)
set_fact: set_fact:
_backend_servers: "{{ backend_servers_to_proxy if backend_servers_to_proxy | length > 0 else groups['backend_servers'] | default([]) }}" _backend_servers: "{{ traefik_backend_servers_to_proxy if traefik_backend_servers_to_proxy | length > 0 else groups['backend_servers'] | default([]) }}"
when: traefik_mode == 'dmz' when: traefik_mode == 'dmz'
- name: Build service registry from backend servers (DMZ mode) - name: Build service registry from backend servers (DMZ mode)
set_fact: set_fact:
proxied_services: "{{ proxied_services | default([]) + hostvars[item].traefik_services | default([]) | map('combine', {'backend_host': hostvars[item].ansible_host | default(item)}) | list }}" proxied_services: "{{ proxied_services | default([]) + hostvars[item].traefik_dmz_exposed_services | default([]) | map('combine', {'backend_host': hostvars[item].ansible_host | default(item)}) | list }}"
loop: "{{ _backend_servers | default([]) }}" loop: "{{ _backend_servers | default([]) }}"
when: traefik_mode == 'dmz' 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 - name: Debug service registry
debug: debug:
var: proxied_services var: proxied_services
@ -43,7 +48,7 @@
path: "{{ docker_volume_dir }}/letsencrypt" path: "{{ docker_volume_dir }}/letsencrypt"
state: directory state: directory
mode: '0755' mode: '0755'
when: cert_mode == 'acme' when: traefik_cert_mode == 'acme'
- name: Create traefik Docker network - name: Create traefik Docker network
community.docker.docker_network: community.docker.docker_network:
@ -71,14 +76,14 @@
dest: "{{ docker_volume_dir }}/config/dashboard.yml" dest: "{{ docker_volume_dir }}/config/dashboard.yml"
mode: '0644' mode: '0644'
notify: restart traefik notify: restart traefik
when: enable_dashboard | bool and dashboard_domain | length > 0 when: traefik_enable_dashboard | bool and traefik_dashboard_domain | length > 0
- name: Remove dashboard routing configuration when not needed - name: Remove dashboard routing configuration when not needed
file: file:
path: "{{ docker_volume_dir }}/config/dashboard.yml" path: "{{ docker_volume_dir }}/config/dashboard.yml"
state: absent state: absent
notify: restart traefik notify: restart traefik
when: not (enable_dashboard | bool) or dashboard_domain | length == 0 when: not (traefik_enable_dashboard | bool) or traefik_dashboard_domain | length == 0
- name: Create docker-compose file for traefik - name: Create docker-compose file for traefik
template: template:

View file

@ -1,15 +1,15 @@
{% set dashboard_ssl = use_ssl_dashboard | default(use_ssl) %} {% set dashboard_ssl = traefik_use_ssl_dashboard | default(traefik_use_ssl) %}
http: http:
routers: routers:
dashboard: dashboard:
rule: "Host(`{{ dashboard_domain }}`)" rule: "Host(`{{ traefik_dashboard_domain }}`)"
service: api@internal service: api@internal
entryPoints: entryPoints:
- {{ 'websecure' if dashboard_ssl else 'web' }} - {{ 'websecure' if dashboard_ssl else 'web' }}
{% if dashboard_ssl %} {% if dashboard_ssl %}
tls: tls:
{% if cert_mode == 'acme' %} {% if traefik_cert_mode == 'acme' %}
certResolver: {{ ssl_cert_resolver }} certResolver: {{ traefik_ssl_cert_resolver }}
{% else %} {% else %}
{} {}
{% endif %} {% endif %}

View file

@ -3,26 +3,26 @@ services:
image: traefik:latest image: traefik:latest
container_name: traefik container_name: traefik
restart: always restart: always
{% if cert_mode == 'acme' %} {% if traefik_cert_mode == 'acme' %}
environment: environment:
RFC2136_NAMESERVER: "{{ acme_dns_nameserver }}" RFC2136_NAMESERVER: "{{ traefik_acme_dns_nameserver }}"
RFC2136_TSIG_ALGORITHM: "{{ acme_tsig_algorithm }}" RFC2136_TSIG_ALGORITHM: "{{ traefik_acme_tsig_algorithm }}"
RFC2136_TSIG_KEY: "{{ acme_tsig_key }}" RFC2136_TSIG_KEY: "{{ traefik_acme_tsig_key }}"
RFC2136_TSIG_SECRET: "{{ acme_tsig_secret }}" RFC2136_TSIG_SECRET: "{{ traefik_acme_tsig_secret }}"
RFC2136_PROPAGATION_TIMEOUT: "{{ acme_propagation_timeout }}" RFC2136_PROPAGATION_TIMEOUT: "{{ traefik_acme_propagation_timeout }}"
RFC2136_POLLING_INTERVAL: "{{ acme_polling_interval }}" RFC2136_POLLING_INTERVAL: "{{ traefik_acme_polling_interval }}"
RFC2136_TTL: "{{ acme_ttl }}" RFC2136_TTL: "{{ traefik_acme_ttl }}"
{% endif %} {% endif %}
ports: ports:
- "80:80" - "80:80"
- "443:443" - "443:443"
{% if enable_dashboard and not dashboard_domain %} {% if traefik_enable_dashboard and not traefik_dashboard_domain %}
- "8080:8080" - "8080:8080"
{% endif %} {% endif %}
volumes: volumes:
- {{ docker_volume_dir }}/traefik.yml:/traefik.yml:ro - {{ docker_volume_dir }}/traefik.yml:/traefik.yml:ro
- {{ docker_volume_dir }}/config:/config:ro - {{ docker_volume_dir }}/config:/config:ro
{% if cert_mode == 'acme' %} {% if traefik_cert_mode == 'acme' %}
- {{ docker_volume_dir }}/letsencrypt:/letsencrypt - {{ docker_volume_dir }}/letsencrypt:/letsencrypt
{% endif %} {% endif %}
{% if traefik_mode == 'backend' %} {% if traefik_mode == 'backend' %}

View file

@ -1,18 +1,18 @@
{% if enable_dashboard %} {% if traefik_enable_dashboard %}
api: api:
dashboard: true dashboard: true
insecure: true insecure: true
{% endif %} {% endif %}
{% if enable_access_logs %} {% if traefik_enable_access_logs %}
accessLog: accessLog:
format: {{ access_log_format }} format: {{ traefik_access_log_format }}
{% endif %} {% endif %}
entryPoints: entryPoints:
web: web:
address: ":80" address: ":80"
{% if use_ssl %} {% if traefik_use_ssl %}
http: http:
redirections: redirections:
entryPoint: entryPoint:

View file

@ -5,11 +5,11 @@ http:
rule: "Host(`{{ service.domain }}`)" rule: "Host(`{{ service.domain }}`)"
service: {{ service.name }}-service service: {{ service.name }}-service
entryPoints: entryPoints:
- {{ 'websecure' if use_ssl else 'web' }} - {{ 'websecure' if traefik_use_ssl else 'web' }}
{% if use_ssl %} {% if traefik_use_ssl %}
tls: tls:
{% if cert_mode == 'acme' %} {% if traefik_cert_mode == 'acme' %}
certResolver: {{ ssl_cert_resolver }} certResolver: {{ traefik_ssl_cert_resolver }}
{% else %} {% else %}
{} {}
{% endif %} {% endif %}
@ -23,12 +23,12 @@ http:
passHostHeader: true passHostHeader: true
servers: servers:
- url: "{{ service.protocol }}://{{ service.backend_host }}:{{ service.port }}" - url: "{{ service.protocol }}://{{ service.backend_host }}:{{ service.port }}"
{% if service.protocol == 'https' and cert_mode == 'selfsigned' %} {% if service.protocol == 'https' and traefik_cert_mode == 'selfsigned' %}
serversTransport: insecure-transport serversTransport: insecure-transport
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% if cert_mode == 'selfsigned' %} {% if traefik_cert_mode == 'selfsigned' %}
serversTransports: serversTransports:
insecure-transport: insecure-transport:
insecureSkipVerify: true insecureSkipVerify: true

View file

@ -1,23 +1,23 @@
log: log:
level: {{ log_level }} level: {{ traefik_log_level }}
{% if enable_dashboard %} {% if traefik_enable_dashboard %}
api: api:
dashboard: true dashboard: true
{% if not dashboard_domain %} {% if not traefik_dashboard_domain %}
insecure: true insecure: true
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if enable_access_logs %} {% if traefik_enable_access_logs %}
accessLog: accessLog:
format: {{ access_log_format }} format: {{ traefik_access_log_format }}
{% endif %} {% endif %}
entryPoints: entryPoints:
web: web:
address: ":80" address: ":80"
{% if use_ssl %} {% if traefik_use_ssl %}
http: http:
redirections: redirections:
entryPoint: entryPoint:
@ -38,19 +38,19 @@ providers:
exposedByDefault: false exposedByDefault: false
{% endif %} {% endif %}
{% if use_ssl and cert_mode == 'acme' %} {% if traefik_use_ssl and traefik_cert_mode == 'acme' %}
certificatesResolvers: certificatesResolvers:
{{ ssl_cert_resolver }}: {{ traefik_ssl_cert_resolver }}:
acme: acme:
email: {{ ssl_email }} email: {{ traefik_ssl_email }}
storage: /letsencrypt/acme.json storage: /letsencrypt/acme.json
dnsChallenge: dnsChallenge:
provider: rfc2136 provider: rfc2136
resolvers: resolvers:
- "{{ acme_dns_nameserver }}" - "{{ traefik_acme_dns_nameserver }}"
{% endif %} {% endif %}
{% if use_ssl %} {% if traefik_use_ssl %}
tls: tls:
options: options:
default: default: