chore: pre-migration snapshot
Layer0, MCP servers, Terraform consolidation
This commit is contained in:
@@ -38,6 +38,8 @@ cloudflare_account_name = "your-account-name"
|
||||
tunnel_secret_vaultmesh = "base64-encoded-secret"
|
||||
tunnel_secret_offsec = "base64-encoded-secret"
|
||||
admin_emails = ["admin@vaultmesh.org"]
|
||||
enable_managed_waf = true
|
||||
enable_bot_management = false
|
||||
EOF
|
||||
|
||||
# Plan
|
||||
@@ -47,6 +49,31 @@ terraform plan
|
||||
terraform apply
|
||||
```
|
||||
|
||||
## Plan-Aware Security Features
|
||||
|
||||
- `enable_managed_waf` applies the managed WAF ruleset only when the zone `plan` is not `"free"`.
|
||||
- `enable_bot_management` applies bot management settings only when the zone `plan` is not `"free"`.
|
||||
|
||||
This lets `terraform apply` succeed on Free-plan zones (DNS, tunnels, Access, settings) while keeping the security posture ready for plan upgrades.
|
||||
|
||||
### WAF Truth Table
|
||||
|
||||
| Zone plan (`var.domains[*].plan`) | `enable_managed_waf` | `enable_bot_management` | Expected resources |
|
||||
| --- | --- | --- | --- |
|
||||
| `free` | any | any | `cloudflare_ruleset.security_rules` only |
|
||||
| not `free` | `false` | any | `cloudflare_ruleset.security_rules` only |
|
||||
| not `free` | `true` | `false` | `cloudflare_ruleset.security_rules`, `cloudflare_ruleset.managed_waf` |
|
||||
| not `free` | `true` | `true` | `cloudflare_ruleset.security_rules`, `cloudflare_ruleset.managed_waf`, `cloudflare_bot_management.domains` |
|
||||
|
||||
### Assurance Varfiles
|
||||
|
||||
For deterministic, token-format-safe gating checks (no apply), use:
|
||||
|
||||
```bash
|
||||
terraform plan -refresh=false -var-file=assurance_free.tfvars
|
||||
terraform plan -refresh=false -var-file=assurance_pro.tfvars
|
||||
```
|
||||
|
||||
## Generate Tunnel Secrets
|
||||
|
||||
```bash
|
||||
|
||||
35
terraform/assurance_free.tfvars
Normal file
35
terraform/assurance_free.tfvars
Normal file
@@ -0,0 +1,35 @@
|
||||
cloudflare_api_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # Placeholder (format-valid)
|
||||
cloudflare_account_id = "00000000000000000000000000000000" # Placeholder (format-valid)
|
||||
cloudflare_account_name = ""
|
||||
|
||||
# Exercise empty-list safety
|
||||
trusted_admin_ips = []
|
||||
blocked_countries = []
|
||||
|
||||
# Even when flags are true, free-plan zones must gate these resources off
|
||||
enable_managed_waf = true
|
||||
enable_bot_management = true
|
||||
|
||||
# Keep the full set of expected zones so hard-coded references stay valid
|
||||
domains = {
|
||||
"offsec.global" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecglobal.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecagent.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecshield.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"vaultmesh.org" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
}
|
||||
34
terraform/assurance_negative_free_should_fail.tfvars
Normal file
34
terraform/assurance_negative_free_should_fail.tfvars
Normal file
@@ -0,0 +1,34 @@
|
||||
cloudflare_api_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # Placeholder (format-valid)
|
||||
cloudflare_account_id = "00000000000000000000000000000000" # Placeholder (format-valid)
|
||||
cloudflare_account_name = ""
|
||||
|
||||
trusted_admin_ips = []
|
||||
blocked_countries = []
|
||||
|
||||
enable_managed_waf = true
|
||||
enable_bot_management = true
|
||||
|
||||
# Intentionally violates the "free plan must gate managed WAF + bot mgmt off".
|
||||
# Used by scripts/waf-and-plan-invariants.sh negative-control check.
|
||||
domains = {
|
||||
"offsec.global" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecglobal.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecagent.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecshield.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"vaultmesh.org" = {
|
||||
plan = "pro"
|
||||
jump_start = false
|
||||
}
|
||||
}
|
||||
34
terraform/assurance_negative_pro_should_fail.tfvars
Normal file
34
terraform/assurance_negative_pro_should_fail.tfvars
Normal file
@@ -0,0 +1,34 @@
|
||||
cloudflare_api_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # Placeholder (format-valid)
|
||||
cloudflare_account_id = "00000000000000000000000000000000" # Placeholder (format-valid)
|
||||
cloudflare_account_name = ""
|
||||
|
||||
trusted_admin_ips = []
|
||||
blocked_countries = []
|
||||
|
||||
enable_managed_waf = true
|
||||
enable_bot_management = false
|
||||
|
||||
# Intentionally violates the "pro plan must create exactly 1 managed_waf + 1 bot_management" invariant.
|
||||
# Used by scripts/waf-and-plan-invariants.sh negative-control check.
|
||||
domains = {
|
||||
"offsec.global" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecglobal.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecagent.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecshield.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"vaultmesh.org" = {
|
||||
plan = "pro"
|
||||
jump_start = false
|
||||
}
|
||||
}
|
||||
34
terraform/assurance_pro.tfvars
Normal file
34
terraform/assurance_pro.tfvars
Normal file
@@ -0,0 +1,34 @@
|
||||
cloudflare_api_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # Placeholder (format-valid)
|
||||
cloudflare_account_id = "00000000000000000000000000000000" # Placeholder (format-valid)
|
||||
cloudflare_account_name = ""
|
||||
|
||||
# Exercise empty-list safety
|
||||
trusted_admin_ips = []
|
||||
blocked_countries = []
|
||||
|
||||
enable_managed_waf = true
|
||||
enable_bot_management = true
|
||||
|
||||
# Mark at least one zone as non-free so plan includes managed WAF + bot mgmt resources.
|
||||
domains = {
|
||||
"offsec.global" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecglobal.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecagent.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"offsecshield.com" = {
|
||||
plan = "free"
|
||||
jump_start = false
|
||||
}
|
||||
"vaultmesh.org" = {
|
||||
plan = "pro"
|
||||
jump_start = false
|
||||
}
|
||||
}
|
||||
@@ -20,10 +20,7 @@ data "cloudflare_accounts" "main" {
|
||||
}
|
||||
|
||||
locals {
|
||||
# Use account ID from data source if available, otherwise use variable
|
||||
account_id = (
|
||||
var.cloudflare_account_name != "" && length(data.cloudflare_accounts.main) > 0 && length(data.cloudflare_accounts.main[0].accounts) > 0
|
||||
? data.cloudflare_accounts.main[0].accounts[0].id
|
||||
: var.cloudflare_account_id
|
||||
)
|
||||
# Use account ID from data source if available, otherwise fall back to variable.
|
||||
# `try()` avoids invalid index errors when the data source count is 0 or no accounts match.
|
||||
account_id = try(data.cloudflare_accounts.main[0].accounts[0].id, var.cloudflare_account_id)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
cloudflare_api_token = "placeholder-token"
|
||||
cloudflare_account_id = "placeholder-account-id"
|
||||
cloudflare_account_name = "" # Leave empty to use hardcoded account_id
|
||||
cloudflare_api_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # Placeholder (format-valid, not a real token)
|
||||
cloudflare_account_id = "00000000000000000000000000000000" # Placeholder (format-valid, not a real account ID)
|
||||
cloudflare_account_name = "" # Leave empty to use cloudflare_account_id
|
||||
|
||||
@@ -64,3 +64,15 @@ variable "blocked_countries" {
|
||||
type = list(string)
|
||||
default = ["CN", "RU", "KP", "IR"]
|
||||
}
|
||||
|
||||
variable "enable_managed_waf" {
|
||||
description = "Enable Cloudflare managed WAF rulesets (requires WAF entitlement; typically not available on Free plan)."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "enable_bot_management" {
|
||||
description = "Enable Cloudflare Bot Management settings (requires Bot Management entitlement)."
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ resource "cloudflare_ruleset" "security_rules" {
|
||||
# Rule 1: Block requests to /admin from non-trusted IPs
|
||||
rules {
|
||||
action = "block"
|
||||
expression = "(http.request.uri.path contains \"/admin\") and not (ip.src in {${join(" ", var.trusted_admin_ips)}})"
|
||||
expression = length(var.trusted_admin_ips) > 0 ? "(http.request.uri.path contains \"/admin\") and not (ip.src in {${join(" ", var.trusted_admin_ips)}})" : "false"
|
||||
description = "Block admin access from untrusted IPs"
|
||||
enabled = length(var.trusted_admin_ips) > 0
|
||||
}
|
||||
@@ -19,9 +19,9 @@ resource "cloudflare_ruleset" "security_rules" {
|
||||
# Rule 2: Challenge suspicious countries
|
||||
rules {
|
||||
action = "managed_challenge"
|
||||
expression = "(ip.src.country in {\"${join("\" \"", var.blocked_countries)}\"})"
|
||||
expression = length(var.blocked_countries) > 0 ? format("(ip.src.country in {%s})", join(" ", [for c in var.blocked_countries : format("\"%s\"", c)])) : "false"
|
||||
description = "Challenge traffic from high-risk countries"
|
||||
enabled = true
|
||||
enabled = length(var.blocked_countries) > 0
|
||||
}
|
||||
|
||||
# Rule 3: Block known bad user agents
|
||||
@@ -49,11 +49,14 @@ resource "cloudflare_ruleset" "security_rules" {
|
||||
|
||||
# Enable Cloudflare Managed WAF Ruleset
|
||||
resource "cloudflare_ruleset" "managed_waf" {
|
||||
for_each = cloudflare_zone.domains
|
||||
zone_id = each.value.id
|
||||
name = "Managed WAF"
|
||||
kind = "zone"
|
||||
phase = "http_request_firewall_managed"
|
||||
for_each = {
|
||||
for domain, zone in cloudflare_zone.domains : domain => zone
|
||||
if var.enable_managed_waf && var.domains[domain].plan != "free"
|
||||
}
|
||||
zone_id = each.value.id
|
||||
name = "Managed WAF"
|
||||
kind = "zone"
|
||||
phase = "http_request_firewall_managed"
|
||||
|
||||
# Cloudflare Managed Ruleset
|
||||
rules {
|
||||
@@ -80,7 +83,10 @@ resource "cloudflare_ruleset" "managed_waf" {
|
||||
|
||||
# Bot Management (if available on plan)
|
||||
resource "cloudflare_bot_management" "domains" {
|
||||
for_each = cloudflare_zone.domains
|
||||
for_each = {
|
||||
for domain, zone in cloudflare_zone.domains : domain => zone
|
||||
if var.enable_bot_management && var.domains[domain].plan != "free"
|
||||
}
|
||||
zone_id = each.value.id
|
||||
enable_js = true
|
||||
fight_mode = true
|
||||
|
||||
Reference in New Issue
Block a user