29

Observe, Back Up, Restore, and Reconstruct

Recover customer outcomes by rebuilding each state owner in dependency order, not by trusting one green dashboard.

Run it in the public monorepo

This course is built around the public Zheta Kubernetes Lab monorepo. The excerpt below is runnable source, not pseudocode.

Source: services/evidence/app.py

for receipt, event in BROKER.receive("evidence"):
                event["evidence_id"] = event.get("evidence_id") or __import__("hashlib").sha256(__import__("json").dumps(event, sort_keys=True).encode()).hexdigest()
                STORE.append(event)
                BROKER.acknowledge("evidence", receipt)

Code to reality

Declared intent
Receive broker deliveries, append idempotent evidence, acknowledge only after success, and expose tenant-scoped queries.
Interpreter
A background subscriber reads local HTTP-broker or SQS receipts; the SQL store deduplicates by evidence ID before acknowledgement.
Software effect
Append failure leaves a message available for redelivery; repeated delivery yields one durable event returned by an authenticated query.
Hardware effect
The evidence process consumes CPU for hashing and commits database pages to durable storage.
Observable evidence
Receipt and acknowledgement observations, forced redelivery, one stored evidence ID, authenticated organization query, and restart prove the contract.

Start with the people and the result they need

The source tables below remain the detailed contract. Begin with these customer paths:

  • D29-UC-01
    • Person: Support engineer
    • Job: Diagnose a failed generated-app action across services
    • Observable result: One trace joins customer request, logs, metrics, release, actor, and owned records without exposing secrets
  • D29-UC-02
    • Person: Disaster-recovery commander
    • Job: Restore durable data and reconstruct the platform in an isolated account
    • Observable result: Restored tenant and artifact pass integrity and lifecycle probes within RPO/RTO

Turn each customer job into a testable story

Now turn each customer job into a story with a result that an engineer can check:

  • D29-US-01
    • Story: As a support engineer, I want tenant-scoped traces connected to releases and services, so that I can diagnose without broad data access
    • Observable acceptance: Accepted/denied queries record actor, tenant, time window, trace, release, service, result, environment, and audit ID
  • D29-US-02
    • Story: As a disaster-recovery commander, I want a rehearsed bottom-up reconstruction, so that backup claims become customer-visible recovery
    • Observable acceptance: Dossier contains recovery point, Terraform/Git revisions, restored IDs, integrity checks, RPO/RTO, affected replay, unaffected control, and run

Add real state and observable proof

Finally trace each story through the system that owns its state and the evidence that proves the outcome:

  • D29-FLOW-01
    • Trigger: Support receives a failed publish evidence ID
    • Responsible systems: OpenTelemetry instrumentation/collector, metrics/log/trace stores, Forge services, release/evidence stores
    • Authoritative state: Each service store for domain state; telemetry stores for observations; provider audit for access
    • Owned record: RecoveryPoint
    • Observable evidence: Actor, tenant, trace, release, observations, owner-directed action, recovered response, environment, time, and audit ID
    • Failure signal: Broken correlation, stale signal, secret/tenant leakage, wrong release, or failed replay
  • D29-FLOW-02
    • Trigger: Scheduled isolated recovery rehearsal begins
    • Responsible systems: Backup service, Aurora/S3/KMS, Terraform, EKS, Argo bootstrap, GitOps, Kubernetes, probe runner
    • Authoritative state: Backup catalog/data stores, Terraform state/Git, AWS/Kubernetes APIs, application/evidence stores
    • Owned record: RestoreRun
    • Observable evidence: Recovery point, restored resources, revisions, identities, integrity, probes, RPO/RTO, production control, environment, time, and run ID
    • Failure signal: Missing key/snapshot, integrity mismatch, stale state, unavailable API, unready workload, wrong revision, or failed customer probe

The enterprise problem and today’s slice

Enterprise problem: Metrics can show a healthy pod while customer data is unrecoverable, and a backup can exist while restore credentials, keys, or procedures fail. Whole-course context: The incoming runtime scales workloads and machines with bounded evidence; today protects its durable state and operational knowledge. Today’s slice: We correlate metrics, logs, and traces; back up Aurora and object artifacts; rehearse restore into isolated staging; and reconstruct VPC, EKS, Argo CD, workloads, and customer flow from authoritative sources. End-of-day evidence: Recovery point, restore resource IDs, Git/Terraform revisions, cluster and workload identities, positive/negative customer probes, recovery times, environment, timestamp, run, and trace IDs form a disaster-recovery dossier. Still unsolved: Production launch approval and live traffic remain deferred.

Customer use cases

A backup is useful only if an accountable operator can restore a consistent customer workflow within objectives. Recovery point objective (RPO) bounds tolerable data loss; recovery time objective (RTO) bounds restoration time.

Use case IDActorCustomer jobSuccess outcomeDenial or recovery evidence
D29-UC-01Support engineerDiagnose a failed generated-app action across servicesOne trace joins customer request, logs, metrics, release, actor, and owned records without exposing secretsUnauthorized tenant trace access is denied while scoped support access succeeds
D29-UC-02Disaster-recovery commanderRestore durable data and reconstruct the platform in an isolated accountRestored tenant and artifact pass integrity and lifecycle probes within RPO/RTOCorrupt/incomplete restore is rejected; source production remains unaffected as positive control

Actor-centred user stories

Observability and recoverability are related but not interchangeable: telemetry explains behavior, while backup and declarative sources recreate state. These stories require both.

Story IDUse case IDsUser storyObservable acceptance conditions
D29-US-01D29-UC-01As a support engineer, I want tenant-scoped traces connected to releases and services, so that I can diagnose without broad data accessAccepted/denied queries record actor, tenant, time window, trace, release, service, result, environment, and audit ID
D29-US-02D29-UC-02As a disaster-recovery commander, I want a rehearsed bottom-up reconstruction, so that backup claims become customer-visible recoveryDossier contains recovery point, Terraform/Git revisions, restored IDs, integrity checks, RPO/RTO, affected replay, unaffected control, and run

End-to-end product flows

Recovery must start from a declared customer impact and proceed through substrate, API, state, workloads, then product evidence. Restoring only one database is not a complete application recovery.

Flow IDUse case IDsPathTriggerNumbered stepsTerminal evidence
D29-FLOW-01D29-UC-01HappySupport receives a failed publish evidence ID1. Authorize tenant scope. 2. Resolve trace and release. 3. Inspect metrics, logs, spans, and owned records. 4. Identify failing boundary. 5. Repair through its owner. 6. Replay and compare.Actor, tenant, trace, release, observations, owner-directed action, recovered response, environment, time, and audit ID
D29-FLOW-02D29-UC-02RecoveryScheduled isolated recovery rehearsal begins1. Select immutable recovery point. 2. Create isolated network and data targets. 3. Restore database/artifacts and verify integrity. 4. Recreate EKS from Terraform. 5. Bootstrap Argo CD. 6. Reconcile digest from Git. 7. Run positive and denied lifecycle probes. 8. Measure RPO/RTO and destroy rehearsal safely.Recovery point, restored resources, revisions, identities, integrity, probes, RPO/RTO, production control, environment, time, and run ID

The minimal recovery model joins accountable action to a customer-observable proof.

System design derived from the flows

Different desired-state owners require a bottom-up order: AWS substrate, intended EKS API, Terraform mapping, Kubernetes controllers, GitOps revision, then customer response. A green upper layer cannot override a failed lower layer.

Use case IDEntry pointResponsible servicesAuthoritative storeFailure evidence
D29-UC-01Evidence/trace ID and scoped support portalOpenTelemetry instrumentation/collector, metrics/log/trace stores, Forge services, release/evidence storesEach service store for domain state; telemetry stores for observations; provider audit for accessBroken correlation, stale signal, secret/tenant leakage, wrong release, or failed replay
D29-UC-02Approved recovery runbookBackup service, Aurora/S3/KMS, Terraform, EKS, Argo bootstrap, GitOps, Kubernetes, probe runnerBackup catalog/data stores, Terraform state/Git, AWS/Kubernetes APIs, application/evidence storesMissing key/snapshot, integrity mismatch, stale state, unavailable API, unready workload, wrong revision, or failed customer probe

The diagram climbs from stored recovery point through physical/cloud substrate to controllers, workload state, and customer evidence.

SRP keeps telemetry, backup, infrastructure, delivery, and domain restoration under separate owners; DRY rebuilds from the same modules and base. IoC/DI switches restored adapters, MVC preserves domain checks during replay, and PubSub queues are reconstructed from authoritative job state rather than treated as databases.

Data model and ownership

Backups cannot merge provider metadata, runtime state, generated-app rows, and source-enterprise data into one unscoped archive. Each owner defines retention, encryption, restore, export, and deletion.

Generated-application database: Required in this slice — isolated restore proves generated-app tenant data, constraints, authorization predicates, and deletion independently of provider records.

Record or entityStore and ownerPrimary keyForeign key or opaque referenceTenant keyMaterial constraintLifecycle and deletionUse case IDs
RecoveryPointBackup catalog, owned by Data Reliabilityrecovery_point_idOpaque Aurora snapshot, S3 version, KMS key, schema, and source refsenvironment_idImmutable, encrypted, integrity/checksum, retention, and restore role requiredCreate, verify, retain/lock, expire by policy after legal holdD29-UC-02
RestoreRunEvidence Store, owned by Operations Assurancerestore_run_idOpaque recovery point, Terraform, cluster, release, and trace refsenvironment_idIsolated target, no source mutation, positive/negative probes, RPO/RTO requiredPlan, execute, seal, review, clean target, retain dossierD29-UC-01, D29-UC-02
RestoredTenantRestored generated-app database, owned by generated applicationapp_tenant_idOpaque original tenant and recovery point refsapp_tenant_idPK/FK, uniqueness, row authorization, and deletion policy pass integrity checksRestore in isolation, validate/export proof, erase rehearsal copyD29-UC-02

The durable recovery point, run dossier, and restored tenant now retain separate authority and deletion outcomes.

Run read-only evidence checks first

Mutation before observation can destroy the clues needed to select the right owner. Run this labelled snippet from the public monorepo using stable paths infra/stacks/prod, argocd/applicationsets/forge-prod.yaml, and scripts/smoke-product.sh.

: "${AWS_PROFILE:?set the approved AWS profile}" "${AWS_REGION:?set the intended AWS region}" "${EXPECTED_ACCOUNT_ID:?set the intended 12-digit AWS account}"
actual_account="$(aws --profile "$AWS_PROFILE" --region "$AWS_REGION" sts get-caller-identity --query Account --output text)"
[ "$actual_account" = "$EXPECTED_ACCOUNT_ID" ] || { echo "AWS account mismatch" >&2; exit 1; }
terraform -chdir=infra/stacks/prod state list
aws --profile "$AWS_PROFILE" --region "$AWS_REGION" eks update-kubeconfig --name zheta-forge-prod --alias zheta-forge-prod
aws --profile "$AWS_PROFILE" --region "$AWS_REGION" eks describe-cluster --name zheta-forge-prod --query 'cluster.status'
kubectl --context zheta-forge-prod get nodes
kubectl --context zheta-forge-prod -n argocd get application forge-prod -o wide
test -n "${FORGE_URL:?set FORGE_URL to the explicit reachable production control-plane URL}"
FORGE_URL="$FORGE_URL" FORGE_TOKEN="${FORGE_TOKEN:?set the explicit bearer token}" ./scripts/smoke-product.sh

The current Terraform module actually declares three Aurora clusters, versioned encrypted S3, a KMS-encrypted AWS Backup vault, daily backup plan, and production 35-day retention. It does not prove a restore; launch remains blocked until a separate-account restore run records integrity, authorization, RPO, and RTO.

Effect fieldWhat happens
Declared intentObserve infrastructure mapping, provider reality, API/runtime, GitOps, and customer path independently
InterpreterTerraform, AWS API, Kubernetes API, Argo CD resources, and Forge HTTP server
Software effectNo desired state changes; evidence gains fresh boundary observations
Hardware effectAPIs and product use small CPU/network capacity to answer
EvidenceState addresses, cluster status, nodes, revision/health, response, freshness, environment, run, and trace

Three authorization planes and lifecycle rule

Support access to provider evidence does not grant runtime secret access or generated-app row access. Restore roles are temporary, account-scoped, audited, and independently revocable.

Decision rule: restore source-owned enterprise data only through its owner; validate generated-app authorization before use; delete rehearsal data and runtime after proof while retaining the immutable recovery dossier.

Key takeaways

Recovery is a customer workflow reconstructed across multiple owners.

  • Observe bottom-up before mutation or state surgery.
  • Test restore, integrity, authorization, RPO, and RTO in isolation.
  • Metrics, logs, traces, backups, Terraform, Git, and controllers complement rather than replace one another.

Checklist

The platform is recoverable only when the rehearsal ends in customer evidence.

  • [ ] Positive and denied support queries preserve tenant scope
  • [ ] Recovery point, key, schema, and checksum are verified
  • [ ] Reconstruction follows substrate to API to state to workload to customer
  • [ ] Rehearsal copy is erased and dossier retained