Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added a dynamic file provider and config options (traefik_qs_exposedbydefault, traefik_qs_tls_options, traefik_qs_middlewares) #5

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from
Open
50 changes: 47 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,15 @@ The quick-setup variables are prefixed with `traefik_qs_`.
| `traefik_qs_https_le` | `false` | wether to setup letsencrypt using tls (only if https is enabled) |
| `traefik_qs_https_le_mail` | undefined | the email to use for letsencrypt (**Required**) |
| `traefik_qs_log_level` | `ERROR` | the loglevel to apply |
| `traefik_qs_exposedbydefault` | `true` | If set to false, services that don't have a traefik.enable=true label will be ignored from the resulting routing configuration. |
| `traefik_use_dynamic_file_config` | `false` | Enable use of dynamic configurations with traefik. This is required for using `traefik_qs_tls_options` and `traefik_qs_middlewares`. It can also be used to load custom configurations. Just put the in the directory `traefik_dynamic_file_config_dir`. |
| `traefik_dynamic_file_config_dir` | `{{ traefik_dir }}/dynamic_conf` | Directory to store dynamic configurations to be used by traefik. |
| `traefik_qs_tls_options` | `false` | Three different setups for tls options (modern, intermediate, old) are created according to https://ssl-config.mozilla.org/#server=traefik. |
| `traefik_qs_middlewares` | `false` | Setup default middleware config for hsts-header, xssfilter-header |
| `traefik_container_name` | `'traefik'` | the container name |
| `traefik_network_name` | `'traefik_proxy'` | the network name |
| `traefik_network_ipam_subnet` | `'172.16.1.0/24'` | subnet |
| `traefik_network_ipam_gateway` | `'172.16.1.1'` | gateway |
| `traefik_network_ipam_iprange` | `'172.16.1.0/24'` | iprange |
| `traefik_network_ipam_config` | - subnet: '172.116.1.0/24'<br>gateway: '172.116.1.1'<br>iprange: '172.116.1.0/24' | Network configuration |
| `traefik_network_enable_ipv6` | `'no'` | Set to 'yes' to enable ipv6 |
| `traefik_image` | `'traefik'` | the image used |
| `traefik_add_volumes` | `[]` | additional volumes to mount |
| `traefik_ports` | `['80:80', '443:443']` | the ports shared |
Expand All @@ -85,6 +89,7 @@ The default names of the generated configs are:
- `https`
- Providers:
- `docker`
- `file` (only if `traefik_use_dynamic_file_config` is set to true)
- Certificate Resolvers:
- `letsencrypt`

Expand All @@ -107,13 +112,52 @@ using the traefik yaml config. The following variables can be used:
| `traefik_confkey_tracing` | undefined | [see Docs 📑](https://docs.traefik.io/observability/tracing/overview/) |
| `traefik_confkey_hostResolver` | undefined | [see Docs 📑](https://docs.traefik.io/reference/static-configuration/file/) |
| `traefik_confkey_certificatesResolvers` | undefined | [see Docs 📑](https://docs.traefik.io/https/acme/#certificate-resolvers) |
| `traefik_confkey_middlewares` | undefined | [see Docs 📑](https://doc.traefik.io/traefik/middlewares/overview/) |
| `traefik_confkey_tls` | undefined | [see Docs 📑](https://doc.traefik.io/traefik/https/tls/) |

These keys are merged into the configuration **after** the quick-setup config using
the [`combine()`](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-hashes-dictionaries)
filter in non recursive mode. This allows you to add configuration options as
you need them. If you want to overwrite the quick-setup items, use their key
(as specified above).

#### Dynamic file provider
A dynamic file provider is setup if `traefik_use_dynamic_file_config` is set tu true (disabled by default). It watches a directory which can be configured by `traefik_dynamic_file_config_dir`. This directory is used with the options `traefik_qs_tls_options` and/or `traefik_qs_middlewares`. By setting `traefik_qs_tls_options` and/or `traefik_qs_middlewares` to true specific config files are autogenerated `qs_traefik_tls_options.yml` and/or `qs_traefik_middlewares.yml`. The watched directory can also be used to add/load custom configurations.

##### qs_traefik_tls_options
To use the `qs_traefik_tls_options` option set it and `traefik_use_dynamic_file_config` to true. You can then use three predefined settings (modern, intermediate, old) to secure tls sessions. To use them just set the according tls settings using labels to configure traefik. The example below show the used lables to use letsencrypt and intermediate tls configuration. https is uses a the entrypoint in traefik an everything is forwarded to port 80 of the container.

```yaml
# May be unnecessary depending on Traefik config, but can't hurt
traefik.enable: 'true'
# The container will receive traffic from these subdomains
traefik.http.routers.uniqueconfigname.rule: 'Host(`www.example.com`)'
# address the entrypoint used in traefik config
traefik.http.routers.uniqueconfigname.entrypoints: 'https'
# (The 'default' certificate resolver must be defined in Traefik config)
traefik.http.routers.uniqueconfigname.tls.certResolver: 'letsencrypt'
traefik.http.routers.uniqueconfigname.tls.options: 'intermediate@file'
# address the internal destination
traefik.http.services.uniqueconfigname.loadbalancer.server.port: '80'
```

##### qs_traefik_middlewares
To use the `qs_traefik_middlewares` option set it and `traefik_use_dynamic_file_config` to true. You can then use two predefined settings (hsts-header, xssfilter-header) to secure the web sessions. To use them just set the according middleware settings using labels to configure traefik. The example below show the used lables to use letsencrypt, hsts-header and xssfilter-header configuration. https is uses a the entrypoint in traefik an everything is forwarded to port 80 of the container.

```yaml
# May be unnecessary depending on Traefik config, but can't hurt
traefik.enable: 'true'
# The container will receive traffic from these subdomains
traefik.http.routers.uniqueconfigname.rule: 'Host(`www.example.com`)'
# address the entrypoint used in traefik config
traefik.http.routers.uniqueconfigname.entrypoints: 'https'
# (The 'default' certificate resolver must be defined in Traefik config)
traefik.http.routers.uniqueconfigname.tls.certResolver: 'letsencrypt'
traefik.http.routers.uniqueconfigname.middlewares: hsts-header@file,xssfilter-header@file
# address the internal destination
traefik.http.services.uniqueconfigname.loadbalancer.server.port: '80'
```

## Compatibility with sbaerlocher/ansible.traefik

This role is intended as a continuation of the
Expand Down
38 changes: 24 additions & 14 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,38 @@ traefik_qs_https: "{{ traefik_https | default(false) }}"
traefik_qs_https_redirect: "{{ traefik_https_redirect | default(false) }}"
traefik_qs_https_le: false
traefik_qs_log_level: "{{ traefik_log_level | default('ERROR') }}"
traefik_qs_exposedbydefault: true

traefik_qs_https_custom_ssl: false
traefik_qs_https_custom_ssl_files: []

traefik_use_dynamic_file_config: false
traefik_dynamic_file_config_dir: "{{ traefik_dir }}/dynamic_conf"

#Setup tls options according to https://ssl-config.mozilla.org/#server=traefik&version=2.3.6
#traefik_use_dynamic_file_config has to be true to use this
traefik_qs_tls_options: false

#hsts-header,xssfilter-header
#traefik_use_dynamic_file_config has to be true to use this
traefik_qs_middlewares: false

# service vars
traefik_container_name: 'traefik'
traefik_network_name: "{{ traefik_network }}"
traefik_network_ipam_temp: "{{ traefik_network_ipam | default({}) }}"
traefik_network_ipam_subnet: "{{
traefik_network_ipam_temp.subnet
| default('172.16.1.0/24')
}}"
traefik_network_ipam_gateway: "{{
traefik_network_ipam_temp.gateway
| default('172.16.1.1')
}}"
traefik_network_ipam_iprange: "{{
traefik_network_ipam_temp.iprange
| default('172.16.1.0/24')
}}"
traefik_network_enable_ipv6: no
traefik_network_ipam_config:
- subnet: '172.116.1.0/24'
gateway: '172.116.1.1'
iprange: '172.116.1.0/24'

traefik_image: 'traefik'
traefik_add_volumes: []
traefik_ports:
- '80:80'
- '443:443'
traefik_labels: {}
traefik_labels: {}
traefik_env: {}

# traefik_confkey_global: {}
# traefik_confkey_serversTransport: {}
Expand All @@ -51,3 +59,5 @@ traefik_labels: {}
# traefik_confkey_tracing: {}
# traefik_confkey_hostResolver: {}
# traefik_confkey_certificatesResolvers: {}
# traefik_confkey_middlewares: {}
# traefik_confkey_tls: {}
7 changes: 7 additions & 0 deletions hosts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---

all:
hosts:
localhost:
ansible_connection: local
ansible_python_interpreter: '/usr/bin/python3'
38 changes: 38 additions & 0 deletions playbook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
- name: Playbook to setup traefik
hosts:
- localhost
become: true
tasks:
- name: Remove already existing traefik container
community.general.docker_container:
name: traefik
state: absent
tags:
- setup-all
- setup-traefik
- include_role:
name: traefik
vars:
traefik_dir: /srv/docker/traefik
traefik_hostname: traefik.example.com'
traefik_qs_https: true
traefik_qs_log_level: INFO
traefik_qs_https_redirect: true
traefik_use_dynamic_file_config: true
traefik_qs_tls_options: true
traefik_qs_middlewares: true
traefik_qs_exposedbydefault: false
traefik_labels:
com.centurylinklabs.watchtower.enable: 'true'
traefik_confkey_certificatesResolvers:
letsencrypt:
acme:
httpChallenge:
entryPoint: "http"
email: '{{ vault_private_email }}'
storage: /letsencrypt/acme.json
caServer: "https://acme-v02.api.letsencrypt.org/directory"
tags:
- setup-all
- setup-traefik
28 changes: 28 additions & 0 deletions tasks/0_config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
---

- name: Warn if old option 'traefik_network_ipam' is used
fail:
msg: "Using 'traefik_network_ipam' is deprecated use traefik_network_ipam_config instead"
when:
- traefik_network_ipam is defined

- name: Warn if old option 'traefik_network_ipam_temp.subnet' is used
fail:
msg: "Using 'traefik_network_ipam_temp.subnet' is deprecated use traefik_network_ipam_config instead"
when:
- traefik_network_ipam_temp.subnet is defined

- name: Warn if old option 'traefik_network_ipam_temp.gateway' is used
fail:
msg: "Using 'traefik_network_ipam_temp.gateway' is deprecated use traefik_network_ipam_config instead"
when:
- traefik_network_ipam_temp.gateway is defined

- name: Warn if old option 'traefik_network_ipam_temp.iprange' is used
fail:
msg: "Using 'traefik_network_ipam_temp.iprange' is deprecated use traefik_network_ipam_config instead"
when:
- traefik_network_ipam_temp.iprange is defined

- name: "config : generate https entrypoint config"
set_fact:
traefik_int_conf_entryPoints: "{{
Expand Down Expand Up @@ -30,6 +54,10 @@
}}"
when: traefik_confkey_certificatesResolvers is defined

- name: "config: check if dynamic_configuration has to be disabled"
set_fact:
traefik_int_conf_providers_dynamic_configuration: ""
when: traefik_use_dynamic_file_config | bool

- name: "config : generate static config"
set_fact:
Expand Down
70 changes: 66 additions & 4 deletions tasks/1_setup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@
with_items:
- '{{ traefik_dir }}'

- name: 'setup : create directory for dynamic config'
become: true
file:
path: '{{ item }}'
state: directory
owner: root
group: docker
mode: 0550
with_items:
- '{{ traefik_dynamic_file_config_dir }}'
when: traefik_use_dynamic_file_config

- name: 'setup : create traefik configuration'
become: true
copy:
Expand All @@ -20,15 +32,63 @@
content: '{{ traefik_static_config | to_nice_yaml }}'
notify:
- restart traefik container

- name: Check if traefik_use_dynamic_file_config is set true if traefik_qs_middlewares is used
fail:
msg: "'traefik_qs_middlewares' is used but 'traefik_use_dynamic_file_config' is not set to true."
when:
- not traefik_use_dynamic_file_config | bool
- traefik_qs_middlewares | bool

- name: Check if traefik_use_dynamic_file_config is set true if traefik_qs_tls_options is used
fail:
msg: "'traefik_qs_tls_options' is used but 'traefik_use_dynamic_file_config' is not set to true."
when:
- not traefik_use_dynamic_file_config | bool
- traefik_qs_tls_options | bool

- name: 'setup: tls options'
become: true
copy:
dest: '{{ traefik_dir }}/dynamic_conf/qs_traefik_tls_options.yml'
owner: root
group: docker
mode: 0550
content: '{{ traefik_conf_tls | to_nice_yaml }}'
notify:
- restart traefik container
when:
- traefik_use_dynamic_file_config | bool
- traefik_qs_tls_options | bool

- name: 'setup: middelware'
become: true
copy:
dest: '{{ traefik_dir }}/dynamic_conf/qs_traefik_middlewares.yml'
owner: root
group: docker
mode: 0550
content: '{{ traefik_conf_middlewares | to_nice_yaml }}'
notify:
- restart traefik container
when:
- traefik_use_dynamic_file_config | bool
- traefik_qs_middlewares | bool

- name: 'setup: custom ssl certificates'
template:
src: https_custom_ssl.j2
dest: '{{ traefik_dir }}/dynamic_conf/https_custom_ssl.yml'
when:
- traefik_use_dynamic_file_config | bool
- traefik_qs_https_custom_ssl | bool

- name: 'setup : create traefik network'
become: true
docker_network:
name: '{{ traefik_network_name }}'
ipam_config:
- subnet: '{{ traefik_network_ipam_subnet }}'
gateway: '{{ traefik_network_ipam_gateway }}'
iprange: '{{ traefik_network_ipam_iprange }}'
enable_ipv6: '{{ traefik_network_enable_ipv6 }}'
ipam_config: '{{ traefik_network_ipam_config }}'

- name: 'setup : start traefik container'
become: true
Expand All @@ -44,3 +104,5 @@
networks:
- name: '{{ traefik_network_name }}'
networks_cli_compatible: true
env: '{{ traefik_env }}'

8 changes: 8 additions & 0 deletions templates/https_custom_ssl.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{% if traefik_qs_https_custom_ssl %}
tls:
certificates:
{% for item in traefik_qs_https_custom_ssl_files %}
- certFile: {{ item.certFile }}
keyFile: {{ item.keyFile }}
{% endfor %}
{% endif %}
Loading