Merge pull request #49 from beatz174-bit/codex/add-live-end-to-end-terraform-example

Add live end-to-end Terraform example for Dynu DNS zone validation
This commit is contained in:
beatz174-bit
2026-05-04 01:03:52 +10:00
committed by GitHub
4 changed files with 234 additions and 0 deletions
@@ -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.
+84
View File
@@ -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]
}
@@ -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.",
]
}
@@ -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
}