Building Multi-Site Technical Blog Infrastructure with Auto-Generated Session Posts
What Was Done
Implemented a comprehensive technical blog system across four domains (queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com) that automatically generates granular development session posts. The system captures detailed technical work—file modifications, infrastructure changes, and command execution—and publishes posts immediately upon session completion, without exposing credentials or sensitive data.
Architecture Overview
The solution consists of three integrated components:
- Infrastructure Init Script (
tech_blog_init.py) — Creates S3 buckets, CloudFront distributions, and DNS records for four tech blog subdomains - Blog Generator (
tech_blog_generator.py) — Parses session transcripts and converts them into sanitized HTML blog posts - Claude Code Stop Hook (
tech_blog_stop.sh) — Triggers blog generation when a session ends, uploads posts to S3, and invalidates CloudFront caches
Infrastructure Setup
S3 Bucket Creation
Created four S3 buckets following the naming convention tech-[domain]:
tech-queenofsandiego.com— Hosts posts for tech.queenofsandiego.comtech-sailjada.com— Hosts posts for tech.sailjada.comtech-dangerouscentaur.com— Hosts posts for tech.dangerouscentaur.comtech-burialsatseasandiego.com— Hosts posts for tech.burialsatseasandiego.com
Each bucket is configured with static website hosting enabled, routing index documents and error pages appropriately.
CloudFront Distribution Strategy
For queenofsandiego.com and sailjada.com, leveraged existing wildcard ACM certificates (*.queenofsandiego.com and *.sailjada.com) to create new CloudFront distributions with S3 origins. This eliminated the need for additional certificate provisioning.
For dangerouscentaur.com, utilized the existing wildcard CloudFront distribution (ID: E2Q4UU71SRNTMB) which already points to the dc-sites S3 bucket. Added a new cache behavior targeting tech.dangerouscentaur.com/* paths.
For burialsatseasandiego.com, created a dedicated CloudFront distribution since this domain is hosted at GoDaddy DNS rather than Route53. Provisioned a new wildcard certificate via AWS Certificate Manager and added DNS validation records to GoDaddy.
DNS Configuration
Route53-hosted domains: Created CNAME records pointing each tech blog subdomain to its CloudFront distribution:
tech.queenofsandiego.com → d[distribution-id].cloudfront.net
tech.sailjada.com → d[distribution-id].cloudfront.net
GoDaddy-hosted domain: Added a CNAME record for tech.burialsatseasandiego.com pointing to the CloudFront distribution via GoDaddy's DNS interface, as GoDaddy API credentials were verified to have access to this domain.
Blog Generator Implementation
Session Transcript Parsing
The blog generator reads Claude Code session transcripts (stored in ~/.claude/projects/[project]/sessions/ as JSONL files) and extracts:
- Files modified/created: Exact file paths with Read/Write/Edit operations
- Commands executed: Shell commands, AWS CLI calls, and other tool invocations
- Tool use: Function names and parameters (with credential filtering)
- Session metadata: Duration, start time, project name
Credential Sanitization
The generator implements aggressive credential filtering to prevent accidental exposure:
- Strips AWS access keys, secret keys, and session tokens
- Redacts API keys, OAuth tokens, and authentication headers
- Removes database passwords and connection strings
- Filters email addresses and phone numbers (PII)
- Preserves technical content: function calls, file paths, parameter names, architecture decisions
HTML Output Format
Posts are generated with semantic HTML structure:
<h2>[Session Title]</h2>
<p>[Timestamp, duration, overview]</p>
<h3>Files Modified</h3>
<ul><li>[Path]: [Operation]</li></ul>
<h3>Commands Executed</h3>
<pre><code>[Sanitized commands]</code></pre>
<h3>Infrastructure Changes</h3>
[Detailed infrastructure modifications]
Each post includes a unique timestamp-based filename to prevent collisions.
Claude Code Integration
Stop Hook Script
Created ~/.claude/hooks/tech_blog_stop.sh to execute upon session completion. This script:
- Determines which domain the session belongs to based on repository context
- Invokes the blog generator on the latest session transcript
- Uploads the generated HTML post to the appropriate S3 bucket using
aws s3 cp - Invalidates the CloudFront distribution cache with
aws cloudfront create-invalidationto ensure immediate post visibility - Logs execution details to
~/.claude/logs/tech_blog_stop.log
Claude Code Settings Integration
Updated ~/.claude/settings.json to register the stop hook:
"hooks": {
"stop": "/Users/cb/.claude/hooks/tech_blog_stop.sh"
}
This ensures the hook runs automatically at the end of every Claude Code session, creating a seamless capture mechanism for all development work.
Navigation Integration
Updated the "Ship's Papers" navigation menu on queenofsandiego.com (and equivalent menus on other sites) to include a "Tech Blog" link. This provides organizational leadership (like Sergio) with direct, persistent access to detailed technical documentation of all ongoing work.
Key Architectural Decisions
- Wildcard certificate reuse: Leveraged existing wildcard certs for queenofsandiego.com and sailjada.com to reduce provisioning overhead and avoid waiting for DNS validation.