A national grocery chain runs its e-commerce estate across two clouds, and not by accident. The storefront and checkout grew up on AWS behind an Application Load Balancer; the loyalty programme, the weekly-offers engine, and the in-store fulfilment APIs were built by a team that standardised on Azure behind Front Door. Both are real production systems, both serve the same shop.example.com brand, and neither team is going to rewrite onto the other cloud to make life tidy. Then a competitor gets taken down by a credential-stuffing attack on Black Friday weekend, the chain’s CISO asks “could that happen to us,” and the honest answer is yes: the AWS ALB and the Azure Front Door each have a public IP an attacker can hit directly, each cloud has its own WAF with its own rule syntax and its own dashboard, and the bot defences are inconsistent across the two. The mandate that comes down is specific — one security perimeter, one set of WAF and bot rules, one place to see the logs, and the origins hidden so nobody can bypass the edge — without forcing a migration. This article is the reference architecture for that: a single Akamai edge in front of both clouds, with the origins cloaked behind it.
The pressures here are the ones retail always brings. Traffic is spiky and adversarial — a flash sale draws real shoppers and bot-driven scalpers and scrapers in the same minute, and the edge has to tell them apart. Latency sells — every extra hundred milliseconds on a product page measurably costs conversions, so static and cacheable content has to be served from close to the shopper, not round-tripped to an origin in another region. The attack surface is plural — two clouds means two public front doors unless you do something about it. And the security team needs one pane of glass, because correlating an attack across an AWS WAF console and an Azure WAF console while the sale is live is how incidents get missed. A single global edge that fronts both origins, enforces one consistent policy, caches aggressively, and cloaks the origins is what satisfies all four at once.
Why not the obvious shortcuts
Three cheaper-sounding options will get proposed in the first planning meeting, and each fails in a way worth naming.
“Just use each cloud’s native CDN and WAF.” CloudFront with AWS WAF in front of the AWS origin, Azure Front Door’s WAF in front of the Azure origin. This is two perimeters, two rule languages, two bot engines, and two log pipelines — exactly the fragmentation the mandate exists to kill. A rule you write to block a new attack pattern has to be authored twice, and it will drift. And neither cloud’s edge naturally fronts the other cloud’s origin, so a unified policy across both is something you would be building by hand anyway.
“Put one cloud’s edge in front of both.” Technically you can point Front Door or CloudFront at a cross-cloud origin. But you have now made one cloud’s edge a hard dependency for the other cloud’s traffic, your egress and cross-cloud data-transfer bill grows, and you still have the native WAF’s rule model rather than a best-of-breed one. It is a half-measure that buys unification at the cost of a new coupling.
“Just lock down the origins with security groups.” Restrict the ALB and Front Door to known IP ranges. This helps, but cloud edge IP ranges are large, change over time, and are shared across every tenant — an allow-list of “CloudFront ranges” still admits anyone else using CloudFront. IP allow-listing alone does not prove a request actually traversed your edge and your WAF.
The architecture that threads the needle puts a single vendor-neutral edge — Akamai — in front of both origins, runs one App & API Protector WAF policy and one Bot Manager policy globally, caches at the edge for both clouds, and then uses Site Shield plus mTLS so each origin will only accept traffic that genuinely came through Akamai. One perimeter, both clouds, origins cloaked.
Architecture overview
The defining property of the topology is that shoppers never reach an origin directly, and the origins are configured to make sure of it. Every request for shop.example.com resolves to Akamai’s anycast edge. Akamai terminates TLS, applies the WAF and bot policies, serves from cache when it can, and only on a cache miss reaches back to an origin — and which origin depends on the path. The AWS ALB and the Azure Front Door each sit behind Site Shield, accepting connections only from Akamai’s published edge node ranges, and each validates a mutual-TLS client certificate that only Akamai presents. A request that tries to hit the ALB’s public DNS name directly, bypassing the edge, is refused at the origin.
Request path, following the control and data flow:
- A shopper’s browser resolves
shop.example.com. DNS (delegated to Edge DNS, Akamai’s authoritative DNS) returns an anycast edge IP, so the shopper lands on the nearest Akamai point of presence. TLS terminates here against the public certificate. - The request enters the App & API Protector WAF. Adaptive Security Engine rules screen for the OWASP-style injection and exploit patterns; rate controls clamp request floods per client; and API definitions (imported from the OpenAPI specs of the fulfilment APIs) enforce schema, method, and per-endpoint rate limits so a malformed or abusive API call is rejected at the edge, not at the origin.
- Bot Manager scores the request. Known-good bots (the chain’s monitoring, legitimate search crawlers) are allowed; the credential-stuffing and scalping bots that motivated the project are detected by behavioural and device signals and either blocked, served a challenge, or quietly tarpitted — the response depends on the category, configured once and applied globally.
- If the request survives the WAF and bot checks, the edge consults cache. Product images, CSS/JS bundles, category pages, and other cacheable content are served straight from the edge PoP — no origin contact at all — which is most of the traffic on a normal browsing session.
- On a cache miss (or a non-cacheable request —
/checkout,/api/loyalty, anything personalised), Akamai’s Property Manager rules route by path./,/product/*,/cart,/checkout/*go forward to the AWS origin (the ALB);/api/loyalty/*,/offers/*,/api/fulfilment/*go to the Azure origin (Front Door). The forward request leaves Akamai’s edge, traverses to the cloud, and — critically — arrives at an origin that has been cloaked. - At the AWS origin, the ALB’s security group (managed as a Site Shield map) admits only Akamai edge ranges, and a listener rule requires the mTLS client certificate Akamai presents; anything else is dropped. The ALB forwards to the ECS/Fargate storefront. At the Azure origin, Front Door’s WAF runs in a thin pass-through mode (the heavy lifting already happened at Akamai), a Front Door rule validates the same client-cert header, and traffic reaches the App Service / AKS loyalty backend. The response flows back through Akamai, which caches it if the headers permit and streams it to the shopper.
Log and telemetry path, running alongside: Akamai’s DataStream 2 streams structured edge logs — every request, its WAF/bot verdict, cache status, origin latency, and response code — in near-real-time to Datadog, where the security and SRE teams get one unified view across both clouds’ traffic. The origins also ship their own logs (CloudWatch for AWS, Azure Monitor for Azure) into the same Datadog tenant, so a single trace of “shopper → edge → which origin → backend” is reconstructable in one place.
Component breakdown
| Component | Service / tool | Role in the platform | Key configuration choices |
|---|---|---|---|
| Authoritative DNS | Akamai Edge DNS | Resolves the brand hostnames to the anycast edge | Delegated zone; health-aware records; CNAME of apex via edge hostname |
| CDN / edge | Akamai (Ion / Property Manager) | TLS termination, caching, path-based origin routing | Cache keys and TTLs per content type; two origin definitions (AWS, Azure) |
| WAF | App & API Protector | One global L7 security policy for both clouds | Adaptive Security Engine rules; rate controls; API definitions from OpenAPI |
| Bot defence | Bot Manager | Detect and act on scalpers, scrapers, credential stuffing | Category-based actions (allow / challenge / deny / tarpit); JS + device signals |
| Origin cloaking | Site Shield | Restrict each origin to Akamai edge node ranges only | Site Shield map per origin; map updates fed into SG / Front Door ACL |
| Origin authentication | mTLS to origin | Prove the request actually came through Akamai | Akamai client cert; ALB mutual-TLS listener; Front Door cert header check |
| AWS origin | ALB → ECS Fargate | Serves storefront, cart, checkout | SG = Site Shield ranges; mTLS listener; private subnets behind |
| Azure origin | Azure Front Door → App Service / AKS | Serves loyalty, offers, fulfilment APIs | Pass-through WAF; cert-header rule; Private Link to backends |
| Edge log streaming | DataStream 2 → Datadog | Near-real-time edge logs to one pane of glass | JSON log format; WAF/bot verdict + cache + origin latency fields |
| Observability | Datadog | Unified dashboards, alerts, SLOs across both clouds | Edge logs + CloudWatch + Azure Monitor in one tenant; bot/attack monitors |
| Edge config as code | Akamai Terraform provider | Version-controlled property, WAF, Site Shield config | akamai_property; security policy resources; activation gated in CI |
| CI / IaC | GitHub Actions + Terraform | Build/validate/activate edge and origin config | Plan on PR; staging activation before production network |
| ITSM | ServiceNow | Change records for edge policy and Site Shield map updates | Change gate before production activation; auto-ticket on a Site Shield map change |
A few of these choices carry the weight of the design, and they are the ones teams get wrong.
Why path-based routing at the edge, not DNS-based split. You could give the two clouds two different hostnames and let DNS send shoppers to one or the other, but then you have two perimeters again and the brand hostname is split. Routing at Akamai’s Property Manager keeps a single shop.example.com for the shopper and a single security policy, while still forwarding /api/loyalty/* to Azure and /checkout/* to AWS underneath. The cloud boundary becomes an implementation detail the shopper and the attacker never see.
Why Site Shield and mTLS, not either alone. Site Shield restricts the origin to Akamai’s edge node IP ranges — necessary, but those ranges are shared infrastructure, so on its own it would admit traffic from any Akamai customer’s edge. Mutual TLS closes that gap: the origin additionally demands a client certificate that only your Akamai configuration presents, proving the request both came from Akamai and came from your property. Together they make origin cloaking real: a direct hit on the ALB’s DNS name fails the IP check, and a request from someone else’s Akamai property fails the certificate check.
Why one WAF policy beats two native ones. The entire point of the mandate is a single rule set. App & API Protector lets the security team author one policy — one set of injection rules, one rate-control posture, one API schema enforcement — that protects AWS-bound and Azure-bound traffic identically. When a new attack pattern appears mid-sale, the rule is written once and is live for both clouds in minutes, with one ServiceNow change record, not two consoles and a drift risk.
Implementation guidance
Manage the edge as code, and stage every activation. Akamai configuration — the property (CDN behaviours and routing), the WAF security policy, the Site Shield maps — all has a Terraform provider, and you want it in version control for the same reasons you want the origins in Terraform: reviewable diffs, a change history, and a CI gate. The non-negotiable discipline is activate to the staging network first, smoke-test, then activate to production, because an edge config error is a production-wide outage, not a single-server one.
A minimal Property Manager shape communicates the two-origin intent — one property, two origin definitions, path rules choosing between them:
resource "akamai_property" "shop" {
name = "shop-example-com"
product_id = "prd_Fresca"
contract_id = var.contract_id
group_id = var.group_id
hostnames {
cname_from = "shop.example.com"
cname_to = "shop.example.com.edgekey.net" # edge hostname
cert_provisioning_type = "CPS_MANAGED"
}
rules = data.akamai_property_rules_template.shop.json # behaviours + path routing
}
The routing logic lives in the rules tree: a default rule forwarding to the AWS origin, and a match on the API and loyalty path prefixes that overrides the origin to Azure Front Door. Both origin definitions point at the cloud edge hostnames (not the backend IPs), set forward_host_header appropriately, and — importantly — attach the client certificate for mTLS.
Cloak the AWS origin. The ALB lives in private subnets; its security group is driven by the Site Shield map so it admits only Akamai edge ranges on 443. Add a mutual-TLS listener so the ALB demands and verifies Akamai’s client certificate. The combination is what makes “you cannot reach this origin except through our edge” true rather than aspirational:
# ALB listener: terminate TLS, require a client cert (mTLS), trust only Akamai's CA
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.storefront.arn
port = 443
protocol = "HTTPS"
certificate_arn = aws_acm_certificate.shop.arn
mutual_authentication {
mode = "verify"
trust_store_arn = aws_lb_trust_store.akamai.arn # Akamai client-cert CA bundle
}
default_action { type = "forward" target_group_arn = aws_lb_target_group.fargate.arn }
}
# Security group source ranges come from the Site Shield map, not 0.0.0.0/0
Cloak the Azure origin. Front Door is reachable publicly by default, so cloaking it takes a different shape than the ALB: keep Front Door as the Azure-side entry, but configure a Front Door rules-engine rule that rejects any request lacking the client-certificate header Akamai injects, and use Private Link from Front Door to the App Service / AKS backend so the backend itself has no public surface. The backend trusts only Front Door; Front Door trusts only requests carrying Akamai’s cert evidence; Akamai is the only thing presenting it. The chain holds.
Get the caching right, because it is most of the win. Set generous TTLs on genuinely static assets (images, fonts, versioned JS/CSS) and cache category and product pages with shorter TTLs and cache-key normalisation so query-string noise does not shatter the cache. Mark /checkout/*, /cart, and every authenticated or personalised API as no-store so they always reach the origin — a cached checkout page is a security incident, not a performance win. Tune the cache key to ignore tracking parameters and to vary correctly on device and language. The payoff: on a normal browsing session the overwhelming majority of requests are served from the edge and never touch either cloud, which is simultaneously the latency win and the origin-protection win.
Enterprise considerations
Security & defence in depth. The architecture is defence-in-depth by construction. At the edge: App & API Protector screens L7 attacks and enforces API schemas, and Bot Manager handles the automated-abuse problem that started the project — credential stuffing against the loyalty login, scalper bots on limited-stock flash-sale items, and price-scraping competitors, each categorised and actioned independently. Behind the edge, Site Shield + mTLS cloak both origins so the WAF cannot be bypassed by hitting an origin directly — the single most important control here, because a WAF you can route around is decorative. The Azure-side Front Door WAF runs as a thin secondary layer (defence in depth, not duplicated effort), and both clouds’ backends sit in private subnets / behind Private Link with no public ingress of their own. A meaningful security event at the edge — a sustained bot attack, a spike in WAF blocks, a Site Shield map change — raises a ServiceNow incident so the SOC has a ticket and an audit trail, not just a Datadog graph. Edge configuration changes flow through CI and a ServiceNow change gate, so nobody hand-edits the WAF in the console during an incident and forgets to record it.
Observability — one pane of glass. This was an explicit requirement, and it is delivered by DataStream 2 streaming Akamai edge logs into Datadog in near-real-time: every request’s WAF verdict, bot score, cache hit/miss, origin latency, and response code, for both AWS-bound and Azure-bound traffic, in one tenant. Layer the origins’ own logs (CloudWatch, Azure Monitor) into the same Datadog tenant and you can follow a single request from shopper through edge to whichever cloud served it. Build the dashboards the teams actually need: cache hit ratio (the lever on both cost and latency), edge-blocked attack volume by category, bot-vs-human traffic split, origin offload percentage per cloud, and p95 latency at the edge vs at each origin. Alert on the things that signal trouble — a sudden cache-hit-ratio drop (a misconfigured no-store rule shedding load onto an origin), a bot-traffic surge against the login endpoint, or origin 5xx climbing on either cloud.
Cost optimization. The economics here are mostly about offload and egress.
| Lever | Mechanism | Typical effect |
|---|---|---|
| Edge offload | High cache hit ratio serves static/semi-static from the edge | Origin compute and cross-cloud egress drop sharply |
| Egress reduction | Cached responses never re-fetch from AWS/Azure | Cloud data-transfer-out bill falls with cache hit ratio |
| One WAF licence | Single Akamai security policy vs two native WAFs to operate | Lower operational cost; one team owns one policy |
| Right-size origins | Edge absorbs spikes; origins scale to steady-state misses | Smaller autoscale floors on ECS and App Service |
| Bot deflection | Blocking scrapers/scalpers at the edge removes junk origin load | Origins serve real shoppers, not bot traffic |
The single biggest cost lever is the cache hit ratio: every percentage point of offload is origin compute you do not run and cloud egress you do not pay for, on both clouds. Track it in Datadog and treat a regression as a cost incident, not just a performance one.
Scalability and traffic surges. Akamai’s edge absorbs flash-sale and Black-Friday spikes natively — that is the whole value of a global anycast CDN, and it means the origins only ever see cache misses and non-cacheable checkout/API traffic, a far smaller and steadier load. Size the AWS ECS/Fargate and Azure App Service / AKS autoscaling to that miss-and-checkout volume, not to raw shopper count. Bot Manager shedding scalper and scraper traffic at the edge further protects origin capacity for genuine buyers during the exact moments — a limited-stock drop — when scalper bots peak hardest.
Failure modes, and what each one looks like. Name them before they page you.
- A Site Shield map update lands late — Akamai periodically rotates its edge node ranges and publishes a new map; if the origin’s security group is not updated before the old ranges retire, legitimate edge traffic gets blocked at the origin and the site appears down. Mitigation: automate the map-to-SG/ACL sync (CI-driven, ServiceNow-recorded), and alert on pending map changes well before the deadline.
- mTLS certificate expiry — the client certificate Akamai presents to the origins expires and every forwarded request is suddenly refused at both clouds at once. Mitigation: monitor cert expiry, rotate ahead of time, and stage the rotation through the Akamai staging network.
- A bad no-store / cache rule — marking something cacheable that should not be (a personalised page) leaks one shopper’s content to another; marking something no-store that could be cached collapses the cache hit ratio and floods the origins. Mitigation: review cache rules in code, and alert on cache-hit-ratio swings.
- An over-aggressive bot rule — a new Bot Manager action misclassifies real shoppers (or the chain’s own monitoring) as bots and challenges or blocks them during a sale. Mitigation: roll bot rule changes out in monitor-then-enforce mode, watch the human-vs-bot split, and stage before production.
- A single-origin outage — one cloud’s backend has an incident. Because routing is path-based, an AWS outage takes down storefront/checkout while Azure-served loyalty/offers stay up (and vice versa). Mitigation: Akamai origin health checks plus a maintenance/failover page served from the edge for the affected paths, so the shopper sees a graceful message, not a raw error.
Reliability & DR. The edge itself is globally distributed and is the most resilient tier; the realistic failure unit is an origin. Because the two clouds serve disjoint path sets, they are partial-failure-isolated by design — a fault in one degrades a slice of the site, not all of it. For true DR, the storefront’s critical paths can be given a secondary origin in a second AWS region (Akamai fails over on health check), and the same pattern applies to the Azure side. A pragmatic target for this estate: edge stays up through any single-region cloud event; storefront RTO of minutes via origin health-checked failover to a standby region; and a static, edge-served “sale paused, back shortly” page as the always-available floor so shoppers never hit a blank error during an incident.
Explicit tradeoffs
Accept these or do not build it. A single vendor-neutral edge in front of both clouds adds a layer — and a vendor — that pure-native architectures do not have: Akamai is now in the critical path for all traffic, its configuration is a production-wide blast radius, and the team has to learn Property Manager, App & API Protector, and Bot Manager rather than the cloud-native consoles they already know. Origin cloaking with Site Shield + mTLS is real operational overhead: maps that must be kept in sync, certificates that must be rotated, and the unforgiving failure mode that getting either wrong blocks all legitimate traffic at once, not one server. The two-origin routing means the path map is now a thing you maintain, and a path added to the wrong cloud is a silent misroute. None of this is free; for a single-cloud, low-threat site it would be over-engineering, and each cloud’s native CDN+WAF would be the right, simpler answer.
The alternatives, and when they win. If you live on one cloud and have no real bot or multi-cloud-unification problem, the native edge — CloudFront + AWS WAF, or Front Door + Azure WAF — is simpler, cheaper to start, and one less vendor; reach for a third-party edge when you genuinely need cross-cloud unification or best-of-breed bot defence. If your only goal is caching and the threat model is light, a CDN without the full WAF/Bot Manager tier is enough. If you need to front many clouds and on-prem with deep customisation, the same Akamai pattern here generalises — add origins and path rules — and that breadth is precisely where a vendor-neutral edge earns its place over any single cloud’s native stack. And if you are early and small, start with native and graduate to this when the second cloud, the bot abuse, and the “one pane of glass” demand all arrive at once — which, for this grocery chain, they did.
The shape of the win
For the grocery chain, the payoff is not “a CDN.” It is that a credential-stuffing wave on the loyalty login during a flash sale is detected and stopped at the edge before it reaches Azure; that the scalper bots on the limited-stock drop are tarpitted while real shoppers check out on AWS unaffected; that the security team writes one WAF rule and it protects both clouds in minutes with one change record; and that when the CISO asks “can someone bypass our WAF and hit the origin directly,” the answer is now a flat no — Site Shield and mTLS see to that. The storefront stayed on AWS, the loyalty platform stayed on Azure, nobody migrated anything, and yet there is one perimeter, one policy, one log stream, and two cloaked origins. That is the sentence that closes the mandate. Everything upstream — the anycast edge, the App & API Protector policy, the Bot Manager categories, the Site Shield maps, the mTLS to both origins, the DataStream-to-Datadog pipeline — exists to let a CISO, an SRE lead, and a CFO each say yes without either cloud team having to give up their cloud.