Dynu Terraform Layer (Brownfield DNS Reconciliation)
This Terraform root is for Dynu DNS brownfield reconciliation. The intended pattern is:
- Import the existing root domain object.
- Read inventory through
data.dynu_dns_records.root. - Generate reviewable
dynu_dns_recordresources and import commands. - Import every existing DNS record into matching Terraform resources.
- Use
terraform planas the reconciliation check before any apply.
Provider behavior to keep in mind
- Source:
beatz174-bit/dynu dynu_domainimport requires a numeric Dynu domain ID.- Importing
dynu_domainimports only the root domain object. - It does not import DNS records/subdomains.
dynu_dns_recordimports require<domain_id>/<record_id>.
Variables
dynu_root_domain(default:lan.ddnsgeek.com)dynu_api_key(sensitive)dynu_username/dynu_password(optional)
Safe validation commands
cd infrastructure/terraform/dynu
terraform fmt -check -recursive
terraform init -backend=false -input=false
terraform validate
python3 -m py_compile scripts/generate-brownfield-records.py
Brownfield workflow
cd infrastructure/terraform/dynu
terraform init
terraform import dynu_domain.lan_ddnsgeek_com '<numeric-dynu-domain-id>'
terraform apply -refresh-only
terraform output -json dynu_dns_records > /tmp/dynu-records.json
python3 scripts/generate-brownfield-records.py --dry-run
python3 scripts/generate-brownfield-records.py --overwrite
# Review generated/dynu_dns_records.generated.tf
# Review generated/import-dynu-dns-records.sh
bash generated/import-dynu-dns-records.sh
terraform plan
What each component means
data.dynu_dns_records.root: read-only live inventory from Dynu.generated/dynu_dns_records.generated.tf: generated management-intent resources; includesprevent_destroy = trueon each record.generated/import-dynu-dns-records.sh: imports each discovered record to its generateddynu_dns_recordaddress using<domain_id>/<record_id>.terraform planafter imports: reconciliation checkpoint. Any create/update/delete must be reviewed manually before apply.
Generated artifacts
The helper script writes these files under generated/:
generated/dynu_dns_records_inventory.jsongenerated/dynu_dns_records.generated.tfgenerated/import-dynu-dns-records.sh
These are generated outputs meant for operator review before use in production.
Generator output selection (interactive + automation)
The brownfield generator defaults to Terraform output dynu_dns_records:
python3 scripts/generate-brownfield-records.py --dry-run
If the default output is missing/unusable and stdin is interactive, the script shows a picker of available Terraform outputs and indicates which ones are usable for DNS imports.
# Interactive mode: choose from available Terraform outputs
python3 scripts/generate-brownfield-records.py --dry-run
# Non-interactive mode: specify output explicitly
python3 scripts/generate-brownfield-records.py \
--records-output dynu_dns_inventory \
--dry-run
# Disable menu and fail fast
python3 scripts/generate-brownfield-records.py \
--no-interactive \
--dry-run
# Use saved terraform output JSON and choose interactively
terraform output -json > generated/terraform-output.json
python3 scripts/generate-brownfield-records.py \
--from-file generated/terraform-output.json \
--dry-run
Notes:
- The menu shows Terraform outputs currently stored in state.
- If newly added outputs do not appear, run:
terraform apply -refresh-only
- The selected output must contain real Dynu provider record fields:
iddomain_idhostnamerecord_type
Troubleshooting
Plan shows a large wall of + values under outputs
Cause:
Terraform is planning to save new output values to state (for example, live records from data.dynu_dns_records.root). This is not creating DNS records by itself.
How to verify:
- Output-only changes appear under
Changes to Outputs. - Real DNS changes appear as
dynu_dns_recordresource create/update/delete actions.
Use:
terraform apply -refresh-only
to persist refreshed data source and output values only.
Error: There is no function named "regexreplace"
Cause:
regexreplace is not a Terraform function. Resource-name slugification should not be implemented in Terraform HCL for this workflow.
Fix:
- Keep
inventory.tffocused on reading live records viadata.dynu_dns_records.root. - Keep Terraform outputs simple (for example,
<domain_id>/<record_id>mappings). - Let
scripts/generate-brownfield-records.pygenerate Terraform-safe resource names with Pythontf_name(record).
Error: '"'"'dynu_dns_records'"'"'
Cause:
The helper script reads terraform output -json and expects an output named dynu_dns_records.
Fix:
cd infrastructure/terraform/dynu
terraform init
terraform apply -refresh-only
terraform output -json | jq 'keys'
Confirm dynu_dns_records appears in the key list.
If it does not, check that the Terraform config contains:
data "dynu_dns_records" "root" {
hostname = var.dynu_root_domain
}
output "dynu_dns_records" {
value = data.dynu_dns_records.root.records
}
Then rerun:
python3 scripts/generate-brownfield-records.py --dry-run