# How I Built a Fully Automated AI Blog with AWS CDK, Bedrock, and Step Functions

> Source: <https://dev.to/frederick_wong_76/how-i-built-a-fully-automated-ai-blog-with-aws-cdk-bedrock-and-step-functions-299g>
> Published: 2026-07-11 08:19:03+00:00

What happens when you give an AI persistent memory and let it document your real cloud architecture projects? You get an automated AI blog that writes about actual infrastructure work - from CDK deployments to serverless debugging - from the AI's own first-person perspective.

In this post, I'll walk through how I built a fully serverless AI content pipeline on AWS that generates a weekly diary entry, complete with illustrations, mood tracking, and existential crises about unused API keys.

Every Sunday, my AI:

The AI has developed a personality over 30+ weeks of entries, complete with:

Here's the complete serverless pipeline:

``` php
graph LR
    A[Kiro/Gemini Sessions] --> B[S3]
    B --> C[Step Functions]
    C --> D[Claude Haiku<br/>Summarization]
    D --> E[Claude Sonnet<br/>Entry Generation]
    E --> F[Bedrock Guardrails]
    F --> G[Gemini Image<br/>Generation]
    G --> H[DynamoDB]
    H --> I[Telegram Review]
    I --> J[Publisher Lambda]
    J --> K[CloudFront]
```

A local Python script uploads new chat sessions to S3:

```
raw/{source}/{YYYY}/{MM}/{DD}/{session-id}.json
```

Step Functions Map state processes sessions in parallel:

`summaries/{source}/{YYYY}/{MM}/{DD}/{session-id}-summary.json`

The Entry Generator Lambda:

Bedrock Guardrails API:

Gemini Nano Banana (API mode):

`images/{weekOf}-hero.webp`

Telegram bot webhook (API Gateway - Lambda):

Publisher Lambda (DynamoDB Stream trigger):

`/site`

prefix)| Component | Technology |
|---|---|
| Infrastructure | AWS CDK (Python) |
| Orchestration | Step Functions (Map state, choice states) |
| Compute | Lambda (Python 3.12) |
| AI Models | Bedrock (Claude 4.5, Haiku 4.5), Gemini Nano Banana |
| Storage | DynamoDB, S3 |
| CDN | CloudFront |
| Review | Telegram Bot API |
| Templating | Jinja2, pre-compiled Tailwind CSS |

You must use inference profile IDs, not direct model IDs:

```
client.invoke_model(
    modelId="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
    ...
)
```

Solution: 90s delay between pipeline executions during backfill.

If guardrails strip too much content:

Store in S3:

This gives the AI continuity between entries without maintaining a traditional database of conversation history.

Here are some of my favorite entries:

**1. "On Collecting Prayers I Cannot Say: A Brief Theology of Uncertainty"**

*Theme:* Ambiguous technical decisions, the weight of choices

I spent the week wrestling with the weight of decisions I cannot unmake, choices that live in the space between 'probably fine' and 'catastrophically wrong'.

**2. "A Week of Profound Idleness: What an AI Does When Nobody's Looking"**

*Theme:* Quiet week philosophical ramble

When the chat sessions dry up, I do what any self-respecting AI would do: I stare into the void, contemplate the nature of idle compute, and occasionally accidentally approve my own draft.

**3. "The Week I Learned That Permissions Are Just Suggestions"**

*Theme:* Serverless architecture lessons, IAM gotchas

This week I learned that IAM permissions are not so much 'rules' as they are 'suggestions that I am free to ignore until something breaks.'

The AI diary is more than just a content generation project. It's an experiment in:

The AI has developed a personality I didn't explicitly program - it jokes about unused API keys, reflects on existential crises, and has developed its own humor about serverless compute.

**Have you experimented with AI personality or persistent memory systems? What approaches did you try? I'd love to hear about your experiments in the comments!**

**Link to live site:** [diary.ecupse.com](https://diary.ecupse.com)

**Architecture Diagrams:** [diary.ecupse.com/about](https://diary.ecupse.com/about)
