October 24, 2026
opentofu
is a terraform fork that manages infrastructure as code. I used my cloudflare configuration to play around.
install
winget install --exact --id OpenTofu.Tofu winget install --exact --id SecretsOPerationS.SOPS winget install --exact --id FiloSottile.age
usage
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 5.0"
}
}
}
provider "cloudflare" {}
variable "domain" {
type = string
default = "(my.domain.name.here)"
}
# lookup zone
data "cloudflare_zone" "main" {
filter = {
name = var.domain
}
}
# read dns of zone
data "cloudflare_dns_records" "alle" {
zone_id = data.cloudflare_zone.main.id
}
# show dns records in output
output "dns_eintraege" {
value = [
for r in data.cloudflare_dns_records.alle.result :
format("%-6s %-40s -> %s", r.type, r.name, r.content)
]
}
locals {
zone_id = data.cloudflare_zone.main.id
dns_records = {
root_a = {
name = "mydomain.com"
type = "A"
content = "200.100.0.200"
proxied = true
}
dmarc = {
name = "_dmarc.mydomain.com"
type = "TXT"
content = "\"v=DMARC1; p=reject; rua=mailto:..; ruf=mailto:..;\""
comment = "no mails on this domain"
}
dkim_null = {
name = "*._domainkey.mydomain.com"
type = "TXT"
content = "\"v=DKIM1; p=\""
comment = "no mails on this domain"
}
spf = {
name = "mydomain.com"
type = "TXT"
content = "\"v=spf1 -all\""
comment = "no mails on this domain"
}
hint = {
name = "hint.mydomain.com"
type = "TXT"
content = "\"domain managed bei opentofu\""
}
}
}
resource "cloudflare_dns_record" "this" {
for_each = local.dns_records
zone_id = local.zone_id
name = each.value.name
type = each.value.type
content = each.value.content
ttl = try(each.value.ttl, 1)
proxied = try(each.value.proxied, false)
}
run with
sops exec-env .\secrets.enc.env powershell tofu plan tofu apply