AWS Builder Center

Building Production-Ready AWS Solutions with Kiro IDE

Automating S3 Bucket Tagging with Kiro IDE: A Spec-Driven Development Approach

Introduction

Modern cloud environments demand consistent tagging for governance, cost allocation, and compliance. Yet, ad-hoc automation often misses edge cases, breaks when AWS permissions vary, or overwrites critical metadata.
In this post, we demonstrate how Kiro IDE’s spec-driven development approach transforms a simple requirement tagging all Amazon S3 buckets by environment into a production-ready automation. By combining structured specifications with Kiro’s intelligent task generation, we build a robust solution that classifies and tags S3 buckets without compromising reliability.

Our use case:

  • Buckets starting with the prefix sagemaker is tagged with Environment=Production.
  • All other buckets is tagged with Environment=Development.

What is Kiro?

Kiro is an AI-powered IDE that combines agentic development with structured engineering practices. Instead of relying solely on raw prompts, Kiro provides two complementary modes of working:
  • Vibe Coding – for quick, exploratory, prompt-driven development. Ideal when you’re configuring an environment, testing AWS CLI commands, or experimenting with new SDK calls.
  • Spec-Driven Development – for systematic, production-ready automation. Developers define requirements and acceptance criteria up front, and Kiro generates design, tasks, and code artifacts that maintain traceability from spec to implementation.
By blending both modes, Kiro supports rapid prototyping and disciplined delivery in the same workflow.

Vibe Coding for AWS Environment Setup

Before applying spec-driven automation to tag buckets, we first needed to configure our AWS environment. Using Kiro Vibe Coding, we quickly set up:
• Installing AWS CLI.
• Running aws configure to set credentials.
• Verifying connectivity by listing S3 buckets.
For example, in Kiro’s vibe coding window we simply entered:
1
aws s3 ls
Kiro guided us through installing AWS CLI, setting profiles, and validating permissions. This is fast, conversational, and unstructured, exactly what vibe coding is for.

Spec-Driven Development for AWS Automation

Once the environment is configured, we switch to Spec-Driven Mode to implement automation tasks like S3 tagging. Unlike vibe coding, which focuses on speed and exploration, spec-driven workflows emphasize:
• Capturing requirements up front.
• Designing for error handling and IAM security.
• Maintaining living documentation in .kiro/specs/.
• Generating traceable, testable, production-ready code.

Key Differences: Vibe Coding vs Spec-Driven:

AspectVibe CodingSpec-Driven Development
PurposeFast prototyping, exploratory codingStructured, production-ready automation
DocumentationAd-hoc, not persistedFormal specs: requirements, design, tasks
Error HandlingReactive, manualDesigned upfront from requirements
IAM & SecurityOften skipped during experimentsEnforced as part of design
Best ForBootstrapping AWS CLI, testing APIsFull workflows, IaC, automation pipelines
In practice, you’ll often use both: vibe coding to quickly set up your environment, then spec-driven mode to build robust AWS solutions like the S3 bucket tagging system in this case study.

From Prompt to Structured Development:

One of the most powerful aspects of Kiro IDE is what happens immediately after you enter a spec-driven prompt.
Instead of jumping into ad-hoc code generation, Kiro automatically scaffolds your project with three living specification files stored under .kiro/specs/:
• requirements.md – captures user stories, acceptance criteria, and business context.
• design.md – documents architecture, error handling strategies, IAM policies, and integration details.
• tasks.md – breaks implementation into trackable units directly linked back to requirements. Run tasks directly in Kiro to build and validate automation.
Note: These files aren’t “frozen outputs.” You can modify them as needed and re-run tasks in Kiro. This ensures you’re always in control of how the solution evolves.
This structure ensures every implementation detail has traceability to business value, and the specifications evolve alongside the code. Unlike traditional documentation, these files are first-class artifacts in your repo, not afterthoughts.

From Discovery to Requirements:

The journey to building an agent or automation often starts with a discovery or brainstorming session where ideas, goals, and constraints are discussed. Instead of turning those notes into lengthy documents, Kiro enables you to capture them directly as a spec-driven prompt.That prompt becomes the foundation for generating the requirements.md file, which outlines structured acceptance criteria in a clear WHEN/THEN format. This file is editable, so teams and stakeholders can refine it together until it fully matches the business and technical context.For example, after an initial discovery session we might draft a prompt like:
1
2
3
4
5
6
7
Create an agent that automatically tags all Amazon S3 buckets.
Buckets starting with "sagemaker" → Environment=Production
All other buckets → Environment=Development
Preserve existing tags
Generate a summary report after execution
Ensure IAM least privilege
Continue processing even if individual buckets fail
From a single prompt, Kiro produces clear acceptance criteria, a detailed architecture with security and error-handling considerations, and an actionable set of implementation steps.

The Challenge: More Than Just “Add a Tag”

At first glance, tagging looks straightforward. In reality, production-ready automation must handle:
• Incomplete requirements: Missing edge cases like existing tags.
• Inconsistent error handling: Some buckets fail silently.
• IAM complexity: Cross-account and permission boundaries.
• Maintainability: Poor documentation makes future updates risky.
This is where Kiro IDE helps forcing clarity before coding, embedding error-handling into design, and tracking requirements all the way to implementation .

Phase 1: Requirements Specification

Kiro starts with structured requirements:
1
2
3
4
5
6
7
8
User Story:
As a DevOps engineer, I want to automatically tag S3 buckets based on naming conventions,
so that I can enforce consistent environment classification.
Acceptance Criteria:
WHEN the system scans all S3 buckets THEN it SHALL identify each bucket.
WHEN a bucket name starts with "sagemaker" THEN it SHALL apply Environment=Production.
WHEN no prefix is matched THEN it SHALL apply Environment=Development.
WHEN tagging completes THEN a summary report SHALL be generated.
Explore the Spec files on GitHub requirements.md 

Phase 2: Design Documentation

1
2
3
4
5
6
S3BucketTagger Architecture
├── AWS Session Management (authentication & validation)
├── Bucket Discovery Service (list all S3 buckets)
├── Classification Engine (apply sagemaker rule)
├── Tag Merge Service (preserve existing tags)
└── Reporting Service (generate logs & summary)
Explore the Spec files on GitHub design.md 

Phase 3: Task-Driven Implementation

1
2
3
4
5
Initialize AWS session
Classify buckets by prefix (sagemaker vs other)
Merge tags with existing ones
Add error handling for AccessDenied, NoSuchBucket, RequestTimeout
Generate execution summary report
Explore the Spec files on GitHub tasks.md 

Code Walkthrough

Classification Logic
1
2
3
4
def classify_bucket_environment(bucket_name: str) -> str:
if bucket_name.lower().startswith("sagemaker"):
return "production"
return "development"
Tag Preservation
1
2
3
4
def merge_environment_tag(existing_tags: Dict[str, str], environment_tag: str) -> Dict[str, str]:
merged_tags = existing_tags.copy()
merged_tags["Environment"] = environment_tag
return merged_tags
Error Handling
1
2
3
4
def is_recoverable_error(error: ClientError) -> bool:
return error.response['Error']['Code'] in {
'AccessDenied', 'NoSuchBucket', 'NoSuchTagSet', 'RequestTimeout'
}

Results

S3 BUCKET TAGGING SUMMARY REPORT:
1
2
3
4
5
6
7
Total buckets processed: 15
Successful operations: 15
Failed operations: 0
Success rate: 100%
Environment Distribution:
Production buckets: 5
Development buckets: 10
IAM Policy Requirements:
1
2
3
4
5
6
7
8
9
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketTagging",
"s3:PutBucketTagging"
],
"Resource": "*"
}

Technical Aspects of Kiro IDE:

  • Integrated Spec Management – Specs live in version control, making them part of your CI/CD lifecycle.
  • Task-Driven Execution – Each line of generated code references the task ID from the spec, ensuring nothing falls through the cracks.
  • Traceability – Requirements, design, and code are connected, enabling developers to audit why a line of code exists.
  • Error-Aware Code Generation – Kiro plans recoverable vs. non-recoverable AWS errors during design, embedding structured error handling into generated code.
  • IAM Least Privilege Awareness – Generated implementations include recommended IAM policies so solutions are secure by default.
  • Iterative Refinement – Updating the spec regenerates tasks and highlights changes’ impact on design and code, avoiding silent drift.

Conclusion:

The S3 tagging automation shows how Kiro’s spec-driven approach transforms a simple ask into a robust, production-ready AWS solution. By capturing requirements, designing for edge cases, and systematically implementing tasks, we built automation that is:
• Reliable (100% success rate across accounts).
• Maintainable (living specs in version control).
• Aligned with stakeholders (clear traceability from spec to implementation).
What looks like a small script becomes a scalable, auditable, and compliant automation because the process was designed with production in mind.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article