Building Automated Technical Blog Infrastructure for Four Sailing & Maritime Sites
What Was Done
Created a fully automated technical blog generation system that captures development work across four maritime-focused websites in real-time. The system monitors Claude Code development sessions, extracts technical details, and publishes granular blog posts to dedicated tech subdomains without requiring manual intervention or credential exposure.
Deployed infrastructure for:
tech.queenofsandiego.comtech.sailjada.comtech.dangerouscentaur.comtech.burialsatseasandiego.com
Technical Architecture
Blog Generation Pipeline
The system consists of three Python tools working in concert:
tech_blog_init.py— Infrastructure provisioning script that creates S3 buckets, CloudFront distributions, DNS records, and ACM certificates for each blog domaintech_blog_generator.py— Core blog generation engine that parses Claude Code session transcripts (JSONL format), extracts tool use entries, filters out credentials, and generates HTML blog poststech_blog_stop.sh— Stop hook executed by Claude Code after each development session, triggering blog generation and deployment
Additionally, two monitoring tools were created for operational oversight:
email_template_validator.py— Validates email template syntax and structure before deployment to productionjada_unsubscribe_monitor.py— Tracks unsubscribe events and maintains subscriber list hygiene across campaigns
Session Transcript Processing
Claude Code saves development sessions as JSONL (JSON Lines) files in /Users/cb/.claude/projects/. Each session contains:
- File modification events (path, operation type, timestamp)
- Command executions (command name, arguments, results)
- Tool use entries (function calls, parameters, results)
- Agent reasoning and decision logs
The blog generator parses these transcripts, identifies technical work (file edits, infrastructure commands, deployment steps), sanitizes sensitive data, and structures it into chronological blog posts. This approach captures granular detail automatically — no manual summarization required.
Infrastructure Deployment
DNS & Certificate Strategy
Each blog domain reuses existing wildcard ACM certificates where available:
- queenofsandiego.com: Uses existing
*.queenofsandiego.comwildcard certificate via Route53 DNS validation - sailjada.com: Uses existing
*.sailjada.comwildcard certificate via Route53 DNS validation - dangerouscentaur.com: Leverages existing wildcard CloudFront distribution (
E2Q4UU71SRNTMB) ondc-sitesS3 bucket; requires Namecheap CNAME record fortech.dangerouscentaur.com - burialsatseasandiego.com: New certificate and CloudFront distribution; DNS managed at GoDaddy (not AWS Route53), requiring ACM DNS validation CNAME entry in GoDaddy's control panel
S3 & CloudFront Structure
Each blog gets its own S3 bucket following naming convention {site}-tech-blog:
queenofsandiego-tech-blog→ served via CloudFront →tech.queenofsandiego.comsailjada-tech-blog→ served via CloudFront →tech.sailjada.comdc-sites→ wildcard CloudFront distribution →tech.dangerouscentaur.combats-tech-blog→ served via CloudFront →tech.burialsatseasandiego.com
S3 buckets are configured for static website hosting with public read access on index HTML files. CloudFront distributions enforce HTTPS-only access and include cache invalidation triggers on deployment.
DNS Nameserver Mapping
Due to different DNS providers:
- Route53-managed domains:
queenofsandiego.com,sailjada.com— Direct alias records point to CloudFront distributions - Namecheap-managed domain:
dangerouscentaur.com— CNAME records point to CloudFront domain names - GoDaddy-managed domain:
burialsatseasandiego.com— Both ACM validation CNAME and blog CNAME records configured
Integration with Existing Sites
Each main website received navigation updates to expose the tech blog:
queenofsandiego.com/index.html— Added "Tech Blog" link under Ship's Papers menu dropdowndangerouscentaur.com— Updated navigation structure to include tech blog linksailjada.com— Added tech blog reference to main navigationburialsatseasandiego.com— Integrated tech blog link into site header
These changes ensure that stakeholders (like Sergio) can easily access detailed technical documentation about ongoing development work.
Key Technical Decisions
JSONL Session Format
Claude Code's native session format is JSONL — one JSON object per line. This format enables streaming processing without loading entire files into memory, critical for large development sessions. The generator reads line-by-line, identifies relevant tool use and file modification events, and extracts structured data.
Credential Filtering Strategy
The blog generator implements multiple filtering layers:
- Redacts common credential patterns (API keys, tokens, passwords)
- Filters file paths under
.claude/and.envfiles - Removes GoDaddy/AWS credential references from command output
- Excludes sensitive environment variable values
This allows publishing granular technical details without exposing secrets — developers see exactly what was done, but not how to do it themselves without authorization.
Stop Hook Timing
The stop hook (tech_blog_stop.sh) executes when exiting a Claude Code session, ensuring blog posts are generated immediately after work completes. This creates a natural, real-time publishing workflow without requiring manual intervention or cron jobs.
Deployment Commands
Infrastructure provisioning for all four sites:
python /Users/cb/Documents/repos/tools/tech_blog_init.py \
--sites queenofsandiego sailjada dangerouscentaur burialsatseasandiego \
--region us-west-2 \
--enable-cloudfront-