Deliverables

The curriculum covers what an architect should know. This covers what an architect actually hands over: 55 artifacts, each with a worked example, a note on when it is worth producing, who reads it, and the ways it usually goes wrong. Filter by the artifact's type, the kind of engagement that calls for it, the stack or industry it is drawn against, or the audience it is written for.

Identify the deliverable → 42 diagrams, shown one at a time with the answer withheld. Nothing to submit.

22 of 55 deliverables shown.

flowchart LR
  crm["CRM"]
  oms["Order Mgmt"]
  erp["ERP"]
  wms["WMS"]
  bill["Billing<br/><i>mainframe</i>"]
  dw[("Warehouse")]
  ptnr["Partner"]

  crm -->|"I-01 · REST · on demand"| oms
  oms -->|"I-02 · SFTP CSV · nightly"| erp
  oms -->|"I-03 · MQ · near real time"| wms
  wms -->|"I-04 · REST · on demand"| oms
  erp -->|"I-05 · flat file · nightly"| bill
  bill -->|"I-06 · DB link · nightly"| dw
  oms -->|"I-07 · CDC · continuous"| dw
  ptnr -->|"I-08 · AS2 EDI · hourly"| oms
  oms -->|"I-09 · AS2 EDI · hourly"| ptnr
Structural View

Integration Landscape Diagram

Every interface between systems, with its mechanism, direction, frequency and owner — the artifact that tells you what a migration will actually break.

flowchart LR
  commit(["commit to main"]) --> build

  subgraph ci["Continuous Integration"]
    direction TB
    build["build<br/><i>pinned deps, hermetic</i>"]
    unit["unit tests<br/><i>&lt; 4 min</i>"]
    scan["SAST + dependency<br/>+ secret scan"]
    sign["sign artifact<br/>+ emit SBOM"]
    build --> unit --> scan --> sign
  end

  sign --> reg[("artifact registry<br/><i>immutable, digest-addressed</i>")]

  subgraph cd["Continuous Delivery"]
    direction TB
    dev["deploy dev<br/><i>auto</i>"]
    ctest["contract tests"]
    stage["deploy staging<br/><i>auto</i>"]
    nft["performance +<br/>resilience suite"]
    dev --> ctest --> stage --> nft
  end

  reg --> dev
  nft --> gate{"release gate<br/><i>automated checks +<br/>change record</i>"}
  gate -->|"pass"| canary["canary 5%<br/><i>15 min bake</i>"]
  gate -->|"fail"| stop(["blocked"])
  canary --> analyse{"error rate and<br/>latency within SLO?"}
  analyse -->|"yes"| full["progressive rollout<br/><i>25% → 50% → 100%</i>"]
  analyse -->|"no"| rollback(["automatic rollback"])
Behavioural View

CI/CD Pipeline Diagram

The path from commit to production as ordered stages, showing what each one proves, what it produces, and where a human is still in the loop.

stateDiagram-v2
  [*] --> Pending: order placed
  Pending --> Authorised: payment approved
  Pending --> Rejected: payment declined
  Pending --> Expired: no response in 24h
  Authorised --> Picking: stock allocated
  Authorised --> Cancelled: customer cancels
  Picking --> Shipped: consignment handed to carrier
  Picking --> Backordered: stock unavailable
  Backordered --> Picking: stock replenished
  Backordered --> Cancelled: customer cancels
  Shipped --> Delivered: carrier confirms
  Shipped --> Lost: no scan in 14 days
  Delivered --> Returned: return accepted
  Rejected --> [*]
  Expired --> [*]
  Cancelled --> [*]
  Delivered --> [*]
  Returned --> [*]
  Lost --> [*]
Behavioural View

State Machine Diagram

The legal states of one entity and the events that move it between them, which is where illegal transitions become visible.

flowchart LR
  a["Idea accepted<br/><i>work 2d</i>"]
  w1(["wait 9d<br/>backlog"])
  b["Refinement<br/><i>work 1d</i>"]
  w2(["wait 4d<br/>awaiting design"])
  c["Build<br/><i>work 5d</i>"]
  w3(["wait 3d<br/>awaiting review"])
  d["Code review<br/><i>work 0.5d</i>"]
  w4(["wait 6d<br/>awaiting test env"])
  e["Test<br/><i>work 2d</i>"]
  w5(["wait 11d<br/>awaiting release window"])
  f["Release<br/><i>work 0.5d</i>"]

  a --> w1 --> b --> w2 --> c --> w3 --> d --> w4 --> e --> w5 --> f
  f --> tot["Work 11d &middot; Wait 33d<br/>Lead time 44d &middot; Flow efficiency 25%"]
Behavioural View

Value Stream Map

Every step from request to delivery with its work time and its wait time, exposing that most of the elapsed time is queueing.

Flow Metrics Discovery
flowchart LR
  src1[("Orders DB")] --> cdc["CDC connector"]
  cdc --> t1[["orders.raw<br/><i>12 parts · key: orderId<br/>retain 7d</i>"]]
  src2["Clickstream"] --> t2[["events.clicks<br/><i>36 parts · key: sessionId<br/>retain 3d</i>"]]

  t1 --> p1["Normalise<br/><i>stateless</i>"]
  p1 --> t3[["orders.clean<br/><i>12 parts · key: orderId<br/>compacted</i>"]]
  t3 --> p2["Enrich + join<br/><i>stateful · 30 min window</i>"]
  t2 --> p2
  p2 --> st[("RocksDB state<br/><i>checkpoint 60s</i>")]
  p2 --> t4[["orders.enriched<br/><i>12 parts · retain 30d</i>"]]
  p2 --> dlq[["orders.dlq"]]

  t4 --> sink1["Serving store"]
  t4 --> sink2["Lakehouse sink<br/><i>5 min commit</i>"]
Data View

Streaming Topology Diagram

Topics, partitions, processors and state stores in one picture, with the retention and keying decisions that determine whether it can be replayed.

flowchart TB
  root["Organisation Root<br/><i>policy: deny unapproved regions</i>"]

  subgraph plat["Platform"]
    direction TB
    ident["Identity<br/><i>directory, privileged access</i>"]
    conn["Connectivity<br/><i>hub VNet/VPC, firewall, DNS, VPN</i>"]
    mgmt["Management<br/><i>logs, backup, monitoring</i>"]
  end

  subgraph land["Landing Zones"]
    direction TB
    subgraph corp["Corporate"]
      p1["Prod A<br/><i>spoke</i>"]
      n1["Non-Prod A<br/><i>spoke</i>"]
    end
    subgraph online["Internet-Facing"]
      p2["Prod B<br/><i>spoke</i>"]
      n2["Non-Prod B<br/><i>spoke</i>"]
    end
  end

  sandbox["Sandbox<br/><i>spend cap, no connectivity, auto-expire</i>"]
  decom["Decommissioned<br/><i>deny all</i>"]

  root --> plat
  root --> land
  root --> sandbox
  root --> decom
  conn --- p1
  conn --- n1
  conn --- p2
  conn --- n2
  mgmt -.->|"diagnostics forwarded"| land
  ident -.->|"roles and groups"| land
Deployment & Infrastructure View

Cloud Landing Zone Diagram

The account, network, identity and policy scaffolding every future workload will be dropped into, drawn before the first workload exists.

Landing Zones Design
flowchart TB
  users(["Users"]) --> dns["Global DNS<br/><i>latency routing + health checks</i>"]

  subgraph r1["Region: primary"]
    direction TB
    lb1["Load Balancer<br/><i>public</i>"]
    subgraph az1["Zone A"]
      n1["Node Pool<br/><i>api ×3, worker ×2</i>"]
    end
    subgraph az2["Zone B"]
      n2["Node Pool<br/><i>api ×3, worker ×2</i>"]
    end
    subgraph az3["Zone C"]
      n3["Node Pool<br/><i>api ×2, worker ×1</i>"]
    end
    db1[("Primary DB<br/><i>synchronous replica in Zone B</i>")]
    lb1 --> n1
    lb1 --> n2
    lb1 --> n3
    n1 --> db1
    n2 --> db1
    n3 --> db1
  end

  subgraph r2["Region: secondary"]
    direction TB
    lb2["Load Balancer<br/><i>warm</i>"]
    n4["Node Pool<br/><i>api ×2, scaled down</i>"]
    db2[("Read Replica<br/><i>asynchronous — RPO 30s</i>")]
    lb2 --> n4 --> db2
  end

  dns --> lb1
  dns -.->|"failover only"| lb2
  db1 -.->|"async replication"| db2
Deployment & Infrastructure View

Deployment Diagram

Which runtime artifact runs on which infrastructure, in which zone and region, and what fails when one of those boundaries fails.

flowchart TB
  subgraph pri["Primary site"]
    direction TB
    p1["Application tier"]
    p2[("Transactional DB")]
    p3[("Object storage")]
    p4["Secrets + config"]
  end
  subgraph dr["Recovery site — warm"]
    direction TB
    d1["Application tier<br/><i>scaled to 0 · IaC ready</i>"]
    d2[("DB replica<br/><i>async · lag &lt; 30s</i>")]
    d3[("Storage replica<br/><i>cross-region · 15 min</i>")]
    d4["Secrets replicated"]
  end

  p2 ==>|"async"| d2
  p3 ==>|"async"| d3
  p4 ==>|"sync"| d4

  subgraph run["Recovery sequence — tested 2026-05-18"]
    direction TB
    s1["1. Declare · 5 min"]
    s2["2. Promote replica · 8 min"]
    s3["3. Scale app tier · 6 min"]
    s4["4. Repoint DNS · 5 min<br/><i>TTL 60s</i>"]
    s5["5. Verify + reconcile · 12 min"]
    s1 --> s2 --> s3 --> s4 --> s5
  end
  dr --> run
  run --> res(["Restored — measured RTO 36 min"])
Deployment & Infrastructure View

Disaster Recovery Topology

What is replicated where, in what order recovery happens, and the tested time each step takes.

flowchart LR
  subgraph e1["Ephemeral / PR"]
    direction TB
    a1["scaled to 1<br/>mocked externals<br/>synthetic data<br/><i>proves: it builds and unit-passes</i><br/>auto-destroy 24h"]
  end
  subgraph e2["Dev"]
    direction TB
    a2["shared<br/>real internal deps<br/>synthetic data<br/><i>proves: integration wiring</i><br/>anyone deploys"]
  end
  subgraph e3["Staging"]
    direction TB
    a3["prod-shaped topology<br/>real deps · sandbox externals<br/>masked prod-like data<br/><i>proves: contracts + performance</i><br/>pipeline only"]
  end
  subgraph e4["Production"]
    direction TB
    a4["full scale · multi-AZ<br/>real data<br/><i>proves: nothing — it serves</i><br/>pipeline + gate"]
  end
  e1 --> e2 --> e3 --> e4
  note["Same artifact promoted throughout.<br/>Config differs; the image digest does not."]
Deployment & Infrastructure View

Environment Topology

Which environments exist, what each one proves, what data it holds and who may deploy to it.

flowchart TB
  subgraph prod["Cluster: prod-eu (regional, 3 AZ)"]
    direction TB
    cp["Control plane<br/><i>managed · private endpoint</i>"]
    subgraph pools["Node pools"]
      direction LR
      np1["system<br/><i>taint: CriticalAddonsOnly</i>"]
      np2["general<br/><i>3–30 nodes · spot 40%</i>"]
      np3["memory<br/><i>taint: workload=memory</i>"]
      np4["gpu<br/><i>taint: workload=gpu</i>"]
    end
    subgraph ns["Namespaces"]
      direction LR
      n1["team-orders<br/><i>quota · NetworkPolicy<br/>default-deny</i>"]
      n2["team-pricing<br/><i>quota · NetworkPolicy</i>"]
      n3["platform<br/><i>mesh · ingress · logging</i>"]
    end
    cp --- pools
    pools --- ns
  end
  subgraph nonprod["Cluster: nonprod-eu"]
    direction TB
    x1["shared node pool<br/><i>spot 90%</i>"]
  end
  reg[("Image registry<br/><i>signed images only</i>")] --> prod
  reg --> nonprod
  gitops["GitOps reconciler"] -.->|"applies desired state"| prod
Deployment & Infrastructure View

Kubernetes Cluster Topology

How many clusters, split by what, which node pools exist and what isolates one tenant from another.

flowchart TB
  u(["Users"]) --> gslb["Global traffic manager<br/><i>health + latency routing</i>"]

  subgraph ra["Region A — write primary"]
    direction TB
    a1["Edge + API"]
    a2["Services"]
    a3[("Primary DB<br/><i>accepts writes</i>")]
    a1 --> a2 --> a3
  end

  subgraph rb["Region B — read + standby"]
    direction TB
    b1["Edge + API"]
    b2["Services"]
    b3[("Replica<br/><i>read only · lag &lt; 2s</i>")]
    b1 --> b2 --> b3
  end

  gslb -->|"reads: nearest"| a1
  gslb -->|"reads: nearest"| b1
  gslb -->|"writes: always A"| a1
  b2 -.->|"write forwarding<br/>+45ms"| a2
  a3 ==>|"async replication"| b3
  arb{{"Failover arbitration<br/><i>manual promote · documented<br/>RPO &le; 2s · RTO 15 min</i>"}}
  arb -.-> a3
  arb -.-> b3
Deployment & Infrastructure View

Multi-Region Topology

How many regions serve traffic, where writes are allowed, how data converges, and what the split-brain answer is.

flowchart TB
  inet(["Internet"])
  dc["Corporate Data Centre<br/><i>10.0.0.0/8</i>"]

  subgraph hub["Hub — 10.100.0.0/16"]
    direction TB
    fw["Egress Firewall<br/><i>FQDN allow-list</i>"]
    vpn["VPN / Direct Link<br/><i>BGP</i>"]
    dns["Private DNS Resolver"]
  end

  subgraph spokeA["Spoke: Prod — 10.101.0.0/16"]
    direction TB
    pub["Public Subnet<br/><i>10.101.0.0/24 — ingress LB only</i>"]
    app["App Subnet<br/><i>10.101.10.0/23 — no public IPs</i>"]
    data["Data Subnet<br/><i>10.101.20.0/24 — private endpoints</i>"]
    pub --> app --> data
  end

  subgraph spokeB["Spoke: Non-Prod — 10.102.0.0/16"]
    appn["App Subnet<br/><i>10.102.10.0/23</i>"]
  end

  inet -->|"443 only"| pub
  app -->|"all egress"| fw --> inet
  appn --> fw
  dc <-->|"BGP"| vpn
  vpn --- spokeA
  vpn --- spokeB
  spokeA x--x spokeB
Deployment & Infrastructure View

Network Topology Diagram

Segments, address ranges, routes and the control points between them — the view that says what can reach what at layer three.

Networking Design
flowchart LR
  subgraph who["Identities"]
    direction TB
    dev(["Developers<br/><i>group</i>"])
    sre(["SRE<br/><i>group</i>"])
    aud(["Auditors<br/><i>group</i>"])
    wl["Workload Identity<br/><i>order-api</i>"]
    ci["Pipeline Identity<br/><i>deploy-prod</i>"]
  end

  subgraph roles["Roles"]
    direction TB
    r1["Reader<br/><i>standing</i>"]
    r2["Operator<br/><i>standing</i>"]
    r3["Break-Glass Admin<br/><i>JIT — 60 min, approved, logged</i>"]
    r4["Deployer<br/><i>pipeline only</i>"]
    r5["Data Reader — Masked<br/><i>no raw PII</i>"]
  end

  subgraph what["Resources"]
    direction TB
    a1["Prod Compute"]
    a2["Prod Data Store"]
    a3["Key Vault"]
    a4["Audit Logs<br/><i>append-only</i>"]
  end

  dev --> r1 --> a1
  dev --> r5 --> a2
  sre --> r2 --> a1
  sre --> r3
  r3 --> a1
  r3 --> a2
  aud --> r1 --> a4
  wl --> r5
  wl --> a3
  ci --> r4 --> a1
Security View

IAM Role Model

Which identities may do what to which resource, expressed through roles rather than by naming people, so that access can be reviewed.

flowchart TB
  hsm[("HSM / Key Service<br/><i>root of trust · FIPS 140-2 L3</i>")]
  cmk["Customer Master Key<br/><i>per environment · rotate 1y</i>"]
  dek["Data Encryption Keys<br/><i>per dataset · rotate 90d</i>"]

  hsm --> cmk -->|"wraps"| dek

  subgraph vault["Secret Store"]
    direction TB
    v1["Static secrets<br/><i>rotate 90d</i>"]
    v2["Dynamic credentials<br/><i>DB · TTL 1h</i>"]
    v3["PKI issuer<br/><i>mTLS certs · TTL 24h</i>"]
  end
  cmk -->|"encrypts vault at rest"| vault

  subgraph wl["Workloads"]
    direction TB
    w1["Service A<br/><i>workload identity</i>"]
    w2["Pipeline<br/><i>OIDC federation</i>"]
  end

  w1 -->|"attests identity — no stored secret"| vault
  w2 -->|"short-lived token — no stored secret"| vault
  vault -->|"lease · auto-renew · revocable"| w1
  dek -->|"envelope decrypt"| w1
  audit[("Audit log<br/><i>every issue and revoke</i>")]
  vault --> audit
Security View

Key & Secret Management Diagram

Where keys and secrets live, what wraps what, how workloads get them without a stored credential, and how rotation actually happens.

flowchart TB
  s(["Alert: order submit p99 > 900 ms<br/>for 5 min"])
  s --> c1["1. Confirm scope<br/><i>one region or global?</i>"]
  c1 --> q1{"Global?"}
  q1 -->|"no"| a1["2a. Check that region's<br/>dependency health"]
  q1 -->|"yes"| a2["2b. Check shared dependencies:<br/>DB, cache, identity"]
  a1 --> q2{"Region-local cause?"}
  q2 -->|"yes"| m1["3. Shift traffic away<br/><i>runbook OPS-04</i>"]
  q2 -->|"no"| a2
  a2 --> q3{"DB CPU > 80%<br/>or replication lag > 10s?"}
  q3 -->|"yes"| m2["4. Enable read-path cache bypass=off<br/>+ raise connection limit<br/><i>flag: cache.aggressive</i>"]
  q3 -->|"no"| q4{"Recent deploy<br/>in last 60 min?"}
  q4 -->|"yes"| m3["5. Roll back<br/><i>runbook OPS-01</i>"]
  q4 -->|"no"| esc(["6. Escalate to<br/>Order team on-call<br/><i>stop investigating</i>"])
  m1 --> v["7. Verify p99 recovers<br/>within 10 min"]
  m2 --> v
  m3 --> v
  v --> q5{"Recovered?"}
  q5 -->|"yes"| done(["Close · record in incident log"])
  q5 -->|"no"| esc
Governance Artifact

Operational Runbook

A specific, tested procedure for one alert — what to check, in what order, what to do, and when to stop and escalate.

flowchart TB
  t1["T-7d · Dry run in staging<br/><i>full rehearsal, timed</i><br/>owner: Delivery"]
  t2["T-1d · Freeze changes · verify backups<br/>confirm rota and bridge<br/>owner: Ops"]
  t3["T-0 00:00 · Enable read-only on legacy<br/>owner: Ops"]
  t4["T-0 00:15 · Final delta migration<br/><i>est 90 min · checkpoint at 60</i><br/>owner: Data"]
  t5["T-0 01:45 · Reconcile counts + checksums<br/>owner: Data"]
  g1{"T-0 02:15 · GO / NO-GO<br/><i>criteria: 100% row match,<br/>0 critical defects, all owners present</i>"}
  t6["T-0 02:30 · Repoint DNS + feature flag<br/><i>TTL pre-lowered to 60s</i><br/>owner: Platform"]
  t7["T-0 02:45 · Smoke suite + 10 manual journeys<br/>owner: QA"]
  g2{"T-0 03:30 · Accept or roll back"}
  t8["T-0 03:30 · Open to 10% traffic<br/>owner: Platform"]
  t9["T-0 06:00 · 100% traffic<br/>owner: Platform"]
  t10["T+24h · Hypercare ends<br/>legacy kept read-only 30d"]
  rb(["ROLLBACK · revert DNS<br/>re-enable legacy writes<br/><i>est 20 min</i>"])
  pnr["POINT OF NO RETURN<br/><i>after first write to new system<br/>rollback needs reverse migration</i>"]

  t1 --> t2 --> t3 --> t4 --> t5 --> g1
  g1 -->|"no-go"| rb
  g1 -->|"go"| t6 --> t7 --> g2
  g2 -->|"roll back"| rb
  g2 -->|"accept"| t8 --> t9 --> t10
  t8 -.-> pnr
Planning Artifact

Cutover Plan

The hour-by-hour sequence of go-live, with owners, checkpoints, the rollback decision point and the moment rollback stops being possible.

flowchart LR
  subgraph w0["Wave 0 — Foundation"]
    direction TB
    f1["Landing zone"]
    f2["Connectivity + DNS"]
    f3["Identity federation"]
    f4["Observability + backup"]
  end

  subgraph w1["Wave 1 — Prove it (6 apps)"]
    direction TB
    a1["Internal wiki<br/><i>rehost</i>"]
    a2["Reporting portal<br/><i>rehost</i>"]
    a3["Batch scheduler<br/><i>replatform</i>"]
  end

  subgraph w2["Wave 2 — Bulk (34 apps)"]
    direction TB
    b1["Departmental apps<br/><i>rehost ×26</i>"]
    b2["Shared services<br/><i>replatform ×8</i>"]
  end

  subgraph w3["Wave 3 — Hard cases (9 apps)"]
    direction TB
    c1["Order management<br/><i>refactor</i>"]
    c2["Data warehouse<br/><i>replatform</i>"]
    c3["Partner gateway<br/><i>refactor</i>"]
  end

  subgraph w4["Wave 4 — Exit"]
    direction TB
    d1["Mainframe interfaces<br/><i>replace</i>"]
    d2["Data centre exit<br/><i>contract ends Q3</i>"]
  end

  w0 -->|"platform accepted<br/>by security + ops"| w1
  w1 -->|"runbook proven<br/>rollback rehearsed"| w2
  w2 -->|"shared services live<br/>latency measured"| w3
  w3 -->|"last dependency<br/>severed"| w4
Planning Artifact

Migration Wave Plan

Which applications move in which batch, in what order, and what the dependency between batches actually is.