Files
docker/docs/dynu-dns-inventory.md
2026-04-21 14:11:25 +10:00

3.7 KiB

Dynu DNS Read-Only Inventory

This repository includes a read-only Dynu DNS inventory workflow for lan.ddnsgeek.com.

This integration is intentionally read-only. No Dynu mutations are permitted in this repo at this stage.

Scope

  • Fetch live DNS/domain data from Dynu using GET requests only.
  • Correlate Dynu hostnames with Traefik Host(...) rules found in compose files.
  • Generate local inventory artifacts for documentation.

Safety Guard Rails

  • Scripts fail unless DYNU_READ_ONLY=true.
  • No Dynu write methods (POST, PUT, PATCH, DELETE) are implemented.
  • No Terraform Dynu provider/resources/modules are introduced.
  • No Ansible Dynu mutation tasks are introduced.
  • API secrets are read from environment variables and are never logged.

Correlation logic

scripts/dynu/correlate_dynu_with_traefik.py uses compose files as the source of truth and parses them as YAML.

It supports both common label formats:

  • list style:
labels:
  - "traefik.http.routers.app.rule=Host(`app.lan.ddnsgeek.com`)"
  • map style:
labels:
  traefik.http.routers.app.rule: "Host(`app.lan.ddnsgeek.com`)"

The parser extracts hostnames from router rules such as:

  • Host(a)
  • Host("a")
  • Host('a')
  • multi-host rules (comma-delimited)
  • combined expressions such as Host(...) && PathPrefix(...)

Route metadata in inventory

Each discovered hostname mapping includes:

  • fqdn
  • compose service name
  • compose file path
  • stack area (apps, monitoring, core)
  • router label key(s)
  • raw router rule
  • uses_tls
  • tls_options
  • middlewares
  • uses_mtls
  • uses_authelia

mTLS is metadata only and never blocks mapping.

Validation model

The generated JSON/Markdown include a top-level validation section with:

  • allowed_unmapped_hostnames
  • unexpected_unmapped_hostnames
  • duplicate_hostnames
  • ambiguous_hostnames
  • validation_ok

Current policy:

  • edge.lan.ddnsgeek.com is the only allowed unmapped DNS hostname.
  • every other *.lan.ddnsgeek.com DNS hostname should map to a compose/Traefik-discovered service.

Optional strict mode:

  • Set DYNU_ENFORCE_VALIDATION=true to make the correlate script exit non-zero when unexpected unmapped hostnames exist.

Required Environment Variables

  • DYNU_API_KEY (required for fetch)
  • DYNU_BASE_URL (optional, defaults to https://api.dynu.com)
  • DYNU_READ_ONLY (must be true)

Recommended local secrets file (not committed): secrets/dynu.env

DYNU_API_KEY=replace-with-real-api-key
DYNU_READ_ONLY=true
DYNU_BASE_URL=https://api.dynu.com

Notes:

  • Keep values unquoted unless required by your shell.
  • scripts/dynu/build_dns_inventory.sh will auto-load secrets/dynu.env when present.

Commands

Run directly:

DYNU_READ_ONLY=true DYNU_API_KEY=... python3 scripts/dynu/fetch_dynu_dns.py
DYNU_READ_ONLY=true python3 scripts/dynu/correlate_dynu_with_traefik.py

Or run the wrapper:

scripts/dynu/build_dns_inventory.sh

Artifacts

  • data/dns/dynu_live.json (generated, untracked by default due to repo data/ ignore)
  • data/dns/dynu_traefik_inventory.json (generated, untracked by default)
  • docs/generated/dns-inventory.md (generated documentation artifact)

Because data/ is gitignored in this repository, JSON outputs are intentionally local-only unless ignore behavior changes in the future.

Ansible Wrapper (Read-Only)

A syntax-safe wrapper playbook is provided at:

  • infrastructure/ansible/playbooks/dns-inventory.yml

It only executes the local read-only scripts and does not call write-capable Dynu APIs.

Not Managed Yet

Dynu DNS records are not managed by Terraform or Ansible in this repository at this stage. No configuration in this repository sends Dynu mutation requests.