8.4 KiB
terraform-provider-dynu
A standalone Terraform provider for Dynu DNS.
Status: early CRUD milestone. This provider includes read-only data sources plus one writable resource (
dynu_dns_record) to establish CRUD foundations.
Quick start (local dev with dev_overrides)
This provider is not published to the Terraform Registry yet. For local development, use Terraform CLI dev_overrides and your local provider binary.
- Build provider binary in repo root:
go build -o terraform-provider-dynu
By default, local builds use embedded metadata values:
version=devcommit=nonebuilt=unknown
- Configure
~/.terraformrc:
provider_installation {
dev_overrides {
"dynu/dynu" = "/path/to/terraform-dynu-provider"
}
direct {}
}
- Run the runnable read-only example:
cd examples/read_only
cp terraform.tfvars.example terraform.tfvars
terraform validate
terraform plan
- Run the live-safe write example (opt-in, creates a disposable DNS record only):
cd examples/live_safe_dns_record
cp terraform.tfvars.example terraform.tfvars
# set only dynu_root_domain to a Dynu-managed root zone you control
terraform validate
terraform plan
Warning
Do not run
terraform initas part of the normal Codex/local test loop for this repo. Because the provider is not yet published to the Terraform Registry,initmay attempt registry/network resolution and fail or give misleading results. Usedev_overrides, rebuild the local binary, then runterraform validateandterraform plan.With
dev_overrides, Terraform uses your local binary fordynu/dynu.
Codex/local validation loop
Use this expected loop for local verification and Codex-driven validation:
go build -o terraform-provider-dynu
cd examples/read_only
terraform validate
terraform plan
When provider configuration or code changes, rebuild the provider binary first, then re-run terraform validate and terraform plan.
Version metadata in binaries
The provider embeds build metadata (version, commit, date) in the binary.
- Local builds (no
-ldflags) default to:version=devcommit=nonebuilt=unknown
- You can inspect metadata from the binary with either:
./terraform-provider-dynu --version./terraform-provider-dynu version
Primary build method (recommended):
./build.sh v0.2.0
build.sh takes exactly one argument (the version string), then derives commit and date automatically:
COMMIT=$(git rev-parse --short HEAD)DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
Manual equivalent (same stamped build command used by build.sh):
VERSION=v0.2.0
COMMIT=$(git rev-parse --short HEAD)
DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
go build -o terraform-provider-dynu \
-ldflags="-X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${DATE}"
Release tag/version mapping:
- Git tag
v0.1.0-> build withVERSION=v0.1.0 - Git tag
v0.2.0-> build withVERSION=v0.2.0
Copy/paste starter configuration
terraform {
required_providers {
dynu = {
source = "dynu/dynu"
}
}
}
provider "dynu" {
api_key = var.dynu_api_key # optional if DYNU_API_KEY is set
}
variable "dynu_api_key" {
type = string
default = null
sensitive = true
}
data "dynu_domains" "all" {}
# Use a real hostname from your Dynu account.
data "dynu_domain" "selected" {
hostname = "www.example.com"
}
data "dynu_dns_records" "selected" {
hostname = "www.example.com"
}
Provider schema reference
Provider: dynu
Optional arguments:
api_key(String, Sensitive)- Falls back to
DYNU_API_KEYenvironment variable when omitted.
- Falls back to
base_url(String)- Test/dev override for Dynu API base URL.
Provider resources:
dynu_dns_record(first writable resource)
dynu_dns_record
Arguments:
hostname(String, required)record_type(String, required)content(String, required)ttl(Number, optional)state(Bool, optional)group(String, optional)host(String, optional)node_name(String, optional)
Attributes:
id(String) indomain_id/record_idformatdomain_id(Number)domain_name(String)updated_on(String)- plus all configurable arguments
Example:
resource "dynu_dns_record" "txt" {
hostname = "api.example.com"
record_type = "TXT"
content = "hello-from-terraform"
ttl = 300
state = true
}
Data source schema reference
dynu_domains
Arguments:
- none
Attributes:
domains(List(Object)):id,name,unicode_name,token(sensitive),state,groupipv4_address,ipv6_address,ttlipv4,ipv6,ipv4_wildcard_alias,ipv6_wildcard_aliasallow_zone_transfer,dnssec,created_on,updated_on
Example:
data "dynu_domains" "all" {}
dynu_domain
Arguments:
hostname(String, required)
Attributes:
domain(Object) with the same fields asdynu_domains.domains[*].
Example:
data "dynu_domain" "selected" {
hostname = "www.example.com"
}
dynu_dns_records
Arguments:
hostname(String, required)
Attributes:
domain_id(Number)domain_name(String)records(List(Object)) with:id,domain_id,domain_name,node_name,hostname,record_typettl,state,content,updated_on,group,host
Example:
data "dynu_dns_records" "selected" {
hostname = "www.example.com"
}
Examples
- Runnable local workflow:
examples/read_only/ - Live-safe write lifecycle workflow:
examples/live_safe_dns_record/ - Provider block example:
examples/provider/provider.tf - Individual data source snippets:
examples/data-sources/dynu_domains/data-source.tfexamples/data-sources/dynu_domain/data-source.tfexamples/data-sources/dynu_dns_records/data-source.tf
- Resource snippet:
examples/resources/dynu_dns_record/resource.tf
Troubleshooting local dev
-
Unsupported provider arguments
- Symptom: errors such as
Unsupported argument(for exampleusername). - Fix: use only
api_keyand/orbase_urlinprovider "dynu".
- Symptom: errors such as
-
Bad API credentials
- Symptom: diagnostics mention authentication failures.
- Fix: verify
api_keyorDYNU_API_KEYand re-runterraform plan.
-
Unknown data source arguments
- Symptom: unsupported argument errors in data blocks.
- Fix:
dynu_domainanddynu_dns_recordsrequire onlyhostname;dynu_domainstakes no arguments.
-
Stale provider binary after code changes
- Symptom: Terraform behavior doesn't reflect latest code.
- Fix: rebuild binary (
go build -o terraform-provider-dynu) and re-runterraform validateandterraform plan.
Development checks
Before committing, run:
./scripts/fix.sh
./scripts/check.sh
fix.sh applies standard formatting and module hygiene.
check.sh is the strict verification script used by CI.
Developer workflow
./scripts/setup-dev.sh- validate local toolchain requirements./scripts/check.sh- formatting, vet, and unit tests./scripts/test-integration.sh- local mock-backed provider integration tests./scripts/testacc.sh- acceptance/integration test wrapper (live tests opt-in)
Live acceptance tests are opt-in and require:
TF_ACC=1DYNU_API_KEY- optional
DYNU_DOMAINfor domain-specific coverage
Live safe write testing
Use examples/live_safe_dns_record when you want to safely validate writable provider behavior against a real Dynu account.
- This example creates a unique temporary subdomain in the form
<prefix>-<random>.<dynu_root_domain>. - It creates exactly one disposable
Arecord using a default IPv4 value accepted by Dynu. - It is designed so
terraform destroyremoves only the created disposable record from that run/state.
Safety guidance:
- Set
dynu_root_domainto a root Dynu-managed zone you control (for exampleexample.com). - Do not supply or target an existing live full hostname you care about.
- If apply is interrupted, rerun
terraform destroyfrom the same directory/state to clean up.
Feature scope
Implemented:
- Provider authentication via
api_keyorDYNU_API_KEY - Optional provider
base_urloverride - Data sources:
dynu_domains,dynu_domain,dynu_dns_records - Resource:
dynu_dns_record(CRUD + import usingdomain_id/record_id)
Not implemented yet:
- Additional Terraform resources beyond
dynu_dns_record - Broader Dynu API coverage outside current DNS/domain scope