CDN Configuration Version Control: GitOps for Edge Infrastructure
Edge infrastructure has traditionally lived outside version control. CDN configurations — cache rules, origin definitions, WAF policies, header transformations, and routing logic — were managed through web portals or ad-hoc API calls. This creates configuration drift, undocumented changes, and painful incident recovery. When a bad cache rule purges critical assets or a WAF exception exposes an origin, there is often no audit trail or one-click revert.
Applying GitOps to CDN management solves this by treating edge configuration as declarative code, versioned in Git, and reconciled automatically by automation. Every change is a pull request, every deployment is auditable, and every environment is reproducible. For teams managing global traffic at the edge, this shift is foundational to reliability, security, and velocity. This guide details a production-ready GitOps architecture for CDN configuration version control, from repository design to automated deployment and drift remediation.
1. Why Edge Configuration Needs Version Control
Unlike application code, CDN configuration directly controls availability and security at the perimeter. A single misconfigured cache-control or origin timeout can cause origin overload, stale content, or downtime for millions of users. Portal-based changes lack peer review, testing, and history.
Common failure modes without version control include:
- Drift: Manual hotfixes in the dashboard diverge from documented runbooks. No one knows the true production state.
- Blind rollbacks: Reverting requires remembering old values and re-entering them manually under pressure.
- No blast radius control: Changes deploy globally instantly with no canary or staged rollout.
- Audit gaps: Compliance requires who-changed-what-when, but portal logs are fragmented and not tied to business approvals.
Version control brings the same guarantees we expect from infrastructure as code: idempotency, diffability, and declarative state. When combined with GitOps, the Git repository becomes the single source of truth. The edge is continuously reconciled to match it.
2. GitOps Principles Applied to CDN
GitOps, popularized for Kubernetes, maps perfectly to edge infrastructure. The four principles are declarative, versioned, pulled, and continuously reconciled.
| Metric | Edge Processing | Origin Processing | Improvement |
|---|---|---|---|
| Latency (p50) | 8–15 ms | 120–300 ms | 15–20x faster |
| Cache Hit Ratio | 85–95% | N/A | Reduces origin load |
| TLS Handshake | 1–5 ms (nearby PoP) | 50–150 ms | 10–30x faster |
| Bandwidth Cost | $0.01–0.04/GB | $0.05–0.12/GB | 3–5x cheaper |
| Availability | 99.99% (multi-PoP) | 99.9% (single DC) | 10x fewer outages |
Declarative Configuration
Define the desired state, not imperative steps. Instead of “purge /api/* and set TTL to 60s”, you declare: route /api/* { cache_ttl = 60, cache_key = "$uri$args", origin = "api-primary" }. Tools like Terraform, Pulumi, or vendor-specific providers (Cloudflare, Fastly, Akamai, AWS CloudFront) convert this declaration into API calls.
Versioned and Immutable
Every configuration version is a Git commit SHA. Tags mark releases (e.g., edge-v2026.09.06-1). Immutable history enables git bisect to find when a performance regression was introduced and git revert to undo it.
Pulled by Automation
An agent or CI pipeline pulls from Git and applies changes, rather than developers pushing from laptops. This eliminates credential sprawl and ensures only reviewed code reaches the edge.
Continuously Reconciled
A controller periodically compares actual CDN state versus Git and alerts or auto-remediates drift. This is critical because portal access often remains for emergencies, and security policies must not silently diverge.
3. Repository Structure for Edge Infrastructure
A well-structured repository prevents monolithic, unreviewable pull requests. Separate concerns by environment, service, and provider.
# Recommended layout for cdn-config repo cdn-config/ ├── environments/ │ ├── production/ │ │ ├── cloudfront.tf │ │ ├── waf.tf │ │ └── variables.tf │ ├── staging/ │ └── global/ │ ├── cache-rules.yaml │ └── edge-functions/ ├── modules/ │ ├── cache-policy/ │ ├── origin-group/ │ └── security-headers/ ├── policies/ │ ├── sentinel.hcl # policy-as-code for compliance │ └── opa/ └── .github/workflows/ ├── plan.yaml └── apply.yaml
Key practices: use reusable modules for cache policies so teams do not duplicate TTL logic, keep secrets out of Git (reference them via Vault or AWS Secrets Manager), and store non-Terraform assets like VCL, Workers, or EdgeWorkers as versioned files alongside their bindings. For large teams, adopt a mono-repo with CODEOWNERS: /environments/production/waf.tf @security-team ensures WAF changes require security review.
Pin provider versions and use remote state with locking (S3 + DynamoDB, Terraform Cloud, or GitLab state). This prevents concurrent applies from corrupting edge state.
4. The GitOps Workflow: From Commit to Edge
The workflow enforces review, validation, and progressive delivery before any byte reaches the edge.
Unlike traditional push models, the pipeline never allows direct apply from a developer machine. All changes flow through CI, where plan output is posted as a PR comment for review. This makes the impact on cache hit ratio, origin load, and security posture visible before merge.
5. Implementation: Terraform and Pipeline
Most teams use Terraform with CDN provider plugins. The following declares a cache policy and origin group that can be versioned and reused.
resource "cloudflare_ruleset" cache_rules { zone_id = var.zone_id name = "edge-cache-v1" kind = "zone" phase = "http_request_cache_settings" rules { action = "set_cache_settings" expression = "(http.request.uri.path contains \"/static/\")" action_parameters { cache = true edge_ttl { mode = "override_origin" default = 86400 status_code_ttl { status_code = 200, value = 86400 } } cache_key { custom_key { query_string { include = ["v"] } } } } } } resource "fastly_service_vcl" api_service { name = "api-edge" domain { name = "api.example.com" } backend { address = "origin.example.com" shield = "iad-va-us" } # VCL file is versioned in Git vcl { name = "main", content = file("./vcl/main.vcl"), main = true } }
Pair this with a GitHub Actions workflow that enforces plan-then-apply:
# .github/workflows/plan.yaml name: cdn-plan on: pull_request jobs: plan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: hashicorp/setup-terraform@v3 - run: terraform init -backend-config=env/production.hcl - run: terraform fmt -check - run: terraform validate - run: terraform plan -out plan.tfplan - uses: actions/github-script@v7 with: { script: "post plan as PR comment for review" } # .github/workflows/apply.yaml - only on main on: push: { branches: [main] } jobs: apply: environment: production # requires approval steps: - run: terraform apply -auto-approve plan.tfplan - run: ./scripts/verify_edge.sh # smoke test cache & WAF
The verify_edge.sh step is essential: it curls edge PoPs, checks x-cache headers, and validates that Core Web Vitals and security headers remain intact. If verification fails, the pipeline auto-reverts via git revert and re-applies the last known good SHA.
6. Branching, Reviews, and CI Checks
Adopt trunk-based development with short-lived feature branches. Every PR must pass:
- Formatting and validation: terraform fmt, tflint, and YAML schema checks for cache rules.
- Policy as code: OPA/Conftest or Sentinel rules that block risky changes — e.g., disabling WAF, setting cache_ttl = 0 on static assets, or opening origins to 0.0.0.0/0.
- Cost and performance diff: Tools like Infracost estimate cache hit ratio impact; custom scripts diff the planned edge config JSON.
- Preview environments: Deploy to a staging zone (e.g., staging.example.com) with identical logic but isolated traffic for integration tests.
Require at least one CODEOWNER approval. For high-risk paths like waf.tf or origin TLS settings, require two approvals including security. This replaces informal Slack approvals with an auditable gate that satisfies SOC 2 and PCI requirements.
| Aspect | Traditional Portal Management | GitOps Version Control |
|---|---|---|
| Source of truth | Dashboard + tribal knowledge | Git repository (declarative code) |
| Change process | Manual clicks, no review | Pull request, CI plan, approval |
| Auditability | Fragmented logs | Git history + signed commits |
| Rollback | Manual re-entry, error-prone | git revert + automated apply in <2 min |
| Drift detection | None — silent divergence | Hourly reconcile + alerts |
| Testing | Production is the test | Plan diff, staging, smoke tests |
7. Drift Detection and Rollback
Even with GitOps, emergency portal changes happen during incidents. Without reconciliation, drift persists. Implement a drift controller that runs terraform plan -detailed-exitcode hourly and posts to Slack/PagerDuty if drift is detected. For stricter enforcement, run it in auto-remediate mode where it re-applies Git state.
Rollback should be a Git operation, not a dashboard action. Tag every successful apply (e.g., edge-prod-124) and keep the last 20 plans as artifacts. When latency spikes or error rates rise after a deploy, the on-call engineer runs:
git revert HEAD --no-edit git push origin main # triggers apply of previous state # or for immediate revert without new commit: terraform apply -target=cloudflare_ruleset.cache_rules -var-file=last-good.tfvars
Because edge propagation can take 10–60 seconds globally, verify rollback via synthetic checks across PoPs. Integrate with your observability stack — if DDoS protection or rate limiting is accidentally loosened, drift detection should fire before exploitation.
8. Security and Compliance Benefits
Version control transforms edge security from reactive to preventive. All WAF rules, bot management, and TLS configurations are reviewed and scanned before deployment. Secrets like origin tokens and API keys are never stored in Git; they are injected via OIDC at apply time.
Enable signed commits (GPG or SSH) and require branch protection to prevent force-pushes. Store state files encrypted and restrict pipeline OIDC roles to least privilege — the CI role can only update the CDN zone it owns. For compliance, Git history provides a complete, tamper-evident trail that maps directly to change tickets.
Finally, treat edge functions as application code: lint, unit test, and bundle them in CI. A versioned Worker that adds security headers should have the same rigor as a backend service, because it runs on every request at the edge.
Frequently Asked Questions
How do you handle CDN provider APIs that lack Terraform support?
Use a hybrid approach. Keep Terraform for supported resources and manage gaps with declarative YAML plus a custom reconciler (e.g., a Python script using the provider SDK) that runs in the same pipeline. Store the YAML in Git and make the script idempotent so the workflow remains GitOps-compliant. Alternatively, use Pulumi or Crossplane which often have broader provider coverage.
Can GitOps support instant emergency fixes at the edge?
Yes. For true emergencies, allow a break-glass portal change, but require that the same change is committed to Git within 30 minutes via an automated “import” job that runs terraform import and opens a PR. Drift detection will flag any uncommitted change, ensuring Git remains authoritative without blocking urgent mitigation.
How do you test CDN configuration changes before global rollout?
Test in three layers: static validation (fmt, lint, policy), staging deployment to a mirrored zone with synthetic traffic, and canary rollout using percentage-based routing or surrogate keys. Run k6 or Playwright checks against staging that assert cache HIT/MISS headers, TLS versions, and WAF block behavior before promoting to production.
What is the best way to manage secrets for edge origins?
Never commit secrets. Store them in a secrets manager (AWS Secrets Manager, HashiCorp Vault) and reference them via data sources at apply time. Use OIDC federation for CI to assume a role that can read secrets without static credentials. Rotate origin tokens automatically and version the rotation in Git as a reference update, not a value.
Adopting GitOps for CDN configuration turns a fragile, manual perimeter into a resilient, auditable system. Start small: codify one cache policy, add CI plan checks, and enforce drift detection. Once the loop is trusted, expand to WAF, routing, and edge compute. Your future incident response will thank you — with a single git revert instead of a midnight dashboard hunt.