Initialize Project
This commit is contained in:
83
playbooks/roles/traefik/tasks/main.yml
Normal file
83
playbooks/roles/traefik/tasks/main.yml
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
- name: Create base volume directory for traefik
|
||||
ansible.builtin.file:
|
||||
path: '{{ base_docker_volumes_dir }}/traefik'
|
||||
state: directory
|
||||
mode: '0755'
|
||||
become: true
|
||||
|
||||
- name: Create volume directory for traefik certificates
|
||||
ansible.builtin.file:
|
||||
path: '{{ base_docker_volumes_dir }}/traefik/certs'
|
||||
state: directory
|
||||
mode: '0755'
|
||||
become: true
|
||||
|
||||
- name: Template traefik configuration files
|
||||
ansible.builtin.template:
|
||||
src: '{{ item }}.toml.j2'
|
||||
dest: '{{ base_docker_volumes_dir }}/traefik/{{ item }}.toml'
|
||||
mode: '0644'
|
||||
loop:
|
||||
- traefik
|
||||
- dynamic
|
||||
become: true
|
||||
|
||||
- name: Install passlib python package
|
||||
ansible.builtin.pip:
|
||||
name: passlib
|
||||
state: present
|
||||
become: true
|
||||
|
||||
- name: Generate passwords for Traefik users
|
||||
ansible.builtin.set_fact:
|
||||
traefik_user_passwords: "{{ traefik_user_passwords | default({}) | combine({item: lookup('ansible.builtin.password', '/dev/null', length=32, chars=['ascii_letters', 'digits'])}) }}" # noqa yaml[line-length]
|
||||
loop: '{{ traefik_auth_users }}'
|
||||
no_log: true
|
||||
|
||||
- name: Create decrypted password file
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
{% for user, password in traefik_user_passwords.items() %}
|
||||
{{ user }}:{{ password }}
|
||||
{% endfor %}
|
||||
dest: '{{ base_docker_volumes_dir }}/traefik/passwords.decrypted'
|
||||
mode: '0640'
|
||||
become: true
|
||||
|
||||
- name: Create password file for traefik with hashed passwords
|
||||
community.general.htpasswd:
|
||||
path: '{{ base_docker_volumes_dir }}/traefik/passwords'
|
||||
name: '{{ item.key }}'
|
||||
password: '{{ item.value }}'
|
||||
crypt_scheme: bcrypt
|
||||
create: true
|
||||
mode: '0640'
|
||||
state: present
|
||||
loop: '{{ traefik_user_passwords | dict2items }}'
|
||||
become: true
|
||||
|
||||
- name: Deploy traefik container
|
||||
community.docker.docker_container:
|
||||
name: traefik
|
||||
image: 'traefik:v3.4.0'
|
||||
state: started
|
||||
recreate: true
|
||||
env:
|
||||
PORT: '80'
|
||||
CLOUDFLARE_EMAIL: "{{ cloudflare_email_address | default('null') }}"
|
||||
CLOUDFLARE_API_KEY: "{{ cloudflare_api_key | default('null') }}"
|
||||
labels: 'traefik.http.services.traefik.loadbalancer.server.port=80'
|
||||
network_mode: host
|
||||
ports:
|
||||
- '80:80'
|
||||
- '443:443'
|
||||
- '8081:8081'
|
||||
volumes:
|
||||
- '{{ base_docker_volumes_dir }}/traefik/traefik.toml:/etc/traefik/traefik.toml'
|
||||
- '{{ base_docker_volumes_dir }}/traefik/dynamic.toml:/opt/traefik/dynamic.toml'
|
||||
- '{{ base_docker_volumes_dir }}/traefik/certs:/certs'
|
||||
- '{{ base_docker_volumes_dir }}/traefik/passwords:/etc/traefik/.htpasswd'
|
||||
- '/var/run/docker.sock:/var/run/docker.sock'
|
||||
restart: false
|
||||
restart_policy: always
|
||||
71
playbooks/roles/traefik/templates/dynamic.toml.j2
Normal file
71
playbooks/roles/traefik/templates/dynamic.toml.j2
Normal file
@@ -0,0 +1,71 @@
|
||||
#jinja2:variable_start_string:'%%', variable_end_string:'%%'
|
||||
[metrics]
|
||||
[metrics.prometheus]
|
||||
addEntryPointsLabels = true
|
||||
addRoutersLabels = true
|
||||
addServicesLabels = true
|
||||
|
||||
[http.serversTransports.default-transport]
|
||||
insecureSkipVerify = true
|
||||
|
||||
[http.middlewares]
|
||||
[http.middlewares.https_redirect.redirectScheme]
|
||||
scheme = "https"
|
||||
permanent = true
|
||||
[http.middlewares.auth.basicAuth]
|
||||
usersfile = "/etc/traefik/.htpasswd"
|
||||
[http.middlewares.global-rate-limit.rateLimit]
|
||||
average = 2000
|
||||
burst = 3000
|
||||
period = "1m"
|
||||
|
||||
[http.routers]
|
||||
[http.routers.traefik-api]
|
||||
rule = "Host(`%% traefik_web_ui_addr %%`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
|
||||
service = "api@internal"
|
||||
middlewares = ["auth"]
|
||||
|
||||
{% for service in traefik_services %}
|
||||
[http.routers.%% service.name %%-http]
|
||||
rule = "Host(`%% service.host %%`)"
|
||||
service = "%% service.name %%"
|
||||
entrypoints = ["http"]
|
||||
# middlewares = ["https_redirect"]
|
||||
[http.routers.%% service.name %%-https]
|
||||
rule = "Host(`%% service.host %%`)"
|
||||
service = "%% service.name %%"
|
||||
entrypoints = ["https"]
|
||||
{% if service.auth is defined and service.auth %}
|
||||
middlewares = ["auth"]
|
||||
{% endif %}
|
||||
[http.routers.%% service.name %%-https.tls]
|
||||
certResolver = "acme-http"
|
||||
{% endfor %}
|
||||
|
||||
{% if traefik_services | length > 0 %}
|
||||
[http.services]
|
||||
{% for service in traefik_services %}
|
||||
[http.services.%% service.name %%.loadBalancer]
|
||||
serversTransport = "default-transport"
|
||||
[[http.services.%% service.name %%.loadBalancer.servers]]
|
||||
scheme = "http"
|
||||
url = "%% service.service %%"
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if traefik_tcp_routers | length > 0 %}
|
||||
[tcp.routers]
|
||||
{% for router in traefik_tcp_routers %}
|
||||
[tcp.routers.%% router.name %%-service-tcp]
|
||||
rule = "HostSNI(`*`)"
|
||||
service = "%% router.name %%-service"
|
||||
entrypoints = ["%% router.entrypoint %%"]
|
||||
{% endfor %}
|
||||
|
||||
[tcp.services]
|
||||
{% for router in traefik_tcp_routers %}
|
||||
[tcp.services.%% router.name %%-service.loadBalancer]
|
||||
[[tcp.services.%% router.name %%-service.loadBalancer.servers]]
|
||||
address = "%% router.target_host %%:%% router.target_port %%"
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
55
playbooks/roles/traefik/templates/traefik.toml.j2
Normal file
55
playbooks/roles/traefik/templates/traefik.toml.j2
Normal file
@@ -0,0 +1,55 @@
|
||||
#jinja2:variable_start_string:'%%', variable_end_string:'%%'
|
||||
[accessLog]
|
||||
|
||||
[metrics]
|
||||
[metrics.prometheus]
|
||||
|
||||
[ping]
|
||||
|
||||
[tracing]
|
||||
addInternals = true
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":80"
|
||||
asDefault = true
|
||||
[entryPoints.http.http]
|
||||
middlewares = ["global-rate-limit@file"]
|
||||
[entryPoints.traefik]
|
||||
address = ":8081"
|
||||
[entryPoints.traefik.http]
|
||||
middlewares = ["global-rate-limit@file"]
|
||||
[entryPoints.https]
|
||||
address = ":443"
|
||||
[entryPoints.https.http]
|
||||
middlewares = ["global-rate-limit@file"]
|
||||
[entryPoints.https.http.tls]
|
||||
certResolver = "acme-http"
|
||||
{% if traefik_tcp_routers is defined %}
|
||||
{% for router in traefik_tcp_routers %}
|
||||
[entryPoints.%% router.entrypoint %%]
|
||||
address = ":%% router.source_port %%"
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
[api]
|
||||
dashboard = true
|
||||
insecure = true
|
||||
|
||||
[providers.file]
|
||||
directory = "/opt/traefik/"
|
||||
|
||||
[certificatesResolvers.acme-http.acme]
|
||||
email = "%% letsencrypt_email_address %%"
|
||||
storage = "/certs/acme.json"
|
||||
caServer = "https://acme-v02.api.letsencrypt.org/directory" # Production
|
||||
# caServer = "https://acme-staging-v02.api.letsencrypt.org/directory" # Staging
|
||||
[certificatesResolvers.acme-http.acme.httpChallenge]
|
||||
entryPoint = "http"
|
||||
|
||||
[providers.docker]
|
||||
endpoint = "unix:///var/run/docker.sock"
|
||||
exposedByDefault = true
|
||||
Reference in New Issue
Block a user