Files
tar-valon-terraform/cloudflare/generate_cf_resources.sh
T

231 lines
7.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -euo pipefail
# -------------------------------
# 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
echo "️ Using $TF_BIN for Terraform operations"
# -------------------------------
# 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
}
# -------------------------------
# Generate Cloudflare resources using cf-terraforming
# -------------------------------
generate_resources() {
echo "🔧 Generating Cloudflare resources via cf-terraforming..."
local output_file="cloudflare_resource_gen.tf"
> "${output_file}"
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}"
}
# -------------------------------
# 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 into state"
read -rp "Enter 1 or 2: " choice
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!"