Architecture Multi-cloud

Secure Multi-Cloud Landing Zone for a Global Logistics Provider — Enterprise Reference Architecture

A global express, freight, and supply-chain carrier that moves parcels, time-critical freight, and temperature-controlled healthcare shipments through a worldwide air-and-ground network of sorting hubs, distribution centres, and a last-mile delivery fleet asked a deceptively simple question: “Give us one secure foundation we can build the next decade on.” Behind that question sits a brutal amount of reality — four on-premises data centres in four countries, a dual-cloud mandate across Azure and AWS, more than 100 applications, SAP at the centre of the business, a hybrid workforce signing in from offices and from home, and a fleet of trucks and containers that needs to report its location and condition in near real time. This article is the target-state reference architecture for that foundation: a secure, policy-driven, multi-cloud landing zone built on the Cloud Adoption Framework, enterprise-scale landing zones, and Well-Architected principles, and justified — not just asserted — with twenty-seven architecture diagrams.

The design brief is uncompromising. Identity is the perimeter, not the network. Platform services come before applications. Platform subscriptions and accounts stay separate from workload subscriptions and accounts so that a compromise or a mistake has a small blast radius. Guardrails, naming, tagging, logging, and CI/CD behave identically whether a team lands in Azure or AWS. And every critical service is engineered for regional and circuit redundancy rather than convenience. The result is not a flat trust zone stretched into the cloud; it is the same or better user and operator experience delivered through integrated identity, DNS, routing, and policy while zero-trust enforcement runs underneath every request.

Target-state overview

The estate is best understood from a single vantage point before drilling into any one domain. Users and partners enter from the top — office staff, work-from-home staff over GlobalProtect VPN, and external partners. Every public request first meets a third-party global edge (CDN, authoritative DNS with global traffic management, and a WAF) that normalises and protects traffic before it touches a cloud. Azure and AWS each host enterprise landing zones; the four on-premises data centres anchor the bottom and connect to both clouds over dual private circuits. Cross-cutting platforms — Okta, Microsoft Entra ID, Wiz, CrowdStrike Falcon, Dynatrace, and ServiceNow — operate horizontally across both clouds so security, observability, and operations are consistent. A dedicated IoT lane carries telemetry from trucks and containers into the platform.

Target-State Overview — Secure Multi-Cloud Logistics Estate

Two design decisions in this overview drive everything that follows. First, the edge is a third-party global tier, not a per-cloud feature. A single CDN/DNS/WAF stack in front of both clouds gives one place to enforce OWASP rules, bot mitigation, API protection, and geo policy, and it lets traffic fail over between Azure and AWS origins without re-architecting each application. Second, the four on-premises data centres are first-class regions, not legacy to be tolerated. SAP dependencies, AD DS, Kerberos-bound systems, and country-level business continuity all assume the on-premises footprint persists, so the connectivity and identity designs treat hybrid as the default rather than a migration afterthought.

Architecture principles and operating model

Six principles govern the build. Platform first — identity, networking, management, and security are established before any workload migrates. Segregation by design — platform and application boundaries never share a subscription or account. Zero trust — no user, device, workload, or path is trusted implicitly; access is evaluated continuously on identity, device, risk, and context. Hybrid by default — every critical service accounts for on-premises integration, SAP, and AD DS. Multi-cloud consistency — one set of guardrails, naming, logging, and CI/CD across both clouds. Resilience over convenience — regional redundancy, redundant circuits, and tested recovery beat the easy path.

These principles only hold if someone owns them. The operating model centres on a Cloud Center of Excellence that owns landing-zone standards, policy-as-code, reference architectures, and onboarding patterns. Around it sit five teams with clear remits: Cloud Platform Engineering (landing zones, automation, shared tooling), Cloud Security and Identity (Okta/Entra federation, PIM, Conditional Access, Wiz, CrowdStrike, secrets, governance), Network and Connectivity (ExpressRoute, Direct Connect, transit, firewalls, DNS, edge, GlobalProtect), Cloud Operations (monitoring, backup, incident response, ServiceNow), and Application Enablement (onboarding blueprints by workload type). The consulting partner’s job is to make those teams self-sufficient after handover, which is why every pattern in this architecture is expressed as reusable code and documented runbooks rather than tribal knowledge.

Requirements and non-functional targets

A design is only as good as the targets it can be tested against, so before any topology is drawn the proposal pins down what the estate must do and how well it must do it. The functional scope is broad but deliberately bounded: a dual-cloud landing zone across Azure and AWS, a zero-trust identity fabric spanning on-premises Active Directory, Entra ID, and Okta, resilient hybrid connectivity from the four data centres, a factory to onboard 100-plus applications, a self-managed SAP landing zone, an event-driven data and integration platform, a fleet-scale IoT backbone, a location-transparent digital workplace, an end-to-end DevSecOps pipeline, and a unified observability and SOC capability. Each of those is a deliverable in its own right; what turns them from a wish list into an engineerable system is the set of non-functional targets that follow, because those are the numbers the platform will be accepted — or rejected — against.

The headline non-functional is availability, and it is engineered to the recovery tier rather than promised as a single blanket figure. The platform and Tier-0 control plane — identity, connectivity, DNS, and security tooling — carries a monthly SLO of 99.99%, because nothing else recovers until it does. Tier-1 services that the business sells against — customer logistics platforms, SAP production, and partner APIs — target 99.95%; Tier-2 line-of-business and analytics workloads target 99.9%; and Tier-3 development, test, and non-critical reporting relax to 99.5%. Latency is treated with the same specificity: edge-cached time-to-first-byte stays under 100 ms globally, the control-tower and tracking APIs hold a p95 under 300 ms in-region, and the real-time IoT alert path — geofence and threshold breaches that a dispatcher acts on — completes end-to-end in under 5 seconds. Scale targets are sized to the fleet the carrier actually runs: 500,000-plus connected devices, 50,000 messages per second at peak ingest, 10,000 tracking events per second sustained, and headroom to onboard 100-plus applications without re-architecting the platform.

Security and operational agility close out the envelope, and both are expressed as measurable commitments rather than intentions, because a posture that cannot be measured cannot be defended in an audit. Every user authenticates with MFA (100% coverage), privileged roles use phishing-resistant factors, and the estate runs with zero standing privilege — all administrative access is brokered just-in-time through PIM with approval and a time box. Posture is held to a Wiz score of at least 85 across both clouds, and the patch SLA is seven days for critical and thirty days for high findings, tracked to closure rather than to detection. On agility, a new subscription or account is vended in under one business day and a new application reaches production-ready in under two weeks through the blueprint — the deliberate counterweight to the governance, so that control does not become a synonym for slow. Recovery objectives are governed by the DR-tier table reproduced in the resiliency section, and the compliance posture — ISO 27001, SOC 2 Type II, PCI-DSS on payment paths, and GDPR with country data-residency — is detailed in the compliance section, with this document carrying only the obligation that the targets exist and are owned. The table below consolidates the non-functionals into the form the programme tracks them in: a dimension, a hard target, and the mechanism by which it is met and measured.

Dimension Target How it’s met / measured
Platform / Tier-0 availability 99.99% monthly Active-active control plane, paired-DR region per geography, RTO 1h / RPO 15m
Tier-1 availability 99.95% monthly Customer platforms, SAP prod, partner APIs across 2 AZs + warm DR
Tier-2 / Tier-3 availability 99.9% / 99.5% monthly Single-region resilient with backup-driven recovery to tier RTO/RPO
Edge latency TTFB < 100 ms globally Third-party CDN anycast caching + health-checked DNS failover
API latency Control-tower & tracking p95 < 300 ms in-region Regional active-active, private back ends, Dynatrace RUM/synthetic
IoT alert latency End-to-end < 5 s Rules engine + stream processing on the hot path, geofence/threshold
Device & ingest scale 500,000+ devices, 50,000 msg/sec peak, 10,000 events/sec sustained AWS IoT Core + Azure IoT Hub, sharded streaming, load-tested
Security posture MFA 100%, zero standing privilege, Wiz ≥ 85 Conditional Access + PIM JIT, continuous CSPM scoring
Patch SLA Critical 7 days / High 30 days Monthly cadence + critical out-of-band, tracked in ServiceNow
Operational agility Vend < 1 business day, new app < 2 weeks Subscription/account factories + application blueprint

Requirements traceability

Stating targets is necessary but not sufficient; the proof that the architecture answers them is traceability — every requirement mapped to a concrete design element and to the diagram that evidences it, so that nothing is asserted in prose and then quietly orphaned. The discipline matters most on a dual-cloud estate, where it is easy for a control to be real in Azure and merely assumed in AWS, or for a resilience claim to lack a rehearsal behind it. The register below is the spine that connects the two halves of the document: read left to right, each row begins with a business or platform requirement, moves to the design response that satisfies it, and ends with the section or diagram a reviewer can open to confirm the response is actually built rather than promised.

The mapping is deliberately complete across the estate’s load-bearing concerns, and it is bidirectional in spirit: every requirement has a design response, and — just as important — no major design element exists without a requirement that justifies it, which is how gold-plating is kept out of the architecture. Guardrail consistency is satisfied by the subscription and account factories that vend governed landing zones identically in both clouds; zero-trust identity by the Conditional Access and PIM model over Entra and Okta; resilient connectivity by the dual ExpressRoute and Direct Connect design; and scale, SAP resilience, multi-layer security, IoT throughput, observability, data residency, and operability each trace to their own design response and evidence. Where a requirement spans several diagrams — multi-layer security and application onboarding both do — the traceability points at the set, because the control only holds when every layer is present. The final row is the one that is easiest to omit and most expensive to skip: the estate must remain operable after handover, which traces to the RACI and the runbooks in the operating-model section, because a platform nobody can run to its targets has not actually met them.

Req ID Requirement Design response Evidence (section / diagram)
REQ-01 Consistent dual-cloud guardrails Subscription factory + Account Factory for Terraform, one policy-as-code set Azure & AWS landing zone sections / governance hierarchy diagram
REQ-02 Zero-trust identity, no standing privilege Entra + Okta, Conditional Access engine, PIM JIT with approval and time-box Identity & Conditional Access sections / identity & CA-PIM diagrams
REQ-03 Resilient hybrid connectivity from 4 DCs 2× ExpressRoute + 2× Direct Connect per region, active-active BGP Global hybrid connectivity section / connectivity diagram
REQ-04 Onboard 100+ applications Application blueprints + factory vending, secure-by-default landing zones Application onboarding section / onboarding diagrams
REQ-05 SAP high availability and DR HANA System Replication across 2 AZs + asynchronous warm-standby DR SAP landing zone section / SAP diagram
REQ-06 Multi-layer, defence-in-depth security Seven-layer model + layered edge ingress, centralised inspection Multi-layer security sections / security & network diagrams
REQ-07 Fleet-scale IoT ingest Split AWS IoT Core (vehicle telemetry) + Azure IoT Hub (control tower) IoT connected logistics section / IoT diagrams
REQ-08 Unified observability and SOC Dynatrace strategic plane, Sentinel SIEM, automated ServiceNow incidents Observability & SOC section / SOC diagram
REQ-09 Data residency and localisation Medallion lakehouse governance band enforcing in-region restricted data Data & integration section / data platform diagram
REQ-10 Operable to target after handover 6-team RACI, tiered DR runbooks, follow-the-sun support model Operating model & DR runbooks section / governance material

Azure landing zone

Azure follows the enterprise-scale design. A Tenant Root Group anchors a management-group hierarchy that pushes policy and RBAC down by inheritance, so a control written once applies everywhere beneath it. The Platform management group holds four dedicated platform subscriptions — Identity, Connectivity, Management, and Security — which keeps shared services out of any single workload’s blast radius and lets the platform teams operate them on their own change cadence. Application workloads live under a Landing Zones management group, split into Corp (internal) and Online (internet-facing) and further separated into production and non-production subscriptions. Sandbox and Decommissioned management groups give experimentation and offboarding their own guarded lifecycles.

Azure Landing Zone — Management Groups & Platform Subscriptions

The platform subscriptions earn their separation. Identity carries domain controllers, Entra Connect, and private DNS support. Connectivity holds the regional hub VNets, Azure Firewall Premium, Application Gateway WAF, the ExpressRoute gateway, DNS Private Resolver, Bastion, and DDoS Network Protection. Management centralises Log Analytics, Azure Monitor, Automation, Update Management, and Backup vaults. Security runs Microsoft Sentinel, Key Vault HSM, break-glass identities, and the integration anchors for Wiz and CrowdStrike. Application subscriptions are vended, not hand-built: a subscription factory places each new subscription under the right management group, inherits policy, assigns RBAC, applies cost tags, and attaches it to the hub — so a workload arrives already governed.

AWS landing zone

AWS mirrors the same intent through AWS Organizations and a multi-account model delivered with Control Tower and Account Factory for Terraform. The Management account sits at the apex; Service Control Policies enforce the same guardrails the Azure policy hierarchy enforces — approved regions only, no public exposure of sensitive services, mandatory tagging. Security-relevant accounts are isolated in a Security OU (a Log Archive account with immutable S3 and Object Lock, and a Security Tooling account). Infrastructure lives in its own OU (a Shared Network account per region carrying the Transit Gateway, and a Shared Services account). Workloads split into Prod and Non-Prod OUs, with application accounts separated by criticality.

AWS Landing Zone — Organizations, OUs & Account Factory

The decisive pattern here is account vending as code. Account Factory for Terraform provisions and customises accounts through a GitOps workflow, so an application account is never a manual ticket — it is a pull request that yields an account already wired with centralised logging, security-tooling enrolment, a Transit Gateway attachment, IAM Identity Center federation, approved-region settings, and KMS governance. That symmetry between Azure subscription vending and AWS account vending is what makes “multi-cloud consistency” real rather than aspirational: a workload team requests an environment the same way and receives the same baseline regardless of cloud.

Governance hierarchy and policy inheritance

The two landing zones look different on the surface — Azure management groups on one side, AWS organisational units on the other — but they are governed by one set of guardrails compiled into both. Policy-as-code in Terraform defines each control once; it is rendered into Azure Policy and RBAC assignments that inherit down the management-group tree, and into Service Control Policies that inherit down the AWS OU tree. A control authored once — approved regions only, no public exposure of sensitive services, mandatory tagging, encryption everywhere, logging to an immutable archive — therefore applies identically in both clouds, which is exactly what stops a multi-cloud estate from drifting into two divergent ones.

Governance Hierarchy & Policy Inheritance — Azure Management Groups + AWS OUs

Inheritance is the mechanism that lets the operating model scale: the platform teams change a guardrail in one place and every subscription and account beneath it conforms on the next pipeline run, while workload teams stay free to build inside the guardrails without being able to weaken them.

Global hybrid connectivity

Connectivity is where the four-data-centre reality becomes architecture. Four strategic regions align to the four on-premises countries. Each region terminates two ExpressRoute circuits to Azure and two Direct Connect circuits to AWS, ideally across diverse providers, with active-active BGP so a single circuit or carrier failure fails over without human intervention. Azure regional hub VNets front the ExpressRoute gateways and route through Azure Firewall to their spokes; AWS regional Transit Gateways attach behind Direct Connect Gateways and fan out to VPCs. Controlled inter-cloud traffic between Azure and AWS routes either through the on-premises core or a dedicated interconnect, chosen per workload on latency, compliance, and cost.

Global Hybrid Connectivity — 4 Regions, Dual ExpressRoute + Dual Direct Connect

Redundancy here is not gold-plating; it is the explicit requirement. A logistics control tower that loses connectivity to SAP or to its tracking back end stops the business, so every region carries two of everything and the routing is engineered to failback cleanly once a circuit recovers. The hub-and-spoke pattern in Azure and the transit-centric pattern in AWS both centralise inspection and egress control, which means the network security policy is enforced in one place per region instead of being re-implemented per workload.

That WAN view shows where the circuits land; the regional internals differ enough per cloud to deserve their own deep dives. In Azure, each region is a hub-and-spoke VNet: the hub carries the ExpressRoute and backup VPN gateways, Azure Firewall Premium, Application Gateway WAF, Bastion, and DNS Private Resolver in their own dedicated subnets, and spoke VNets for prod and shared services peer in — forced through the firewall by user-defined routes and reaching PaaS only over Private Endpoints.

Azure Regional Hub-and-Spoke Network (Deep Dive)

AWS uses a transit-centric design: a regional Transit Gateway with separate route tables stitches together a dedicated inspection VPC (AWS Network Firewall in appliance mode), an ingress VPC (ALB + WAF across two Availability Zones), an egress VPC (a NAT gateway per AZ), and the workload VPCs — each reaching AWS services privately through Gateway and Interface VPC endpoints, with the Direct Connect Gateway terminating the dual circuits.

AWS Regional Transit-Centric Network (Deep Dive)

IP address management plan

Addressing on a multi-cloud estate is a governance problem long before it is a routing problem. The CIDR ranges that appear throughout the network diagrams are not chosen per project; they are issued from a single, centrally governed plan held in Azure IPAM and AWS VPC IPAM, so that every block is globally non-overlapping and an address can be read like a coordinate. The whole private estate lives inside the 10.0.0.0/8 supernet, allocated as a predictable /16 per (cloud, region, environment, role) — large enough that no workload ever has to renumber, and structured enough that a packet’s source address tells an operator which cloud, which region, and which tier it came from. That discipline is what makes the firewall rules, the route tables, and the on-premises BGP advertisements tractable across two clouds and four data centres.

Global IPAM Allocation Map

The Azure plan encodes meaning into the second and third octets with the scheme 10.[role][region].0.0/16: the role digit is 1 for hub/platform, 2 for production, 3 for shared/non-prod, and the region digit runs 0–3 for the four primary regions and 4–7 for their paired-DR partners. So Region-1’s primary hub is 10.10.0.0/16, its production spoke is 10.20.0.0/16, and its shared/non-prod spoke is 10.30.0.0/16 — exactly the blocks the regional network diagrams carry — while the same region’s DR partner mirrors them at 10.14/10.24/10.34. Inside the Region-1 hub the subnets are themselves reserved by purpose (GatewaySubnet, AzureFirewallSubnet, AppGatewaySubnet, AzureBastionSubnet, and the DNS Private Resolver), and the production spoke is tiered into web, app, and data/Private-Endpoint subnets. AWS follows the same philosophy with its own ranges: a network/inspection VPC at 10.100.0.0/16, ingress and egress VPCs alongside it, a production application VPC at 10.200.0.0/16, and a shared-services VPC at 10.210.0.0/16, with two Availability Zones and /20 subnets per AZ per tier so capacity is never the constraint. On-premises occupies 172.16.0.0/12, partitioned cleanly into four /14 blocks — one per data centre — and 192.168.0.0/16 is held back entirely for lab, edge, and OT use so it can never collide with a routed range.

The master allocation below is the authoritative slice of that plan. Every row is a block the factories may draw from; everything outside it is, by policy, unallocated and therefore safe to grow into. The key invariant is that the address is the identity — because the role and region are baked into the prefix, segmentation rules and residency boundaries can be expressed against CIDR ranges directly, and a misrouted or unexpectedly sourced packet is visible the moment it crosses a firewall.

Scope Region / Env CIDR Purpose
Global supernet All 10.0.0.0/8 Centrally governed private space (Azure IPAM + AWS VPC IPAM)
Azure hub Region-1 primary 10.10.0.0/16 Connectivity hub — gateways, firewall, App Gateway, Bastion, DNS
Azure prod Region-1 primary 10.20.0.0/16 Production workload spokes (web 10.20.1.0/24, app 10.20.2.0/24, data/PE 10.20.3.0/24)
Azure shared Region-1 primary 10.30.0.0/16 Shared services / non-production spokes
Azure hub Region-1 DR 10.14.0.0/16 Paired-DR connectivity hub (prod 10.24.0.0/16, shared 10.34.0.0/16)
Azure region-2 Primary (hub/prod/shared) 10.11.0.0/16 / 10.21.0.0/16 / 10.31.0.0/16 Region-2 strategic geography
Azure region-3 Primary (hub/prod/shared) 10.12.0.0/16 / 10.22.0.0/16 / 10.32.0.0/16 Region-3 strategic geography
Azure region-4 Primary (hub/prod/shared) 10.13.0.0/16 / 10.23.0.0/16 / 10.33.0.0/16 Region-4 strategic geography
AWS network Region-1 primary 10.100.0.0/16 Network / inspection VPC (Network Firewall, Transit Gateway)
AWS ingress/egress Region-1 primary 10.101.0.0/16 / 10.102.0.0/16 Ingress VPC (ALB + WAF) and egress VPC (NAT per AZ)
AWS prod app Region-1 primary 10.200.0.0/16 Production application VPC (two AZs, /20 subnets per tier)
AWS shared services Region-1 primary 10.210.0.0/16 Shared-services VPC
On-premises 4 data centres 172.16.0.0/12 DC1 172.16/14, DC2 172.20/14, DC3 172.24/14, DC4 172.28/14
Reserved Lab / edge / OT 192.168.0.0/16 Held back — never routed into the cloud estate

Capacity and sizing

Capacity on this estate is engineered against the non-functional targets, not guessed at from a rule of thumb. Every tier is sized to the service-level objective and throughput it must sustain, and almost everything autoscales with a floor — a minimum instance count or zone-redundant footprint that holds availability up even at idle, scaling out under load rather than being provisioned for peak the whole month. The connectivity layer is the foundation: each region terminates two ExpressRoute circuits at 10 Gbps (Premium) and two Direct Connect circuits at 10 Gbps (dedicated) in active-active BGP, fronted by an Azure ErGw3AZ gateway with a VpnGw2AZ backup on the Azure side and a Direct Connect Gateway plus Transit Gateway on the AWS side. That is deliberate over-provisioning — a control tower that loses its path to SAP or to tracking stops the business, so the circuits carry headroom and fail over cleanly rather than running hot.

Above the network, compute is sized per cloud and per domain. The Azure edge and security plane runs Azure Firewall Premium (auto-scaling) and a zone-redundant Application Gateway WAF v2 that scales between 2 and 10 instances; web and application tiers run on VM Scale Sets and AKS node pools that scale from a resilient floor toward generous ceilings, backed by zone-redundant Azure SQL Business Critical and PostgreSQL Flexible Server. AWS mirrors the pattern with ALB and Network Firewall, m6i-class Auto Scaling groups and EKS node groups, and Aurora Multi-AZ or RDS for stateful data. SAP is the outlier that earns bespoke sizing: HANA runs on certified high-memory compute — Azure M-series (M128s, ~2 TB) or AWS High Memory / X2iedn — with clustered ASCS/ERS on D-series, HANA System Replication synchronous between the two production zones and asynchronous to the DR region. The IoT lane is sized to the hardest numbers in the brief — 500,000+ connected devices and a 50,000 msg/sec peak — across AWS IoT Core with throughput-sharded Kinesis into Timestream, and Azure IoT Hub with an Azure Data Explorer cluster, while the data backbone runs Event Hubs premium / Kinesis feeding a lakehouse on ADLS Gen2 and S3.

The table below maps each domain to the service and scale unit it is built on and the autoscale or high-availability posture that protects it. The discipline running through all of it is that resilience is a floor, not a feature toggled on under load — minimum instance counts, zone redundancy, and rehearsed replication are sized in from the start, and elasticity handles the variance above that line rather than the availability of the service itself.

Domain Service / SKU Scale unit Autoscale / HA
Hybrid connectivity 2× ExpressRoute (Premium) + 2× Direct Connect (dedicated) per region 10 Gbps per circuit Active-active BGP; ErGw3AZ + VpnGw2AZ backup; DX Gateway + TGW
Azure edge security Azure Firewall Premium Per-region instance Auto-scale, zone-redundant
Azure ingress Application Gateway WAF v2 2–10 instances Autoscale, zone-redundant
Azure web tier VMSS Standard_D4s_v5 3–20 instances Autoscale across zones
Azure app tier VMSS Standard_D8s_v5 3–20 instances Autoscale across zones
Azure containers AKS node pool D8s_v5 3–30 nodes Cluster autoscaler, zone-spread
Azure data Azure SQL Business Critical / PostgreSQL Flexible Per-database Zone-redundant replicas
AWS workloads m6i.xlarge / 2xlarge Auto Scaling; EKS m6i.2xlarge Auto Scaling group / node group Multi-AZ autoscale; ALB + Network Firewall
AWS data Aurora (Multi-AZ) / RDS Per-cluster Multi-AZ replicas, automated failover
SAP HANA Azure M128s (~2 TB) / AWS High Memory u-* / X2iedn High-memory node per zone HSR sync primary↔secondary AZ; async to DR
IoT ingestion AWS IoT Core + Kinesis + Timestream; Azure IoT Hub + ADX 500k devices, 50k msg/sec peak Sharded to throughput; scaled units, ADX cluster
Data & integration Event Hubs premium / Kinesis; lakehouse on ADLS Gen2 + S3 Throughput units / shards Elastic streaming; Databricks/Synapse + Glue/EMR

Identity and zero-trust control plane

Identity is the primary security perimeter, and the design is deliberately identity-first. On-premises AD DS remains authoritative for domain-joined workloads and Group Policy-bound systems; Entra Connect synchronises it into Microsoft Entra ID, which becomes the control plane for Microsoft 365, Intune, Conditional Access, PIM, guest access, and device compliance. Okta is the strategic SSO provider for SaaS and the federation broker into AWS. Workday drives joiner-mover-leaver automation into Okta over SCIM, so access is provisioned and — critically — deprovisioned from the HR source of truth. AWS access flows through Okta-federated roles; Azure administrative access flows through Entra with RBAC and PIM.

Identity & Zero-Trust Control Plane

The enforcement point is a Conditional Access engine that evaluates every authentication against user risk, device compliance (Intune plus CrowdStrike posture), location, and application sensitivity, then grants, demands step-up MFA, or blocks. MFA is mandatory for everyone; phishing-resistant MFA is mandatory for privileged roles and high-risk apps. Standing privilege is eliminated: administrators activate roles just-in-time through PIM with approval and a time box, the most sensitive operations run only from Privileged Access Workstations, and a pair of monitored, cloud-only break-glass accounts exist for genuine emergencies. This is the zero-trust trinity in practice — verify explicitly, grant least privilege, assume breach.

Employee digital workplace

The hardest part of “as if you’re on the local network” is delivering the experience without extending flat network trust. The design uses three access channels. Office users get local internet breakout to Microsoft 365 and approved SaaS — protected by identity and endpoint policy rather than by backhauling everything to a data centre — plus direct private-app access. Work-from-home users reach private applications over GlobalProtect VPN with Okta/Entra MFA, and selected apps are modernised toward Microsoft Entra Private Access for per-app, identity-aware connectivity that does not rely on legacy VPN. The third channel is direct SaaS — Microsoft 365, ADP, Workday, ServiceNow, Bitbucket — all behind Okta SSO.

Employee Digital Workplace — Office, VPN & SaaS Access

What ties the three channels into one experience is unified identity, consistent DNS resolution across office and VPN, and Conditional Access that is invisible to a compliant user but decisive when risk changes. ADP and every enterprise SaaS app follow the same model: SSO through Okta, mandatory MFA, role-based provisioning from HR attributes, and step-up authentication for payroll and admin actions. Device trust — Intune compliance and CrowdStrike posture — gates access to sensitive systems, and unmanaged devices are restricted to web-only sessions for Microsoft 365 or blocked outright for sensitive workloads. The user never needs to know whether a service runs on-premises, in Azure, or in AWS; application publishing hides the location.

Conditional Access and PIM policy model

Because identity does the heavy lifting, the policy model deserves its own view. Conditional Access is expressed as a decision flow: inputs (user and group, device state, location, sign-in risk, application sensitivity) feed a policy engine that outputs grant, require-MFA, require-compliant-device, block, or session control. The baseline policies are non-negotiable — block legacy authentication, require MFA for all cloud apps, require a compliant or hybrid-joined device for admin portals and sensitive data, enforce phishing-resistant MFA for privileged roles, apply session controls to unmanaged-device Microsoft 365 web access, and demand stronger controls for SAP administration and finance or operations data.

Conditional Access & Privileged Identity Management Model

PIM complements Conditional Access on the privileged path. A role is eligible rather than active; an administrator requests activation, an approver grants it, the elevation is time-bound and auto-expires, and every step is written to an immutable audit log. The combination matters: Conditional Access decides whether you may authenticate and from what device, and PIM decides whether — and for how long — you may wield privilege once you are in. Together they remove the two biggest enterprise weaknesses at once: weak authentication and standing administrative access.

Global edge and ingress

Public ingress is a layered funnel that the proposal mandates be third-party and cross-cloud. A request resolves through third-party authoritative DNS with global traffic management, health checks, and automatic failover. It lands on a third-party CDN for global anycast ingress, caching, and TLS. It passes through a third-party WAF that applies OWASP rules in prevention mode, bot management, API security with schema validation, rate limiting, country and ASN allow-deny lists, and reputation filtering. Only the CDN/WAF egress addresses are permitted to reach the origins — origin cloaking that removes the option of bypassing the edge. Regional Azure Application Gateway WAF and AWS ALB-plus-WAF act as a secondary enforcement and app-delivery tier before traffic reaches the application and its private data services.

Global Edge & Ingress Flow — CDN, DNS, WAF to Cloud Origins

The win is defence in depth with a single global control point. A new bot-mitigation rule or a country block is applied once at the edge and protects every public application in both clouds, while the regional WAF tier catches anything cloud-specific and keeps origins private. Every transaction, log, and security signal from the edge is forwarded to the SIEM and to Dynatrace, so the same request can be followed from the user’s browser all the way to the database.

Logistics operating model and domains

The landing zone described so far is a foundation, and a foundation is only interesting for what it carries. What the carrier actually runs is not one system but five operating segments, each with its own cadence, regulator, partners, and definition of “an event.” A booking taken at a freight-forwarding branch, a pallet putaway in a distribution centre, a load tendered to a road carrier, a parcel handed to a consignee, and a customs entry lodged with a border authority are five different businesses that share a brand, a balance sheet, and — if the platform is built correctly — one canonical record of the shipment they all touch. The first job of the industry architecture is therefore to decompose the estate by domain before it is decomposed by technology, so each segment lands in the right subscription or account, at the right recovery tier, behind the right isolation boundary, carrying data of the right class. The segmentation is not cosmetic: customs data is regulated and residency-pinned in a way freight rate cards are not, last-mile carries consignee personal data at a scale the forwarding desk never sees, and a warehouse must keep running when the WAN drops in a way a partner API never has to.

The matrix below is the spine of that decomposition — one row per domain, with the applications it runs, the highest data class it handles, its landing zone, its recovery tier, and the isolation boundary that contains a compromise. It is the bridge between the generic landing-zone controls earlier in this document and the logistics-specific systems that follow: every OMS and WMS component in the next two sections inherits its guardrails, tier, and blast-radius boundary from exactly one of these rows.

Domain Core applications Highest data class Landing zone Tier Isolation boundary
Freight forwarding Booking & forwarding (CargoWise-class), rating/quotation, consolidation, house/master bill of lading Confidential Azure Online prod / AWS Prod OU Tier-1 Dedicated subscription + account; commercial rate data segregated
Warehousing / 3PL WMS, slotting, replenishment, 3PL activity-based billing, yard management Confidential + Restricted (cold-chain custody) Azure Corp prod + per-site edge zone Tier-1 Per-site edge boundary; customer inventory logically partitioned
Transportation / fleet TMS, route & load optimiser, telematics ingest, fleet maintenance Internal + Restricted (driver PII) AWS Prod OU (IoT-adjacent) Tier-1 Dedicated account; IoT lane segmented from business network
Last-mile Delivery orchestration, driver-app backend, proof-of-delivery, PUDO network Restricted (consignee PII) Azure Online prod Tier-1 Internet-facing; PII tokenised; high-scale account isolated
Customs / trade compliance Customs filing (CUSDEC/entry), denied-party screening, HS classification, duty & tax Restricted (regulated) + Confidential Azure Corp prod (residency-pinned in-region) Tier-1 Strong segmentation; in-region only; screening kept auditable
Order & visibility (cross-cutting) OMS, consignment ledger, control tower, customer track-and-trace portal Confidential + Restricted (PII) Azure Online / AWS Prod (dual) Tier-1 SoR/SoE split; ledger runs single-writer, portals read-only projections

The final row binds the other five together, and it deserves the architectural care the bank gives its ledger. In logistics the authoritative fact is not “the order” — orders are customer intent, and one order can spawn several shipments, split across depots, or be cancelled before a wheel turns — it is the consignment: a physical, trackable movement with a canonical lifecycle from booked to delivered. The design therefore names one system of record, the consignment ledger, and treats everything a human or partner looks at — the tracking page, the control-tower map, the partner status feed, the driver app — as a system of engagement that projects off that ledger rather than owning any truth of its own. This is the direct logistics analogue of the bank’s “the ledger is the system of record; channels are systems of engagement,” enforced the same way: the ledger is the single writer of consignment state, it appends immutable events, and the SoE surfaces are eventually-consistent read models rebuilt from the stream. The payoff is that a new portal, marketplace, or partner feed subscribes to existing events instead of reaching into a production database, and no volume of read traffic on the SoE tier can corrupt or slow the SoR.

The event backbone that carries those state transitions — Azure Event Hubs and Kafka on the Azure side, Kinesis on the AWS side, stitched into one common-schema bus — is the same backbone the event-driven pipeline patterns elsewhere in the estate describe, applied to shipment lifecycle rather than checkout. Every hop is at-least-once and, across two clouds, potentially out of order, so the ledger tolerates exactly that: idempotent event keys, per-consignment ordering, and a dedup gate before any consumer sees a transition twice. The table below pins the SoR/SoE split down system by system, because the distinction only protects the estate if every component knows which side of the line it sits on and what consistency it may assume.

System Role SoR / SoE Cloud & tier Consistency model Data class
Consignment ledger Canonical shipment lifecycle state SoR Event Hubs + Cosmos DB, multi-region · Tier-1 Strong on write — single writer, idempotent append Confidential / Restricted
SAP S/4HANA Finance, billing, freight invoicing, goods movement SoR Certified IaaS, 2 AZs + DR · Tier-1 Strong (ACID) Confidential
WMS (per site) Inventory-at-rest for one distribution centre SoR (site-local) Warehouse edge + Azure Corp · Tier-1 Strong locally; store-and-forward to cloud Confidential
TMS Movement plan, load build, carrier assignment SoR (movement) AWS Prod OU · Tier-1 Strong on plan; eventual on status Internal
Customer track-and-trace portal Shipment visibility to shippers & consignees SoE APIM + Cosmos read model · Tier-1 active-active Eventually consistent (CQRS projection) Restricted (PII)
Partner API (204/214/EPCIS) Carrier & partner integration surface SoE API Management · Tier-1 Eventually consistent Confidential
Control tower & exception dashboards Operations visibility and intervention SoE Dynatrace + read models · Tier-2 Eventually consistent Internal
Driver / delivery app Last-mile execution and proof-of-delivery SoE (writes events back) Azure Online · Tier-1 Local-first; event write-back to ledger Restricted (PII)

None of this integrates with the outside world in JSON alone. Logistics is the last great stronghold of EDI, and a global carrier lives or dies by how cleanly it speaks both dialects — UN/EDIFACT in Europe and Asia, ANSI ASC X12 in North America — alongside the REST and webhook surfaces newer partners expect. The estate runs a hardened B2B/EDI gateway (Logic Apps Standard integration accounts fronted by a partner-managed AS2/OFTP2 endpoint) that translates every inbound interchange into the canonical event model before it reaches the ledger, and reverses that on the way out. Identity down to the message matters as much as it does for users: interchanges are authenticated by AS2 certificates, validated against agreed schemas, and always acknowledged — an unacknowledged 856 or 214 is an invisible failure that surfaces as a “lost” shipment days later. Underneath the messages, GS1 supplies the identity of the physical things — the SSCC license plate on every pallet and carton, the GTIN on every item, the GLN on every location — so a scan in a Rotterdam cross-dock and a status message from a Chicago line-haul carrier refer to the same consignment without a lookup table in the middle.

Logistics operating model — five domains and the SoR/SoE split over the event backbone

The diagram reads left to right from the two commercial and three physical domains, through the EDI and API ingress that normalises every partner dialect, into the consignment ledger and event backbone that hold the single truth, and out to the engagement surfaces that project it — with badges on the six places the split is enforced, from the 997/APERAK handshake to the idempotent, single-writer append that keeps the ledger authoritative. The standards table below is the working reference the integration team builds against: each row is a message, the business event it carries, its direction, its transport, and where it lands, so that a new partner onboarding is a matter of mapping to an existing row rather than inventing a bespoke interface.

Standard / message Business event Direction Transport Landing / consumer
EDIFACT IFTMIN / IFTMBF Transport booking / firm booking instruction Inbound (shipper) AS2 / OFTP2 EDI gateway → OMS capture
EDIFACT IFTSTA Shipment status / milestone Outbound (shipper, consignee) AS2 Ledger → EDI gateway
EDIFACT CUSDEC / CUSRES Customs declaration / authority response Both (border authority) AS2 / portal Customs domain (in-region)
EDIFACT DESADV Despatch advice (ASN, EDIFACT dialect) Outbound (consignee) AS2 WMS ship-confirm
X12 204 / 990 Motor-carrier load tender / tender response Out / In (road carrier) AS2 TMS ↔ carrier
X12 214 Transportation carrier shipment status Inbound (carrier) AS2 Carrier → ledger status
X12 210 Motor-carrier freight details & invoice Inbound (carrier) AS2 Freight audit → SAP
X12 856 Advance ship notice (ASN) Outbound (consignee) AS2 WMS → consignee
X12 940 / 945 Warehouse shipping order / shipping advice OMS ↔ 3PL WMS AS2 / REST OMS ↔ WMS
X12 846 Inventory inquiry / advice Outbound (customer) AS2 WMS → customer
X12 997 / EDIFACT CONTRL Functional acknowledgement Both AS2 Every interchange (mandatory)
GS1 SSCC / GTIN / GLN Pallet / item / location identity Labels + internal GS1-128 barcode WMS, ASN, EPCIS
GS1 EPCIS Scan / observation events (what-where-when-why) Internal REST / event Event backbone

Order management and fulfilment

The order-management platform is the demand-facing front of the consignment ledger — the layer that turns a heterogeneous stream of customer intent into validated, priced, sourced, and released consignments the warehouses and carriers execute against. It sits on the SoE side for capture (permissive, multi-channel, always available to take an order) and hands off to the SoR the moment an order becomes a committed consignment. Keeping that boundary crisp is what stops the OMS from becoming a second, competing record of shipment truth: the OMS owns the order until release, the ledger owns the consignment from creation, and the two are joined by events, not a shared database.

Demand arrives through channels that could not differ more in shape, and the platform normalises all of them into one canonical order model at the edge. A small shipper books on the web portal; a large retail customer drops an X12 850 purchase order or a 204 load tender over AS2 on a nightly schedule; a marketplace fires a webhook the instant a buyer checks out; a strategic partner calls the booking API through API Management with an OAuth2 client-credentials token; an operations desk keys a correction into an internal console. Each channel has its own authentication, latency expectation, and failure mode, and the capture tier is sized so the slowest, chattiest channel cannot starve the others.

Channel Protocol Format Latency profile Authentication Landing zone
Web / customer portal HTTPS REST JSON (canonical) Real-time, interactive Okta OIDC + step-up MFA Azure Online
EDI (850 PO / 204 tender) AS2 / SFTP X12 / EDIFACT Batch to near-real-time AS2 certificate + PGP EDI gateway → integration
Marketplace REST webhook JSON Real-time, bursty HMAC-signed webhook / OAuth2 Azure Online
Partner booking API REST / GraphQL via APIM JSON Real-time OAuth2 client credentials API Management
Bulk upload Portal file upload CSV → canonical Batch Portal session (Entra) Azure Online
CSR / call centre Internal web UI JSON Interactive Entra ID + PIM for overrides Azure Corp

Once captured, an order is orchestrated through a saga rather than a monolithic transaction, because fulfilment spans systems that fail independently and cannot be locked together. A durable orchestrator — Azure Durable Functions, AWS Step Functions — drives the order through validation, rating, availability, allocation, and release, holding a compensating action for every step so a late failure unwinds cleanly instead of leaving a half-committed shipment. The systems inventory below is the OMS as actually deployed: each component, its function, the compute it runs on, its tier, its HA posture, and the data class it handles. Note that the consignment ledger appears here as the point of hand-off — the OMS writes the first authoritative consignment event and thereafter reads state back like every other engagement surface.

System Function Cloud / SKU Tier HA posture Data class
Order Capture API Ingest, canonicalise, validate orders Azure AKS / AWS EKS Tier-1 Multi-AZ + warm DR Confidential
Order Orchestrator Saga / state machine over fulfilment Durable Functions / Step Functions Tier-1 Regional active-active Confidential
ATP / Inventory service Availability check + reservation Azure SQL Business Critical / Aurora Tier-1 Zone-redundant, auto-failover Confidential
Rating & quotation Rate cards, dims, accessorials, surcharge AKS + Redis cache Tier-1 Zone-redundant, cached Confidential
Allocation / sourcing DC and carrier selection, split logic AKS / EKS Tier-1 Multi-AZ Confidential
Consignment ledger Canonical shipment state (event store) Event Hubs + Cosmos DB / Kinesis + DynamoDB Tier-1 Multi-region, idempotent Confidential / Restricted
Exception management Hold, resolve, re-drive stuck orders Functions + Service Bus Tier-2 Zone-redundant queues Internal
Customer visibility API Track-and-trace read model (SoE) APIM + Cosmos read model Tier-1 Active-active Restricted (PII)

Two OMS decisions carry disproportionate weight, and both are about promising. The first is available-to-promise: before accepting an order the platform must know whether it can be filled, and from where. ATP is on-hand minus already-allocated plus scheduled-inbound within the promise window, evaluated across a network of distribution centres rather than a single building, so a stockout in one DC sources from another instead of failing the order. The reservation that follows is the dangerous part — under concurrent demand two orders can each read “one unit available” and both commit it — so it is a conditional write on the inventory record (the ledger’s idempotency discipline), turning an oversell into a clean, retryable failure rather than a promise the warehouse cannot keep. The second is rating: freight is priced on dimensional as much as actual weight, and a wrong quote is a margin leak on every shipment that carries it. The engine takes chargeable weight as the greater of actual and dimensional weight (L × W × H ÷ the carrier’s divisor), applies the contract or published rate for the origin-destination zone, then layers accessorials — residential, liftgate, inside delivery — and a fuel surcharge indexed to a published rate. The inputs are worth tabulating, because a rating dispute always comes down to which of them was wrong.

Rating / ATP input Source Example value Effect on outcome
Actual weight Pack-station scale (WMS) 14.2 kg Floor for chargeable weight
Dimensional weight Dimensioner (L×W×H ÷ divisor) 40×30×25 cm ÷ 5000 = 6.0 kg Chargeable = max(actual, dim)
Zone Origin GLN → destination postcode Zone 4 Selects rate-card row
Contract rate Customer rate card £14.90 base Overrides published rate
Accessorials Order flags (residential, liftgate) +£3.50 Added to base
Fuel surcharge Published index 14.5% Multiplier on linehaul
On-hand − allocated + inbound ATP across DC network 3 units at DC-LHR Determines sourcing DC

The lifecycle that ties capture, rating, allocation, and execution together is expressed as events on the backbone, not as calls between services, which is what lets the WMS, TMS, invoicing, and customer visibility all react to the same transition without the OMS knowing they exist. The table below is the order-to-delivery event flow — each event, the service that emits it, the subject it is published under, and the consumers that act on it — and it is the contract every downstream team codes against.

Event Producer Subject / topic Primary consumers SLA
order.captured Capture API orders.captured Orchestrator, audit < 1 s
order.validated Orchestrator orders.validated Rating < 2 s
order.rated Rating engine orders.rated Allocation, customer quote < 2 s
consignment.created Orchestrator consignment.created Ledger, WMS, TMS < 1 s
consignment.allocated Allocation consignment.allocated WMS (wave), TMS (plan) < 3 s
consignment.released Orchestrator consignment.released WMS (940 shipping order) < 2 s
consignment.shipped WMS consignment.shipped Ledger, ASN 856, invoicing < 2 s
consignment.status.changed TMS / carrier 214 consignment.status Visibility API, notifications < 5 s
consignment.delivered Last-mile / POD consignment.delivered Ledger, invoicing, customer < 5 s
consignment.exception Any producer consignment.exception Exception mgmt, ServiceNow < 3 s

The canonical event on that backbone is worth showing in full, because its shape is what makes two clouds and a dozen consumers agree on one truth. Every consignment transition is published as a CloudEvents-wrapped message whose data carries GS1 identity, an X12-214-aligned status code, and a GLN-coded location, so that an EDIFACT IFTSTA, an X12 214, and a portal update all render from the same fact:

{
  "specversion": "1.0",
  "type": "com.globallogistics.consignment.status.changed",
  "source": "/tms/eu-west/linehaul",
  "id": "018f7c2a-9b41-7e02-a3d6-2f5c1e77d901",
  "subject": "CONS-778812",
  "time": "2026-07-09T14:35:02Z",
  "datacontenttype": "application/json",
  "data": {
    "consignmentId": "CONS-778812",
    "sscc": "00354123450000000019",
    "statusCode": "X6",                 // X12 214: "In-transit"
    "statusReason": "AF",               // "Carrier departed"
    "locationGln": "5412345000176",
    "locationName": "Hub LHR-Gateway",
    "occurredAt": "2026-07-09T14:34:58Z",
    "carrierScac": "GLEX",
    "sequence": 7,                       // per-consignment ordering
    "idempotencyKey": "CONS-778812:7:X6"
  }
}

Exceptions are not an afterthought in logistics; they are a first-class flow, because a meaningful fraction of consignments hit a hold, a re-route, an address correction, or a customs stop before they deliver. The exception service subscribes to the consignment.exception stream, opens or enriches a ServiceNow incident against the affected consignment’s configuration item, and either auto-resolves (a transient carrier-API timeout re-driven from the queue) or routes to a human queue (a customs documentation gap). The table below is the exception playbook — the trigger, how it is detected, the automated action, and the owner — so the difference between a shipment that self-heals and one that pages someone is a policy decision rather than an accident.

Exception Trigger Detection Automated action Owner
Oversell / stock-out Reservation conditional-write fails ATP service returns conflict Re-source from alternate DC; else backorder event OMS / Inventory
Rating failure No rate-card row for zone Rating engine no-match Fall back to published rate; flag for review OMS / Commercial
Tender rejected X12 990 declines the load 990 parsed at gateway Re-tender to next carrier in routing guide TMS
Address / postal invalid Validation or carrier API 4xx Capture / manifest step Address-cleanse; hold + CSR queue if unresolved Last-mile
Customs stop CUSRES query or missing docs Customs domain Hold consignment; open documentation task Customs / Trade
Carrier-API timeout Manifest call exceeds SLA Circuit breaker / DLQ Re-drive from queue with idempotency key Platform / WMS

OMS and fulfilment — order sources through orchestration, ATP and allocation to WMS/TMS

The diagram traces one order left to right: from the four capture channels, into the AKS capture API and durable orchestrator, through the ATP reservation and rating that turn intent into a priced promise, into allocation and the first authoritative ledger append, and out to the WMS release and TMS tender — with badges on the six control points that keep the flow safe, from the functional-acknowledgement handshake on inbound EDI to the conditional reservation that makes oversell a retry rather than a broken promise.

Warehouse management and automation

If the OMS is where the business promises, the warehouse is where it delivers — and the warehouse has a property no other domain shares: it must keep running when the cloud does not. A distribution centre with a severed WAN link is still a building full of people, trucks, and automation that has to receive, store, pick, pack, and ship, and a WMS that stops because it cannot reach a control plane in another region has failed at the one job that cannot pause. The design therefore treats each site as a local system of record for inventory-at-rest on a resilient edge, synchronising to the cloud ledger through store-and-forward, rather than as a thin client of a cloud service. Everything else in this section — the process flow, the automation integration, the EDI and carrier interfaces — is built on that foundation of site autonomy.

The WMS runs the four walls as a directed, event-emitting process. Inbound begins when an ASN (X12 856 or EDIFACT DESADV) arrives ahead of the truck, so the dock knows what to expect before the doors open; receiving reconciles the physical unload against that ASN by scanning the SSCC license plate on each pallet, and any discrepancy is captured then and there rather than at cycle count. Putaway is directed by slotting rules that place fast-moving GTINs in golden-zone pick faces and bulk in reserve; picking is organised into waves cut by carrier cut-off and route; pack cartonises, weighs, and labels; and ship manifests the consignment, calls the carrier for a label and tracking number, and emits the consignment.shipped event that fires the ledger, the ASN to the consignee, and invoicing. The table below is that flow with its triggers, automation, and captured data — the operational contract between the WMS, the automation on the floor, and the events that reach the cloud.

Process Trigger Key steps Automation involved Data captured
Inbound / receiving ASN 856 / 943 arrives Dock check-in, unload, scan SSCC, verify vs ASN RF scanners, dock-door sensors GRN, discrepancy, quantity
Putaway Receipt confirmed Directed putaway by slotting rule AS/RS, RF forklift terminals Bin location assignment
Slotting Velocity re-eval (scheduled) ABC re-slot, golden-zone assignment Slotting analytics Bin velocity class
Replenishment Pick-face min/max breach Top-off from reserve to pick face Conveyor, AGV/AMR Replen task, moved qty
Wave planning Order release / carrier cut-off Batch orders into waves by route/carrier Wave & labour engine Wave, workload balance
Picking Wave / task assigned Directed pick, confirm by scan/light/voice Pick-to-light, robots, RF Pick confirm, short-pick
Pack Pick complete Cartonise, weigh, dimension, label Auto-bagger, scale, dimensioner, printer Carton, weight, dims, SSCC
Ship / manifest Pack complete Manifest, carrier label, ASN, load sequence Carrier API, print-and-apply, sortation Tracking #, 856, manifest
Cycle count Schedule / trigger Count bins, reconcile to system RF terminals Count variance, adjustment
Yard / dock Appointment / gate event Gate-in/out, dock assign, trailer move YMS, ANPR cameras CODECO / gate event

Automation is where the warehouse stops being a database problem and becomes a real-time control problem, and it is the sharpest reason the site cannot depend on a distant cloud. Beneath the WMS sits a warehouse control / execution system (WCS/WES) that speaks to physical equipment on hard real-time deadlines a cross-region round-trip would blow. The WMS decides what — pick these lines for this wave — and hands discrete tasks to the WCS, which decides how the crane, conveyor, or robot does it; the two are joined by an on-site message interface, not a chatty API across the WAN. The table below maps the automation subsystems to how they connect and where they run, and the recurring answer in the last column is the same: Tier-1, at the edge, on the site LAN.

Subsystem Vendor class (example) Protocol Integrates via Runs at
AS/RS (crane, shuttle) Dematic, SSI Schäfer OPC-UA / message queue WMS → WCS task interface Tier-1 edge
Conveyor & sortation Honeywell Intelligrated PLC / SCADA, MQTT WCS / WES Tier-1 edge
Robotics (AMR, goods-to-person) Locus, AutoStore, 6 River REST / gRPC + MQTT WES Tier-1 edge
Pick-to-light / put-to-light Lightning Pick, Kardex Serial / Ethernet to controller WMS Tier-2 edge
RF / handheld scanners Zebra (Android) HTTPS over site Wi-Fi WMS session Tier-1 edge
Print-and-apply / labelling Zebra (ZPL) TCP 9100 / IPP WMS / carrier label service Tier-2 edge
Weigh & dimensioning Mettler Toledo, Cubiscan Serial / REST Pack station Tier-2 edge
Yard cameras / ANPR RTSP / REST YMS Tier-2 edge

The edge-resilience design is therefore explicit rather than assumed. Each distribution centre runs a local control plane — Azure Arc-enabled Kubernetes (or AWS EKS Anywhere / Outposts where the site is AWS-aligned) hosting the WMS execution services, a local database as the authoritative store for inventory-at-rest (SQL Server Always On or PostgreSQL with a hot standby in the same building), and a local store-and-forward broker (Arc data services Service Bus, or an on-site Kafka/MQTT broker) that buffers every event when the WAN is down and replays it in order on reconnect. With the link healthy the site streams events to the cloud ledger in near real time and pulls new orders, ATP, and slotting down; when it drops, the site falls into a defined degraded mode rather than an undefined outage. The matrix below is the contract for that degradation — what each capability does with the WAN up, what it does with it down, and how it reconciles on recovery — the difference between “the site keeps shipping” and “the site stops.”

Capability WAN up (normal) WAN down (degraded) On reconnect
Receiving / putaway Full, events streamed live Full — ASN cached locally, scans stored Buffered events replay to ledger in order
Pick / pack / ship Full, live ledger updates Full — local WMS + WCS authoritative Ship events + 856 flush from store-and-forward
Carrier label / manifest Live carrier API call Cached rates + queued manifest; local label print Manifest calls re-driven with idempotency key
New order intake Real-time from OMS Paused — no new waves from cloud Backlog pulls on link restore
ATP / cross-DC sourcing Live network availability Local on-hand only, no network sourcing Re-syncs on reconnect
Customer visibility (SoE) Live projection Stale until reconnect Rebuilds from replayed events

That autonomy is not free-floating; it is a concrete footprint the site build ships with — small enough to fit a distribution-centre comms room and standardised so every DC recovers the same way. The table below is that per-site edge inventory: the components each warehouse runs locally to stay authoritative, and how each rejoins the cloud when the link returns.

Edge component Technology Local role Sync to cloud
Edge cluster Azure Arc-enabled AKS / EKS Anywhere (3-node) Hosts WMS execution + WCS adapters GitOps config pull; heartbeat
Local inventory DB SQL Server Always On / PostgreSQL + hot standby Authoritative inventory-at-rest Change feed → ledger (store-fwd)
Store-and-forward broker Arc Service Bus / on-site Kafka / MQTT Buffer events during WAN loss Ordered replay on reconnect
Identity cache Entra ID / Okta token cache + on-site PAW Auth when the IdP is unreachable Re-validates on reconnect
RF & label network Dedicated Wi-Fi SSID/VLAN, ZPL print-and-apply Scanner and labelling plane Local only
Local observability Dynatrace ActiveGate (edge) Buffer telemetry, local dashboards Forwards on reconnect

Two pieces of real configuration make the warehouse’s external contracts concrete. The first is the Advance Ship Notice the WMS transmits to the consignee the moment a load is confirmed — an X12 856 whose whole value is its hierarchical structure: a Shipment loop that nests Order, then Tare (pallet), then Pack (carton), then Item, so the receiver can put away by pallet without opening it and reconcile down to the unit if they need to. The MAN segments carry the GS1 SSCC license plates generated at the pack station, which is what lets a single scan at the consignee’s dock match a whole pallet against this ASN:

ST*856*0001~
BSN*00*000012345*20260709*1435*0001~          Beginning of hierarchical transaction
HL*1**S~                                       Shipment level
TD1*CTN25*12****G*350*LB~                       12 cartons, gross 350 lb
TD5**2*GLEX*M*LTL~                              Carrier = SCAC GLEX, motor, LTL
REF*BM*BOL00098765~                            Bill of lading number
DTM*011*20260709~                              Shipped date
N1*ST*ACME DISTRIBUTION*92*DC42~               Ship-to (buyer DC 42)
N1*SF*GLOBAL LOGISTICS DC-LHR*92*GB-LHR-01~     Ship-from (our DC)
HL*2*1*O~                                       Order level (child of shipment)
PRF*PO554433~                                  Purchase order 554433
HL*3*2*T~                                        Tare / pallet level
MAN*GM*00354123450000000019~                    SSCC-18 pallet license plate
HL*4*3*P~                                        Pack / carton level
MAN*GM*00354123450000000026~                    SSCC-18 carton license plate
HL*5*4*I~                                        Item level
LIN**UP*00812345600012~                         GTIN of the item
SN1**24*EA~                                     24 each in this carton
SE*20*0001~                                     20 segments, control 0001

The gateway wraps that transaction in its ISA/GS envelope, transmits it over AS2, and expects a 997 functional acknowledgement back; an ASN that is never acknowledged is escalated like any unacknowledged status event, because a receiver expecting a pallet no ASN described is a delay waiting to happen. The second piece of real config is the WMS-to-carrier call that produces the label the ship step depends on. At manifest the WMS posts the consignment to the carrier’s shipping API and gets back a tracking number and a print-ready ZPL label; the request carries an Idempotency-Key set to the consignment id, so a retried call after a timeout never books — or bills — the shipment twice:

POST /v1/shipments HTTP/1.1
Host: api.carrier.example.com
Authorization: Bearer {oauth2_access_token}
Idempotency-Key: CONS-778812
Content-Type: application/json

{
  "serviceCode": "EXPRESS_1000",
  "reference": "CONS-778812",
  "shipFrom": { "gln": "5412345000015", "name": "Global Logistics DC-LHR",
                "postcode": "TW6 2GA", "country": "GB" },
  "shipTo":   { "name": "ACME Distribution", "postcode": "M1 4WP", "country": "GB" },
  "parcels": [ { "sscc": "00354123450000000026", "weightKg": 14.2,
                 "dimsCm": [40, 30, 25] } ],
  "labelFormat": "ZPL_203DPI",
  "codRequired": false
}
{
  "shipmentId": "SHP-9F2C41A8",
  "trackingNumber": "GLEX778812004417",
  "parcels": [ { "sscc": "00354123450000000026",
                 "trackingNumber": "GLEX778812004417",
                 "labelZpl": "^XA...^XZ" } ],
  "estimatedDelivery": "2026-07-10T10:00:00Z",
  "rate": { "currency": "GBP", "amount": 18.40 }
}

The tracking number returned there is written straight to the consignment ledger and surfaces on the customer portal within seconds, the ZPL streams to the print-and-apply head on the sortation line at 203 dpi, and the whole exchange is captured for the freight audit that later reconciles the carrier’s X12 210 invoice against this quoted rate. The integration surface is broader than these two flows, and the table below closes the section by naming every interface the WMS holds — to the OMS above it, the TMS beside it, SAP behind it, the carriers in front, and the automation beneath — because a warehouse is defined as much by its edges as by its four walls.

Interface Partner system Protocol / message Direction Cadence
WMS ↔ OMS Order management X12 940 in / 945 out, or REST Bidirectional Event-driven
WMS ↔ TMS Transportation Load, manifest, carrier assignment (REST) Bidirectional Per shipment
WMS ↔ SAP S/4HANA Goods movement (IDoc / BAPI, MIGO) Bidirectional Per posting
WMS ↔ carrier Carrier shipping API REST (rate, label, manifest, track) Outbound Per parcel
WMS ↔ consignee Customer X12 856 ASN, 846 inventory Outbound Per shipment / daily
WMS ↔ WCS/WES On-site automation OPC-UA / MQTT / message queue Bidirectional Real-time (edge)
WMS ↔ event backbone Consignment ledger CloudEvents over Event Hubs / Kafka Outbound (store-fwd) Near real-time

Warehouse management — inbound through automation, pick-pack-ship and yard, on a resilient edge

The diagram follows a consignment left to right — receiving and SSCC verification, storage and automation, wave/pick/pack/ship, and the yard — with the warehouse-edge node beneath carrying the resilience story: an Arc-enabled cluster and local database that keep the four walls authoritative, and a store-and-forward buffer that replays every event to the cloud ledger when the WAN returns. The badges mark the six points where the design earns its keep, from ASN-versus-GRN reconciliation at the dock to the WAN-drop autonomy that lets the site keep shipping when everything upstream goes dark.

Transportation management and fleet telematics

If IoT is where the estate meets the physical world, transportation management is where the physical world meets money — every load planned badly, every empty mile driven, every carrier over-paid, and every reefer that drifts out of temperature shows up directly in margin. The Transportation Management System (TMS) is therefore treated as a Tier-1 workload with the same availability envelope as the customer platforms it feeds: it runs active-active across two availability zones behind the regional Application Gateway WAF v2 and AWS ALB, its ledger of loads and rates lives on zone-redundant Azure SQL Business Critical with an asynchronous warm standby in the paired DR region, and it never talks to a carrier, a warehouse, or a truck except over a governed, event-driven path. What follows is the operational core of that domain — how a load is planned, priced, tendered, dispatched, tracked, and closed — and the real-time telemetry pipeline that keeps the fleet observable from the moment a driver accepts a load to the moment they capture proof of delivery.

The TMS is not one program but a stack of decisions, each owned by a distinct capability and each emitting an event the rest of the estate can subscribe to. Load planning and optimisation consolidates orders into loads, respecting weight, cube, hazmat segregation, temperature class, and delivery windows, then hands the candidate loads to a solver that minimises total landed cost across the available carrier lanes. Carrier selection and rating scores each lane against a rate matrix — contract rates, spot rates, fuel surcharges, accessorials — and a service-level and sustainability weighting, so the cheapest carrier is not chosen when it blows the delivery window or the CO2 budget. Only once a load is planned and priced does it move to tendering, and only once tendered-and-accepted does it move to dispatch. The table below is the capability spine: each row is a decision the TMS makes, the system of record that owns it, the cloud it runs on, and the artefact it emits that everything downstream keys off.

Capability Decision it makes System of record Cloud / platform Artefact emitted
Load planning & consolidation Which orders combine into which loads TMS planning module Azure AKS (D8s_v5 pool) load.planned event + load ID
Route optimisation Stop sequence, lane, mode, ETA Optimisation solver Azure Functions Premium + solver Optimised route + planned ETA
Carrier selection & rating Which carrier, at what rate Rating engine + rate tables Azure SQL Business Critical Ranked carrier list + landed cost
Tendering Offer/accept with the chosen carrier B2B/EDI (Logic Apps Standard) Azure Logic Apps + Service Bus EDI 204 out / 990 back
Dispatch Bind driver, tractor, trailer to the load Dispatch module Azure AKS load.dispatched + asset IDs
Execution & telematics Where the load is, in what condition IoT + streaming Azure IoT Hub / AWS IoT Core EDI 214 milestones + telemetry
Settlement What the carrier is owed Freight settlement Azure SQL + SAP freight.rated + invoice match

Tendering is where the TMS stops being an internal optimiser and starts speaking the lingua franca of freight, which is still overwhelmingly EDI — X12 in North America, EDIFACT elsewhere — carried over AS2 or increasingly over carrier REST APIs. The estate standardises B2B onto Azure Logic Apps Standard with the Integration Account for X12/EDIFACT schemas and trading-partner agreements, because it runs inside the VNet, does stateful correlation, and gives every message a run history that ties back to a ServiceNow change. A load tenders outbound as a 204 (Motor Carrier Load Tender); the carrier must answer with a 990 (Response to Load Tender) carrying accept or decline; execution status flows back as a stream of 214 (Transportation Carrier Shipment Status) messages; and the carrier bills with a 210 (Motor Carrier Freight Details and Invoice) that freight settlement matches against the rated load. The table pins the transaction set the domain actually implements, in both directions.

Transaction Name Direction Fires when Consumed by
EDI 204 Motor carrier load tender TMS → carrier Load planned, carrier selected Carrier TMS
EDI 990 Response to load tender Carrier → TMS Carrier accepts / declines TMS tendering (auto-retender on decline)
EDI 214 Shipment status message Carrier → TMS Each milestone (pickup, in-transit, delivery) Track-and-trace platform
EDI 210 Freight details & invoice Carrier → TMS Carrier bills the load Freight settlement / SAP
EDI 856 Advance ship notice (ASN) Shipper ↔ consignee Goods dispatched WMS / consignee receiving
EDIFACT IFTMIN Instruction message TMS → carrier International forwarding leg Forwarder / ocean carrier
EDI 997 Functional acknowledgement Both Any interchange received The sender (delivery proof)

Transportation management and fleet telematics — plan and tender to telematics ingest and ePOD

The diagram reads left to right as the load’s own lifecycle: the TMS plans and rates a load and the optimiser decides carrier and route (badge 1) before it tenders as an EDI 204 and waits for the 990 accept (badge 2); dispatch binds a driver and asset; then trucks and containers stream telematics over the IoT lane, onboarding with an X.509 certificate through the Device Provisioning Service (badge 3) and landing on IoT Hub / IoT Core and the Kinesis/Event Hubs stream; the hot path runs geofence rules in under five seconds (badge 4) and detects cold-chain excursions (badge 5); and ePOD closes the loop idempotently (badge 6) into the lakehouse and Dynatrace.

Execution is where telematics takes over from EDI, and the ingest path is deliberately split the same way the wider IoT lane is: AWS IoT Core carries fleet-scale vehicle telemetry — GPS, speed, engine and ELD (Electronic Logging Device) hours-of-service, fuel, odometer — while Azure IoT Hub carries the container and control-tower telemetry that integrates with business processes, including reefer temperature and door sensors. Every device holds a certificate-based identity, supports store-and-forward for the long stretches where cellular or LPWAN coverage drops, and is provisioned through DPS (Azure) or the registry (AWS) so an un-attested device can never publish a position. The systems table below is the concrete inventory of the domain — the TMS and fleet platforms, what each is for, the cloud and SKU it runs on, and what it integrates with — so an operator can see the whole moving estate at a glance.

System Role Cloud / SKU Integrates with
TMS core (planning, rating, dispatch) Plan, price, tender, dispatch loads Azure AKS D8s_v5, Azure SQL Business Critical SAP (order/settlement), carriers (EDI), track-and-trace
Route optimisation solver Minimise landed cost, sequence stops Azure Functions Premium EP2 TMS core, map/traffic APIs, telematics ETA feedback
B2B / EDI gateway X12 & EDIFACT 204/990/214/210 Azure Logic Apps Standard + Integration Account Carrier VANs/APIs over AS2, TMS core, SAP
Telematics ingest (fleet) Vehicle GPS/ELD/fuel at scale AWS IoT Core + Kinesis Data Streams Fleet devices (mTLS), Managed Flink, Timestream
Telematics ingest (control tower) Container / reefer / door / control Azure IoT Hub S3 tier + DPS Container trackers (mTLS), Stream Analytics, ADX
Fleet & reefer analytics Fuel, utilisation, cold-chain, CO2 Databricks on ADLS Gen2 + Timestream Lakehouse governed band, sustainability reporting
ePOD (proof of delivery) Capture scan, signature, geo, photo Azure App Service + Cosmos DB Driver mobile app (UEM), billing, customer portal

The real-time telemetry pipeline is the hot path that turns a raw device message into an actionable event inside the five-second SLA the architecture commits to. Ingest terminates mutual TLS and validates device identity; a decode-and-enrich stage normalises vendor payloads and joins the deviceId to its current shipmentId from the device twin; a stateful streaming stage runs the geofence, route-deviation, and threshold rules; and a routing stage forks each detected event to the hot store (live position for the control tower), to the notification path (dispatcher and consignee), and to the lakehouse for history. The table breaks the pipeline into its stages, the service that runs each on either cloud, the transform it performs, and the latency budget it holds.

Stage Azure service AWS service Transform Budget
Ingest & authenticate IoT Hub + DPS (mTLS, X.509) IoT Core (mTLS, registry) Terminate TLS, verify device, accept/queue < 500 ms
Decode & enrich Azure Functions Lambda Normalise payload, join twin → shipmentId < 800 ms
Stream detect Stream Analytics (SU-scaled) Managed Service for Apache Flink Geofence, deviation, threshold, watermarking < 2 s
Route & fan-out Event Hubs + Service Bus Kinesis + SNS/SQS Fork to hot store, notify, lakehouse < 1 s
Hot store Cosmos DB (session consistency) DynamoDB / Timestream Upsert live position, last-known state < 700 ms

Because the geofence and cold-chain rules are the events a dispatcher actually acts on, they are worth stating as concrete rule config rather than prose. The AWS IoT Core topic rule below selects only the vehicle messages that matter and routes them to Kinesis; the Azure IoT Hub route promotes reefer excursions to the hot path; and the Azure Stream Analytics query is the geofence itself, using ST_WITHIN against a per-shipment polygon so a value of zero means the asset has left its corridor.

-- AWS IoT Core rule: forward only actionable ELD/telematics to Kinesis
SELECT deviceId, ts, lat, lon, speed, odometer, fuelPct, reeferC
FROM 'fleet/+/telematics'
WHERE reeferC > 8 OR speed > 105 OR fuelPct < 10
-- Action: kinesis (stream = fleet-telematics-hot, partitionKey = deviceId)
# Azure IoT Hub message route — reefer excursion to the hot path
Name        : coldchain-breach
Source      : DeviceMessages
Endpoint    : eh-telematics-hot   (Event Hubs, 8 partitions)
Condition   : $body.metric = 'reeferTemp'
              AND $body.celsius > $twin.desired.coldChain.maxC
              AND $connectionDeviceId LIKE 'reefer-%'
Enrich      : shipmentId = $twin.tags.shipmentId
-- Azure Stream Analytics: geofence / route-deviation, < 5 s end to end
SELECT t.deviceId, t.shipmentId, t.eventTime, g.geofenceId, 'CORRIDOR_EXIT' AS event
INTO   [alerts-hot]
FROM   [telematics] t TIMESTAMP BY t.eventTime
JOIN   [geofences] g ON t.shipmentId = g.shipmentId
WHERE  ST_WITHIN(CreatePoint(t.lat, t.lon), g.polygon) = 0

The detection rules the pipeline enforces are few but load-bearing, and each one names an action rather than merely a threshold — a breach is a business event with an owner, not a chart that someone might notice. The final table of this section is the rule book the fleet runs against: the rule, the signal and condition that trips it, the action it fires, and the SLA it holds. ePOD closes the loop idempotently — a driver on a dead-zone road re-syncs the same delivery, and the exactly-once effect guarantees one delivery record and one billing trigger — which is the seam that ties fleet execution into the order-to-delivery workflow the third section traces end to end.

Rule Signal & condition Action SLA
Corridor exit / deviation GPS outside per-shipment geofence polygon Alert dispatcher, recompute ETA < 5 s
Cold-chain excursion Reefer temp > twin maxC for > 5 min Open ServiceNow case, alert consignee < 5 s
Harsh-driving / safety Accel/brake threshold, ELD HOS near limit Safety flag, driver + fleet manager notify < 10 s
Fuel / theft anomaly Fuel drop with engine off, off-route stop Fraud flag, dispatcher review < 30 s
ePOD capture Scan + signature + geo at delivery point Idempotent close, trigger billing Exactly once
Dwell / detention Asset stationary at stop > contracted free time Accrue accessorial, notify shipper < 60 s

Customs, trade compliance and track-and-trace

A shipment that crosses a border twice touches two customs regimes, a fistful of party and product screens, and a documentation pack that must be right before the cargo arrives rather than after — and the same shipment, seen from the customer’s side, is a single question repeated hourly: where is my freight and when will it land? Those two faces of the same movement — regulatory clearance and customer visibility — are built on one shared spine: a stream of milestone events, normalised to a common model, that both files with the authorities and paints the customer timeline. This section covers customs filing, denied-party and sanctions screening, HS classification and duty, the documentation pack, and the multi-source track-and-trace platform that turns raw events into a single shipment story and a proactive ETA.

Customs filing is a set of pre-arrival obligations, and the estate treats each regime as an integration with a hard deadline rather than a form someone fills in. Into the United States, cargo files through ACE (Automated Commercial Environment) with an ISF (“10+2”) before an ocean lade and an entry on arrival, and exports file through AES (Automated Export System). Into the EU, the security filing is ICS2 (Import Control System 2) carrying the ENS (Entry Summary Declaration) before the goods reach the first point of entry. Every filing is assembled from the same event and master data the track-and-trace platform holds, submitted over a governed B2G connector, and — critically — tracked to an accepted response, because a submitted-but-rejected filing holds cargo just as surely as no filing at all. The table below is the filing map the compliance domain runs against.

Regime / message Authority System Cloud / connector Trigger Deadline
ISF (10+2) US CBP ACE filing Azure Logic Apps (B2G AS2/API) Booking confirmed, pre-lade ≥ 24 h before vessel load
Customs entry US CBP ACE entry / broker Azure Logic Apps + broker API Arrival / pre-arrival On/most before arrival
ENS (ICS2) EU customs ICS2 declaration Azure Logic Apps (ICS2 STI) Pre-loading / pre-arrival Mode-specific, pre-arrival
Export declaration US CBP AES (EEI) Azure Logic Apps Export booking Pre-departure
Transit / T1 EU / national NCTS connector Azure Logic Apps Bonded movement start Before movement
Duty & tax calc Multiple Landed-cost engine Azure Functions + tariff data HS + value + origin known Before entry

Filing is only safe if the parties and the products are clean, so screening runs before a shipment moves, not as an afterthought. Denied-party and sanctions screening checks consignor, consignee, notify party, and end user against consolidated lists (OFAC SDN, EU consolidated, UN, and carrier-specific) on every booking and again on any party change; a hit holds the shipment and routes it to compliance for adjudication rather than merely logging a warning. HS (Harmonised System) classification assigns the tariff code that drives duty, tax, licence, and admissibility, increasingly with an ML-assisted classifier whose suggestions a licensed broker confirms. Duty and tax are computed by a landed-cost engine from HS code, customs value, and origin, feeding both the quote and the entry. The controls table states what each screen checks, the source it checks against, and what a hit does.

Control What it checks Source / tool On a hit
Denied-party / sanctions Consignor, consignee, notify, end user OFAC SDN, EU/UN lists, screening API Block shipment, route to compliance
Restricted-party re-screen Any party change mid-shipment Same lists, event-triggered Re-hold, re-adjudicate
HS classification Correct tariff code for the goods ML classifier + broker confirm Reclassify, recompute duty
Licence / admissibility Export licence, dual-use, embargo Trade-content database Hold pending licence
Duty & tax Landed cost, VAT, preferential origin Tariff engine + FTA rules Recompute, flag under/over
Document completeness Invoice, packing list, CoO, cert Doc-gen + checklist Block filing until complete

The visibility half of the domain rests on GS1 EPCIS (Electronic Product Code Information Services), the standard that lets a scan from any system — a WMS pick, a carrier gate-in, a telematics geofence — be described in the same four dimensions and stacked onto one timeline. Every event answers what (the EPC or SSCC identifying the physical unit), where (the readPoint and business location as GS1 SGLNs), when (the event time and time-zone offset), and why (the bizStep and disposition — departing, in transit, receiving, in progress). Normalising to EPCIS is what makes the track-and-trace platform a unified timeline rather than a pile of vendor formats, and it is the model the milestone store persists. The dimension table below maps the concept to the concrete EPCIS field and a real value.

EPCIS dimension Field Example value
What (object) epcList / SSCC urn:epc:id:sscc:0614141.1234567890
Why (step) bizStep urn:epcglobal:cbv:bizstep:departing
State disposition urn:epcglobal:cbv:disp:in_transit
Where (read) readPoint (SGLN) urn:epc:id:sgln:0614141.00777.0
Where (business) bizLocation (SGLN) urn:epc:id:sgln:0614141.00888.0
When eventTime + offset 2026-07-09T14:32:11Z / -05:00
Link bizTransactionList desadvSHIP-8837462

Customs and track-and-trace — event sources normalise to EPCIS, build one timeline, and fan out to the portal while customs filing runs in parallel

The diagram is the platform in one glance: milestone events from OMS/WMS, TMS/telematics, and carrier EDI/API (badge 1, the EDI 214) land on an append-only bus, normalise to the EPCIS model (badge 2), and build a de-duplicated shipment timeline (badge 3); from that single timeline the platform files customs pre-arrival (badge 5) and screens parties (badge 4) on one branch, and serves the customer portal, track API, and proactive ETA alerts (badge 6) on the other. A concrete EPCIS 2.0 capture event — the JSON the normaliser emits and the timeline store persists — makes the model tangible:

{
  "type": "ObjectEvent",
  "eventTime": "2026-07-09T14:32:11.000Z",
  "eventTimeZoneOffset": "-05:00",
  "epcList": ["urn:epc:id:sscc:0614141.1234567890"],
  "action": "OBSERVE",
  "bizStep": "urn:epcglobal:cbv:bizstep:departing",
  "disposition": "urn:epcglobal:cbv:disp:in_transit",
  "readPoint":   { "id": "urn:epc:id:sgln:0614141.00777.0" },
  "bizLocation": { "id": "urn:epc:id:sgln:0614141.00888.0" },
  "bizTransactionList": [
    { "type": "urn:epcglobal:cbv:btt:desadv",
      "bizTransaction": "urn:epc:id:gsrn:0614141.SHIP-8837462" }
  ]
}

Behind that clean model sits a messy reality: the same physical milestone often arrives from two systems at once, out of order, minutes or hours apart. The milestone-event table is the platform’s canonical vocabulary — each customer-visible milestone, the EDI or status code that signals it, the source that emits it, the EPCIS bizStep it normalises to, and whether the customer sees it — and it is what lets the milestone engine dedupe on (shipmentId, bizStep, eventTime) and show each hop exactly once.

Milestone Code Source system EPCIS bizStep Customer-visible
Order booked OMS commissioning Yes — “Order received”
Picked & packed ASN 856 WMS packing No
Tendered to carrier 204/990 TMS staging_outbound No
Picked up 214 AF Carrier departing Yes — “Collected”
In transit / gate events 214 X6 Carrier / telematics transporting Yes — “In transit”
Customs cleared ICS2/ACE resp. Customs platform inspecting Yes — “Cleared customs”
Out for delivery 214 OA Last-mile departing Yes — “Out for delivery”
Delivered (POD) 214 D1 Last-mile ePOD receiving Yes — “Delivered”
Exception 214 SD/AG Any holding Yes — reason shown

The EDI 214 deserves a specific note because it is the heartbeat of the whole timeline. A 214 is the X12 Transportation Carrier Shipment Status Message; its AT7 segment carries the status and the reason code, and the MS1/MS2 segments carry the geography and equipment. A single delivery milestone looks like this on the wire:

ST*214*0001~
B10*4938*8837462*SCAC~          # ref, shipment id, carrier SCAC
LX*1~
AT7*D1**NS**20260709*1432*LT~   # D1 = delivered/completed, at local time
MS1*NEWARK*NJ*US~               # event location
MS2*SCAC*TRLR-4471~             # equipment / trailer
SE*7*0001~

The track-and-trace platform is only as good as the feeds it fuses, and each feed has its own cadence, transport, and dedup key. The source table closes the section: it is the reconciliation map the platform runs, and it is why a shipment that goes quiet on one feed — a carrier that stops sending 214s — can be kept alive by inferring the hop from a telematics geofence crossing rather than simply going dark on the customer’s screen.

Source Events it emits Transport Dedup / correlation key
OMS Order booked, amended, cancelled Event Hubs (native) orderId → shipmentId
WMS / 3PL Pick, pack, ASN, load Event Hubs / EDI 856 SSCC + orderId
TMS Tender, dispatch, plan change Service Bus loadId → shipmentId
Telematics GPS, geofence, dwell, cold-chain IoT → Event Hubs deviceId + shipmentId
Carrier 214 status milestones EDI (AS2) / status API proNumber + SCAC
Customs Filing accepted / cleared / held B2G connector entryId → shipmentId

End-to-end order-to-delivery workflow

The surest way to see whether all of this actually holds together is to follow one shipment the whole way — from the customer’s click to the reconciled invoice — and to name, at every hop, the system that owns it, the cloud it runs on, the event it emits, the way it can fail, and the control that makes the hand-off safe. That trace is the subject of this section. The shipment is SHIP-8837462: a two-pallet, temperature-controlled load booked in the customer portal, picked at a European 3PL warehouse, line-hauled by a contracted carrier, cleared through customs, delivered on the last mile, and billed. Nothing about the journey is special — which is exactly why it is a good test of the platform.

Order-to-delivery — one shipment traced hop by hop from order and OMS through WMS, TMS/carrier, customs and last-mile POD to billing

The diagram is the trace at a glance: the order enters through the API guarded by an Idempotency-Key (badge 1), the WMS pack emits an SSCC milestone (badge 2), line-haul reports EDI 214 heartbeats (badge 3), the last-mile POD closes exactly once (badge 4), billing settles against the recorded milestones (badge 5), and a zero-downtime release of any consumer replays cleanly from the last committed offset (badge 6). Every hop is joined to the next by an event, and every event in this estate is at-least-once: the bus, the queues, and the carrier feeds can all deliver the same message twice or out of order, so correctness cannot depend on a message arriving exactly once — it has to depend on each consumer being idempotent. The per-hop table below is the spine of the workflow. Read a row as: the step, the system that owns it, the cloud it runs on, the event it publishes, the failure mode that hop is most prone to, and the control that neutralises the failure.

# Step System Cloud Event emitted Failure mode Control
1 Order capture Order API / portal Azure APIM + AKS order.placed Double-submit on retry Idempotency-Key → one shipmentId
2 Allocate & promise OMS Azure AKS order.allocated Oversell / no stock ATP check, reserve then confirm
3 Pick & pack WMS / 3PL Azure (3PL) + EDI 856 shipment.packed (SSCC) Pack without SSCC Reject to quarantine topic
4 Tender TMS + Logic Apps Azure Logic Apps EDI 204 → 990 No 990 (limbo) Auto-retender next carrier
5 Pickup Carrier Carrier + EDI 214 AF No status message Infer from geofence crossing
6 Line-haul Telematics AWS IoT Core / Azure IoT 214 X6 + telemetry Coverage gap Store-and-forward, replay
7 Customs Customs platform Azure Logic Apps (B2G) customs.cleared Rejected filing Correct HS/party, refile
8 Last-mile Last-mile app Azure App Service 214 OA Mis-scan / wrong stop Geo + barcode validation
9 POD ePOD Azure Cosmos DB shipment.delivered Duplicate POD on resync Exactly-once conditional write
10 Bill & settle Billing + SAP Azure SQL + SAP freight.rated Under/over-bill Rate from milestone set, reconcile

The two controls that make this workflow survivable are idempotency and replay, and they are engineered per event rather than hoped for globally. Each event names a business key, a store that records “this effect already happened”, and a source it can be replayed from if a consumer was down or a region was lost. Order capture dedupes on a client Idempotency-Key; POD dedupes on the shipment plus the delivered step; billing dedupes on the shipment plus the invoice period. The exactly-once effect — not exactly-once delivery, which is a fiction — is a conditional write on the business key, so a duplicate is a no-op:

# Exactly-once POD effect — conditional write on the business key
Item      : pk = "shipment#8837462"   sk = "event#delivered"
Condition : attribute_not_exists(pk AND sk)   # duplicate POD → no-op
TTL       : eventTime + 30d
Effect    : first write triggers billing; every replay is swallowed
Event Idempotency key Dedup store Replay source Window
order.placed client Idempotency-Key Cosmos DB (key→result) APIM retry / Event Hubs 24 h
shipment.packed SSCC + orderId WMS / bus offset Event Hubs (retained) 7 days
214 milestones proNumber + status + time Milestone store Carrier redelivery / archive 7 days
customs.cleared entryId Filing store B2G re-poll Until cleared
shipment.delivered shipmentId#delivered Cosmos DB (conditional) Device store-and-forward 30 days
freight.rated shipmentId#period Billing ledger Event replay Billing cycle

Security travels with the shipment hop by hop, because “identity is the perimeter” has to mean something at every seam, not just at the front door. Each hop authenticates with a workload identity — a managed identity or IAM role, never a shared secret — reaches data over a private path (Private Endpoint or VPC endpoint, never the public internet), and applies the data control the class demands: the cold-chain and PII fields on this shipment are Restricted, so they stay in-region and are encrypted with a customer-managed key. The per-hop security table makes the seam-by-seam posture explicit.

Hop Workload identity Data control Network path
Order API APIM + Entra-issued token PII encrypted, tokenised card WAF → private AKS
OMS / WMS Managed identity Restricted stays in-region Private Endpoint to SQL
Tender (EDI) Logic Apps managed identity Signed AS2, partner-scoped VNet-integrated, no public
Telematics Device X.509 (mTLS) Per-device identity, twin IoT lane, segmented
Customs (B2G) Connector cert Filing data least-privilege Governed egress, logged
POD / billing Managed identity CMK encryption, immutable Private Link to Cosmos/SQL

Observability is the other constant, and Dynatrace is the single pane that follows SHIP-8837462 as one distributed trace across ten systems and two clouds — from the portal PurePath, through APIM, OMS, the bus, the carrier webhook, the customs connector, and into billing — correlating the business shipmentId with the technical trace so an operator can answer “where is this shipment, and is any hop unhealthy?” from one place. Real-user and synthetic monitoring watch the customer journey; Davis AI baselines the milestone cadence and flags a shipment that has gone quiet against its own history. The signals table is what the on-call actually watches.

Signal (Dynatrace) What it catches Threshold / alert
End-to-end trace on shipmentId A hop that failed or stalled Any span error / gap > SLA
Consumer lag per topic A backed-up or dead consumer Lag rising or > N minutes
Milestone cadence (Davis AI) A shipment gone quiet Missing expected 214 in window
DLQ depth per integration A failing connector (carrier, customs) DLQ > 0 (page)
Duplicate-effect rate Broken idempotency Dup effect > 0
Portal RUM / synthetic Customer-facing degradation p95 > 300 ms, journey fail

The last property the workflow has to prove is that it survives its own change: a zero-downtime release of any consumer must not lose, duplicate, or reorder a shipment’s events. Because every hop is already idempotent and replayable, a release is a controlled, observable event rather than a risk — the deploy drains in-flight work, runs old and new consumers side by side on the same topic, and a rollback simply re-processes from the last committed offset. The table states, for each concern, the mechanism that handles it and — the column that matters to the business — what the in-flight shipment actually experiences.

Concern Mechanism What the shipment sees
In-flight events during deploy Drain, then blue-green the consumer group No loss — events buffered on the bus
Old + new consumer together Idempotent handlers, versioned schema No duplication — dedup on business key
Schema change Backward-compatible, additive fields No break — new fields ignored by old
Bad release Roll back, replay from committed offset No gap — reprocessed exactly once in effect
DB migration Expand-migrate-contract, online No downtime — reads/writes continue
Region loss mid-flight Fail over, replay from retained offsets Continues — RPO 15 min, timeline rebuilt

Traced end to end, SHIP-8837462 is the whole architecture in miniature: ten systems across two clouds and four data centres, joined not by brittle point-to-point calls but by idempotent, replayable events; screened, filed, and cleared before it moves; visible to the customer as one clean timeline; billed against the milestones it actually generated; and carried safely through both a coverage gap on a mountain road and a Tuesday-afternoon deployment of the billing service. That is what “zero-downtime” means when it is made concrete — not a slogan on a slide, but a single parcel that never notices the machinery working underneath it.

Multi-layer security model

Zero trust is not a single product; it is seven layers that each assume the layer outside them may already be compromised. Identity (Okta, Entra, MFA, PIM, Conditional Access, SCIM) is layer one. Device (Intune, CrowdStrike Falcon, encryption, EDR) is layer two. Network (segmented hubs, firewalls, private endpoints, restricted peering, inspection) is layer three. Application (secure SDLC, Wiz Code, SAST, dependency scanning, secrets management, WAF, API protection) is layer four. Workload (hardened images, vulnerability management, image signing, runtime detection) is layer five. Data (encryption, classification, tokenisation, DLP) is layer six. Monitoring (Dynatrace, cloud logs, SIEM, ServiceNow) is layer seven. Spanning all of them is Wiz for cloud security posture and exposure management.

Multi-Layer Zero-Trust Security Model

The reason to draw it as layers is operational: each layer has an owner, a tool, and a measurable control, and a gap in one is caught by the next. If a credential is phished (layer one), device compliance and runtime detection (layers two and five) still stand in the way; if a workload is exploited (layer five), network segmentation and data encryption (layers three and six) limit what the attacker can reach and read. Posture management ties the picture together by continuously checking that the controls are actually present and configured, not merely documented.

Multi-layer network security

The network expresses the same defence-in-depth as a path through six controls. Layer one is the third-party DNS/CDN/WAF for public ingress. Layer two is the Azure Application Gateway WAF and AWS regional ingress that protect origins and route at the app level. Layer three is Azure Firewall Premium and AWS Network Firewall behind a centralised inspection VPC/VNet, enforcing policy-controlled egress, optional TLS inspection, threat intelligence, and east-west rules. Layer four is the workhorse — NSGs, security groups, route tables, and subnet segmentation implementing a default-deny posture between application environments. Layer five is private connectivity to PaaS through Private Endpoints, Private Link, and VPC endpoints with private DNS. Layer six is the host and workload itself, hardened and running with least-privilege identity.

The same six layers look different inside each cloud, so each earns its own deep dive. In Azure, ingress lands on Application Gateway WAF v2, egress and east-west are forced through Azure Firewall Premium (with IDPS and TLS inspection) by user-defined routes, NSGs and Application Security Groups segment the spoke subnets default-deny, and PaaS is reachable only over Private Endpoints with public access disabled.

Azure Network Security Layers (Deep Dive)

In AWS, ingress is an ALB behind AWS WAF, all east-west and egress traffic is steered through a centralised AWS Network Firewall in an appliance-mode inspection VPC, security groups and network ACLs enforce default-deny, and services are reached privately through Gateway and Interface VPC endpoints — administration via Session Manager rather than open SSH.

AWS Network Security Layers (Deep Dive)

Two rules make this design defensible rather than merely layered. First, no unrestricted east-west routing — application environments cannot talk to each other unless a rule explicitly allows it, which contains lateral movement. Second, internet egress is policy-controlled and logged, so an exfiltration attempt has to pass a firewall that is recording it. Administrative access traverses only approved secure paths (Bastion and jump services), and flow logs from every layer feed central monitoring so the network is observable as well as segmented.

Compliance, data residency and control mapping

A global carrier that handles card payments at the point of booking, personal data for consignees across the European Union, and temperature-controlled pharmaceutical shipments under cold-chain custody does not get to assert that it is secure — it has to prove it, repeatedly, to auditors who do not take diagrams on trust. Four frameworks are therefore in scope, each treated as a distinct obligation rather than one undifferentiated “compliance” bucket. ISO/IEC 27001:2022 is the umbrella information-security management system the whole estate is certified against; SOC 2 Type II evidences that the security, availability, and confidentiality controls operated effectively over a period, not merely on audit day; PCI-DSS v4.0 applies only to the payment paths, which are deliberately tokenised and network-segmented so the cardholder-data environment stays small and the rest of the estate falls out of scope; and GDPR, with country-specific data-residency and localisation rules, governs how EU personal data and other regulated records are stored, moved, and erased. The design philosophy throughout is that one control set, expressed as policy-as-code and inherited by every landing zone, satisfies several frameworks at once — so the carrier maintains a single estate of controls and maps it outward to ISO, NIST, and CIS rather than running a separate stack per certification.

The pivot that makes residency tractable is a four-level data classification baked into the platform: Public, Internal, Confidential, and Restricted, where Restricted covers exactly the data the regulators care about most — personally identifiable information, payment data, and pharma cold-chain custody records. Classification is not a spreadsheet exercise; it is enforced where data lives. Restricted data stays in-region by default, the medallion lakehouse governance band carries the catalog, lineage, and classification tags that pin each dataset to an allowed geography, and regulated data crosses a border only over a governed, consented path the governance band itself authorises. That single rule — residency enforced at the data layer rather than asked of every application — is what lets a business operating in 70-plus countries share data globally without quietly breaching a localisation law somewhere in the network.

The control matrix below is the spine of the evidence pack: each row is a single auditable line per control domain, restating the control this estate actually runs in the language each assessor speaks — ISO 27001:2022 Annex A, NIST CSF plus the 800-53 family, and CIS Controls v8 — alongside the team that owns it. Crucially, every control names a real tool from this estate, because an auditor asks “show me” and the answer has to be Entra, Sentinel, Wiz, or an immutable Log Archive, not an aspiration.

Control domain This estate’s control ISO 27001:2022 NIST CSF / 800-53 CIS v8 Owner
Identity & access Entra ID + Okta SSO/federation, Conditional Access, PIM JIT (approval + time-box), MFA for all and phishing-resistant for privileged, SCIM leaver flow from Workday A.5.15, A.5.16, A.5.17, A.5.18 PR.AA / IA-2, IA-5, AC-2, AC-6 CIS 5, 6 Cloud Security & Identity
Network security Azure Firewall Premium + AWS Network Firewall behind centralised inspection, default-deny segmentation, Private Endpoints, no unrestricted east-west A.8.20, A.8.21, A.8.22 PR.IR / SC-7, AC-4 CIS 4, 12 Network & Connectivity
Data protection Encryption in transit and at rest (Key Vault HSM / KMS), four-level classification, payment-path tokenisation, DLP A.8.10, A.8.11, A.8.12, A.8.24 PR.DS / SC-28, SC-13 CIS 3 Cloud Security & Identity
Logging & monitoring Microsoft Sentinel SIEM, Azure Monitor / Log Analytics + CloudTrail / CloudWatch, immutable Log Archive (S3 Object Lock) A.8.15, A.8.16 DE.CM, DE.AE / AU-2, AU-6, AU-9 CIS 8 Cloud Operations
Vulnerability management Wiz exposure scanning, Defender for Cloud + AWS GuardDuty, patch SLA (critical 7 days / high 30 days) A.8.8 ID.RA / RA-5, SI-2 CIS 7 Cloud Platform Engineering
Backup & disaster recovery Geo-redundant and cross-cloud backup, recovery-tier RTO/RPO model, immutable restore points, rehearsed failover A.8.13, A.8.14 RC.RP / CP-9, CP-10 CIS 11 Cloud Operations
Change management Mandatory PR review, policy-as-code gates (tfsec / Checkov), CAB approval tied to ServiceNow change A.8.32 PR.PS / CM-3, CM-4 CIS 4 Cloud Platform Engineering
Endpoint security Microsoft Intune compliance, CrowdStrike Falcon EDR, full-disk encryption, device trust gating Conditional Access A.8.1, A.8.7 PR.PS / SI-3, SI-4 CIS 1, 2 Cloud Security & Identity
Cloud posture Wiz CSPM with posture score ≥ 85 enforced as an onboarding gate, drift and exposure detection across both clouds A.5.36, A.8.9 ID.IM, PR.PS / CA-2, CM-6 CIS 7 Cloud Security & Identity
Software supply chain Wiz Code (SAST / SCA / IaC scanning), governed internal artifact repositories, container scanning and image signing A.8.28, A.8.30, A.8.31 PR.PS / SA-11, SA-12, SR-3 CIS 16 Cloud Platform Engineering
Application security Secure SDLC, App Gateway WAF v2 + AWS WAF, third-party edge WAF (OWASP, bot, API schema), runtime-injected secrets A.8.25, A.8.26, A.8.27 PR.PS / SC-7, SA-15 CIS 16 Application Enablement
Compliance & audit ISMS governance, SOC 2 Type II evidence collection, PCI-DSS scope management on segmented payment paths, ServiceNow CMDB system of record A.5.31, A.5.34, A.5.35 GV.OC, ID.GV / CA-7, PM-9 CIS 17, 18 Cloud Center of Excellence

Two patterns in that matrix do the heavy lifting. First, identity and posture are the domains where a single control answers to every framework at once — Conditional Access plus PIM is simultaneously ISO A.5.15–A.5.18, NIST PR.AA, and CIS 5/6, and a Wiz posture score above threshold is at once an ISO A.5.36 expectation, a NIST ID.IM signal, and a CIS 7 measurement — so the carrier earns disproportionate audit coverage from getting those two right. Second, the immutable Log Archive with Object Lock is the keystone of the evidence chain: it satisfies ISO A.8.15, NIST AU-9, and the SOC 2 criteria for tamper-evident audit trails with the same artefact, and it is the reason a ransomware actor cannot erase the very logs that would prove what they did.

Residency then gets its own table, because the rule differs by data class and so does the enforcement point: Public material can sit on the global edge, while Restricted records cannot leave their geography without an explicit, governed crossing. The table makes the boundary precise.

Data class Examples Residency rule Enforcement
Public Marketing pages, public tracking status, published rate cards No restriction; served globally from the edge CDN Third-party CDN/WAF; no regulated content permitted at this tier
Internal Operational dashboards, internal knowledge, non-sensitive telemetry Regional preference; cross-region replication allowed for resilience Lakehouse governance band tags; storage account / S3 region policy
Confidential Commercial contracts, partner agreements, pricing models, business analytics Stored in approved business regions; access on least-privilege and need-to-know RBAC + Conditional Access; encryption with Key Vault HSM / KMS; DLP
Restricted — personal data (GDPR) Consignee PII, employee records, contact and address data Stays in-region (EU data in EU); cross-border only over governed, consented paths Governance-band classification + residency rules; Private Endpoints; lineage and consent tracking
Restricted — payment & cold-chain Cardholder data, payment tokens, pharma temperature and chain-of-custody records Payment data tokenised and confined to the segmented PCI scope; cold-chain records pinned in-region Tokenisation + network segmentation (PCI-DSS v4.0); Object Lock retention; in-region storage only

The thread tying the section together is that compliance here is a property of the platform, not a quarterly scramble. Because classification, residency, encryption, logging, and posture are all enforced by inherited policy and named tooling — and because every one maps cleanly to ISO, NIST, and CIS through the matrix above — the carrier can hand an auditor a single coherent control estate and demonstrate, with evidence rather than assertion, that a parcel’s payment, a consignee’s personal data, and a pharma shipment’s cold-chain record are each governed exactly as the regulator demands.

Application onboarding for 100+ applications

A foundation is only as good as the rate at which workloads can land on it safely. The onboarding model turns 100-plus applications into a repeatable pipeline rather than 100 bespoke projects. A request is raised in ServiceNow; an automated vend (Azure subscription factory or AWS Account Factory) creates the environment under the correct management group or OU with policy, RBAC, tags, and hub or Transit Gateway attachment; a baseline is applied at creation — logging, monitoring, Wiz and CrowdStrike enrolment, backup, private DNS linking, and CI/CD bootstrap. A blueprint per application type (web, API, integration, SAP-adjacent, data, batch) supplies the right network and platform pattern, always with production and non-production separation.

The vend itself is cloud-specific but symmetrical. In Azure, a subscription is created under the right management group so it inherits Azure Policy and RBAC, then wired with diagnostic settings, Defender for Cloud, Wiz and CrowdStrike enrolment, a Recovery Services backup, hub peering, and Private DNS links.

Azure Application Onboarding & Subscription Vending (Deep Dive)

In AWS, Account Factory for Terraform provisions the account into the right OU under its SCP guardrails, then applies CloudTrail and Config logging, GuardDuty, Security Hub, Wiz and CrowdStrike enrolment, AWS Backup, a Transit Gateway attachment, and IAM Identity Center permission sets.

AWS Account Factory Onboarding (Deep Dive)

Crucially, nothing reaches production until it passes a fixed set of gates: a completed threat model, a passed security baseline, a Wiz posture score above threshold, an active Dynatrace observability baseline, a DR classification, a tested backup and restore, and a registered ServiceNow configuration item with a runbook. Because the blueprint, the gates, and the pipeline templates are all reusable, the platform team improves the standard once and propagates it to every team through controlled version upgrades — agility for application teams, governance for the platform.

SAP landing zone

SAP is treated as a business-critical shared domain with its own landing zone, not as just another application. Production runs across two availability zones: clustered ASCS/ERS application servers and a SAP HANA database replicated synchronously between zones with HANA System Replication, on high-memory certified compute. QA, non-production, and sandbox environments are separated from production with their own change windows. A paired DR region holds a warm-standby HANA replicated asynchronously, with a documented and rehearsed failover path. Connectivity to on-premises systems and business partners runs privately over the same ExpressRoute and Direct Connect circuits the rest of the estate uses.

SAP Landing Zone — HA/DR & Integration

The integration surface is as important as the runtime. SAP connects to on-premises identity and legacy services, to the customer-facing logistics platforms and their APIs, to the data platform for reporting and analytics, and to ServiceNow for CMDB and change. Each of those is a private, governed path with its own privileged-access controls, because SAP sits on the critical-data tier and earns the strongest authentication and segmentation in the estate. Dedicated backup, monitoring through Dynatrace, and a separate change cadence keep SAP’s stringent availability and performance requirements from being diluted by general-purpose platform operations.

Data and integration platform

End-to-end visibility, shipment and fleet tracking, partner integration, and sustainability reporting all depend on treating data as a platform capability rather than something each application hoards locally. Sources — SAP, the 100-plus applications, IoT telemetry, and partner feeds — flow into an event-driven integration backbone (Azure Event Hubs, Kafka, or AWS Kinesis) carrying booking, tracking, telemetry, and exception events. A medallion lakehouse organises the data into raw, curated, and governed zones separated by domain, with a master-data band for customers, assets, routes, depots, and partners. Serving spans analytics and BI, sustainability and fleet-efficiency datasets, and secure partner API exposure through the edge WAF and API management.

Data & Integration Platform — Medallion Lakehouse + Event-Driven

The governance band — catalog, lineage, classification, and regional data-residency controls — is what lets a global business share data without breaking country rules. Event-driven integration decouples producers from consumers, so a new analytics use case or a new partner feed can subscribe to existing event streams without touching the source systems. That decoupling is the difference between a data platform that scales with the business and a tangle of point-to-point integrations that calcifies it.

Zero-downtime release patterns

The carrier’s operating reality is that nothing shares a maintenance window. A sortation centre runs three shifts and never goes dark; a WMS handheld in a distribution centre holds a live pick wave; a driver mid-route carries a manifest that the TMS is still tendering against; a customs broker is clearing a container before a berth deadline; and the customer portal is being refreshed by a shipper in a timezone where it is the middle of the working day. There is no 02:00 on a Sunday that is quiet everywhere. So “zero-downtime” is not an aspiration bolted onto the release process — it is the release process, and it rests on one discipline: a deploy (code reaches a server) is decoupled from a release (customers see the change). Deployment becomes boring, reversible, and continuous; the business decision to expose a change becomes a controlled, instantly reversible flip. During the November-to-January peak the change-advisory board freezes risky change, but flag-gated and canary-gated releases continue precisely because their blast radius is bounded and their rollback is pre-wired.

Every Tier-1 logistics service is mapped to the release pattern that fits its shape and its runtime, and each pattern respects a specific “cannot-stop” constraint. The portal and the public tracking API tolerate an atomic slot swap; the OMS microservices on AKS want a metric-gated canary; the TMS API on ECS uses managed blue-green with CodeDeploy; the WMS — which is closest to physical work and hardest to interrupt — leans on feature flags and a quorum-safe rolling update so a DC never loses its control plane mid-wave.

Pattern Logistics service Platform mechanism “Cannot-stop” constraint it respects Rollback path
Blue-green (slot swap) Customer portal, public track-and-trace API Azure App Service deployment slots (stagingproduction swap) Shippers hit the portal 24/7 across all zones — no drain window exists Swap back (VIP re-points to old slot in seconds)
Blue-green (managed) TMS API (rating, tendering) ECS + CodeDeploy blue/green, dual ALB target groups Carriers tender against live loads; a broken deploy strands freight CodeDeploy alarm-triggered auto-rollback to blue
Canary (analysis-gated) OMS microservices (order capture, quote) AKS + Argo Rollouts, weighted traffic + AnalysisRun Order intake must never drop; prove new code on 5% first Argo abort → weight returns to stable automatically
Rolling (quorum-safe) WMS services, label/print, EDI gateway Kubernetes rolling update + PodDisruptionBudget A DC must keep a serving quorum through the whole roll Roll forward to previous tag; PDB blocks over-eviction
Feature flags (dark launch) WMS, last-mile dispatch, portal features Azure App Configuration feature manager / LaunchDarkly Turn a feature on per-DC/per-region, kill instantly Flag → off (no redeploy; effect is immediate)
Expand-contract (DB) OMS order schema, TMS shipment schema Additive migrations + views; contract weeks later Two app versions run on one schema during rollout Stop at expand; destructive step never shipped yet
Health-based traffic shift Cross-region + cross-cloud origins Front Door / Traffic Manager / Route 53 weighted + probes A degraded origin must bleed traffic, not fail closed Shift weight back / DNS priority flip

Blue-green for the portal and tracking API — App Service slot swap

The customer portal and the public track-and-trace endpoint are stateless read-mostly front ends, which makes them the textbook case for blue-green via deployment slots. The new build is deployed to a staging slot, warmed on its readiness path, then swapped into production in a single atomic operation — the front-end VIP re-points to an already-hot set of workers, so there is no cold start and no dropped connection. Region-specific and secret settings are marked slot-sticky so they stay put and never travel across the swap.

# Track-and-trace portal — blue-green via App Service slots (West Europe, Tier-1)
az webapp deployment slot create -g rg-track-weu -n app-track-weu --slot staging
az webapp deploy -g rg-track-weu -n app-track-weu --slot staging --type zip --src-path track-v43.zip

# Warm the slot on the real readiness probe BEFORE it can take traffic
az webapp config appsettings set -g rg-track-weu -n app-track-weu --slot staging --settings \
  WEBSITE_SWAP_WARMUP_PING_PATH=/health/ready \
  WEBSITE_SWAP_WARMUP_PING_STATUSES=200

# Keep region/DB/secret settings pinned to their slot — they must NOT swap
az webapp config appsettings set -g rg-track-weu -n app-track-weu --slot-settings \
  REGION=westeurope SQL_CONN="@Microsoft.KeyVault(SecretUri=...)"

# Atomic swap — a failed warm-up aborts the swap; production never sees a bad worker
az webapp deployment slot swap -g rg-track-weu -n app-track-weu --slot staging --target-slot production
Slot-swap control Setting / command Effect
Warm-up path WEBSITE_SWAP_WARMUP_PING_PATH=/health/ready Swap waits until the new slot returns 200 on the real readiness check
Warm-up gate WEBSITE_SWAP_WARMUP_PING_STATUSES=200 Any non-200 aborts the swap — production stays on the good slot
Sticky config --slot-settings on region/secret keys Connection strings and region do not travel in the swap
Instant reversal swap ... --action swap back VIP re-points to the previous slot in seconds (MTTR ≈ swap time)
Pre-swap validation swap ... --action preview (multi-phase) Applies production config to staging so you test the exact prod wiring first

Canary for OMS — AKS with Argo Rollouts

Order capture is the service that must never silently regress, so the OMS microservices on AKS release as an analysis-gated canary. Argo Rollouts holds a stable and a canary ReplicaSet behind the ingress, shifts a small weight of live traffic to the canary, and — this is the point — makes the promotion decision from telemetry, not from a human watching a dashboard. An AnalysisRun queries Dynatrace (or Prometheus) every minute for the canary’s p95 latency and 5xx ratio; a breach aborts the rollout and Argo returns 100% of traffic to stable on its own.

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata: { name: oms-order-api, namespace: oms }
spec:
  replicas: 12
  strategy:
    canary:
      canaryService: oms-order-api-canary
      stableService: oms-order-api-stable
      trafficRouting: { nginx: { stableIngress: oms-order-api } }
      steps:
        - setWeight: 5
        - pause: { duration: 10m }
        - analysis: { templates: [{ templateName: oms-slo }] }   # p95 + 5xx gate
        - setWeight: 25
        - pause: { duration: 30m }
        - setWeight: 50
        - pause: {}            # hard manual gate before 100% during peak freeze
Canary step Traffic weight Pause / gate Abort criterion (auto → return to stable)
1 — smoke 5% 10 min bake canary 5xx ratio > 0.5% or p95 > 300 ms
2 — analyse 5% AnalysisRun (Dynatrace) any metric query fails its threshold
3 — ramp 25% 30 min bake error-budget burn-rate alarm fires
4 — half 50% manual gate (peak season) on-call declines promotion
5 — full 100% promote, retire old RS

Blue-green for the TMS API — ECS with CodeDeploy

The TMS rating-and-tendering API runs on ECS Fargate and releases with CodeDeploy blue/green, which stands up a green task set behind a test listener, lets you validate it privately, then shifts the production listener from blue to green on a linear or canary schedule with CloudWatch alarms wired to auto-rollback. The appspec.yaml binds the new task definition to the load-balancer container/port, and a rollback is a listener flip back to the still-running blue task set — no rebuild, MTTR in seconds.

# appspec.yaml — ECS blue/green for the TMS rating API
version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: <arn:...:task-definition/tms-rating:47>   # green
        LoadBalancerInfo: { ContainerName: tms-rating, ContainerPort: 8080 }
# Canary 10% for 5 min, then all — auto-rollback on the p95/5xx alarms
aws deploy create-deployment --application-name tms-rating \
  --deployment-group-name tms-rating-bg \
  --deployment-config-name CodeDeployDefault.ECSCanary10Percent5Minutes \
  --auto-rollback-configuration enabled=true,events=DEPLOYMENT_FAILURE,DEPLOYMENT_STOP_ON_ALARM
CodeDeploy element Value Purpose
Deployment config CodeDeployDefault.ECSCanary10Percent5Minutes Shift 10% to green, bake 5 min, then the rest
Test listener separate ALB listener → green target group Validate green privately before the prod listener flips
Alarm rollback events=DEPLOYMENT_STOP_ON_ALARM on p95/5xx CloudWatch alarm during shift reverts to blue automatically
Termination wait BlueGreenDeploymentConfiguration terminationWaitTimeInMinutes Keep blue tasks alive N min so rollback is instant
Traffic reroute deploymentReadyOption Auto or manual gate before production traffic moves

Feature flags and quorum-safe rolling for the WMS

The WMS is the hardest service to interrupt because it is bolted to physical work: a rolling wave of picks, a conveyor sorter, a label printer. It cannot tolerate an atomic swap that momentarily quiesces connections, so its release model is feature flags plus a quorum-safe rolling update. New behaviour ships dark behind an App Configuration flag and is switched on one DC at a time; the deployment itself rolls pod-by-pod under a PodDisruptionBudget that guarantees the DC never drops below a serving quorum mid-wave.

Flag type Logistics example Lifetime Owner
Release toggle New OMS rating engine behind v43-rating Days–weeks (removed after 100% rollout) Delivery team
Ops kill switch Disable EDI partner X connector under load Permanent Platform on-call
Experiment Alternate ETA model for last-mile, 10% of routes Weeks (until decision) Data science
Per-tenant / per-DC Enable new putaway logic for one distribution centre Long-lived WMS product
Circuit breaker Shed customs-lookup calls when the broker API is slow Permanent SRE

Expand-contract database change — the linchpin

None of the above survives a breaking schema migration, so every stateful change follows expand-contract: the schema only ever adds in the release that ships, so the old and new app versions run against the same database simultaneously; the destructive change (dropping a column, tightening a constraint) is a separate migration weeks later, once the new version is the only one live. This is what lets a canary or a slot swap touch the OMS order table at all — at no point does a running version meet a schema it does not understand.

Phase Schema action App behaviour Reversible?
1 · Expand Add nullable column / new table / compatibility view Old + new versions both read old shape Yes — pure additive
2 · Migrate Backfill new column online, in batches New writes populate both old and new Yes — backfill re-runnable
3 · Dual-write (behind flag) write old + new, read new Canary reads new; stable reads old Yes — flag off reverts reads
4 · Contract Drop old column / constraint Only new version remains No — gated on 100% + soak

Health-based traffic shift and rollback

Above the individual services, the global edge treats traffic as a dial, not a switch. Front Door, Traffic Manager, and Route 53 weight origins and probe their health, so a degraded region bleeds traffic away instead of failing closed, and a fast error-budget burn-rate alarm in Dynatrace is the single trigger that fires the correct reverse action per pattern.

Signal Threshold Automated action Typical MTTR
Slot swap warm-up fails any non-200 on /health/ready Swap aborts; production untouched 0 (never exposed)
Canary metric breach 5xx > 0.5% or p95 > 300 ms Argo abort → 100% to stable < 60 s
ECS deploy alarm CloudWatch p95/5xx alarm CodeDeploy rollback to blue < 60 s
Feature regression flag-scoped error spike App Config flag → off Seconds
Region degradation health probe 3× fail / burn-rate ≥ 14.4 Edge weight → 0 / DNS priority flip < 2 min

Zero-downtime release for a Tier-1 logistics service — blue-green portal, canary track API, expand-contract state and SLO-gated rollback

Reading the diagram left to right: the global edge sends the whole portal to the warmed slot but only a thin 5% slice of the tracking API to the canary; both versions share one expand-contract database and a feature-flagged read path; and a Dynatrace SLO burn-rate alarm is wired to the pattern-specific rollback so recovery is measured in seconds because the previous good version was never torn down.

Active-active multi-region data topology

The hard part of running two regions live is never the compute — stateless portal and API pods scale in any region — it is the data. The design starts from a blunt classification: which data can safely take writes in more than one region, and which data has exactly one writer, ever. Track-and-trace positions, shipment scan events, portal session and catalogue state, and fleet telemetry are high-volume, commutative or last-writer-wins-tolerant facts — they go active-active. The OMS order ledger, financial postings, and the customs declaration of record are legally and numerically singular: you cannot merge two divergent versions of an invoice or a customs entry, so they are region-pinned to a single writer with read replicas elsewhere. Getting this split right is the whole game; everything downstream is mechanism.

Data class / logistics service Store Write topology Region-pinned rule
Track-and-trace positions & scans Cosmos DB Multi-region write None — any region writes; conflicts auto-resolved
Fleet telemetry (500k devices) DynamoDB global table Multi-region write None — last-writer-wins per item
Portal session / catalogue / rates Cosmos DB / DynamoDB Multi-region write None — LWW acceptable
Shipment events (GS1 EPCIS) Event Hubs / Kafka / Kinesis Producers in both regions Ordered per shipment key, idempotent
OMS order ledger Azure SQL failover group Single writer Writes only to primary region; replica is read-only
Financial postings / SAP Aurora Global / HANA Single writer / primary One primary region; async replica for DR
Proof-of-delivery images, customs docs Blob RA-GRS / S3 CRR Object replication Immutable original in one region, replicated read copies

The track-and-trace event pipeline is the canonical active-active consumer here: it is written from whichever region a scan or a device reports to, and every downstream reader sees a single converged model because the event backbone enforces per-shipment ordering and idempotency.

Which datastore replicates how

Each store earns its own replication mechanism, RPO, and conflict rule — there is no single “replicate the region” button, and pretending there is causes silent data loss. The table below is the reference the platform team builds against.

Datastore Replication mechanism Topology RPO Conflict handling
Cosmos DB Native multi-write, async, bounded staleness Active-active Seconds (sub-5s typical) LWW on /_ts or custom merge sproc
DynamoDB global tables Stream-based cross-region replication Active-active ≈ 1 s Last-writer-wins on item (built-in)
Azure SQL failover group Async geo-replication, one primary Active-passive (writer) ≈ 5 s N/A — single writer, no conflict
Aurora Global Database Storage-level cross-region replication Active-passive (writer) < 1 s (typ. ~1 s lag) N/A — single writer
Event Hubs Geo-replication (data) — Geo-DR replicates metadata only Active-active producers Seconds (Geo-repl) / config-only (Geo-DR) Idempotent keys + per-key ordering
Kafka (Confluent/self-managed) MirrorMaker 2 / Cluster Linking Active-active Seconds Consumer-side dedupe on key
Kinesis Data Streams App-level cross-region replicator (no native) Active-active Seconds Idempotent consumers
Blob storage RA-GRS / object replication Read replica (async) < 15 min N/A — immutable original
Amazon S3 Cross-Region Replication (+ RTC 15-min SLA) Read replica (async) < 15 min (RTC) N/A — versioned, immutable

A note that separates real designs from diagrams: Event Hubs Geo-DR (the alias/failover feature) replicates namespace configuration only — it does not copy your event data. For genuine cross-region message continuity you use the newer Event Hubs Geo-replication (premium/dedicated) or federate with a MirrorMaker-style pump; treating Geo-DR as a data-replication feature is a classic and expensive misread.

Region-pinned writers and conflict resolution

For the multi-write stores, a conflict policy is not optional — under concurrent writes the store will diverge, and the only question is whether resolution is deterministic. Cosmos is configured with an explicit conflict-resolution policy per container: last-writer-wins on a timestamp path for telemetry, or a custom stored procedure where two depots legitimately update the same shipment and a naive overwrite would lose a scan. DynamoDB global tables apply last-writer-wins automatically. The pinned stores sidestep the problem entirely by having one writer.

# Cosmos DB — multi-region write for track-and-trace, bounded staleness + LWW
resource "azurerm_cosmosdb_account" "track" {
  name                = "cosmos-track-global"
  offer_type          = "Standard"
  kind                = "GlobalDocumentDB"
  multiple_write_locations_enabled = true          # active-active writes
  consistency_policy {
    consistency_level       = "BoundedStaleness"    # bounded lag, not eventual
    max_staleness_prefix    = 100000
    max_interval_in_seconds = 5                      # ≤ 5 s replication window
  }
  geo_location { location = "westeurope"  failover_priority = 0 }
  geo_location { location = "northeurope" failover_priority = 1 }
}

resource "azurerm_cosmosdb_sql_container" "events" {
  # ... partition_key_path = "/shipmentId" keeps a shipment's events co-located
  conflict_resolution_policy {
    mode                     = "LastWriterWins"
    conflict_resolution_path = "/_ts"               # highest timestamp wins
  }
}
# DynamoDB global table — fleet telemetry, active-active, LWW built in
resource "aws_dynamodb_table" "fleet" {
  name         = "fleet-telemetry"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "deviceId"
  stream_enabled   = true
  stream_view_type = "NEW_AND_OLD_IMAGES"
  replica { region_name = "eu-west-1" }
  replica { region_name = "eu-central-1" }
}
Store Resolution mode Config Logistics example
Cosmos (telemetry) Last-writer-wins conflict_resolution_path = /_ts Two GPS pings for one truck — newest wins
Cosmos (shipment) Custom merge sproc mode = "Custom" + JS procedure Two depots scan same parcel — union the scans
DynamoDB global Last-writer-wins built-in (per-item, replica timestamp) Device state update from two gateways
SQL / Aurora None (single writer) failover group / global cluster OMS order total — never multi-mastered
Event backbone Idempotent + ordered key = shipmentId, dedupe window Replayed EPCIS event is a no-op

Write routing and consistency knobs

Latency-based DNS pins each user to the nearest active region for reads and local writes, while the pinned-writer paths route their writes to the owner region regardless of where the user landed — the portal in Region B can read an order locally but its write to the order ledger is proxied to the primary region’s SQL listener.

Path Router Rule Failure behaviour
Portal / tracking reads Traffic Manager (Performance) / Route 53 latency Nearest region Reroute to healthy region
Telemetry / track writes Local region endpoint Write local, replicate async Buffer at edge, replay on backbone
OMS order writes SQL failover-group R/W listener Always to primary region Blocks until primary reachable / failover
Object upload (POD) Region-local bucket/container Write local; CRR/RA-GRS replicates Retry; original is immutable
Store Consistency setting Read latency Write latency / cost note
Cosmos multi-write Bounded staleness (≤ 5 s / 100k ops) Single-digit ms local Higher RU cost than eventual; predictable lag
DynamoDB global Eventually consistent cross-region Single-digit ms local Replication billed as replicated write units
SQL failover group Strong in-region; async to secondary ms in primary region Cross-region write = primary round-trip
Aurora Global Strong primary; < 1 s replica lag ms in primary Secondary is read-only until promoted

Active-active data topology — two live regions, a geo-replicated shipment-event backbone, region-pinned ledger and deterministic conflict resolution

The diagram shows latency-based DNS pinning each shipper to the nearest active region, Cosmos and DynamoDB taking multi-region writes for track-and-trace while the OMS SQL ledger keeps a single writer, and the GS1 EPCIS event backbone carrying ordered, idempotent facts between the regions with a mandatory conflict policy and object replication underneath.

Active-passive and warm-standby topology

Active-active is the right answer only where the data model tolerates it; for the stateful writers — the OMS ledger, SAP, the TMS shipment store — the carrier runs active-passive on a warm standby, and chooses the rung on the DR ladder per tier by trading recovery speed against standing cost. The ladder runs from cheap-and-slow backup-and-restore, through pilot-light (data replicating, compute switched off), to warm-standby (a small always-on copy), to full active-active. Tier-3 workloads sit on backup-restore; Tier-2 on pilot-light; the Tier-1 stateful services on warm-standby; and only the stateless edge and read paths on active-active. The point of the ladder is that you do not pay active-active prices to protect a nightly analytics job, and you do not accept a 24-hour restore for order intake.

Strategy Standby footprint RTO RPO Rel. monthly cost Logistics tier / service
Backup & restore Backups only; nothing running Hours–day Hours (last backup) ~5% Tier 3 — dev/test, non-critical reporting
Pilot light Data replicating; compute off 1–4 h Minutes ~15% Tier 2 — internal apps, analytics, lakehouse
Warm standby Small always-on copy + replica 15 min–2 h Seconds ~35% Tier 1 — OMS, TMS, SAP prod, partner APIs
Active-active Full second region, live Seconds (auto) Seconds ~100% Tier 0/1 edge — portal, tracking, DNS, identity

Mapping the estate onto the ladder makes the standby posture explicit for each service, and pins the exact primary-to-DR replication mechanism that sets its RPO.

Logistics service Tier Strategy Primary → DR mechanism
Customer portal, public tracking 1 (edge) Active-active Multi-region Cosmos + health-checked DNS
OMS order ledger 1 Warm standby Azure SQL failover group, async geo-replica
TMS shipment store 1 Warm standby Aurora Global Database, < 1 s replica
SAP (HANA) 1 Warm standby HANA System Replication, async to DR region
Line-of-business apps 2 Pilot light Geo-replicated data; IaC re-hydrates compute
Data lakehouse / analytics 2 Pilot light GRS storage + event-backbone replay
Dev / test / reporting 3 Backup & restore GRS immutable backup, restore on demand

Promotion and failover mechanics

A warm standby only earns its keep if promotion is scripted, deterministic, and one-way. Each stateful store has a defined failover command and a defined RTO, and — critically — the SAP HANA promotion is not a database button but a cluster takeover that must fence the old primary first.

# Azure SQL — auto-failover group protects the OMS ledger; RW listener follows primary
az sql failover-group create -g rg-oms -n fog-oms --server sql-oms-weu \
  --partner-server sql-oms-neu --failover-policy Automatic --grace-period 1 \
  --add-db oms-orders
# Unplanned, disaster promote (accepts the async-replication RPO gap):
az sql failover-group set-primary -g rg-oms -n fog-oms --server sql-oms-neu --allow-data-loss
# Aurora Global — planned switchover is RPO 0; unplanned failover accepts a few seconds
aws rds failover-global-cluster --global-cluster-identifier gc-tms \
  --target-db-cluster-identifier arn:aws:rds:eu-central-1:...:cluster:tms-neu   # planned (RPO 0)
aws rds failover-global-cluster --global-cluster-identifier gc-tms \
  --target-db-cluster-identifier arn:aws:rds:eu-central-1:...:cluster:tms-neu --allow-data-loss  # unplanned
# SAP HANA — takeover on the DR secondary AFTER the old primary is fenced (STONITH)
hdbnsutil -sr_takeover     # promote secondary; cluster must guarantee old primary is stopped
Datastore Failover type Command / action RTO One-way?
Azure SQL failover group Auto (grace-bounded) or forced set-primary --allow-data-loss Seconds–1 h grace Yes — old = new secondary
Aurora Global Planned switchover / unplanned failover-global-cluster [--allow-data-loss] < 1 min / seconds Yes — re-seed old
Cosmos (single-write mode) Priority-based az cosmosdb failover-priority-change Seconds (auto) Auto-failback optional (off)
SAP HANA Cluster takeover hdbnsutil -sr_takeover + fence Within Tier-1 2 h Yes — manual failback
Event backbone Alias / consumer re-point Geo-repl failover / re-point group Seconds Re-pair after

Split-brain avoidance and failover testing

The failure that turns a DR event into a data-loss event is split-brain: two regions each believing they are primary and both accepting writes to the ledger, producing two divergent truths that cannot be merged. The design forbids it structurally — there is exactly one writer at all times, the old primary is fenced before the new one is promoted, and failback is always a planned, scheduled event rather than an automatic race against replication.

Risk Control Mechanism
Two writers accept ledger writes Single-writer invariant Failover promotes exactly one; old primary demoted/fenced
Old primary returns and writes Fencing (STONITH) Stop/isolate old node before promote; SQL FoG guarantees single R/W listener
DNS flaps both regions live TTL + probe hysteresis 30 s TTL, 3-failure threshold — a blip does not flip
Auto-failback corrupts data Manual, scheduled failback No auto-failback on stateful writers; re-seed then cut over in a window
Replicated corruption / ransomware Immutable backup floor GRS + Object Lock; point-in-time restore is a separate control

Finally, an RTO that has never been rehearsed is a guess, so the recovery paths are exercised on a calendar rather than in an emergency. The cadence mirrors the estate’s DR programme: a rotating quarterly per-tier component test against the paired region, and an annual full-region game-day in which a whole region is declared lost and dependent workloads fail over in strict tier order (0 → 1 → 2 → 3), with business sign-off before a controlled failback.

Cadence Scope What’s rehearsed Pass criterion
Quarterly One tier’s recovery path (rotating) SQL/Aurora promote, HANA takeover, DNS cutover Meets tier RTO/RPO; deviations logged as ServiceNow change
Quarterly Zero-downtime rollback Slot swap-back, Argo abort, flag kill Recovery in target MTTR, no customer-visible error
Annual Full-region game-day Region loss, ordered tier failover, split-brain drill Business sign-off; failback clean; runbook corrections filed
Continuous Health-checked DNS failover Automatic origin failover under synthetic fault Traffic shifts within TTL; no split-brain observed

Active-passive topology — an active region replicating async to a scaled-down warm standby, with health-checked DNS, one-way promotion and immutable backup underneath

The diagram traces the active region serving OMS/TMS with SQL and HANA primaries, async replication and immutable GRS backup feeding a pilot-lit warm standby that runs one instance and a read-only replica, and a health-checked DNS layer that flips priority to the standby on failure — after which promotion is one-way and the old primary is fenced, so the ledger never has two writers.

Disaster recovery and resiliency

Resilience is designed by classifying workloads into recovery tiers and engineering each tier to its target. Tier 0 — identity, the network control plane, DNS, VPN, and security tooling — carries an RTO of one hour and an RPO of fifteen minutes because nothing else recovers until it does. Tier 1 — customer logistics platforms, SAP production, and partner APIs — matches that fifteen-minute RPO with a two-hour RTO. Tier 2 (line-of-business apps and analytics) and Tier 3 (dev, test, and non-critical reporting) relax to hours. Each strategic geography runs a primary and a paired DR region in both Azure and AWS; edge services and selected APIs run active-active behind global DNS failover, while stateful back ends use active-passive or warm standby where active-active is impractical.

Disaster Recovery & Resiliency Tiers

Tier Example workloads RTO RPO
Tier 0 Identity, connectivity, security control plane 1 hour 15 minutes
Tier 1 Customer platforms, SAP prod, partner APIs 2 hours 15 minutes
Tier 2 Internal apps, analytics, collaboration 8 hours 4 hours
Tier 3 Dev, test, non-critical reporting 24 hours 24 hours

The redundant ExpressRoute and Direct Connect circuits, cross-cloud and cross-region backup, and regular DR testing — identity recovery, DNS failover, circuit failover, and SAP recovery — turn these numbers from aspiration into something the business can actually rely on. A recovery target that has never been rehearsed is a guess; the operations model bakes the rehearsals in.

Disaster recovery runbooks

A recovery target that nobody has rehearsed is not a commitment, it is a guess. The DR tiers earlier in this document set the contractual envelope — Tier 0 at RTO 1 hour / RPO 15 minutes, Tier 1 at RTO 2 hours / RPO 15 minutes, Tier 2 at RTO 8 hours / RPO 4 hours, and Tier 3 at RTO 24 hours / RPO 24 hours — but the envelope is only credible if every scenario behind it has a written procedure with a named trigger, ordered steps, a single accountable owner, and an explicit validation that proves the workload is actually serving traffic again. The runbooks below are deliberately operational rather than aspirational: each one is the script an on-call engineer follows under pressure at 03:00, not a paragraph of intent. They presume the dual-cloud, four-region estate already in place — paired-DR regions in both Azure and AWS, asynchronous HANA System Replication to the DR region, immutable backup with Object Lock in the AWS Log Archive, and third-party DNS health-checking in front of both clouds — so recovery is a matter of promotion and re-pointing, not rebuilding.

Procedures decay unless they are exercised, so the operating model treats DR as a calendar event rather than an emergency-only capability. The carrier runs quarterly per-tier component tests — a rotating schedule in which one tier’s recovery path (identity failover, a SAP DR promotion, a data-replay, an edge origin swap) is rehearsed in isolation against the paired region, with results, timings, and any deviation from RTO/RPO logged as a ServiceNow change and fed back into the runbook. Once a year the programme runs a full-region failover game-day: an entire strategic region is declared lost and the dependent workloads are failed over in tier order — Tier 0 first to re-establish the identity and connectivity control plane, then Tier 1, and so on — with business stakeholders signing off recovery before a controlled failback. Game-day findings are the single most reliable source of runbook corrections, because they surface the dependencies and sequencing assumptions that component tests in isolation never expose.

Scenario Trigger Procedure steps Owner Target Validation
Identity & control-plane recovery (Tier 0) Loss of Microsoft Entra ID / AD DS authentication or security control plane in primary region Detect via Sentinel/Dynatrace alert → activate a monitored break-glass account → fail Entra ID and on-prem AD DS services over to the paired region → trigger third-party DNS failover for identity endpoints → confirm Conditional Access and PIM are serving → controlled failback once primary is healthy Cloud Security & Identity RTO 1 hour / RPO 15 minutes Test interactive sign-in, MFA challenge and a PIM JIT elevation against the recovered control plane
Connectivity / circuit failover Loss of an ExpressRoute or Direct Connect circuit in a region Active-active BGP withdraws the failed path automatically → on-call confirms the surviving circuit is carrying the load and is not saturated → raise carrier ticket → restore and re-balance BGP on circuit return Network & Connectivity Sub-minute (automatic) Synthetic reachability probe across the surviving path; confirm no asymmetric routing
SAP DR (Tier 1) Loss of the SAP primary region or unrecoverable HANA primary Declare DR → promote the asynchronously replicated HANA secondary in the paired DR region → start ASCS/ERS in DR → re-point application servers and integration to DR endpoints → run smoke tests → obtain business sign-off → controlled failback when primary is restored Cloud Platform Engineering + SAP Basis RTO 2 hours / RPO 15 minutes Execute the agreed SAP transaction set (order-to-cash / tracking posting) and reconcile against last committed state
Edge / application failover DNS health checks mark a region’s origin unhealthy Third-party DNS + health checks automatically fail the affected service over from Azure origin to AWS origin (or vice versa) → on-call confirms the healthy origin is scaled and serving → monitor error budget → revert when the failed origin recovers Network & Connectivity + Application Enablement Automatic Synthetic end-to-end user journey (login → track shipment) against the failed-over origin
Data platform recovery (Tier 2) Loss or corruption of streaming / lakehouse storage in a region Replay event streams from retained offsets (Event Hubs / Kafka / Kinesis) → restore the lakehouse from geo-redundant storage in the paired region → re-run curation to rebuild governed and master-data bands → resume downstream consumers Cloud Operations RTO 8 hours / RPO 4 hours Record-count and checksum reconciliation between source offsets and restored curated datasets
Ransomware / full region loss Confirmed destructive compromise or total region outage Isolate the affected accounts/subscriptions → stand up (or vend) a clean landing zone → restore from immutable, Object-Lock backup into the clean estate → recover workloads in strict tier order (0 → 1 → 2 → 3) → forensics before any re-connection Cloud Security & Identity + Cloud Operations Per affected tier Integrity verification of restored data against backup hashes; clean-state attestation before traffic is admitted

Backup, immutability and ransomware recovery

Replication answers one question — the primary region is gone, where do I run? — and the resiliency and DR-runbook sections answer it with paired regions, HANA System Replication, and DNS failover. Backup answers a darker one: the data itself is wrong — corrupted by a bad release, fat-fingered by an operator, or encrypted by an intruder holding valid credentials — where do I go back to? Replication copies corruption to the secondary in milliseconds, so a warm standby that has just mirrored a ransomware payload is not a recovery, it is a second casualty. Backup is therefore a separate control plane from DR — its own vaults, retention, immutability, and, above all, its own trust boundary — so an actor who can reach production cannot reach the copies that would rebuild it.

The carrier’s data does not all carry the same recovery weight, so the backup estate is tiered by what the data means to the business, not by the technology that stores it. At the centre sits the shipment and consignment record — the system of record (SoR) for the physical network — the authoritative ledger of every parcel, pallet, and container the carrier has taken into custody; around it run the Order (OMS), Warehouse (WMS), and Transport Management Systems (TMS) that act on that record, and beneath them the SAP core that settles the money. These are the datasets a customs authority, an insurer, or a court demands years after the shipment moved, and precisely the ones a ransomware crew encrypts first. The matrix pins each class to a source engine, a backup frequency (its true backup RPO, distinct from the replication RPO the DR tiers quote), operational and long-term retention windows, and the immutable copies that make the record un-erasable.

Data class / system Tier Source & engine Backup RPO Op. retention Long-term Immutable copies
Shipment / consignment SoR 1 Azure SQL BC / Aurora — PITR + export Log 5–15 min; daily full 35 d 7 yr (customs) Locked RSV + Object Lock + air-gap
OMS / WMS / TMS operational DBs 1 Azure SQL, PostgreSQL Flex, Aurora, RDS PITR 15 min; daily 35 d 1 yr Locked vault + cross-region
SAP HANA (production) 1 Backint → RSV / AWS Backup Log 15 min; daily full 35 d 7 yr monthly Locked vault + air-gap
Master data & lakehouse band 2 ADLS Gen2 / S3 versioning + snapshots Daily 30 d 1 yr Object Lock + versioning + CRR
Platform config & IaC state 1 Git + Terraform state + policy export On change + daily 90 d Git history Object-Lock backup of state
Secrets & keys 0 Key Vault soft-delete + purge / KMS Continuous 90-d soft-delete Re-issue Purge protection + multi-region KMS
IaaS VMs & file shares 2 Azure Backup / AWS Backup (EBS, EFS) Daily 30 d 90 d Locked vault
IoT offsets & cold telemetry 2/3 Event Hubs Capture / Kinesis → S3 Continuous 30 d 1–7 yr Object-Lock cold tier

The line running through that table is the gap between backup RPO and replication RPO, and conflating the two is how an enterprise discovers mid-incident that it cannot recover. The DR tiers promise a 15-minute replication RPO for Tier-1 because HANA System Replication and geo-redundant storage keep a near-live mirror — but a mirror corrupts when the source does. Backup adds point-in-time copies you can walk backwards through: when the latest state is poisoned the carrier steps to the last log backup, then yesterday’s full, then a monthly copy inside the seven-year window the SoR earns because a mis-delivered pharmaceutical consignment or a disputed customs claim surfaces long after the operational systems have forgotten it.

Backup is expressed differently per resource type and per cloud, and getting the engine right per workload is what separates a backup policy from a backup product slide: IaaS and SAP HANA back up through a vault, PaaS databases lean on native point-in-time plus a periodic export into a WORM target, object stores rely on versioning and Object Lock.

Workload type Primary engine Method Vault / target Notable control
IaaS VM (Windows / Linux) Azure Backup (RSV) / AWS Backup App-consistent snapshot Locked RSV (GRS) / Backup vault Instant-restore + long-term tier
PaaS relational DB (SQL, PostgreSQL, Aurora, RDS) Native PITR + LTR; AWS Backup Continuous log + periodic export Geo-redundant storage + Object-Lock export LTR to 10 yr; export = WORM
NoSQL (Cosmos DB, DynamoDB) Continuous backup / PITR; AWS Backup Point-in-time restore Service-managed + Backup vault PITR window + export
SAP HANA Backint-certified agent Log 15 min + daily data backup RSV / AWS Backup Savepoint-consistent stream
PaaS storage / object (Blob, ADLS, S3) Versioning + soft delete + AWS Backup Version retention + object copy Object Lock (S3) / immutable Blob WORM at the object
Config & IaC state Git + pipeline export Versioned commit + state backup Object-Lock bucket + Git Rebuild from code
Secrets & keys Key Vault / KMS + Secrets Manager Soft-delete + purge protection Vault-managed; multi-region key Recover, not into old trust
Kubernetes (AKS / EKS) state Azure Backup for AKS / AWS Backup + Velero Namespace + PV snapshot Backup vault + Object-Lock bucket Manifests in Git; data in vault

Immutable multi-cloud backup and the clean-room ransomware recovery path

Reading left to right: the data classes — IaaS and SAP HANA, the managed OMS/WMS/TMS databases, and the platform’s own config and secrets — back up into WORM-locked vaults in both clouds (1), held by a soft-delete safety net (2) and copied to an air-gapped vault in an isolated account no production credential can reach (3). Recovery never runs back into the blast radius: a validated, known-clean restore point (5) is restored into a freshly vended clean landing zone (4), and forensics preserves evidence before traffic is readmitted (6).

Immutability is the load-bearing control, because every other backup discipline is defeated the moment a privileged attacker deletes the backups before encrypting the primaries — and modern operators target the backup catalog first. The estate answers with independent controls, none trusted to hold alone: WORM immutability sets a floor beneath which nothing can be deleted or shortened; soft delete catches what immutability does not; multi-user authorisation forces destructive operations through an approver the backup admin cannot touch; and the air-gapped copy sits outside the production trust boundary.

Control Azure mechanism AWS mechanism What it blocks Confirm
WORM / immutability RSV / Backup-vault immutability = Locked S3 Object Lock COMPLIANCE; AWS Backup Vault Lock Delete-before-retention; retention shortening — even by root state = Locked; Vault Lock COMPLIANCE
Soft delete / recycle Backup soft delete AlwaysON, 14–180 d AWS Backup retention + delete protection Accidental or malicious RP deletion softDeleteFeatureState = AlwaysON
Retention lock Immutable policy floor per vault Vault Lock min / max_retention_days An admin rewriting policy to 1 day Policy diff blocked post-lock
Multi-user authorisation Resource Guard in a separate tenant (PIM-gated) SCP deny on backup:Delete*; separate account Solo-admin destruction of copies Resource-guard mapping present
Encryption of backups CMK in Key Vault HSM KMS CMK per backup vault Reading / exfiltrating backups Vault bound to customer key
Destructive-op alerting Diagnostics → Sentinel on StopProtection CloudTrail → SIEM on DeleteBackupVault A silent strip going unnoticed Alert fires on the operation

The Azure vault is provisioned immutable, geo-redundant, and CRR-capable in one declaration — and the ordering matters: GRS and the CRR flag must be set before any item is protected, and the Locked state is irreversible, so the platform team soaks on Unlocked first.

resource "azurerm_recovery_services_vault" "logistics" {
  name                         = "rsv-log-weu-prod"
  location                     = "westeurope"
  resource_group_name          = azurerm_resource_group.backup.name
  sku                          = "Standard"
  storage_mode_type            = "GeoRedundant"   # GRS — enables cross-region restore
  cross_region_restore_enabled = true             # must be set BEFORE protecting items
  soft_delete_enabled          = true             # 14-day floor, extendable to 180
  immutability                 = "Locked"         # WORM — irreversible; soak on Unlocked first
  identity { type = "SystemAssigned" }
}
# Prove the immutability state is the irreversible Locked, not merely Unlocked
az resource show --ids "$VAULT_ID" \
  --query "properties.securitySettings.immutabilitySettings.state" -o tsv   # -> Locked

On AWS, the air-gap copy lands in an S3 bucket with Object Lock in COMPLIANCE mode — a retention no principal, including account root, can shorten — while AWS Backup’s own vault is sealed with a Vault Lock whose short cooling-off window is the last chance to correct a mistake before the lock is permanent. A backup plan then does the copying, so immutability travels with the data: one rule writes the daily point into the locked vault and fans out two copy_action blocks — cross-region to the paired DR region, and cross-account into the air-gap vault.

resource "aws_s3_bucket" "backup_airgap" {
  bucket              = "log-backup-airgap-euc1"
  object_lock_enabled = true                      # only settable at bucket creation
}
resource "aws_s3_bucket_object_lock_configuration" "airgap" {
  bucket = aws_s3_bucket.backup_airgap.id
  rule { default_retention { mode = "COMPLIANCE"  # not even root deletes before expiry
                             days = 35 } }
}

resource "aws_backup_vault_lock_configuration" "logistics" {
  backup_vault_name   = aws_backup_vault.logistics.name
  changeable_for_days = 3       # cooling-off; after this, compliance mode is permanent
  min_retention_days  = 35
  max_retention_days  = 2555    # 7 years for SoR / compliance copies
}

resource "aws_backup_plan" "sor" {
  name = "log-sor-daily"
  rule {
    rule_name         = "daily-35d"
    target_vault_name = aws_backup_vault.logistics.name
    schedule          = "cron(0 2 * * ? *)"
    lifecycle { delete_after = 35 }
    copy_action {                                 # cross-region copy (offsite)
      destination_vault_arn = aws_backup_vault.dr_euw1.arn
      lifecycle { delete_after = 35 }
    }
    copy_action {                                 # cross-account copy (air-gap)
      destination_vault_arn = "arn:aws:backup:eu-central-1:${var.vault_account}:backup-vault:log-airgap"
    }
  }
}

The whole design is a modern reading of the 3-2-1-1-0 rule, updated for a dual-cloud estate where “a second building” becomes “a second cloud and a second, un-trusted account”. The two additions to the classic 3-2-1 — the extra 1 for an offline/immutable copy, the 0 for verified-zero recovery errors — are the ones that specifically defeat ransomware and silent corruption, so the carrier treats them as non-negotiable.

Rule Meaning How the estate meets it
3 copies Three copies of the data Production + backup vault + cross-region / air-gap copy
2 media / platforms Two different platforms Azure Backup and AWS Backup + object stores — no single vendor holds all copies
1 offsite One copy elsewhere Cross-region copy into the paired DR region in both clouds
1 offline / immutable One air-gapped or WORM copy Object Lock COMPLIANCE + Vault Lock in an isolated account with no standing production trust
0 errors Recoveries verified, not assumed Automated restore drills + hash and reconciliation checks before a backup counts as “green”

The estate is therefore explicit about where each tier’s copies live, so no single failure — a region, a cloud account, a compromised admin — takes the primary and every copy at once. Tier-0 and Tier-1 carry the full complement; lower tiers taper the far copies to control cost without breaching the floor.

Tier Primary vault Cross-region copy Cross-cloud / cross-account Air-gap / offline
Tier 0 (identity, config, secrets) Locked vault + Git, primary Paired region Mirrored across both clouds Object-Lock copy, isolated account
Tier 1 (SoR, OMS/WMS/TMS, SAP) Locked RSV / AWS Backup Paired DR region Cross-account to backup account Object Lock COMPLIANCE, 7-yr floor
Tier 2 (VMs, master data, lakehouse) Locked vault, primary Paired DR region Optional cross-account Object Lock 30–90 days
Tier 3 (dev, test, reporting) Vault, primary Optional Rebuildable from IaC + source

An “air gap” in a cloud is not a tape in a drawer, so the carrier’s air-gap copy is defined by trust, not distance: it lives in a dedicated backup account/subscription that production holds no standing management-plane rights over, sealed with Object Lock COMPLIANCE and its own KMS/HSM keys, reachable only through a break-glass, MUA-approved path. An attacker who has fully compromised the production tenant still cannot reach into that account to delete or re-key the copies — which is the entire point of the control.

Immutable copies are half a recovery capability; the other half is knowing how fast, and back to what point, each tier restores. The DR RTOs (1h/2h/8h/24h) describe failover to a live replica; a backup-driven clean rebuild is slower, because the team must first choose and validate a known-clean point, then restore into new infrastructure. The table quotes two restore points per tier: the normal one for everyday corruption, and the ransomware clean one, which may be hours or days older because its defining property is being provably uninfected, not most recent.

Tier Restore RTO Normal restore point Ransomware clean point Method Validation
Tier 0 1 hour Last change Last known-clean commit / key version Key Vault undelete; redeploy IaC Sign-in + PIM JIT test
Tier 1 4 hours ≤ 15 min (log) Last verified-clean daily full PITR / HANA Backint into clean LZ Transaction-set reconciliation
Tier 2 8 hours ≤ 24 h (daily) Last clean daily snapshot Vault VM restore; object versioning Count + checksum reconciliation
Tier 3 24 hours+ ≤ 24 h Last clean weekly Rebuild from IaC + restore data Smoke test of recovered service

A restore SLA that has never been exercised is a number on a slide, so the carrier treats restore testing as a scheduled obligation with evidence. The cadence rotates through the estate so every tier and mechanism is proven on a known schedule, logged as a ServiceNow change and fed back into the runbooks; a recovery point is not “protected” until a restore has round-tripped it.

Test Scope Frequency Owner Evidence
Item-level restore spot-check Random files / DB rows Weekly Cloud Operations Restored item + hash match
Database PITR drill SoR + one OMS/WMS/TMS DB to scratch Monthly Platform Engineering Reconciled row counts
SAP HANA restore Backint restore to isolated subscription Quarterly Platform + SAP Basis Consistent start + replay
Full-VM restore Representative Tier-2 VMs, cross-region Quarterly Cloud Operations Booted VM + smoke test
Clean-room ransomware rehearsal Vend clean LZ, restore Tier-0/1 immutably Semi-annual Security & Identity + Ops Runbook timing vs RTO
Immutability & lock attestation Confirm Locked / COMPLIANCE across vaults Monthly Cloud Security & Identity State outputs to evidence

When the worst happens, improvisation is the enemy, so the ransomware path is a written, phased runbook that operationalises the “Ransomware / full region loss” row from the DR-runbooks section into the sequence an incident commander follows. Its governing principle is that recovery runs into a clean landing zone, never back into the blast radius — restoring into the compromised estate simply hands an attacker who may still hold persistence a freshly decrypted target. Each phase has a trigger, an action, its tooling, an owner, and an exit gate that must close before the next begins.

Phase Trigger / action Tooling Owner Exit gate
0 · Detect & declare Correlated destructive event; commander declares ransomware Sentinel, Wiz, CrowdStrike, ServiceNow Security & Identity Incident declared; scope estimated
1 · Isolate & contain Revoke sessions/tokens; disable federation; sever peering/TGW to affected accounts; freeze CI/CD Entra / Okta, Conditional Access, NSG/SCP Security & Identity + Network Blast radius contained; no lateral path
2 · Validate a clean restore point Enumerate immutable RPs; scan for payload / IoC; pick newest provably clean per tier AWS Backup / RSV catalog, AV/IoC scan, hash manifest Cloud Operations Named clean RP per Tier-0/1
3 · Restore into a clean landing zone Vend fresh sub/account (no trust to the estate); restore from immutable / air-gap copy; rotate all secrets Subscription/Account factory, Backup restore, Key Vault/KMS Platform + Operations Data restored + integrity-verified
4 · Resume in tier order Bring up 0 → 1 → 2 → 3; re-point edge/DNS; business sign-off before traffic DNS failover, App Gateway/ALB, ServiceNow Operations + App Enablement Tier serving + validated
5 · Forensics & closure Preserve isolated images and immutable logs; root-cause; feed fixes into guardrails Immutable Log Archive (S3 Object Lock), forensic images Security & Identity RCA signed; controls hardened

Two properties make that runbook survivable. First, the immutable Log Archive is untouched by the attack — the Object-Lock evidence chain means the logs that prove what happened cannot be erased by the actor who did it. Second, the clean landing zone is vended, not repaired — the factories stamp out a governed, policy-inherited environment in under a business day, so the team recovers forward into a known-good estate rather than disinfecting the compromised one.

Protection carries a price, and the design keeps it honest by fitting inside the ≈ $35,000/month backup, DR and storage line the cost model already carries. The bill concentrates where the risk does — geo-redundant Azure and AWS backup storage holding the bulk of the recovery points, and the air-gapped Object-Lock copy that is the estate’s last line — with archive tiering pushing the seven-year retention down the cost curve so long-term compliance does not dominate the run-rate.

Cost line Driver ~USD/month
Azure Backup — GRS vault + cross-region restore VMs, SAP HANA, SQL-in-VM, PostgreSQL, Blob across 4 regions $12,000
AWS Backup — vault storage + cross-region copy EBS, EC2, RDS, Aurora, DynamoDB, EFS, S3 across 4 regions $9,000
Air-gap S3 Object Lock (COMPLIANCE), isolated account SoR, SAP, config — 7-year WORM copies $5,000
Long-term archive (Archive Blob / Glacier Deep Archive) Customs / claims retention to 7 years $3,500
Cross-region + cross-cloud copy transfer Inter-region and inter-account egress $3,000
Instant-restore snapshots + PITR storage Short-window fast-restore tier $2,500
TOTAL Immutable, cross-region, air-gapped backup estate ≈ $35,000/month

Read whole, the backup design is the estate’s admission that prevention is necessary but not sufficient: identity, segmentation, and posture reduce the probability of a destructive compromise but cannot drive it to zero, and the only honest answer to a determined ransomware actor is a set of copies they cannot reach, alter, or delete, restored into an estate they no longer control. Immutability makes the copies un-erasable, the air gap puts them beyond production’s reach, cross-region and cross-cloud spread survives the loss of a region or account, and rehearsed restores turn a stored artefact back into a running business — the difference, for a carrier moving temperature-controlled freight worldwide, between an incident and an extinction event.

Terraform and Ansible multi-stage CI/CD

Every layer above is delivered as code through a promotion pipeline that moves the same reviewed change from Dev to UAT to Staging to Production. Source lives in Bitbucket — Terraform modules, environment definitions, Ansible roles, and deployment manifests — behind mandatory pull-request review. Static validation runs first: Terraform fmt, validate, and lint, policy-as-code with tfsec or Checkov, and secrets scanning, all before a plan is allowed. Terraform applies against separate, locked, encrypted remote state per environment, region, and scope so a change in one environment can never corrupt another. Ansible then enforces OS, middleware, and SAP-host configuration from a dynamic Azure/AWS inventory using idempotent roles, with secrets injected at runtime rather than stored in code.

Terraform + Ansible Multi-Stage CI/CD

Two controls make this production-grade. Artifact-based promotion means the exact change validated in Dev is what reaches Production — environments stop drifting because they are no longer rebuilt differently each time. And manual approval gates before Staging and Production, with security and platform sign-off, give change governance a real enforcement point that ties into ServiceNow change records. The subscription and account factories feed the same pipeline, so even the creation of new landing zones is a reviewed, auditable code change.

DevSecOps software supply chain

The pipeline above is one slice of a larger software supply chain that the proposal asks to be engineered end to end. Reuse is enforced through a deliberate repository strategy: dedicated projects for Terraform modules, for YAML pipeline templates, for application code, for artifacts (npm, Maven, PyPI, NuGet, containers, generic), for policy-as-code, for Ansible roles, and for shared test assets. An application repository composes the shared modules and templates rather than duplicating them, so the platform team raises the standard once and every application inherits it on a controlled upgrade. Security runs across the whole path — SAST, secrets, SCA, and IaC/policy scanning (Wiz Code) early; build and dependency resolution through governed internal artifact repositories; container build, scan, and signing; Terraform plan and Ansible validation; functional, API, smoke, DAST, UI, integration, load, and resilience testing across the environments; database schema-as-code migrations that are versioned, reviewed, and approved like any other change; and mobile build, scan, and distribution through UEM test rings.

DevSecOps Software Supply Chain

The principle running through it is traceability from source to production: every release path includes layered scanning and quality gates, every artifact is built once and promoted rather than rebuilt, and every production change — including database schema and mobile builds — carries provenance, approval, and a rollback plan. Treating endpoints and mobile delivery as pipeline-integrated release domains, and database changes as code, closes the two gaps that most enterprise pipelines leave open.

IoT connected logistics

The fleet is where the business meets the physical world, and IoT is a core platform capability rather than an add-on. Device and edge classes range from truck telematics and GPS to container low-power trackers, BLE/RFID asset tags, environmental sensors for temperature-sensitive cargo, and depot edge gateways that aggregate where direct cloud connectivity is unreliable. Every device carries a certificate-based identity and supports store-and-forward for intermittent links. Connectivity spans cellular, LPWAN, Wi-Fi, and cross-country roaming for 70-plus countries. Ingestion is deliberately split across both clouds: AWS IoT Core handles fleet-scale vehicle telemetry with its device registry, mutual TLS, and rules engine, while Azure IoT Hub carries the operational and control-tower telemetry that integrates with business processes.

IoT Connected Logistics — Multi-Cloud Telemetry Platform

Telemetry then fans out across three processing paths: a real-time path (Stream Analytics or Kinesis) for geofence, route-deviation, threshold-breach, and anomaly alerts; a near-real-time path feeding control-tower and customer visibility; and a historical path landing in the lakehouse for trend analysis, maintenance planning, and sustainability reporting. The platform integrates with SAP for shipment and asset context, with customer tracking portals, with ServiceNow for asset and incident workflows, and with notification services. The same zero-trust principles apply down to the device: unique identity per device, mutual authentication, certificate lifecycle management, a quarantine path for anomalous devices, and segmentation between device ingestion, management, analytics, and business networks. Hot, warm, and cold data zones keep live dashboards fast while preserving years of history for claims and emissions analysis.

Each cloud’s ingestion path earns its own deep dive. AWS is the primary for fleet-scale vehicle data: devices connect through AWS IoT Core with its rules engine, IoT FleetWise collects vehicle signals, Device Defender watches for anomalies, and Kinesis with Managed Service for Apache Flink drives the real-time path into Timestream and the lakehouse.

AWS IoT — Fleet-Scale Telemetry Platform (Deep Dive)

Azure is the primary for operational and control-tower integration: IoT Hub and the Device Provisioning Service handle device identity and twins, Stream Analytics runs the geofence and threshold rules, Logic Apps push events into SAP and ServiceNow, and Azure Data Explorer holds the queryable time-series history.

Azure IoT — Control-Tower Telemetry Platform (Deep Dive)

Observability and SOC integration

A platform this large is only operable if it is observable end to end. Dynatrace is the strategic observability plane, tracing a single request from the user through the CDN and WAF, into cloud ingress, the application, the database, and downstream integrations — the same path the edge and security diagrams describe, now instrumented. Around that topology sit Real User Monitoring for web apps, synthetic monitoring for customer portals and control towers, infrastructure and Kubernetes observability, and cost and capacity dashboards. Cloud-native telemetry from Azure Monitor, Log Analytics, and CloudWatch feeds the same plane. On the security side, cloud audit logs plus Wiz, CrowdStrike, and WAF signals flow into a SIEM (Microsoft Sentinel) and on into SOC workflows, with automated incident creation and enrichment in ServiceNow against the CMDB.

Observability & SOC Integration

The outcome the business cares about is a closed loop: a degradation or an attack is detected, correlated, and turned into an enriched ServiceNow incident with the affected configuration item already attached, so the right team acts on context instead of a raw alert. Observability and security stop being separate consoles and become two views of the same telemetry, which is exactly what an estate spanning two clouds, four data centres, a global workforce, and a connected fleet needs.

Cost model and TCO

A reference architecture that cannot be costed is an academic exercise, so the design carries a budget envelope as a first-class artefact. The figures below are planning-grade estimates for a steady-state production estate running across four strategic regions in both Azure and AWS — expressed in USD per month, built bottom-up from the services each landing zone provisions, and meant to size a budget and frame FinOps conversations rather than to stand in for a vendor quote. They assume roughly one hundred applications live across the two clouds, reserved-instance and savings-plan commitments applied to steady-state compute, non-production environments scaled down outside business hours, and security and observability tooling priced at enterprise list less the discount a carrier of this size negotiates. Actual spend will move with traffic, device counts, data volumes, and the commercial terms struck with each provider; the value here is the shape of the spend — where the money concentrates and which levers move it — not a figure to the dollar.

Two characteristics of the model are worth calling out. First, application compute and the SAP landing zone together account for the largest share of the bill — a little under half of it — exactly where it should sit for a business whose value is in its applications and its SAP core rather than in undifferentiated platform plumbing. Second, the platform, edge, connectivity, and tooling lines are the price of running consistently and securely across two clouds and four data centres: dual circuits in every region, central inspection and posture management, and a single global edge are deliberate recurring costs the resilience and security requirements make non-negotiable rather than discretionary.

Cost area Drivers ~USD/month
Hybrid connectivity 8 ExpressRoute + 8 Direct Connect circuits (10 Gbps each) + gateways across 4 regions $45,000
Azure platform Firewalls, gateways, Bastion, DNS, Sentinel, Log Analytics, Key Vault HSM, Backup $60,000
AWS platform Network Firewall, Transit Gateway, NAT, GuardDuty, Security Hub, Control Tower, CloudWatch $45,000
Application compute & workloads 100+ applications across both clouds (web, app, API, batch, container tiers) $220,000
SAP landing zone HANA high-memory certified compute, HA across 2 AZs + asynchronous DR region $120,000
Data & integration platform Lakehouse, event streaming, analytics and BI compute and storage $85,000
IoT platform AWS IoT Core / Azure IoT Hub, streaming, time-series stores $40,000
Observability & security tooling Dynatrace, Wiz, CrowdStrike Falcon, Okta licences $95,000
Backup, DR & storage Geo-redundant backup, immutable archive, cross-region replication, object storage $35,000
Third-party edge Global CDN, authoritative DNS, WAF $25,000
TOTAL Steady-state production estate, 4 regions, dual-cloud ≈ $770,000/month (~$9.2M/year)

The model is not a fixed cost — it is an envelope the FinOps practice is expected to work against. The largest structural saving is commitment-based pricing: reserved instances and savings plans on the steady-state compute trim that base by roughly thirty per cent, which is why the compute lines assume committed rather than on-demand rates. On top of that sit operational levers the platform makes routine — autoscaling with a resilience floor so the estate never pays for idle headroom, scheduled shutdown of non-production outside business hours, continuous right-sizing driven by Dynatrace capacity signals, and storage lifecycle tiering that moves cold data down the cost curve automatically. Spend is made visible and accountable through tagging-driven showback and chargeback on the cost dashboards, so each team owns its consumption rather than the bill arriving as an undifferentiated lump, and the enterprise tooling agreements carry their own committed-volume discounts. One-time build and migration cost — discovery, landing-zone construction, the migration factory, and SAP cutover — is deliberately not folded into this run-rate; it is governed separately through the delivery roadmap and its waves so steady-state and programme economics never blur.

Bill of materials

Where the cost model says what the estate spends, the bill of materials says what the estate is — the resource inventory the subscription and account factories actually produce, and the concrete definition of what “done” looks like at the end of the build. It is deliberately expressed by landing zone and domain rather than as a flat resource list, because the value of the platform is that these resources arrive governed, repeatable, and identical across regions through code, not hand-built one ticket at a time. The counts below are the target-state footprint for the four-region dual-cloud design; per-application resources scale with the roughly one hundred workloads the onboarding factory vends, while the platform and shared-service rows are fixed regardless of how many applications land on top of them.

Landing zone / domain Key resources (count)
Azure platform 4 regional hub VNets, 4 Azure Firewall Premium, 4 Application Gateway WAF v2, 8 ExpressRoute gateways (+ backup VPN gateways), Microsoft Sentinel, Key Vault HSM, Log Analytics, Recovery Services backup vaults
Azure identity & management Identity, Connectivity, Management, and Security platform subscriptions; Entra Connect; Private DNS Resolver; Azure Monitor / Automation / Update Management
Azure workloads Separate production and non-production subscriptions vended per application (≈100 applications), each hub-peered, policy-governed, and baseline-enrolled
AWS platform 4 regional Transit Gateways, 4 AWS Network Firewall, Control Tower, Log Archive account (immutable S3 + Object Lock), Security Tooling account, GuardDuty + Security Hub org-wide
AWS network & shared services Inspection / ingress / egress VPCs per region, Direct Connect Gateways, Shared Network and Shared Services accounts, IAM Identity Center
AWS workloads Vended application accounts across Prod and Non-Prod OUs (≈100 applications), each TGW-attached, SCP-guarded, and baseline-enrolled
SAP landing zone HANA production across 2 AZs (HSR synchronous) + warm-standby HANA in the paired DR region (asynchronous), clustered ASCS/ERS, dedicated backup and monitoring
Data & integration platform Event Hubs / Kafka / Kinesis backbone, medallion lakehouse (raw / curated / governed + master-data band), data catalog, lineage and classification, analytics and BI
IoT platform AWS IoT Core (fleet telemetry) + Azure IoT Hub (control-tower telemetry), Kinesis / Stream Analytics streaming, Timestream and Azure Data Explorer time-series stores
Connectivity 8 ExpressRoute circuits + 8 Direct Connect circuits (10 Gbps, active-active BGP) across 4 regions, diverse carriers per region
Third-party edge Global CDN, authoritative DNS with global traffic management and failover, WAF with OWASP / bot / API / rate-limit policy
Shared SaaS & tooling Okta, Microsoft Entra ID, Wiz, CrowdStrike Falcon, Dynatrace, ServiceNow, Bitbucket, Microsoft Intune — operating horizontally across both clouds

Read together, the two tables close the loop between intent and economics. The bill of materials enumerates the building blocks the factories emit on demand; the cost model prices them at steady state and points at the levers that keep the run-rate honest. Both are living artefacts — the inventory grows as applications onboard through the waves, and the spend is reforecast against actuals each cycle — but holding the design to an explicit, planning-grade number from the outset is what turns “a secure multi-cloud foundation” from an aspiration into something the business can budget, govern, and operate with its eyes open.

Operating model and RACI

The six teams plus the Cloud Center of Excellence only deliver a stable estate if their responsibilities are unambiguous; the most common cause of a missed RTO is not a technology failure but two teams each assuming the other owned the decision. The operating model therefore pins three things explicitly. Support runs as follow-the-sun, 24×7, tiered L1 → L2 → L3: the ServiceNow service desk (L1) triages and runs standard runbooks, Cloud Operations (L2) owns operational restoration and incident command, and Cloud Platform Engineering or the relevant vendor (L3) handles deep platform and product engineering. Change runs in three lanes — standard (pre-approved, automated), normal (CAB-reviewed within published change windows), and emergency (post-implementation review) — every one of which is raised and recorded against the CMDB in ServiceNow, with manual approval gates before Staging and Production tied to the change record. Patching follows a monthly cadence with critical out-of-band releases, honouring the patch SLA of 7 days for critical and 30 days for high-severity vulnerabilities surfaced by Wiz and the cloud-native scanners.

The RACI below allocates the load-bearing activities across the six teams. The recurring pattern is deliberate: the CCoE is accountable for standards and guardrails but delegates execution, security holds identity and incident authority, the platform team owns the factories and the build path, and Cloud Operations carries day-two run. One accountable (A) owner per row keeps decisions unambiguous; R is shared where genuine joint delivery is required.

Activity CCoE Platform Eng Security & Identity Network Operations App Enablement
Landing-zone standards & reference architecture A R C C I C
Subscription / account vending (factory) A R C C I I
Policy / guardrail change (Policy + SCP) A R R C I I
Identity & PIM access approval C I A/R I I I
Network & firewall change I C C A/R I I
Application onboarding to the estate C C C I I A/R
Incident response & major-incident command I C A/R C R C
DR test execution & game-day A R R R R C
Cost management & FinOps A R I I R C
Patching & vulnerability remediation I R A I R C

Migration and onboarding waves

A landing zone is only worth building if the estate can actually be moved into it without stalling, and that movement has to be sequenced rather than improvised. The estate is populated through a migration factory: a repeatable discovery-to-cutover pipeline in which every application is assessed, dispositioned, scheduled into a wave, and admitted only once the wave ahead of it has proven its foundations. The work is organised into six waves over roughly twenty-four months, each with explicit entry and exit gates so that no wave inherits half-finished plumbing from the one before it. The early waves deliberately deliver platform and low-risk workloads first, building operational muscle and confidence before the customer-facing, data, and SAP estates — the genuinely business-critical tier — are touched. The roadmap diagram sequences this progression; the table below pins the scope and gating of each wave.

Delivery Roadmap — CAF Workstreams & Six Migration Waves over 24 Months

Wave Months Scope (representative) Entry criteria Exit criteria
W1 — Foundation and pilots 0–3 Landing zones, identity, hybrid connectivity, guardrails, and 2–3 pilot applications Design signed off Platform baseline live; DR Tier-0 tested
W2 — Shared services and low-risk internal 3–6 ~20 shared-services and low-risk internal applications Wave 1 exit achieved Operations runbooks live
W3 — Customer web and API 6–10 ~25 customer web and API workloads; third-party edge cutover Security gates green Edge live across both clouds
W4 — Data and integration 9–12 Lakehouse, streaming backbone, partner feeds Data governance ready Golden datasets served
W5 — SAP and high-criticality 12–18 SAP landing zone and remaining Tier-1 workloads HANA sizing confirmed SAP DR rehearsed
W6 — Optimisation and operating-model transition 18–24 Right-sizing, FinOps, handover to internal teams Estate stable Teams self-sufficient

Disposition is decided per application at discovery using the standard 6R model — rehost, replatform, refactor, repurchase, retain, or retire — so that each workload earns its place in a wave rather than being lifted wholesale. In practice most internal applications fall to rehost or replatform, taking the path of least friction onto the new platform; the customer-facing and data workloads are where refactoring concentrates, because cloud-native rebuild is what unlocks their scale and resilience targets; and a meaningful tail of legacy systems is retired outright rather than carried forward, shrinking the estate that the operating model ultimately has to run.

Architecture decision records

Reviewers should be able to see the trade-offs behind the design, not just its conclusions. Each load-bearing decision is therefore captured as an architecture decision record that names the alternative that was rejected and the reasoning that settled it — so the design can be interrogated, and so future teams understand which doors were deliberately closed and why. The records below are the ten decisions that shape the estate most; several of them, notably the dual-cloud posture and the split IoT platform, are direct consequences of the business mandate rather than free engineering choices, and the records make that provenance explicit.

ID Decision Alternative considered Rationale / trade-off
ADR-01 Dual-cloud landing zone across Azure and AWS Single-cloud consolidation Business mandate plus resilience and best-of-breed services; accepts higher operational complexity, mitigated by one common guardrail set across both clouds
ADR-02 Azure hub-and-spoke topology Azure Virtual WAN Greater control, lower cost, and team maturity at current scale; Virtual WAN to be revisited as the estate grows
ADR-03 AWS Transit Gateway with a central inspection VPC VPC peering mesh Central policy enforcement and clean scaling, avoiding the unmanageable sprawl of a full peering mesh
ADR-04 Okta as federation broker with Microsoft Entra ID as control plane Entra ID only Preserves the existing SaaS estate already standardised on Okta and brokers AWS federation cleanly
ADR-05 Third-party global edge for CDN, DNS, and WAF Per-cloud Azure Front Door plus CloudFront A single cross-cloud control point with health-checked failover between clouds, rather than two disjoint edges
ADR-06 SAP self-managed on certified IaaS RISE with SAP Retains control, leverages existing operations skills, and keeps integration close; RISE deferred, not ruled out
ADR-07 Split IoT — AWS IoT Core for fleet, Azure IoT Hub for control tower Single unified IoT platform Best-fit service per workload and consistent with the dual-cloud mandate
ADR-08 Terraform with Ansible as the IaC and configuration standard Native Bicep plus CloudFormation Cross-cloud consistency from one toolchain instead of two divergent native stacks
ADR-09 Factory-based vending — AFT plus an Azure subscription factory Manual provisioning Governed, fast, and repeatable account and subscription delivery within a business day
ADR-10 Centralised egress inspection per region Per-VNet and per-VPC firewalls One policy enforcement point per region, avoiding inconsistent rule sets scattered across every network

Risks, assumptions, issues and dependencies

A programme of this scope is governed against a live RAID register, reviewed continuously rather than written once and shelved. Risks are tracked with owners and mitigations; assumptions are stated so that, if they break, the impact is visible immediately; open issues are worked to closure; and external dependencies are surfaced early, because several of them — circuit delivery and SAP Basis capacity in particular — sit on the critical path and can move whole waves if they slip. The register below is the working view the programme governs against.

Type Item Impact Mitigation / owner
Risk Cross-cloud skills gap across delivery teams Slower delivery; operational errors Structured enablement and handover plan; CCoE
Risk Circuit-provider concentration in a region Correlated connectivity loss Diverse carriers per region; Network and Connectivity
Risk SAP migration complexity Tier-1 cutover delay or instability Early sizing and rehearsed failover; Platform plus SAP Basis
Risk Cost overrun against the budget envelope Programme funding pressure FinOps guardrails and budgets; CCoE
Risk IoT ingest spikes beyond plan Telemetry loss or back-pressure Autoscale and load test to 50,000 msg/sec; Platform
Risk Data-residency breach Regulatory and contractual exposure Lakehouse governance band enforcement; Security and Identity
Risk Tooling lock-in Reduced future flexibility Infrastructure-as-code and portability discipline; Platform
Assumption The four on-prem data centres persist as first-class regions Network and DR design depend on it Validated with infrastructure owners
Assumption The dual-cloud mandate is fixed Whole topology assumes it Confirmed with business sponsors
Assumption Workday remains the authoritative HR source Joiner-mover-leaver identity flow depends on it Confirmed with HR and Identity teams
Assumption Circuit lead times are met Wave 1 foundation timing depends on it Tracked against procurement milestones
Issue (open) Circuit procurement pending Blocks connectivity baseline Expedited ordering; Network and Connectivity
Issue (open) SAP sizing to be confirmed Gates Wave 5 entry Sizing exercise in progress; Platform plus SAP Basis
Issue (open) Country data-residency list to finalise Governance rules incomplete Legal and compliance review under way; Security and Identity
Dependency Carrier circuit delivery Foundation and connectivity External telecom carriers
Dependency SAP Basis team availability Wave 5 SAP migration Internal SAP Basis function
Dependency Okta and Workday integration Identity lifecycle automation Identity team plus vendors
Dependency Security-tooling licences Posture, EDR, and SIEM coverage Procurement and vendors

Delivery roadmap and acceptance

The work is sequenced as Cloud Adoption Framework workstreams so the engagement has clear governance: Strategy and Plan (portfolio discovery, dependency mapping, country and data-residency constraints, SAP assessment), Ready (landing-zone build, identity foundation, connectivity, guardrails, operations baseline), Adopt (migration in waves), and Govern and Manage (policy, cost, monitoring, backup, DR, incident response). Migration itself runs as the six waves detailed above — each gated and sequenced on the delivery-roadmap timeline — so the Adopt workstream proceeds through explicit checkpoints rather than as an open-ended lift.

The architecture is complete only when it demonstrates the acceptance criteria the business set: a fully defined Azure and AWS landing zone with clean platform/application separation; a zero-trust identity model covering office and home users with SSO, MFA, Conditional Access, and PIM; resilient hybrid connectivity from all four data centres with dual ExpressRoute and dual Direct Connect; multi-layer security spanning a third-party edge, cloud posture, EDR, observability, and policy-as-code; a tested HA and DR design for critical services including SAP; a scalable onboarding model for 100-plus applications; and a governance and operations model the internal teams can run after handover. Twenty-seven diagrams do not make a design correct on their own — but a design that can be drawn this precisely, decision by decision, is one a consulting partner can actually build, and one the logistics business can actually operate.

Multi-cloudLanding ZoneZero TrustAzureAWSEnterprise ArchitectureIoT
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments

Keep Reading