Doing Everything from Spec to IaC with Kiro (Blog Author Stats Batch)

Doing Everything from Spec to IaC with Kiro (Blog Author Stats Batch)

Using the AI editor Kiro, I built a batch process that auto-generates monthly post graphs for DevelopersIO authors. I cover the workflow from interactive prototyping to writing a Spec and codifying it as IaC with CloudFormation.
2025.11.26

This page has been translated by machine translation. View original

I had the opportunity to try a development flow that uses the AI editor "Kiro" end to end, from defining specifications, through implementation, to turning the infrastructure into IaC (CloudFormation).

This article introduces the process of building a batch job that automatically generates monthly post count trend graphs for each author, based on DevelopersIO writing data that is exported daily to S3.

In particular, this time we carried out "elevating a prototype to IaC" through the following steps:

  1. Interactive CLI construction: Kiro, given instructions, executes AWS CLI commands
  2. Recording the specification: In parallel, the construction steps are written into a document (Spec).
  3. IaC conversion: Generate a CloudFormation template from the Spec and rebuild it as the production environment.

Development Background and Architecture

The goal this time is to visualize past writing achievements and help boost authors' motivation.
For the input data, the JSONL file on S3, we reused data that had been exported for our existing internal BI tools (Looker, QuickSuite).

Architecture:

  1. Input: all-blog-posts.jsonl.gz (existing S3 data)
  2. Process: Lambda (Python/Matplotlib/Seaborn) with EventBridge Scheduler
  3. Output: PNG images per author (S3 + CloudFront with OAC)

1. Investigating the Existing Data Assets and Turning Them into a Spec

First, to understand the structure of the input data, I investigated the actual data and created data-spec.md.

Checking the Actual Data

I retrieved the actual data on S3 using the AWS CLI and checked its structure.

# Download the latest dump file from S3
# <SOURCE-BUCKET-NAME> is the actual bucket name
aws s3 cp s3://<SOURCE-BUCKET-NAME>/contentful/all-blog-posts.jsonl.gz .
gzip -dc all-blog-posts.jsonl.gz | head -n 1 | jq .

Reflecting in the Spec File

Based on the investigation results, I defined the specification document data-spec.md for Kiro to read.
Here, from the huge number of data fields, I extracted only the elements essential to this batch process (aggregation, joining, and visualization), keeping the AI focused.

data-spec.md (excerpt):

## データスキーマ仕様
BIツール連携用の既存データを流用する。

### all-blog-posts.jsonl.gz (トランザクション)
- **必須フィールド**:
  - `author_id`: **結合キー**。著者マスタと紐付けるために必須。
  - `first_published_at`: **集計軸**。月次でグルーピングするために必須。
  - `title`: 検証・デバッグ用。

### authorProfile.jsonl.gz (マスタ)
- **必須フィールド**:
  - `id`: **結合キー**。
  - `slug`: **出力ファイル名**(例: `suzuki-ryo.png`)に使用。
  - `display_name`: **グラフタイトル**(表示名)に使用。

Thanks to this Spec definition, Kiro was able to implement the logic for "master join," "time-series aggregation," and "deliverable generation" without hesitation.


2. Application Implementation: Master Join

Kiro read data-spec.md and implemented the join between "transactions (posts)" and "master (authors)".
Since there are about 60,000 records, it generated efficient code (lambda_batch.py) that turns the master into a dictionary (hash map) for fast O(1) lookups.

    # 1. Convert the author master into a dictionary
    authors = {}
    with gzip.open(authors_file, 'rt', encoding='utf-8') as f:
        # ... master loading process ...

    # 2. For the aggregated post data, look up info from the dictionary
    for author_id, monthly_data in data.items():
        if author_id in authors:
             # ...

3. Prototyping and Refactoring to IaC

This is the highlight of this development. Instead of writing CloudFormation right away, I took the approach of first building an environment that works interactively.

3.1 Kiro Performing AWS Operations on My Behalf (Prototyping)

First, I instructed Kiro in chat format: "I want to build an AWS environment where this Python code runs."
Here, I did not run AWS CLI commands directly. Instead, I conveyed the requirements to Kiro interactively, and used Kiro's built-in use_aws tool to generate and execute the necessary commands.

  • User: "Create an S3 bucket and use it as the output destination"
    • Kiro: Runs aws s3 mb ...
  • User: "Run my local Python code as a Docker container"
    • Kiro: Creates a Dockerfile and runs the docker build command to build the image
  • User: "Run this image that worked locally on AWS Lambda"
    • Kiro: Suggests, "To use a container image with Lambda, it needs to be pushed to Amazon ECR. Shall I create a repository?"
    • Kiro: (After approval) Runs aws ecr create-repository ... and pushes the Docker image

In this way, the human gives instructions for "abstract requirements and goals," while "resolving concrete steps and dependencies (e.g., Lambda requires ECR)" and "entering commands" are left to Kiro.

After construction, I verified operation on the actual environment and confirmed that aggregation for the last 7 days was performed correctly.

3.2 Documenting the Steps and Turning Them into a Spec

In parallel with the construction work, I instructed Kiro to document the steps, creating spec/batch-setup.md.
Rather than analyzing logs afterward, by instructing "add this setting to the Spec" each time a resource was created, I ended up with a procedure document that always reflected the latest state.

spec/batch-setup.md (excerpt):

1. Dockerイメージビルド・プッシュ
2. IAMロール作成(信頼ポリシー、S3アクセスポリシー)
3. Lambda関数作成
4. CloudFront配信設定(OAC作成、ディストリビューション作成)

3.3 Converting to a CloudFormation Template

Finally, I had it create a CloudFormation template based on this spec/batch-setup.md.
Because there was a "verified CLI procedure document," the refactoring work of converting it into an "IaC template" went very smoothly.

Instruction to Kiro:

Convert the contents of spec/batch-setup.md into a CloudFormation template (author-stats-batch.yaml).

As a result, an accurate template was generated, including complex settings such as the OAC configuration and the S3 bucket policy.


4. Redeploying to a Clean Environment and Verification

After the template was completed, I deleted the resources of the prototype environment and carried out a "production-equivalent" deployment using CloudFormation.

4.1 Deploying the Stack

aws cloudformation create-stack \
  --stack-name author-stats-batch-stack \
  --template-body file://cloudformation/author-stats-batch.yaml \
  --parameters \
    ParameterKey=SourceBucketName,ParameterValue=<SOURCE-BUCKET-NAME> \
    ParameterKey=ECRImageUri,ParameterValue=<ACCOUNT-ID>.dkr.ecr.us-east-1.amazonaws.com/author-stats-batch:latest \
    ParameterKey=ScheduleExpression,ParameterValue="cron(45 17 * * ? *)" \
  --capabilities CAPABILITY_NAMED_IAM \
  --region us-east-1

Execution result:

Waiting for stack creation...
Stack created successfully!

Stack creation completed in a few minutes, and I confirmed that the CloudFront domain and S3 bucket had been provisioned.

4.2 Final Operation Verification

I ran the test again in the rebuilt environment.

Update for the Last 7 Days (Normal Operation)

2025-11-25T22:11:57 Found 68 active authors
2025-11-25T22:12:24 REPORT Duration: 27054.79 ms   Max Memory Used: 259 MB

Graphs for 68 authors were generated successfully.

Bulk Generation for the Entire Period (15 Years) (High-Load Test)

2025-11-25T22:13:54 Processing authors active in last 5475 days
2025-11-25T22:13:54 Found 1056 active authors
...
2025-11-25T22:18:28 Processed: littleossa

Graph generation for all 1,056 authors completed in about 5 minutes without errors.

S3 output check:

aws s3 ls s3://<DEST-BUCKET-NAME>/author-monthly-stats/ | wc -l
> 1047

Display check:
Graph sample

The number of generated image files also matched, confirming that the rebuild via IaC was done perfectly.


5. Future Outlook and About the Release

With this verification, the backend generation logic and delivery infrastructure are complete. Going forward, I will make the following adjustments and proceed toward deployment to production.

  • Checking job stability: Monitor the daily execution by EventBridge for several days.
  • Design adjustments: Fine-tune the colors and font sizes of the generated graphs to match the DevelopersIO site design.

After these checks, we plan to actually publish these statistics graphs on each author's profile page on DevelopersIO in the near future. Please look forward to it.

Summary

In this verification, I was able to practice the following modern development flow using Kiro:

  1. Interactive prototyping: By giving instructions in natural language and having Kiro act on the CLI, the trial and error of creating resources was accelerated.
  2. Specifying the process: Record the steps in Markdown while building, preventing a black box.
  3. Refactoring to IaC: Generate a CFn template from the verified procedure document and move to a robust environment.

"First build something that works, leave documentation in parallel, and finally turn it into code." Being able to realize this ideal cycle through pair programming with AI was a great gain.

Share this article

AWSのお困り事はクラスメソッドへ