add cloudflare

This commit is contained in:
Graham McIntire 2026-02-18 12:55:34 -06:00
parent b3bb484bf0
commit ee5d485808
No known key found for this signature in database
5 changed files with 401 additions and 3 deletions

View file

@ -1,6 +1,29 @@
# This file is maintained automatically by "tofu init".
# Manual edits may be lost in future updates.
provider "registry.opentofu.org/cloudflare/cloudflare" {
version = "4.52.5"
constraints = "~> 4.0"
hashes = [
"h1:+rfzF+16ZcWZWnTyW/p1HHTzYbPKX8Zt2nIFtR/+f+E=",
"zh:1a3400cb38863b2585968d1876706bcfc67a148e1318a1d325c6c7704adc999b",
"zh:4c5062cb9e9da1676f06ae92b8370186d98976cc4c7030d3cd76df12af54282a",
"zh:52110f493b5f0587ef77a1cfd1a67001fd4c617b14c6502d732ab47352bdc2f7",
"zh:5aa536f9eaeb43823aaf2aa80e7d39b25ef2b383405ed034aa16a28b446a9238",
"zh:5cc39459a1c6be8a918f17054e4fbba573825ed5597dcada588fe99614d98a5b",
"zh:629ae6a7ba298815131da826474d199312d21cec53a4d5ded4fa56a692e6f072",
"zh:719cc7c75dc1d3eb30c22ff5102a017996d9788b948078c7e1c5b3446aeca661",
"zh:8698635a3ca04383c1e93b21d6963346bdae54d27177a48e4b1435b7f731731c",
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
"zh:8a9993f1dcadf1dd6ca43b23348abe374605d29945a2fafc07fb3457644e6a54",
"zh:b1b9a1e6bcc24d5863a664a411d2dc906373ae7a2399d2d65548ce7377057852",
"zh:b270184cdeec277218e84b94cb136fead753da717f9b9dc378e51907f3f00bb0",
"zh:dff2bc10071210181726ce270f954995fe42c696e61e2e8f874021fed02521e5",
"zh:e8e87b40b6a87dc097b0fdc20d3f725cec0d82abc9cc3755c1f89f8f6e8b0036",
"zh:ee964a6573d399a5dd22ce328fb38ca1207797a02248f14b2e4913ee390e7803",
]
}
provider "registry.opentofu.org/marcfrederick/porkbun" {
version = "1.3.1"
constraints = "~> 1.3"

366
tofu/cloudflare.tf Normal file
View file

@ -0,0 +1,366 @@
locals {
cloudflare_account_id = "4d18148a82b0a91f289afbbd2944a603"
cloudflare_zones = {
"aprs.me" = "09da59049b0ecad7b734ce3d902bf581"
"gridmap.org" = "836f24d97eb51ffc18aa10c0a98efa48"
"towerops.net" = "c275d35a8885de79ca8e61c17ac97ab6"
}
cloudflare_records = {
# =========================================================================
# towerops.net - A records
# =========================================================================
"towerops.net-a-dfw-poller" = {
zone_key = "towerops.net"
type = "A"
name = "dfw.poller"
content = "144.202.64.79"
proxied = false
record_id = "aa8183b748f1bf0e3850d9dabb91ee3a"
}
"towerops.net-a-lon-poller" = {
zone_key = "towerops.net"
type = "A"
name = "lon.poller"
content = "45.77.228.168"
proxied = false
record_id = "2a25c3ee47284833cea451170d3bd61d"
}
"towerops.net-a-staging" = {
zone_key = "towerops.net"
type = "A"
name = "staging"
content = "204.110.191.231"
proxied = true
record_id = "8430e2789d5700c556dc7a598d49d8fd"
}
"towerops.net-a-www" = {
zone_key = "towerops.net"
type = "A"
name = "www"
content = "192.0.2.1"
proxied = true
comment = "Created during Cloudflare Rules deployment process for Redirect from WWW to root [Template]"
record_id = "689c47b0e5ed68427f2c3b9e25bdf602"
}
# =========================================================================
# towerops.net - AAAA records
# =========================================================================
"towerops.net-aaaa-dfw-poller" = {
zone_key = "towerops.net"
type = "AAAA"
name = "dfw.poller"
content = "2001:19f0:6401:af2:5400:5ff:fee7:1bfb"
proxied = false
record_id = "2edc0cf203313e67d64316daf8a0490e"
}
"towerops.net-aaaa-lon-poller" = {
zone_key = "towerops.net"
type = "AAAA"
name = "lon.poller"
content = "2001:19f0:7400:1195:5400:5ff:feee:a0c3"
proxied = false
record_id = "610f21b8597a1ce6ad4020f15311787a"
}
# =========================================================================
# towerops.net - CNAME records
# =========================================================================
"towerops.net-cname-root" = {
zone_key = "towerops.net"
type = "CNAME"
name = "towerops.net"
content = "d3d819ba-925c-4d84-8052-68ed32b686bb.cfargotunnel.com"
proxied = true
record_id = "cf1bc4e745466032786db854f4294f99"
}
"towerops.net-cname-dev" = {
zone_key = "towerops.net"
type = "CNAME"
name = "dev"
content = "db59aa44-79de-4522-9593-43e828f3215a.cfargotunnel.com"
proxied = true
record_id = "21b470e19493c856ce697052dabc90e5"
}
"towerops.net-cname-autoconfig" = {
zone_key = "towerops.net"
type = "CNAME"
name = "autoconfig"
content = "mail.mcintire.me"
proxied = false
record_id = "1c0f59e7bd583f8971f50231e6fad3cf"
}
"towerops.net-cname-autodiscover" = {
zone_key = "towerops.net"
type = "CNAME"
name = "autodiscover"
content = "mail.mcintire.me"
proxied = false
record_id = "34a4a9bde8cf4626635cfa3cb5f8c408"
}
"towerops.net-cname-dkim-ses-1" = {
zone_key = "towerops.net"
type = "CNAME"
name = "2skkb53ep3vfbkdstfmm2elfthurggid._domainkey"
content = "2skkb53ep3vfbkdstfmm2elfthurggid.dkim.amazonses.com"
proxied = false
record_id = "f4a446531128011a1a6b896010983901"
}
"towerops.net-cname-dkim-ses-2" = {
zone_key = "towerops.net"
type = "CNAME"
name = "4uwsaywjpmk35j36pfiz4vr37dyy4v7z._domainkey"
content = "4uwsaywjpmk35j36pfiz4vr37dyy4v7z.dkim.amazonses.com"
proxied = false
record_id = "aefc5c72e25e3656dbccf0fdf2fc6f48"
}
"towerops.net-cname-dkim-ses-3" = {
zone_key = "towerops.net"
type = "CNAME"
name = "l7lbifvot6nv3wwho5rs35xzqzzinz5f._domainkey"
content = "l7lbifvot6nv3wwho5rs35xzqzzinz5f.dkim.amazonses.com"
proxied = false
record_id = "02a4cfa316dae29898a8270f2c3aceda"
}
# =========================================================================
# towerops.net - MX records
# =========================================================================
"towerops.net-mx-root-primary" = {
zone_key = "towerops.net"
type = "MX"
name = "towerops.net"
content = "mail.mcintire.me"
priority = 10
record_id = "a5dc7d6dc6d9085132a8fa0b7db1b69a"
}
"towerops.net-mx-root-backup" = {
zone_key = "towerops.net"
type = "MX"
name = "towerops.net"
content = "mail.nsnw.ca"
priority = 20
record_id = "bbd552d191e61345f19f8dae10281f9e"
}
"towerops.net-mx-mail" = {
zone_key = "towerops.net"
type = "MX"
name = "mail"
content = "feedback-smtp.us-east-1.amazonses.com"
priority = 10
record_id = "a2486e2bbb4d6aca978d28807893e346"
}
# =========================================================================
# towerops.net - TXT records
# =========================================================================
"towerops.net-txt-spf" = {
zone_key = "towerops.net"
type = "TXT"
name = "towerops.net"
content = "v=spf1 mx a ip4:107.174.178.20 ~all"
record_id = "cf2f74d345960700a81a6025e7a89642"
}
"towerops.net-txt-dmarc" = {
zone_key = "towerops.net"
type = "TXT"
name = "_dmarc"
content = "v=DMARC1; p=none;"
record_id = "bd236f9a89fc42f45fd7f4b076478880"
}
"towerops.net-txt-dkim" = {
zone_key = "towerops.net"
type = "TXT"
name = "dkim._domainkey"
content = "v=DKIM1;k=rsa;t=s;s=email;p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuFm6nd0L7/nAO4m0MPxdjwRAup5C90DPSPa0TQBDT8S2WvASyQUPV8xSbICGMj6FjZYNd5ph/0VK47gDulxQgNQT96IVf2ooTfkvY/80bAyEdtJbpjEUzQnX5YBi/pJigQx2EeCdaojUZumeIdlFlzeb8QQIEtQhVnyc1Xc/Z8ljPMW1H9DXLSDINjV6UTaXX+PZ7jgpRKgU+RnJNcqTAkhhKQ4bMcRfOam/lF6wPOWte1A7ir08TdE8O67ioqygkr/ivAp7xvV4vGOkY6buLLE+c3exY+my2qTCZgJyUMAhkZzYqzGo1csfHH8x+O2XN/k8Z5jPhq8LSvl9XkllKwIDAQAB"
record_id = "3872e537e8cee4087ead7eb5785e1426"
}
"towerops.net-txt-mail-spf" = {
zone_key = "towerops.net"
type = "TXT"
name = "mail"
content = "v=spf1 include:amazonses.com ~all"
record_id = "76b8314432391c6630e9e1b2edfce65d"
}
}
}
# =============================================================================
# Zones
# =============================================================================
import {
for_each = local.cloudflare_zones
to = cloudflare_zone.zones[each.key]
id = each.value
}
resource "cloudflare_zone" "zones" {
for_each = local.cloudflare_zones
account_id = local.cloudflare_account_id
zone = each.key
}
# =============================================================================
# DNS Records (A, AAAA, CNAME, MX, TXT)
# =============================================================================
import {
for_each = local.cloudflare_records
to = cloudflare_record.records[each.key]
id = "${local.cloudflare_zones[each.value.zone_key]}/${each.value.record_id}"
}
resource "cloudflare_record" "records" {
for_each = local.cloudflare_records
zone_id = cloudflare_zone.zones[each.value.zone_key].id
type = each.value.type
name = each.value.name
content = each.value.content
proxied = lookup(each.value, "proxied", false)
ttl = lookup(each.value, "ttl", 1)
priority = lookup(each.value, "priority", null)
comment = lookup(each.value, "comment", null)
}
# =============================================================================
# DNS Records - aprs.me tunnel CNAME
# =============================================================================
resource "cloudflare_record" "aprs_me_tunnel" {
zone_id = cloudflare_zone.zones["aprs.me"].id
type = "CNAME"
name = "aprs.me"
content = "d3d819ba-925c-4d84-8052-68ed32b686bb.cfargotunnel.com"
proxied = true
}
resource "cloudflare_record" "gridmap_org_tunnel" {
zone_id = cloudflare_zone.zones["gridmap.org"].id
type = "CNAME"
name = "gridmap.org"
content = "d3d819ba-925c-4d84-8052-68ed32b686bb.cfargotunnel.com"
proxied = true
}
# =============================================================================
# DNS Records (SRV) - separate due to data block
# =============================================================================
import {
to = cloudflare_record.towerops_srv_autodiscover
id = "${local.cloudflare_zones["towerops.net"]}/26db78978535d1d630432970b9a4e279"
}
resource "cloudflare_record" "towerops_srv_autodiscover" {
zone_id = cloudflare_zone.zones["towerops.net"].id
type = "SRV"
name = "_autodiscover._tcp"
data {
service = "_autodiscover"
proto = "_tcp"
name = "towerops.net"
priority = 0
weight = 0
port = 443
target = "mail.mcintire.me"
}
}
# =============================================================================
# Zone Settings
#
# cloudflare_zone_settings_override doesn't support import, so zone settings
# are not managed here. Current non-default settings on towerops.net:
# - zero_rtt: on
# - always_use_https: on
# - min_tls_version: 1.2
# - pseudo_ipv4: add_header
# - tls_1_3: zrt (0-RTT)
# - HSTS: enabled, max_age=15552000, preload=true, nosniff=true
# =============================================================================
# =============================================================================
# Firewall - towerops.net custom rules
# =============================================================================
import {
to = cloudflare_ruleset.towerops_firewall
id = "zone/${local.cloudflare_zones["towerops.net"]}/3c209e50f21b40388733a7cfe8f62f4e"
}
resource "cloudflare_ruleset" "towerops_firewall" {
zone_id = cloudflare_zone.zones["towerops.net"].id
name = "default"
kind = "zone"
phase = "http_request_firewall_custom"
rules {
action = "block"
expression = "(http.request.uri.path wildcard r\"/wp-content/*\") or (http.request.uri.path wildcard r\"/wp-admin/*\") or (http.request.uri.path wildcard r\"/*.php\")"
description = "wordpress"
enabled = true
}
}
# =============================================================================
# Tunnel Configs
#
# Tunnel resources themselves are not managed here because the tunnel secrets
# are not recoverable from the API. The tunnels were created via the dashboard:
# - towerops: d3d819ba-925c-4d84-8052-68ed32b686bb (healthy)
# - towerops-dev: db59aa44-79de-4522-9593-43e828f3215a (down)
# =============================================================================
import {
to = cloudflare_zero_trust_tunnel_cloudflared_config.towerops
id = "${local.cloudflare_account_id}/d3d819ba-925c-4d84-8052-68ed32b686bb"
}
resource "cloudflare_zero_trust_tunnel_cloudflared_config" "towerops" {
account_id = local.cloudflare_account_id
tunnel_id = "d3d819ba-925c-4d84-8052-68ed32b686bb"
config {
ingress_rule {
hostname = "aprs.me"
service = "http://aprs.aprs.svc.cluster.local:4000"
}
ingress_rule {
hostname = "gridmap.org"
service = "http://gridmap.gridmap.svc.cluster.local:4000"
}
ingress_rule {
hostname = "towerops.net"
service = "http://towerops.towerops.svc.cluster.local:4000"
}
ingress_rule {
service = "http_status:404"
}
}
}
import {
to = cloudflare_zero_trust_tunnel_cloudflared_config.towerops_dev
id = "${local.cloudflare_account_id}/db59aa44-79de-4522-9593-43e828f3215a"
}
resource "cloudflare_zero_trust_tunnel_cloudflared_config" "towerops_dev" {
account_id = local.cloudflare_account_id
tunnel_id = "db59aa44-79de-4522-9593-43e828f3215a"
config {
ingress_rule {
hostname = "dev.towerops.net"
service = "http://localhost:4000"
}
ingress_rule {
service = "http_status:404"
}
}
}

View file

@ -26,6 +26,7 @@ locals {
"mcintire.me" = local.as393837_ns
"ntxarms.com" = local.as393837_ns
"qth.social" = local.porkbun_ns
# towerops.net is not opted in to Porkbun API access
"vntx.org" = local.as393837_ns
"w5isp.com" = local.as393837_ns
}

View file

@ -4,9 +4,17 @@ terraform {
source = "marcfrederick/porkbun"
version = "~> 1.3"
}
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "porkbun" {
# Credentials via PORKBUN_API_KEY and PORKBUN_SECRET_API_KEY env vars
}
provider "cloudflare" {
# Credentials via CLOUDFLARE_API_TOKEN env var
}

File diff suppressed because one or more lines are too long