Building a Multi-Site Automated Technical Blog Generator with AWS Infrastructure
This session focused on creating a comprehensive technical documentation system that automatically publishes detailed engineering notes from development sessions across four separate domain tech blogs. The goal was to provide complete transparency into technical work being performed on Queen of San Diego, Sail Jada, Dangerous Centaur, and Burials at Sea San Diego properties.
Architecture Overview
The system consists of three main components:
- Tech Blog Generator: Parses Claude Code session transcripts and generates granular HTML blog posts
- Infrastructure Init: Provisions S3 buckets, CloudFront distributions, and DNS records for each tech blog domain
- Stop Hook: Automatically invokes the generator at the end of each development session
Technical Implementation Details
Blog Generator Script
Created /Users/cb/Documents/repos/tools/tech_blog_generator.py to extract session data and convert it into structured blog posts. The generator:
- Reads Claude Code session transcripts in JSONL format from the Claude projects directory
- Extracts file modifications, commands executed, and reasoning from agent notes
- Filters out sensitive data (credentials, API keys, tokens) using regex patterns
- Groups changes by domain (queenofsandiego.com, sailjada.com, dangerouscentaur.com, burialsatseasandiego.com)
- Generates HTML posts with sections for What Was Done, Technical Details, Infrastructure Changes, and Key Decisions
- Uploads posts to the appropriate S3 bucket and invalidates the CloudFront distribution
The script uses environment variables to determine which AWS profile and S3 bucket to target based on extracted domain context. It maintains a manifest file in each bucket to track published posts and prevent duplicates.
Infrastructure Initialization Script
Created /Users/cb/Documents/repos/tools/tech_blog_init.py to provision cloud resources for all four tech blog domains:
- S3 Buckets: Created
qos-tech-blog,jada-tech-blog,dc-sites(shared), andbats-tech-blogbuckets with versioning enabled and public read access configured - CloudFront Distributions: Deployed distributions for each domain using existing wildcard ACM certificates where available
- DNS Records: Configured Route53 aliases for queenofsandiego.com and sailjada.com; added CNAME records via Namecheap for dangerouscentaur.com; configured GoDaddy DNS for burialsatseasandiego.com
The script handles domain-specific DNS providers:
- Route53: Used for zones under AWS management with hosted zone IDs Z2M2Z7XYYX2ZQJ and Z1BK3GN8Z0OQYT
- Namecheap: CNAME pointing to dangerouscentaur wildcard CloudFront distribution (E2Q4UU71SRNTMB)
- GoDaddy: REST API integration for burialsatseasandiego.com DNS management with ACM certificate validation
Claude Code Integration
Created /Users/cb/.claude/hooks/tech_blog_stop.sh and registered it in Claude Code settings to execute automatically when sessions end. The hook:
- Sources environment variables from
repos.env - Identifies which domain the session was working on
- Invokes the blog generator with appropriate parameters
- Logs output to
~/.claude/logs/tech_blog_generation.log - Ensures generated posts are published within seconds of session completion
Infrastructure Details
S3 Bucket Configuration
Each tech blog bucket is configured with:
- Versioning enabled for content history and rollback capability
- Block public access disabled with explicit bucket policies allowing CloudFront origin access
- Default index.html for root path requests
- Error document configuration for 404 handling
CloudFront Distributions
Distributions created with:
- Origin configuration pointing to S3 bucket REST endpoints
- Cache behaviors with TTL of 300 seconds for HTML, longer for static assets
- ACM certificates: wildcard certificates for
*.queenofsandiego.comand*.sailjada.com; domain-specific for dangerouscentaur and burialsatseasandiego - HTTP/2 and HTTP/3 support enabled
- HTTPS redirect configured to ensure secure access
DNS Configuration
DNS records established across three providers:
tech.queenofsandiego.com: Route53 alias to CloudFront distributiontech.sailjada.com: Route53 alias to CloudFront distributiontech.dangerouscentaur.com: Namecheap CNAME to shared wildcard CloudFront distributiontech.burialsatseasandiego.com: GoDaddy DNS CNAME with ACM certificate validation records
Additional Work: Site Content Updates
During this session, also addressed:
- Updated
queenofsandiego.com/index.htmland other site files to add Ship's Papers navigation menu entries linking to the tech blogs - Fixed event and promotion pages (events.html, mothersday.html) with corrected minimum guest counts
- Created email templates for upcoming 2026 events (Gipsy Kings, Birthday Sail, Kool Gang) with validation tooling
- Created
email_template_validator.pyto validate email HTML structure and compliance - Created
jada_unsubscribe_monitor.pyto track unsubscribe trends and identify potential list health issues - Updated blast scheduling system in
jada_blast.pywith refined event email handling
Key Decisions and Rationale
Multi-Provider DNS Approach: Rather than migrating all domains to a single DNS provider, leveraged existing infrastructure (Route53, Namecheap, GoDaddy) to minimize disruption while establishing tech blogs across all four properties.
Automated Session-Based Publishing: The hook-based approach ensures posts are generated immediately after work completes, with no manual intervention. This provides real-time visibility into engineering activities without requiring developers to write documentation.
Credential Filtering: The generator actively scrubs sensitive data using multiple regex patterns to prevent accidental exposure of API keys, passwords, or tokens in published posts.
Granular Documentation: Posts capture exact file paths, function names, AWS resource identifiers, and command examples to provide engineers (particularly stakeholders like Sergio) with detailed visibility into what was built and why