From 75ff4fe5b1fdb7def1718ddd92963a36509218b1 Mon Sep 17 00:00:00 2001 From: beatz174-bit Date: Mon, 4 May 2026 01:01:59 +1000 Subject: [PATCH] Add live end-to-end DNS zone Terraform example --- examples/live_end_to_end_dns_zone/README.md | 58 +++++++++++++ examples/live_end_to_end_dns_zone/main.tf | 84 +++++++++++++++++++ examples/live_end_to_end_dns_zone/outputs.tf | 70 ++++++++++++++++ .../live_end_to_end_dns_zone/variables.tf | 22 +++++ 4 files changed, 234 insertions(+) create mode 100644 examples/live_end_to_end_dns_zone/README.md create mode 100644 examples/live_end_to_end_dns_zone/main.tf create mode 100644 examples/live_end_to_end_dns_zone/outputs.tf create mode 100644 examples/live_end_to_end_dns_zone/variables.tf diff --git a/examples/live_end_to_end_dns_zone/README.md b/examples/live_end_to_end_dns_zone/README.md new file mode 100644 index 0000000..3bab247 --- /dev/null +++ b/examples/live_end_to_end_dns_zone/README.md @@ -0,0 +1,58 @@ +# Live End-to-End Dynu DNS Zone Example + +> [!WARNING] +> **This is a live destructive test.** +> +> - Do **not** use a real production domain. +> - Use only a disposable test domain. +> - `terraform destroy` will remove the test domain and all records created by this example. + +This example performs full live validation of the Dynu provider lifecycle by creating and then destroying a disposable Dynu domain plus one DNS record for each currently supported record type in this provider example: + +- A +- AAAA +- CNAME +- MX +- TXT +- SRV +- CAA + +## Prerequisites + +- A local build of this provider with Terraform `dev_overrides` for `dynu/dynu`. +- Dynu API key provided either by: + - environment variable `DYNU_API_KEY`, or + - Terraform variable `dynu_api_key`. +- A disposable domain value for `test_domain`. + +## Required variables + +Create `terraform.tfvars` in this folder: + +```hcl +test_domain = "my-disposable-test-domain.example" +# dynu_api_key = "..." # optional if DYNU_API_KEY is exported +``` + +## Commands + +```bash +terraform init +terraform validate +terraform plan +terraform apply +terraform plan +terraform destroy +``` + +## Expected results + +- `terraform validate` should pass. +- First `terraform plan` should show creation of: + - one disposable test domain (`dynu_domain.test`), and + - one record each for A, AAAA, CNAME, MX, TXT, SRV, and CAA. +- `terraform apply` should create the domain and records. +- Second `terraform plan` (after apply) should show **no changes**. +- Manually verify in the Dynu web UI that the test domain and records exist after apply. +- `terraform destroy` should remove the test domain and all records from state. +- Final manual verification should confirm the test domain is gone from Dynu. diff --git a/examples/live_end_to_end_dns_zone/main.tf b/examples/live_end_to_end_dns_zone/main.tf new file mode 100644 index 0000000..e4a0fda --- /dev/null +++ b/examples/live_end_to_end_dns_zone/main.tf @@ -0,0 +1,84 @@ +provider "dynu" { + api_key = var.dynu_api_key +} + +resource "dynu_domain" "test" { + name = var.test_domain +} + +resource "dynu_dns_record" "a" { + hostname = "a.${var.test_domain}" + record_type = "A" + content = "192.0.2.10" + ttl = var.test_ttl + enabled = true + + depends_on = [dynu_domain.test] +} + +resource "dynu_dns_record" "aaaa" { + hostname = "aaaa.${var.test_domain}" + record_type = "AAAA" + content = "2001:db8::10" + ttl = var.test_ttl + enabled = true + + depends_on = [dynu_domain.test] +} + +resource "dynu_dns_record" "cname" { + hostname = "www.${var.test_domain}" + record_type = "CNAME" + content = "target.${var.test_domain}" + ttl = var.test_ttl + enabled = true + + depends_on = [dynu_domain.test] +} + +resource "dynu_dns_record" "mx" { + hostname = var.test_domain + record_type = "MX" + content = "mail.${var.test_domain}" + priority = 10 + ttl = var.test_ttl + enabled = true + + depends_on = [dynu_domain.test] +} + +resource "dynu_dns_record" "txt" { + hostname = "txt.${var.test_domain}" + record_type = "TXT" + content = "v=spf1 include:example.com -all" + ttl = var.test_ttl + enabled = true + + depends_on = [dynu_domain.test] +} + +resource "dynu_dns_record" "srv" { + hostname = "_sip._tcp.${var.test_domain}" + record_type = "SRV" + content = "target.${var.test_domain}" + priority = 10 + weight = 5 + port = 5060 + ttl = var.test_ttl + enabled = true + + depends_on = [dynu_domain.test] +} + +resource "dynu_dns_record" "caa" { + hostname = var.test_domain + record_type = "CAA" + content = "letsencrypt.org" + flags = 0 + tag = "issue" + value = "letsencrypt.org" + ttl = var.test_ttl + enabled = true + + depends_on = [dynu_domain.test] +} diff --git a/examples/live_end_to_end_dns_zone/outputs.tf b/examples/live_end_to_end_dns_zone/outputs.tf new file mode 100644 index 0000000..b1187d9 --- /dev/null +++ b/examples/live_end_to_end_dns_zone/outputs.tf @@ -0,0 +1,70 @@ +output "domain_name" { + description = "Disposable test domain managed by this live example." + value = dynu_domain.test.name +} + +output "domain_id" { + description = "Dynu numeric domain ID for the disposable test domain." + value = dynu_domain.test.id +} + +output "created_record_summary" { + description = "Summary of disposable DNS records created for end-to-end validation." + value = { + a = { + id = dynu_dns_record.a.id + hostname = dynu_dns_record.a.hostname + type = dynu_dns_record.a.record_type + content = dynu_dns_record.a.content + } + aaaa = { + id = dynu_dns_record.aaaa.id + hostname = dynu_dns_record.aaaa.hostname + type = dynu_dns_record.aaaa.record_type + content = dynu_dns_record.aaaa.content + } + cname = { + id = dynu_dns_record.cname.id + hostname = dynu_dns_record.cname.hostname + type = dynu_dns_record.cname.record_type + content = dynu_dns_record.cname.content + } + mx = { + id = dynu_dns_record.mx.id + hostname = dynu_dns_record.mx.hostname + type = dynu_dns_record.mx.record_type + content = dynu_dns_record.mx.content + } + txt = { + id = dynu_dns_record.txt.id + hostname = dynu_dns_record.txt.hostname + type = dynu_dns_record.txt.record_type + content = dynu_dns_record.txt.content + } + srv = { + id = dynu_dns_record.srv.id + hostname = dynu_dns_record.srv.hostname + type = dynu_dns_record.srv.record_type + content = dynu_dns_record.srv.content + } + caa = { + id = dynu_dns_record.caa.id + hostname = dynu_dns_record.caa.hostname + type = dynu_dns_record.caa.record_type + content = dynu_dns_record.caa.content + flags = dynu_dns_record.caa.flags + tag = dynu_dns_record.caa.tag + value = dynu_dns_record.caa.value + } + } +} + +output "suggested_manual_checks" { + description = "Guidance for live manual verification in Dynu UI and DNS lookups." + value = [ + "Confirm domain ${dynu_domain.test.name} exists in the Dynu web UI after apply.", + "Confirm A, AAAA, CNAME, MX, TXT, SRV, and CAA records exist for ${dynu_domain.test.name} in the Dynu web UI after apply.", + "Run 'terraform plan' after apply and confirm Terraform reports no changes.", + "Run terraform destroy and confirm ${dynu_domain.test.name} is removed from the Dynu web UI.", + ] +} diff --git a/examples/live_end_to_end_dns_zone/variables.tf b/examples/live_end_to_end_dns_zone/variables.tf new file mode 100644 index 0000000..5c7c8ba --- /dev/null +++ b/examples/live_end_to_end_dns_zone/variables.tf @@ -0,0 +1,22 @@ +variable "dynu_api_key" { + description = "Dynu API key. Leave null to use DYNU_API_KEY from environment." + type = string + default = null + sensitive = true +} + +variable "test_domain" { + type = string + description = "Disposable Dynu test domain to create and destroy during live end-to-end testing." + + validation { + condition = trimspace(var.test_domain) != "" + error_message = "test_domain must be a non-empty domain name." + } +} + +variable "test_ttl" { + description = "TTL in seconds for disposable DNS records. Must be 0 (provider/API default) or >= 90." + type = number + default = 300 +}