Introduction
Overview
When a modern web application scales beyond a handful of users, the need for a robust edge network becomes critical. Cloudflare offers a unified platform that delivers global content delivery, DDoS mitigation, WAF (Web Application Firewall), and SSL/TLS termination without the overhead of managing individual servers.
In this guide we will:
- Create a production‑ready Cloudflare zone.
- Enable core security features (SSL, WAF, Bot Management).
- Configure the CDN for optimal caching.
- Automate the entire workflow using Terraform and a Python API client.
- Visualize the architecture to illustrate how traffic flows from the Internet to the origin server.
The example mirrors a typical SaaS deployment: a static front‑end hosted on Amazon S3, a dynamic API running on AWS Elastic Beanstalk, and a private PostgreSQL database behind a VPC.
SEO tip: Keywords such as Cloudflare security setup, CDN configuration, and Terraform Cloudflare are strategically placed throughout the article to improve discoverability.
Architectural Blueprint
High‑Level Architecture
mermaid flowchart TD Internet([Internet]) -->|HTTPS| CF[Cloudflare Edge] CF -->|Cache Hit| S3[Amazon S3 (Static Assets)] CF -->|Cache Miss| EB[Elastic Beanstalk (API)] EB --> RDS[PostgreSQL (VPC Private)] CF -->|Security Checks| WAF[Web Application Firewall] CF -->|Rate Limiting| BotM[Bot Management]
Key components
- Cloudflare Edge - Serves as the first line of defense and the CDN cache.
- SSL/TLS - Terminates encrypted traffic at Cloudflare, then re‑encrypts to the origin using Full (Strict) mode.
- WAF Ruleset - Leverages Cloudflare’s Managed Rulesets plus custom policies.
- Rate Limiting & Bot Management - Thwarts abusive traffic before it reaches the origin.
- Origin Servers - S3 for static files, Elastic Beanstalk for the API, both protected by origin‑pull authentication.
By offloading security and caching to Cloudflare, the origin can focus on business logic, resulting in lower latency, reduced cost, and higher availability.
Step‑by‑Step Configuration
1. Provision the Cloudflare Zone with Terraform
Terraform provides a repeatable, version‑controlled method to configure Cloudflare resources. Below is a minimal main.tf that creates the zone, enables SSL, and activates the WAF.
hcl provider "cloudflare" { api_token = var.cloudflare_api_token }
resource "cloudflare_zone" "example" { zone = "example.com" plan = "pro" }
resource "cloudflare_ssl_certificate_pack" "example_ssl" { zone_id = cloudflare_zone.example.id type = "advanced" validation_method = "txt" }
resource "cloudflare_zone_settings_override" "security" { zone_id = cloudflare_zone.example.id
settings { ssl = "strict" security_level = "high" min_tls_version = "1.2" automatic_https_rewrites = "on" always_use_https = "on" challenge_ttl = 1800 } }
resource "cloudflare_waf_package" "managed" { zone_id = cloudflare_zone.example.id package_id = "efbe3c9db611fa03c9c678a8677c36e5" // Cloudflare Managed Ruleset ID }
resource "cloudflare_rate_limit" "api" { zone_id = cloudflare_zone.example.id threshold = 1000 period = 60 description = "Limit API calls to 1000 req/min" match { request { url = "/api/*" methods = ["GET", "POST", "PUT", "DELETE"] } response { status = [200, 401, 403] } } action { mode = "simulate" timeout = 30 } }
Tip: Store
var.cloudflare_api_tokenin a secured secret manager (e.g., AWS Secrets Manager or HashiCorp Vault) and reference it via Terraform'svarblock.
2. Configure DNS Records for Edge Routing
After the zone is created, define DNS entries that point to your origin services. The following example uses CNAME flattening for the API sub‑domain, ensuring Cloudflare continues to proxy the traffic.
hcl resource "cloudflare_record" "www" { zone_id = cloudflare_zone.example.id name = "www" type = "CNAME" value = "example.com" ttl = 1 proxied = true }
resource "cloudflare_record" "api" { zone_id = cloudflare_zone.example.id name = "api" type = "CNAME" value = "myapp.elasticbeanstalk.com" ttl = 1 proxied = true }
3. Enable Origin Pull Authentication (Optional but Recommended)
Origin Pull uses a signed client certificate to verify that requests truly come from Cloudflare. Generate a key pair on the origin server and upload the public certificate to Cloudflare.
bash
Generate a private key (keep secret on the origin)
openssl genrsa -out cloudflare_origin_key.pem 2048
Create a self‑signed certificate
openssl req -new -x509 -key cloudflare_origin_key.pem -out cloudflare_origin_cert.pem -days 3650 -subj "/CN=Cloudflare Origin Pull"
Upload the certificate via Terraform:
hcl resource "cloudflare_ssl_certificate" "origin_pull" { zone_id = cloudflare_zone.example.id certificate = file("cloudflare_origin_cert.pem") private_key = file("cloudflare_origin_key.pem") type = "origin_pull" }
On the origin (e.g., Nginx), enforce the client cert:
nginx server { listen 443 ssl; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_client_certificate /etc/nginx/ssl/cloudflare_origin_cert.pem; ssl_verify_client on; # ... other config ... }
4. Fine‑Tune Caching Rules
Cloudflare’s default cache respects standard Cache‑Control headers, but you can add page rules for finer control.
hcl resource "cloudflare_page_rule" "static_assets" { zone_id = cloudflare_zone.example.id target = "example.com/static/*" priority = 1
actions { cache_level = "cache_everything" edge_cache_ttl = 604800 # 7 days browser_cache_ttl = 86400 # 1 day } }
Dynamic endpoints (e.g., /api/*) should be bypassed:
hcl resource "cloudflare_page_rule" "api_no_cache" { zone_id = cloudflare_zone.example.id target = "api.example.com/*" priority = 2
actions { cache_level = "bypass" security_level = "high" } }
5. Automate Runtime Updates with the Cloudflare API (Python Example)
Sometimes you need to adjust WAF rules on the fly - for instance, toggling a rule during a security incident. The following script demonstrates how to disable a specific rule for 30 minutes using the official Cloudflare Python SDK.
python import os, time from cloudflare import CloudFlare
Authentication - API token stored in an environment variable
cf = CloudFlare(token=os.getenv('CF_API_TOKEN')) zone_name = "example.com" rule_id = "100001" # Replace with the actual rule ID you wish to modify
Fetch the zone identifier
zones = cf.zones.get(params={'name': zone_name}) zone_id = zones[0]['id']
Disable the rule
cf.zones.firewall.rules.patch(zone_id, rule_id, data={'mode': 'disable'}) print(f"Rule {rule_id} disabled for zone {zone_name}")
Sleep for 30 minutes then re‑enable
time.sleep(30 * 60) cf.zones.firewall.rules.patch(zone_id, rule_id, data={'mode': 'challenge'}) print(f"Rule {rule_id} re‑enabled (challenge mode)")
Run the script as part of an incident response playbook, or schedule it via AWS Lambda for automated temporary mitigations.
FAQs
Frequently Asked Questions
Q1: Do I need to expose my origin servers to the public internet after enabling Cloudflare?
A: No. By configuring Origin Pull Authentication and restricting inbound traffic to Cloudflare IP ranges (using a firewall or security group), the origin can remain private. This drastically reduces the attack surface.
Q2: How does Cloudflare handle TLS certificates for sub‑domains like api.example.com?
A: Cloudflare issues a Universal SSL certificate that covers the root domain and all sub‑domains automatically. For stricter compliance (e.g., EV certificates), you can upload a custom certificate via the SSL for SaaS feature or use Dedicated SSL.
Q3: What is the impact of enabling "Cache Everything" on dynamic pages?
A: The Cache Everything page rule tells Cloudflare to store any response, regardless of Cache‑Control. For truly dynamic content you should bypass caching or implement Cache‑Tag headers that let you purge individual objects when data changes.
Q4: Can I monitor Cloudflare traffic and security events from my existing observability stack?
A: Yes. Cloudflare provides Enterprise Log Share (ELSG) and Logpush to stream logs to S3, Azure Blob, or a SIEM like Splunk. Additionally, the Analytics API offers real‑time metrics that can be scraped by Prometheus.
Q5: Is there a way to test my WAF rules without impacting live traffic?
A: Deploy the rules in "Simulate" mode first. Cloudflare logs the potential matches without blocking them. Once you verify the false‑positive rate, switch the mode to "Block" or "Challenge".
Conclusion
Wrapping Up
Implementing Cloudflare as both a security gateway and CDN transforms a conventional web stack into a resilient, high‑performance architecture. By leveraging Terraform for infrastructure as code, origin‑pull authentication for private origins, and programmatic rule management via the Cloudflare API, teams can achieve:
- Reduced latency - Edge caching delivers static assets from the nearest PoP.
- Robust protection - WAF, rate limiting, and bot management mitigate attacks before they hit the origin.
- Operational efficiency - Automated pipelines guarantee repeatable, auditable deployments.
- Scalable observability - Logs and analytics integrate with existing monitoring tools.
The real‑world example presented here mirrors production environments, yet the concepts scale down to startups and up to enterprise‑grade deployments. Adopt the patterns, adjust the parameters to fit your traffic profile, and let Cloudflare handle the heavy lifting so you can focus on delivering value to your users.
