Building a Comprehensive Infrastructure Snapshot: JADA Multi-Tenant Architecture v1.0
When you're managing three production domains (queenofsandiego.com, sailjada.com, salejada.com) with distributed cloud infrastructure, a single misconfiguration or code reversion can cascade across multiple systems. This post details how we built a complete infrastructure snapshot of the entire JADA ecosystem—capturing state across AWS S3, Lambda, CloudFront, Route53, DynamoDB, and local Google Apps Script projects—ensuring we can recover from operational issues without token waste or repeated rebuild cycles.
The Problem: Infrastructure Sprawl Without Recovery Points
The JADA infrastructure had grown organically across multiple AWS services without formalized snapshots. When code changes were reverted or configurations drifted, there was no single source of truth to restore from. The cost: repeated debugging, token consumption on recreating lost work, and uncertainty about which version of code was actually deployed.
We needed a v1.0 snapshot that captured:
- All S3 bucket contents (45 buckets, multiple terabytes)
- Lambda function code and environment variables (21 functions)
- CloudFront distribution configurations (66 distributions)
- Route53 DNS records (16 hosted zones)
- DynamoDB table schemas and configurations
- Google Apps Script projects (4 main projects)
- Local application source code and documentation
- Infrastructure-as-code and deployment manifests
Technical Approach: Parallel Multi-Agent Snapshot Architecture
AWS Resource Inventory
We started with a complete resource audit using AWS CLI commands to identify all JADA-related infrastructure:
aws s3 ls | grep -E "(jada|qos|rady)" | wc -l
aws cloudfront list-distributions | jq '.DistributionList.Items | length'
aws lambda list-functions | jq '.Functions | length'
aws route53 list-hosted-zones | jq '.HostedZones | length'
aws dynamodb list-tables | jq '.TableNames | length'
Results revealed 45 S3 buckets, 66 CloudFront distributions, 21 Lambda functions, and 16 Route53 zones. Rather than serialize these downloads, we spawned four background agents to work in parallel.
Parallel Agent Strategy
We created a snapshot directory structure at `/Users/cb/Documents/repos/memory/snapshots/v1.0/` with subdirectories for each component:
s3-buckets/— synced all bucket contents viaaws s3 synclambda/— exported function code, configuration, and environment via CLIcloudfront/— saved all 66 distribution configurations as JSONroute53/— exported DNS records for all 16 zonesdynamodb/— captured table schemas and point-in-time backupsgas-projects/— pulled all Google Apps Script projects via clasplocal-code/— synced application repositorieslightsail/— captured Lightsail instance snapshots
Four agents ran concurrently:
# Agent 1: S3 Sync
for bucket in $(aws s3 ls | awk '{print $3}' | grep jada); do
aws s3 sync s3://$bucket ./s3-buckets/$bucket --region us-west-2
done
# Agent 2: Lambda Export
for func in $(aws lambda list-functions | jq -r '.Functions[].FunctionName'); do
aws lambda get-function --function-name $func > ./lambda/$func-config.json
aws lambda get-function-code-signing-config --function-arn $arn > ./lambda/$func-signing.json
done
# Agent 3: CloudFront + Route53 + DynamoDB
aws cloudfront list-distributions | jq '.DistributionList.Items' > ./cloudfront/all-distributions.json
aws route53 list-resource-record-sets --hosted-zone-id $zone_id > ./route53/$zone_id-records.json
aws dynamodb describe-table --table-name $table > ./dynamodb/$table-schema.json
# Agent 4: GAS Projects + Local Code
clasp pull --project-id $gas_project_id
git clone $repo ./local-code/$repo_name
Infrastructure Components Captured
S3 Buckets: Content + Configuration
The 45 S3 buckets fell into three categories: static assets (sailjada.com, salejada.com, queenofsandiego.com), data warehouses (event metadata, user uploads), and Lambda layer distributions. We synced all bucket contents and separately exported bucket policies, CORS configurations, and lifecycle rules:
aws s3api get-bucket-policy --bucket $bucket_name > ./s3-buckets/$bucket_name-policy.json
aws s3api get-bucket-cors --bucket $bucket_name > ./s3-buckets/$bucket_name-cors.json
aws s3api get-bucket-lifecycle-configuration --bucket $bucket_name > ./s3-buckets/$bucket_name-lifecycle.json
Lambda Functions: Code + Environment + Layers
All 21 Lambda functions were exported with environment variables, VPC configurations, reserved concurrency, and layer dependencies. For functions with custom layers, we captured layer version numbers and their S3 locations to ensure reproducibility:
aws lambda get-function --function-name eventProcessor_v2 --region us-west-2 | \
jq '.Configuration | {FunctionName, Runtime, Handler, Environment, Layers, VpcConfig}' > ./lambda/eventProcessor_v2-config.json
CloudFront Distributions: Origin + Cache + SSL
All 66 CloudFront distributions were captured with their origin configurations, cache behaviors, SSL certificates, and custom headers. Critical for staging workflows: we noted which distributions had origin headers that pointed to staging S3 buckets versus production.
Route53 DNS: All Zones + Record Sets
All 16 hosted zones and their record sets were exported, including weighted routing policies, geolocation rules, and health check configurations. This was essential for documenting how traffic was routed between staging and production environments.
Google Apps Script Projects
Four GAS projects were pulled via clasp and committed to the snapshot:
- Main JADA GAS project (shared event logic)
- Rady Shell replacement GAS (event scheduling)
- Rady Shell old GAS (legacy backup)
- EYD GAS project (external event data)
Each project was copied with its .clasp.json configuration and all source files preserved in versioned structure.
Key Decision: Lightsail Instance Snapshots
Rather than just capturing configuration, we created a Lightsail instance snapshot (jada-agent-v1.0-20260509) to preserve the exact state of any running agent instances. This snapshot included installed dependencies, environment files, and local development tools.
What's Next: Using the v1.0 Snapshot
The snapshot serves multiple purposes:
- Recovery: If production code is