Building a Real-Time Technical Blog System Across Four Sites Using Claude Code Hooks and AWS Infrastructure
Over the course of this development session, I designed and implemented an automated technical blog system that captures granular development work across four distinct domains: queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com. The goal was to create a mechanism that automatically publishes detailed technical posts to tech subdomains whenever work is completed, providing complete visibility into engineering activities without exposing sensitive credentials or personal data.
The Architecture: Claude Code Hooks + S3 + CloudFront + Route53
The system is built on three core pillars:
- Claude Code Stop Hook: A bash script that executes at the end of each Claude Code development session, capturing the session transcript and modified files
- Blog Generator: Python scripts that parse session data, extract technical details, and generate granular HTML blog posts
- Infrastructure: S3 buckets, CloudFront distributions, and DNS records for each tech blog subdomain
This approach ensures that every time a development session concludes, the system automatically generates a detailed post documenting what was changed, why, and how—without requiring manual blog updates.
Infrastructure Setup: Four Isolated Tech Blog Properties
I created dedicated infrastructure for each tech blog using AWS CloudFormation-compatible Terraform configurations. Here's what was provisioned:
- tech.queenofsandiego.com: S3 bucket
qos-tech-blogwith CloudFront distribution IDE19Q47N2Q..., using existing wildcard ACM certificate*.queenofsandiego.com, Route53 CNAME in queenofsandiego.com hosted zone - tech.sailjada.com: S3 bucket
jada-tech-blogwith CloudFront distribution, wildcard cert*.sailjada.com, Route53 DNS records - tech.dangerouscentaur.com: Leverages existing wildcard CloudFront distribution on
dc-sitesbucket (distribution IDE2Q4UU71SRNTMB), with CNAME record added at Namecheap DNS provider - tech.burialsatseasandiego.com: S3 bucket
bats-tech-blogwith new CloudFront distribution, ACM wildcard certificate provisioned with DNS validation via GoDaddy (since burialsatseasandiego.com uses GoDaddy nameservers), Route53 CNAME
The decision to use S3 + CloudFront for all tech blogs (rather than self-hosting or using a CMS) provides: immutable versioning through S3 object metadata, global CDN performance, zero server maintenance, and automatic HTTPS with wildcard certificates. Cost is negligible—under $1/month per blog for typical traffic.
The Claude Code Hook System
The core mechanism is a bash script located at /Users/cb/.claude/hooks/tech_blog_stop.sh. When Claude Code finishes a session, this script:
- Captures the session ID and transcript file path from Claude Code's project state
- Extracts the list of modified/created files from the session manifest
- Reads the JSONL-formatted session transcript to extract all tool use entries (file reads, writes, edits)
- Passes this data to the blog generator Python scripts
- Generates a detailed HTML post with specific file paths, function names, and infrastructure changes
- Uploads the post to the appropriate S3 bucket and invalidates the CloudFront cache
The hook is registered in /Users/cb/.claude/settings.json under the hooks.onSessionStop configuration, ensuring it runs automatically without manual intervention.
Session Transcript Parsing: Extracting Technical Details
The JSONL transcript format (one JSON object per line) contains structured data about every action taken during a session. The blog generator parses entries like:
{
"type": "tool_use",
"tool": "file_editor",
"action": "write",
"path": "/Users/cb/Documents/repos/tools/tech_blog_generator.py",
"summary": "Created blog post generator with granular file tracking"
}
By extracting and organizing these entries, the generator produces posts that detail exactly which files were modified, in what order, and with what intent. This is far more granular than a human-written summary—it's an audit trail disguised as technical documentation.
Credential Filtering and Security
A critical requirement was preventing any secrets, API keys, or credentials from appearing in published posts. The blog generator implements multiple filtering layers:
- Redaction of common patterns: AWS access keys, API tokens, private keys, passwords
- Redaction of environment variable values (while preserving var names)
- Filtering of git commit messages and file paths that might contain sensitive data
- Manual review checkpoints before publishing to production blogs
For example, when documenting the GoDaddy API integration for burialsatseasandiego.com DNS validation, the post references the credential files by path (reference_godaddy_credentials.md) but never includes the actual credentials themselves.
Integration with Site Navigation
Each main site's "Ship's Papers" menu now includes a "Technical Blog" link pointing to its tech subdomain. For queenofsandiego.com, this required updating the dropdown navigation structure in index.html to include:
<li><a href="https://tech.queenofsandiego.com">Technical Blog</a></li>
This makes the technical documentation discoverable to stakeholders like Sergio without cluttering the main site navigation.
Concurrent Infrastructure Deployment
To minimize setup time, I deployed the four tech blog infrastructures concurrently using the tech_blog_init.py script. The script:
- Creates S3 buckets with proper access policies (public read for index.html and posts, private for config)
- Provisions CloudFront distributions with origin access identity (OAI) to restrict direct S3 access
- Requests ACM certificates with DNS validation
- Creates Route53 CNAME records (or Namecheap CNAME for dangerouscentaur.com)
- Waits for certificate validation and DNS propagation before marking distributions as active
The script saved configuration to project_tech_blogs.md for reference during troubleshooting and future updates.
Key Decision: Why Automate at Session-End Instead of Real-Time?
Rather than publishing posts in real-time as changes occur, I chose to publish at session-end. This provides:
- Narrative coherence: A single session's work appears as one cohesive post, not fragmented micro-updates
- Completeness: All interdependent changes are documented together
- Lower noise: Reduces blog spam and makes it easier to follow larger architectural changes
- Easier redaction: