Building a Deterministic Git Mirror for Multi-Environment Deployment
\n\nWhat Was Done
\n\nThe Jada estate infrastructure underwent a major architectural decision: rejecting a complex CI/CD toolchain in favor of a lean, git-mirror-based deployment system that prioritizes determinism and operational simplicity. This post covers the infrastructure patterns, deployment automation, and Lambda-based architecture deployed across the Jada estate to replace traditional CI/CD pipelines with a git-synchronized model.
\n\nThe Problem: Why Reject Traditional CI/CD?
\n\nThe Jada estate consists of approximately 15 static S3+CloudFront sites, single-file Lambda functions, launchd/cron-based scheduling, and nightly deterministic test suites. A proposal to introduce a full CI/CD toolchain (traditional build pipelines, artifact repositories, deployment orchestration) was evaluated by the board and rejected in favor of existing proven patterns.
\n\nKey rejection criteria:
\n- \n
- Estate is not the target use case for complex CI/CD tooling (small, static deployments) \n
- Operational burden outweighs benefits for current scale and deployment frequency \n
- Git mirror approach already provides determinism and traceability \n
- Nightly test suite provides sufficient validation without pipeline stages \n
Technical Architecture: Git Mirror as Source of Truth
\n\nThe solution centers on a git mirror system that serves as the single source of truth for all deployments:
\n\ngit repository (main branch)\n ↓\njada-git-snapshot.py (hourly via launchd)\n ↓\nlocal git mirror (/var/mirrors/jada-estate.git)\n ↓\ndeployment scripts (S3 sync, Lambda update, CloudFront invalidate)\n ↓\nlive infrastructure (S3 buckets, CloudFront, Lambda)\n\n\nThe git mirror system is implemented via jada-git-snapshot.py, which runs hourly on the deployment host and ensures the local mirror stays synchronized with the authoritative repository. This approach provides:
- \n
- Determinism: Every commit hash in git is an immutable deployment artifact \n
- Traceability:
git log,git show <hash>provide full audit trail \n - Rollback capability:
git checkout <previous-hash>+ redeploy is instant \n - No external dependencies: Only git, AWS CLI, and shell scripts required \n
Deployment Pipeline: Shell Scripts + AWS CLI
\n\nDeployment is handled by straightforward shell scripts that use the AWS CLI, avoiding vendor-specific tooling:
\n\nStatic site deployment (S3 + CloudFront):
\n#!/bin/bash\n# From git tree at $COMMIT_HASH\ncd /var/mirrors/jada-estate.git\ngit checkout $COMMIT_HASH\n\n# Sync to S3 bucket\naws s3 sync ./sites/my-site s3://jada-site-production/ --delete\n\n# Invalidate CloudFront distribution\naws cloudfront create-invalidation \\\n --distribution-id E2K7ABCD1234EF \\\n --paths \"/*\"\n\n\nLambda deployment:
\n#!/bin/bash\n# Package and deploy single-file Lambda functions\ncd /var/mirrors/jada-estate.git\ngit checkout $COMMIT_HASH\n\ncd ./lambdas/my-function\nzip -q function.zip index.py requirements.txt\n\naws lambda update-function-code \\\n --function-name jada-my-function-prod \\\n --zip-file fileb://function.zip\n\n\nInfrastructure Components
\n\nS3 Buckets: Approximately 15 production S3 buckets host static assets, each with predictable naming (e.g., jada-site-production, jada-site-staging). Bucket policies enforce versioning and MFA delete where required.
CloudFront Distributions: Each production site has a corresponding CloudFront distribution (e.g., E2K7ABCD1234EF pattern). Distributions are configured with:
- \n
- Origin pointing to S3 bucket \n
- Default cache TTL of 86400 seconds (1 day) \n
- Automatic cache invalidation on deploy via distribution ID \n
Lambda Functions: Single-file Lambda functions deployed from git tree, named with pattern jada-*-prod and jada-*-staging. Environment variables stored in git-tracked env.json (no secrets), with credentials fetched from AWS Secrets Manager at runtime.
launchd/cron Scheduling: Deployment runs on a predictable schedule via launchd on macOS or cron on Linux hosts. Git mirror refresh runs hourly; deployment checks and nightly test suite run at fixed times (typically 02:00 UTC).
\n\nNightly Deterministic Tests
\n\nThe estate includes nightly test suites that validate deployments:
\n\n- \n
- HTTP status checks: Verify all CloudFront distributions respond with 200/301 \n
- S3 content validation: Sample files on S3 match git tree checksums \n
- Lambda execution tests: Invoke functions with test payloads, verify output schema \n
- DNS resolution: Verify Route53 records resolve to CloudFront CNAME \n
Test results are logged and alerting is configured via CloudWatch; failures trigger Slack notifications to the ops channel.
\n\nKey Decisions
\n\nDecision 1: Git as deployment artifact store
\nRather than building artifacts in a CI system and storing them in S3/artifact repo, we use git commits as immutable deployment artifacts. This means every commit in the repo is a potential production deployment, with no separate artifact build step.
\n\nDecision 2: Local git mirror over git clone
\nWe maintain a bare git mirror locally rather than cloning fresh each deploy. This reduces network overhead for hourly syncs and provides offline resilience if the origin repository is temporarily unavailable.
\n\nDecision 3: Shell scripts over IaC frameworks
\nWe use Bash/shell scripts with AWS CLI rather than Terraform, CloudFormation, or deployment orchestration tools. For the estate's current scale (15 static sites, handful of Lambdas), shell scripts are maintainable and transparent. Infrastructure changes are committed to git and deployed the same way as code changes.
\n\nDecision 4: Nightly testing over continuous deployment
\nRather than deploy on every commit (continuous deployment), we deploy on a nightly schedule after running the full test suite. This reduces production noise and gives 24 hours for stakeholders to review staged changes.
\n\nWhat's Next
\n\nCurrent work includes:
\n\n- \n
- DBG mobile app deployment path: Evaluating Lambda-based deployment for mobile backend without requiring a full application server \n
- Lightsail peer synchronization: Extended git mirror approach to peer Lightsail instance for geographic redundancy \n
- Autonomous peer-sync watchdog: Implementing health checks and automatic failover between primary and peer deployment hosts \n
The Terraform principle (infrastructure as immutable, versioned code) has been adopted for new infrastructure, using CloudFormation templates stored in git rather than manual AWS console changes.
"}} ]