cloudflare: disable managed robots.txt; fix v5 config bugs

- Add cloudflare_bot_management for all zones with is_robots_txt_managed=false
  so each app's own robots.txt is served instead of Cloudflare's managed one
- Fix zone_setting id zero_rtt -> 0rtt (invalid id rejected by API)
- Fix security_header value: object instead of jsonencode (avoids perpetual diff)
- Fix firewall expression http.request.user_agent -> http.user_agent (invalid field)
- tofu fmt reindentation
This commit is contained in:
Graham McIntire 2026-06-04 17:41:45 -05:00
parent c5b658d653
commit d632095eb2
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59

View file

@ -327,10 +327,10 @@ resource "cloudflare_dns_record" "caa" {
ttl = 86400 ttl = 86400
data = { data = {
flags = 0 flags = 0
tag = "issue" tag = "issue"
value = each.value.ca value = each.value.ca
} }
} }
# ============================================================================= # =============================================================================
@ -349,11 +349,11 @@ resource "cloudflare_dns_record" "towerops_srv_autodiscover" {
ttl = 86400 ttl = 86400
data = { data = {
priority = 0 priority = 0
weight = 0 weight = 0
port = 443 port = 443
target = "mail.mcintire.me" target = "mail.mcintire.me"
} }
} }
# ============================================================================= # =============================================================================
@ -383,7 +383,7 @@ resource "cloudflare_zone_setting" "aprs_me_tls_1_3" {
resource "cloudflare_zone_setting" "aprs_me_zero_rtt" { resource "cloudflare_zone_setting" "aprs_me_zero_rtt" {
zone_id = cloudflare_zone.zones["aprs.me"].id zone_id = cloudflare_zone.zones["aprs.me"].id
setting_id = "zero_rtt" setting_id = "0rtt"
value = "on" value = "on"
} }
@ -396,7 +396,7 @@ resource "cloudflare_zone_setting" "aprs_me_ssl" {
resource "cloudflare_zone_setting" "aprs_me_security_header" { resource "cloudflare_zone_setting" "aprs_me_security_header" {
zone_id = cloudflare_zone.zones["aprs.me"].id zone_id = cloudflare_zone.zones["aprs.me"].id
setting_id = "security_header" setting_id = "security_header"
value = jsonencode({ value = {
strict_transport_security = { strict_transport_security = {
enabled = true enabled = true
max_age = 15552000 max_age = 15552000
@ -404,7 +404,7 @@ resource "cloudflare_zone_setting" "aprs_me_security_header" {
preload = true preload = true
nosniff = true nosniff = true
} }
}) }
} }
# towerops.net # towerops.net
@ -428,7 +428,7 @@ resource "cloudflare_zone_setting" "towerops_net_tls_1_3" {
resource "cloudflare_zone_setting" "towerops_net_zero_rtt" { resource "cloudflare_zone_setting" "towerops_net_zero_rtt" {
zone_id = cloudflare_zone.zones["towerops.net"].id zone_id = cloudflare_zone.zones["towerops.net"].id
setting_id = "zero_rtt" setting_id = "0rtt"
value = "on" value = "on"
} }
@ -441,7 +441,7 @@ resource "cloudflare_zone_setting" "towerops_net_ssl" {
resource "cloudflare_zone_setting" "towerops_net_security_header" { resource "cloudflare_zone_setting" "towerops_net_security_header" {
zone_id = cloudflare_zone.zones["towerops.net"].id zone_id = cloudflare_zone.zones["towerops.net"].id
setting_id = "security_header" setting_id = "security_header"
value = jsonencode({ value = {
strict_transport_security = { strict_transport_security = {
enabled = true enabled = true
max_age = 15552000 max_age = 15552000
@ -449,7 +449,7 @@ resource "cloudflare_zone_setting" "towerops_net_security_header" {
preload = true preload = true
nosniff = true nosniff = true
} }
}) }
} }
# gridmap.org # gridmap.org
@ -473,7 +473,7 @@ resource "cloudflare_zone_setting" "gridmap_org_tls_1_3" {
resource "cloudflare_zone_setting" "gridmap_org_zero_rtt" { resource "cloudflare_zone_setting" "gridmap_org_zero_rtt" {
zone_id = cloudflare_zone.zones["gridmap.org"].id zone_id = cloudflare_zone.zones["gridmap.org"].id
setting_id = "zero_rtt" setting_id = "0rtt"
value = "on" value = "on"
} }
@ -486,7 +486,7 @@ resource "cloudflare_zone_setting" "gridmap_org_ssl" {
resource "cloudflare_zone_setting" "gridmap_org_security_header" { resource "cloudflare_zone_setting" "gridmap_org_security_header" {
zone_id = cloudflare_zone.zones["gridmap.org"].id zone_id = cloudflare_zone.zones["gridmap.org"].id
setting_id = "security_header" setting_id = "security_header"
value = jsonencode({ value = {
strict_transport_security = { strict_transport_security = {
enabled = true enabled = true
max_age = 15552000 max_age = 15552000
@ -494,8 +494,34 @@ resource "cloudflare_zone_setting" "gridmap_org_security_header" {
preload = true preload = true
nosniff = true nosniff = true
} }
}) }
} }
# =============================================================================
# Bot Management - disable Cloudflare managed robots.txt
#
# Each app repo ships its own robots.txt. Turning off the managed robots.txt
# feature ("Instruct AI bot traffic with robots.txt") stops Cloudflare from
# prepending/serving its own robots.txt at the zone edge, so the origin's file
# is returned unchanged. All other bot_management fields are Optional+Computed,
# so omitting them preserves their current values (e.g. Super Bot Fight Mode).
#
# NOTE: requires CLOUDFLARE_API_TOKEN to include the "Bot Management Write"
# permission for these zones; the DNS-scoped token cannot apply this.
# =============================================================================
resource "cloudflare_bot_management" "zones" {
for_each = cloudflare_zone.zones
zone_id = each.value.id
is_robots_txt_managed = false
}
resource "cloudflare_bot_management" "w5isp_com" {
zone_id = cloudflare_zone.w5isp_com.id
is_robots_txt_managed = false
}
# ============================================================================= # =============================================================================
# Firewall - custom rules (applied to all zones) # Firewall - custom rules (applied to all zones)
# ============================================================================= # =============================================================================
@ -514,7 +540,7 @@ locals {
"(http.request.uri.path contains \"/.git\")", "(http.request.uri.path contains \"/.git\")",
"(http.request.uri.path contains \"/phpmyadmin\")", "(http.request.uri.path contains \"/phpmyadmin\")",
"(http.request.uri.path contains \"/cgi-bin\")", "(http.request.uri.path contains \"/cgi-bin\")",
"(not http.request.user_agent exists)", "(not http.user_agent ne \"\")",
]) ])
} }
@ -581,13 +607,13 @@ resource "cloudflare_ruleset" "towerops_firewall" {
logging = { logging = {
enabled = false enabled = false
} }
}, },
{ {
action = "block" action = "block"
expression = local.firewall_expression expression = local.firewall_expression
description = "block abusers" description = "block abusers"
enabled = true enabled = true
}] }]
} }
import { import {
@ -1017,11 +1043,11 @@ resource "cloudflare_dns_record" "w5isp_srv_autodiscover" {
ttl = 86400 ttl = 86400
data = { data = {
priority = 0 priority = 0
weight = 0 weight = 0
port = 443 port = 443
target = "mail.w5isp.com" target = "mail.w5isp.com"
} }
} }
# ============================================================================= # =============================================================================
@ -1048,7 +1074,7 @@ resource "cloudflare_zone_setting" "w5isp_com_tls_1_3" {
resource "cloudflare_zone_setting" "w5isp_com_zero_rtt" { resource "cloudflare_zone_setting" "w5isp_com_zero_rtt" {
zone_id = cloudflare_zone.w5isp_com.id zone_id = cloudflare_zone.w5isp_com.id
setting_id = "zero_rtt" setting_id = "0rtt"
value = "on" value = "on"
} }
@ -1061,7 +1087,7 @@ resource "cloudflare_zone_setting" "w5isp_com_ssl" {
resource "cloudflare_zone_setting" "w5isp_com_security_header" { resource "cloudflare_zone_setting" "w5isp_com_security_header" {
zone_id = cloudflare_zone.w5isp_com.id zone_id = cloudflare_zone.w5isp_com.id
setting_id = "security_header" setting_id = "security_header"
value = jsonencode({ value = {
strict_transport_security = { strict_transport_security = {
enabled = true enabled = true
max_age = 15552000 max_age = 15552000
@ -1069,7 +1095,7 @@ resource "cloudflare_zone_setting" "w5isp_com_security_header" {
preload = true preload = true
nosniff = true nosniff = true
} }
}) }
} }
# ============================================================================= # =============================================================================
@ -1096,13 +1122,13 @@ resource "cloudflare_ruleset" "w5isp_firewall" {
logging = { logging = {
enabled = false enabled = false
} }
}, },
{ {
action = "block" action = "block"
expression = local.firewall_expression expression = local.firewall_expression
description = "block abusers" description = "block abusers"
enabled = true enabled = true
}] }]
} }
# ============================================================================= # =============================================================================
@ -1118,10 +1144,10 @@ resource "cloudflare_dns_record" "w5isp_caa" {
ttl = 86400 ttl = 86400
data = { data = {
flags = 0 flags = 0
tag = "issue" tag = "issue"
value = each.value value = each.value
} }
} }
resource "cloudflare_zero_trust_tunnel_cloudflared_config" "towerops_dev" { resource "cloudflare_zero_trust_tunnel_cloudflared_config" "towerops_dev" {