Overhaul of Cloudflare script.

This commit is contained in:
2025-11-02 09:37:57 -05:00
parent be45db6186
commit b6ea6a581c
10 changed files with 230 additions and 2914 deletions
+2
View File
@@ -6,6 +6,8 @@ on:
branches-ignore:
- "main"
- "renovate/**"
paths:
- "cloudflare/**"
env:
OPENTOFU_VERSION: "1.10.6"
HC_VAULT_VERSION: "1.20.4"
+10 -10
View File
@@ -2,18 +2,18 @@
# Manual edits may be lost in future updates.
provider "registry.opentofu.org/cloudflare/cloudflare" {
version = "5.11.0"
version = "5.12.0"
constraints = "~> 5.0"
hashes = [
"h1:jgb1wjIOM91LvApId25gmz6X5NcfS0e10flOrndNwqM=",
"zh:0848e1ac58cbca0adeba216742a5a7054a10386f019d4358eb69afa3ac4dc247",
"zh:3212393037e7a5db03d81d652d15a6343befffbf1ed643b5ad60bf4b157762ac",
"zh:3d89d228d0931c891b8e3ecdba28182e6a97972d1c1c7088360f7f0a40d49f97",
"zh:aef6572e45bdf05765db2976625eaa1997116e17d68e82d36ff0c5090690b758",
"zh:b8ba44b1a3a52252b9fe33611310869820e8610e3ae6ca67bb14134dcd20a306",
"zh:e0099f6d61c552c3fd7801d06f3d6912cb26dc3d808f97fa69015adcc4485e4d",
"zh:e937b5d23a6373417f4e4f80bb89b1865d783af7d7baccf8547c59b4d38707ec",
"zh:ed2417b3d7487227bf78c70c372fc9fa711d83ea073755e3ff8484af7ca194c1",
"h1:IvMPMJrmyw6x+8GZklY7qb8VXrjr00zwsN+TFlxkCTM=",
"zh:06166a72e69eb712ad2c8b49c1ed060223b0d57bb95ce5f6c8440ce19253913e",
"zh:484c32dc4fbe1f7baaf00f8d0d1774d259e1a602aebf60b8dea8c6dd122c1d27",
"zh:914b4796a5f2c5914cb94864a7541ce132c0e287bf49a5328706d50152117bc4",
"zh:bbcf3effe11ad44988c2aa4482c3fd0089ca86527463a9a873cecda1a4a022bc",
"zh:c2a59f29b4b4c0344dbb9ab3d78ebcc1d32153f1fd7e919eba7edf7d825119c2",
"zh:d6900b39b9c58743e6b1f05b2db7c39276c94f74d501f23bebb88d413266c57c",
"zh:f000d33075c30e616df8e58e341614e958eed4a51f3427d2e1a18ea1b7e0c6c6",
"zh:f809ab383cca0a5f83072981c64208cbd7fa67e986a86ee02dd2c82333221e32",
"zh:ff4fd5b3b0327f8f41fc65d909839288fb98ecfe32a9aff11d2e2638f2109302",
]
}
@@ -1,5 +0,0 @@
resource "cloudflare_argo_tiered_caching" "terraform_managed_resource_tiered_caching_0" {
value = "on"
zone_id = "17dbb71212204583b777783d25eb6738"
}
File diff suppressed because it is too large Load Diff
@@ -1,25 +0,0 @@
resource "cloudflare_email_routing_dns" "terraform_managed_resource_17dbb71212204583b777783d25eb6738_0" {
name = "trez.wtf"
zone_id = "17dbb71212204583b777783d25eb6738"
}
resource "cloudflare_email_routing_dns" "terraform_managed_resource_17dbb71212204583b777783d25eb6738_1" {
name = "trez.wtf"
zone_id = "17dbb71212204583b777783d25eb6738"
}
resource "cloudflare_email_routing_dns" "terraform_managed_resource_17dbb71212204583b777783d25eb6738_2" {
name = "trez.wtf"
zone_id = "17dbb71212204583b777783d25eb6738"
}
resource "cloudflare_email_routing_dns" "terraform_managed_resource_17dbb71212204583b777783d25eb6738_3" {
name = "cf2024-1._domainkey.trez.wtf"
zone_id = "17dbb71212204583b777783d25eb6738"
}
resource "cloudflare_email_routing_dns" "terraform_managed_resource_17dbb71212204583b777783d25eb6738_4" {
name = "trez.wtf"
zone_id = "17dbb71212204583b777783d25eb6738"
}
@@ -1,4 +0,0 @@
resource "cloudflare_email_routing_settings" "terraform_managed_resource_17dbb71212204583b777783d25eb6738_0" {
zone_id = "17dbb71212204583b777783d25eb6738"
}
-5
View File
@@ -1,5 +0,0 @@
resource "cloudflare_tiered_cache" "terraform_managed_resource_tiered_cache_smart_topology_enable_0" {
value = "on"
zone_id = "17dbb71212204583b777783d25eb6738"
}
-11
View File
@@ -1,11 +0,0 @@
resource "cloudflare_zone" "terraform_managed_resource_17dbb71212204583b777783d25eb6738_0" {
name = "trez.wtf"
paused = false
type = "full"
vanity_name_servers = []
account = {
id = "f5a5c0098ccae27fb0486ffbc2ee6087"
name = "Charish.patel@trez.wtf's Account"
}
}
-6
View File
@@ -1,6 +0,0 @@
resource "cloudflare_zone_dnssec" "terraform_managed_resource_17dbb71212204583b777783d25eb6738_0" {
dnssec_multi_signer = true
status = "active"
zone_id = "17dbb71212204583b777783d25eb6738"
}
+218 -169
View File
@@ -1,181 +1,230 @@
#!/bin/bash
#!/usr/bin/env bash
set -euo pipefail
cf_generate () {
resources=(
cloudflare_account
cloudflare_account_member
cloudflare_account_subscription
cloudflare_address_map
cloudflare_api_shield_discovery_operation
cloudflare_api_shield_operation
cloudflare_api_shield_operation_schema_validation_settings
cloudflare_api_shield_schema
cloudflare_api_shield_schema_validation_settings
cloudflare_argo_smart_routing
cloudflare_argo_tiered_caching
cloudflare_authenticated_origin_pulls
cloudflare_authenticated_origin_pulls_certificate
cloudflare_bot_management
cloudflare_calls_sfu_app
cloudflare_calls_turn_app
cloudflare_certificate_pack
cloudflare_content_scanning_expression
cloudflare_custom_hostname
cloudflare_custom_hostname_fallback_origin
cloudflare_d1_database
cloudflare_dns_firewall
cloudflare_dns_record
cloudflare_dns_zone_transfers_acl
cloudflare_dns_zone_transfers_incoming
cloudflare_dns_zone_transfers_outgoing
cloudflare_dns_zone_transfers_peer
cloudflare_dns_zone_transfers_tsig
cloudflare_email_routing_address
cloudflare_email_routing_catch_all
cloudflare_email_routing_dns
cloudflare_email_routing_rule
cloudflare_email_routing_settings
cloudflare_email_security_block_sender
cloudflare_email_security_impersonation_registry
cloudflare_email_security_trusted_domains
cloudflare_filter
cloudflare_healthcheck
cloudflare_hostname_tls_setting
cloudflare_keyless_certificate
cloudflare_leaked_credential_check
cloudflare_leaked_credential_check_rule
cloudflare_list
cloudflare_list_item
cloudflare_load_balancer
cloudflare_load_balancer_monitor
cloudflare_load_balancer_pool
cloudflare_logpull_retention
cloudflare_logpush_job
cloudflare_magic_wan_static_route
cloudflare_managed_transforms
cloudflare_mtls_certificate
cloudflare_notification_policy
cloudflare_notification_policy_webhooks
cloudflare_observatory_scheduled_test
cloudflare_origin_ca_certificate
cloudflare_page_rule
cloudflare_page_shield_policy
cloudflare_pages_domain
cloudflare_pages_project
cloudflare_queue
cloudflare_queue_consumer
cloudflare_r2_bucket
cloudflare_r2_custom_domain
cloudflare_r2_managed_domain
cloudflare_rate_limit
cloudflare_regional_hostname
cloudflare_regional_tiered_cache
cloudflare_registrar_domain
cloudflare_ruleset
cloudflare_snippet_rules
cloudflare_snippets
cloudflare_spectrum_application
cloudflare_stream
cloudflare_stream_key
cloudflare_stream_live_input
cloudflare_stream_watermark
cloudflare_stream_webhook
cloudflare_tiered_cache
cloudflare_total_tls
cloudflare_turnstile_widget
cloudflare_url_normalization_settings
cloudflare_user
cloudflare_waiting_room
cloudflare_waiting_room_event
cloudflare_waiting_room_rules
cloudflare_waiting_room_settings
cloudflare_web3_hostname
cloudflare_web_analytics_rule
cloudflare_web_analytics_site
cloudflare_workers_cron_trigger
cloudflare_workers_custom_domain
cloudflare_workers_deployment
cloudflare_workers_for_platforms_dispatch_namespace
cloudflare_workers_kv_namespace
cloudflare_workers_script_subdomain
cloudflare_zero_trust_access_application
cloudflare_zero_trust_access_custom_page
cloudflare_zero_trust_access_group
cloudflare_zero_trust_access_identity_provider
cloudflare_zero_trust_access_infrastructure_target
cloudflare_zero_trust_access_key_configuration
cloudflare_zero_trust_access_mtls_certificate
cloudflare_zero_trust_access_mtls_hostname_settings
cloudflare_zero_trust_access_policy
cloudflare_zero_trust_access_service_token
cloudflare_zero_trust_access_short_lived_certificate
cloudflare_zero_trust_access_tag
cloudflare_zero_trust_device_custom_profile
cloudflare_zero_trust_device_default_profile
cloudflare_zero_trust_device_default_profile_certificates
cloudflare_zero_trust_device_default_profile_local_domain_fallback
cloudflare_zero_trust_device_managed_networks
cloudflare_zero_trust_device_posture_integration
cloudflare_zero_trust_device_posture_rule
cloudflare_zero_trust_dex_test
cloudflare_zero_trust_dlp_custom_profile
cloudflare_zero_trust_dlp_dataset
cloudflare_zero_trust_dlp_predefined_profile
cloudflare_zero_trust_dns_location
cloudflare_zero_trust_gateway_certificate
cloudflare_zero_trust_gateway_policy
cloudflare_zero_trust_gateway_proxy_endpoint
cloudflare_zero_trust_gateway_settings
cloudflare_zero_trust_list
cloudflare_zero_trust_organization
cloudflare_zero_trust_risk_behavior
cloudflare_zero_trust_risk_scoring_integration
cloudflare_zero_trust_tunnel_cloudflared
cloudflare_zero_trust_tunnel_cloudflared_config
cloudflare_zero_trust_tunnel_cloudflared_route
cloudflare_zero_trust_tunnel_cloudflared_virtual_network
cloudflare_zone
cloudflare_zone_cache_reserve
cloudflare_zone_cache_variants
cloudflare_zone_dnssec
cloudflare_zone_lockdown
cloudflare_zone_setting
)
# -------------------------------
# Detect Terraform binary: tofu vs terraform
# -------------------------------
if command -v tofu &>/dev/null; then
TF_BIN="tofu"
elif command -v terraform &>/dev/null; then
TF_BIN="terraform"
else
echo "❌ Neither 'terraform' nor 'tofu' found in PATH"
exit 1
fi
for resource in "${resources[@]}"; do
echo "Generating ${resource}.tf..."
cf-terraforming generate --zone ${CLOUDFLARE_ZONE_ID} --resource-type ${resource} > ${resource}.tf
done
echo "️ Using $TF_BIN for Terraform operations"
echo "🧹 Cleaning up empty files..."
find . -size 0 -name "*.tf" | xargs rm
echo "✅ All Terraform files generated!"
# -------------------------------
# Ensure CF API token
# -------------------------------
CF_API_TOKEN="${CLOUDFLARE_API_TOKEN:-}"
if [[ -z "${CF_API_TOKEN}" ]]; then
echo "Please set CF_API_TOKEN before running this script."
exit 1
fi
# -------------------------------
# Helper: fetch paginated results from Cloudflare API
# -------------------------------
cf_paginate() {
local endpoint="$1"
local page=1
local per_page=100
while :; do
local result
result=$(curl -s -X GET "${endpoint}?page=${page}&per_page=${per_page}" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json")
local items
items=$(echo "${result}" | jq -r '.result[]? | @base64')
[[ -z "$items" ]] && break
echo "$items"
local total_pages
total_pages=$(echo "$result" | jq -r '.result_info.total_pages')
((page++))
[[ $page -gt $total_pages ]] && break
done
}
cf_import () {
for cfresource in $(find . -type f -name "cloudflare_*.tf"); do
echo "Importing ${cfresource}..."
cf-terraforming import --zone ${CLOUDFLARE_ZONE_ID} --modern-import-block --resource-type $(echo ${cfresource} | sed -e 's/.\///' -e 's/\.tf//') >> imports.tf
done
# -------------------------------
# Generate Cloudflare resources using cf-terraforming
# -------------------------------
generate_resources() {
echo "🔧 Generating Cloudflare resources via cf-terraforming..."
local output_file="cloudflare_resource_gen.tf"
> "${output_file}"
echo "✅ All Cloudflare resources imported. Please check imports.tf"
resources=(
cloudflare_account
cloudflare_account_member
cloudflare_account_subscription
cloudflare_address_map
cloudflare_argo_tiered_caching
cloudflare_authenticated_origin_pulls
cloudflare_authenticated_origin_pulls_certificate
cloudflare_bot_management
cloudflare_certificate_pack
cloudflare_content_scanning_expression
cloudflare_custom_hostname
cloudflare_custom_hostname_fallback_origin
cloudflare_d1_database
cloudflare_dns_firewall
cloudflare_dns_record
cloudflare_dns_zone_transfers_acl
cloudflare_dns_zone_transfers_incoming
cloudflare_dns_zone_transfers_outgoing
cloudflare_dns_zone_transfers_peer
cloudflare_dns_zone_transfers_tsig
cloudflare_email_routing_address
cloudflare_email_routing_catch_all
cloudflare_email_routing_dns
cloudflare_email_routing_rule
cloudflare_email_routing_settings
cloudflare_filter
cloudflare_healthcheck
cloudflare_hostname_tls_setting
cloudflare_keyless_certificate
cloudflare_leaked_credential_check
cloudflare_leaked_credential_check_rule
cloudflare_list_item
cloudflare_load_balancer
cloudflare_load_balancer_monitor
cloudflare_load_balancer_pool
cloudflare_logpull_retention
cloudflare_logpush_job
cloudflare_magic_wan_static_route
cloudflare_managed_transforms
cloudflare_mtls_certificate
cloudflare_notification_policy
cloudflare_notification_policy_webhooks
cloudflare_observatory_scheduled_test
cloudflare_origin_ca_certificate
cloudflare_page_rule
cloudflare_page_shield_policy
cloudflare_pages_domain
cloudflare_pages_project
cloudflare_queue
cloudflare_queue_consumer
cloudflare_r2_bucket
cloudflare_r2_custom_domain
cloudflare_r2_managed_domain
cloudflare_rate_limit
cloudflare_regional_hostname
cloudflare_regional_tiered_cache
cloudflare_registrar_domain
cloudflare_ruleset
cloudflare_snippet_rules
cloudflare_snippets
cloudflare_spectrum_application
cloudflare_stream
cloudflare_stream_key
cloudflare_stream_live_input
cloudflare_stream_watermark
cloudflare_stream_webhook
cloudflare_tiered_cache
cloudflare_total_tls
cloudflare_turnstile_widget
cloudflare_url_normalization_settings
cloudflare_user
cloudflare_waiting_room
cloudflare_waiting_room_event
cloudflare_waiting_room_rules
cloudflare_waiting_room_settings
cloudflare_web3_hostname
cloudflare_web_analytics_rule
cloudflare_web_analytics_site
cloudflare_workers_cron_trigger
cloudflare_workers_custom_domain
cloudflare_workers_deployment
cloudflare_workers_for_platforms_dispatch_namespace
cloudflare_workers_kv_namespace
cloudflare_workers_script_subdomain
cloudflare_zone
cloudflare_zone_cache_reserve
cloudflare_zone_cache_variants
cloudflare_zone_dnssec
cloudflare_zone_lockdown
cloudflare_zone_setting
)
for r in "${resources[@]}"; do
echo "Generating $r ..."
cf-terraforming generate \
--token "${CF_API_TOKEN}" \
--resource-type "${r}" >> "${output_file}" || true
done
echo "✅ Terraform resources generated in ${output_file}"
}
# Prompt user for input
# -------------------------------
# Import Cloudflare resources into state using cf-terraforming
# -------------------------------
import_zone_resources() {
local zone_id="$1"
local zone_name="$2"
echo "⏳ Importing zone $zone_name ..."
cf-terraforming import \
--token "${CF_API_TOKEN}" \
--modern-import-block \
--resource-type cloudflare_zone \
--resource-id "$zone_id" >> cloudflare_resource_imp.tf || true
echo "✅ Imported cloudflare_zone for $zone_name"
echo "🔄 Importing DNS records for $zone_name ..."
cf-terraforming import \
--token "${CF_API_TOKEN}" \
--zone "$zone_id" \
--modern-import-block \
--resource-type cloudflare_dns_record >> cloudflare_resource_imp.tf || true
echo "✅ Imported DNS records for $zone_name"
# Optional: import other zone-level resources
for res in cloudflare_argo_tiered_caching cloudflare_email_routing_settings cloudflare_tiered_cache cloudflare_zone_dnssec; do
cf-terraforming import \
--token "${CF_API_TOKEN}" \
--resource-type "$res" \
--modern-import-block \
--resource-id "$zone_id" >> cloudflare_resource_imp.tf || true
echo "✅ Imported $res for $zone_name"
done
}
# -------------------------------
# Main
# -------------------------------
echo "Choose an option:"
echo "1) Generate Cloudflare Terraform resources"
echo "2) Import Cloudflare Terraform resources"
read -rp "Enter 1 or 2: " user_choice
echo "2) Import Cloudflare Terraform resources into state"
read -rp "Enter 1 or 2: " choice
case "$user_choice" in
1)
cf_generate
;;
2)
cf_import
;;
*)
echo "Invalid option. Please enter 1 or 2."
exit 1
;;
case "$choice" in
1)
generate_resources
;;
2)
echo "🔄 Fetching zones..."
zones=$(cf_paginate "https://api.cloudflare.com/client/v4/zones")
declare -A zone_map
while read -r z; do
zname=$(echo "$z" | base64 --decode | jq -r '.name')
zid=$(echo "$z" | base64 --decode | jq -r '.id')
zone_map["$zname"]="$zid"
done <<< "$zones"
echo "⚡ Found ${#zone_map[@]} zones."
for zone_name in "${!zone_map[@]}"; do
zid="${zone_map[$zone_name]}"
import_zone_resources "$zid" "$zone_name"
done
;;
*)
echo "Invalid option. Enter 1 or 2."
exit 1
;;
esac
echo "🎉 All operations completed!"