```html

Building a Comprehensive Infrastructure Snapshot: The JADA v1.0 Backup Strategy

When you're managing three interconnected production sites with distributed cloud infrastructure, a single misconfiguration or unintended reversion can cascade across multiple systems. This post details how we built a complete v1.0 snapshot of the entire JADA ecosystem—covering 45 S3 buckets, 66 CloudFront distributions, 21 Lambda functions, and 16 Route53 hosted zones—ensuring we never lose critical infrastructure state again.

The Problem: Distributed State with No Single Source of Truth

The JADA infrastructure spans three production domains:

  • queenofsandiego.com — event management and commerce
  • sailjada.com — primary brand site
  • salejada.com — sales/affiliate properties

This infrastructure includes:

  • 45 S3 buckets (production, staging, backups, archives)
  • 66 CloudFront distributions (CDN, API caching, origin failover)
  • 21 Lambda functions (event handlers, transformations, webhooks)
  • 16 Route53 hosted zones (DNS, traffic routing, health checks)
  • Google Apps Script (GAS) projects (4 main automation engines)
  • Lightsail instances (development, staging, production environments)
  • DynamoDB tables (14 tables for state management)
  • SES, API Gateway, ACM certificates, and IAM policies

Without a comprehensive snapshot, infrastructure changes become difficult to audit, rollback, or replicate in disaster recovery scenarios.

Snapshot Architecture: Four Parallel Agents

Rather than sequential downloads that would take hours, we deployed four parallel background agents, each handling a different component class:

Agent 1: S3 Bucket Synchronization

# Sync all JADA-related S3 buckets to local snapshot
aws s3 ls | grep -E "(jada|qos|sailjada|salejada)" | awk '{print $3}' > /tmp/jada_buckets.txt

for bucket in $(cat /tmp/jada_buckets.txt); do
  aws s3 sync s3://$bucket /snapshot/v1.0/s3/$bucket \
    --region us-west-2 \
    --exclude ".git/*" \
    --exclude "node_modules/*" \
    --exclude "venv/*"
done

Result: 45 buckets synced (68MB+ total), organized by bucket name. This preserves bucket structure exactly as it exists in production.

Agent 2: Lambda Code & Configuration Export

Lambda functions were pulled using the AWS CLI and aws lambda get-function for code, plus describe-function for configuration:

# Export all Lambda functions with their code and metadata
aws lambda list-functions --region us-west-2 --query 'Functions[*].FunctionName' \
  --output text | tr '\t' '\n' | while read func; do
  
  # Create function directory
  mkdir -p /snapshot/v1.0/lambda/$func
  
  # Export function code and configuration
  aws lambda get-function --function-name $func --region us-west-2 \
    --query 'Code.Location' --output text | xargs -I {} curl -o /snapshot/v1.0/lambda/$func/code.zip {}
  
  # Export function configuration
  aws lambda get-function-configuration --function-name $func --region us-west-2 \
    > /snapshot/v1.0/lambda/$func/config.json
done

Key detail: We exported both compiled code (as .zip files) and full function metadata (timeout, memory, environment variables structure, VPC configuration, IAM execution role ARN). This ensures we can rebuild identical Lambda functions from snapshot.

Agent 3: AWS Infrastructure Configuration

CloudFront, Route53, DynamoDB, SES, API Gateway, and ACM were exported using describe-* and list-* operations:

# CloudFront distributions
aws cloudfront list-distributions > /snapshot/v1.0/aws/cloudfront-distributions.json

# Route53 hosted zones and records
aws route53 list-hosted-zones > /snapshot/v1.0/aws/route53-zones.json
aws route53 list-resource-record-sets --hosted-zone-id Z1234ABCD > /snapshot/v1.0/aws/route53-records.json

# DynamoDB table schemas
aws dynamodb list-tables > /snapshot/v1.0/aws/dynamodb-tables.json
for table in $(aws dynamodb list-tables --query 'TableNames' --output text); do
  aws dynamodb describe-table --table-name $table \
    > /snapshot/v1.0/aws/dynamodb/${table}-schema.json
done

All credentials and sensitive values were stripped from these exports before storage.

Agent 4: Google Apps Script & Local Code

GAS projects were pulled using Clasp (the Google Apps Script CLI), then all local repositories and configuration were copied:

# Pull main JADA GAS project
clasp pull --projectId abc123def456 -r main
cp -R ~/.clasp/* /snapshot/v1.0/gas/main-jada/

# Pull Rady Shell GAS (replacement version)
clasp pull --projectId xyz789uvw456 -r main
cp -R ~/.clasp/* /snapshot/v1.0/gas/rady-shell-replacement/

This captured four distinct GAS automation engines used for event management, data syncing, and webhook processing.

Special Handling: Lightsail Instance Snapshot

For stateful instances running development and staging environments, we triggered AWS Lightsail snapshots that capture disk state, application code, and database dumps at the instance level. The Lightsail snapshot ID jada-agent-v1.0-20260509 was generated and tracked separately, with AWS handling the ~15 minute creation process asynchronously.

Staging Workflow Integration

During snapshot creation, we also synchronized production assets to staging CloudFront distributions:

  • QOS production bucket → staging bucket (full sync)
  • Sailjada production bucket → staging bucket (full sync)
  • CloudFront cache invalidation on staging distributions (ensuring fresh content)

This allowed parallel verification that staging mirrors production exactly, detected via file count comparison:

# Verify file count parity
prod_count=$(aws s3 ls s3://sailjada-prod --recursive | wc -l)
staging_count=$(aws s3 ls s3://sailjada-staging --recursive | wc -l)

if [ "$prod_count" -eq "$staging_count" ]; then
  echo "✓ Staging matches production ($prod_count files)"
else
  echo "✗ Mismatch: prod=$prod_count, staging=$staging_count"
fi

Snapshot Structure & Manifest

The complete v1.0 snapshot is organized as:

/snapshot/v1.0/
├── MANIFEST.md              # Complete inventory with file counts
├── s3/                      # 45 buckets, organized by name
│   ├── sailjada-prod/
│