feat(dns): rewrite add_service_route.yml to support multi-host Traefik configs
- Parse Host() rules from router definitions - Supports multiple hostnames per service file (e.g. semaphore + imagineering) - More robust and future-proof
This commit is contained in:
@@ -6,7 +6,8 @@
|
|||||||
#
|
#
|
||||||
# 1. Syncs boilerplates/traefik/dynamic/ to lightning-lane
|
# 1. Syncs boilerplates/traefik/dynamic/ to lightning-lane
|
||||||
# 2. Scans the directory for service configs
|
# 2. Scans the directory for service configs
|
||||||
# 3. Creates CNAME records for each service -> lightning-lane
|
# 3. Extracts all hostnames from Host() rules (supports multi-host)
|
||||||
|
# 4. Creates CNAME records for each hostname -> lightning-lane
|
||||||
#
|
#
|
||||||
# PREREQUISITES:
|
# PREREQUISITES:
|
||||||
# - Service dynamic config YAML committed to boilerplates/traefik/dynamic/
|
# - Service dynamic config YAML committed to boilerplates/traefik/dynamic/
|
||||||
@@ -14,15 +15,6 @@
|
|||||||
#
|
#
|
||||||
# USAGE:
|
# USAGE:
|
||||||
# ansible-playbook -i inventory.yml playbooks/add_service_route.yml
|
# ansible-playbook -i inventory.yml playbooks/add_service_route.yml
|
||||||
#
|
|
||||||
# ADDING A NEW SERVICE:
|
|
||||||
# 1. Create boilerplates/traefik/dynamic/<service>.yml
|
|
||||||
# 2. Commit and push
|
|
||||||
# 3. Run this playbook
|
|
||||||
#
|
|
||||||
# EXCLUDING FILES:
|
|
||||||
# Files that are not service routes (e.g., default.yml for middleware
|
|
||||||
# definitions) should be added to the exclude_configs list below.
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
- name: Sync Traefik routes and ensure DNS records
|
- name: Sync Traefik routes and ensure DNS records
|
||||||
@@ -39,7 +31,6 @@
|
|||||||
dynamic_config_dir: "{{ playbook_dir }}/../../boilerplates/traefik/dynamic"
|
dynamic_config_dir: "{{ playbook_dir }}/../../boilerplates/traefik/dynamic"
|
||||||
|
|
||||||
# Files in the dynamic directory that are NOT service routes
|
# Files in the dynamic directory that are NOT service routes
|
||||||
# (middleware definitions, TLS options, etc.)
|
|
||||||
exclude_configs:
|
exclude_configs:
|
||||||
- default.yml
|
- default.yml
|
||||||
|
|
||||||
@@ -53,38 +44,53 @@
|
|||||||
register: sync_result
|
register: sync_result
|
||||||
changed_when: "'sending incremental file list' in sync_result.stdout"
|
changed_when: "'sending incremental file list' in sync_result.stdout"
|
||||||
|
|
||||||
# ── Step 2: Discover service configs ──
|
# ── Step 2: Discover hostnames from Traefik router rules ──
|
||||||
- name: Find all dynamic config files
|
- name: Find all dynamic config files
|
||||||
ansible.builtin.find:
|
ansible.builtin.find:
|
||||||
paths: "{{ dynamic_config_dir }}"
|
paths: "{{ dynamic_config_dir }}"
|
||||||
patterns: "*.yml"
|
patterns: "*.yml"
|
||||||
register: config_files
|
register: config_files
|
||||||
|
|
||||||
- name: Build service list from config filenames
|
- name: Read config files
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.slurp:
|
||||||
service_names: >-
|
src: "{{ item.path }}"
|
||||||
{{ config_files.files
|
register: slurped_configs
|
||||||
| map(attribute='path')
|
loop: "{{ config_files.files }}"
|
||||||
| map('basename')
|
when: item.path | basename not in exclude_configs
|
||||||
| reject('in', exclude_configs)
|
|
||||||
| map('regex_replace', '\.yml$', '')
|
|
||||||
| list }}
|
|
||||||
|
|
||||||
- name: Display services to route
|
- name: Extract all hostnames from Host() rules
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
hostnames: >-
|
||||||
|
{{
|
||||||
|
slurped_configs.results
|
||||||
|
| selectattr('content', 'defined')
|
||||||
|
| map(attribute='content')
|
||||||
|
| map('b64decode')
|
||||||
|
| map('regex_findall', 'Host\\(`([^`]+)`\\)')
|
||||||
|
| flatten
|
||||||
|
| map('split', ' || ')
|
||||||
|
| flatten
|
||||||
|
| map('regex_replace', '`', '')
|
||||||
|
| select('match', '.*\\.local\\.mk-labs\\.cloud$')
|
||||||
|
| unique
|
||||||
|
| list
|
||||||
|
}}
|
||||||
|
|
||||||
|
- name: Display hostnames to create
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg: "Services found: {{ service_names }}"
|
msg: "Hostnames found: {{ hostnames }}"
|
||||||
|
|
||||||
# ── Step 3: Create DNS CNAME records ──
|
# ── Step 3: Create DNS CNAME records ──
|
||||||
- name: Create DNS CNAME record for each service
|
- name: Create DNS CNAME record for each hostname
|
||||||
effectivelywild.technitium_dns.technitium_dns_add_record:
|
effectivelywild.technitium_dns.technitium_dns_add_record:
|
||||||
api_url: "http://{{ dns_server }}.{{ base_domain }}"
|
api_url: "http://{{ dns_server }}.{{ base_domain }}"
|
||||||
api_token: "{{ vault_technitium_api_key }}"
|
api_token: "{{ vault_technitium_api_key }}"
|
||||||
zone: "{{ base_domain }}"
|
zone: "{{ base_domain }}"
|
||||||
name: "{{ item }}.{{ base_domain }}"
|
name: "{{ item }}"
|
||||||
type: "CNAME"
|
type: "CNAME"
|
||||||
cname: "lightning-lane.{{ base_domain }}"
|
cname: "lightning-lane.{{ base_domain }}"
|
||||||
ttl: 360
|
ttl: 360
|
||||||
validate_certs: false
|
validate_certs: false
|
||||||
loop: "{{ service_names }}"
|
loop: "{{ hostnames }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
label: "{{ item }}.{{ base_domain }}"
|
label: "{{ item }}"
|
||||||
|
|||||||
Reference in New Issue
Block a user