Visualize your terraform plan as an animated city skyline — buildings rise
with cranes, get renovated with scaffolding, or demolished with wrecking balls.
Built end-to-end with Kiro IDE to show how an AI-powered development environment architects a complete solution: from container packaging and modular Terraform to a zero-dependency CLI tool and CI/CD pipeline.
# Quickest way to try it (from the cli/ directory)
cd cli && npx . --file examples/sample-plan.jsonOr pipe a real plan:
cd infra
terraform show -json plan.tfplan | npx ../cli┌─────────────────────────────────────────────────────────────────────┐
│ AWS Cloud │
│ │
│ ┌──────────── VPC (10.0.0.0/16) ────────────────────────────────┐ │
│ │ │ │
│ │ ┌─── Public Subnets ───┐ ┌─── Private Subnets ───┐ │ │
│ │ │ │ │ │ │ │
│ │ │ ┌──────────────┐ │ │ ┌────────────────┐ │ │ │
│ │ │ │ ALB (managed)│───│────│──▶│ ECS Fargate │ │ │ │
│ │ │ │ HTTPS/TLS │ │ │ │ (Express Mode)│ │ │ │
│ │ │ └──────────────┘ │ │ └────────────────┘ │ │ │
│ │ │ │ │ │ │ │ │
│ │ │ ┌──────────────┐ │ │ ┌──────▼─────────┐ │ │ │
│ │ │ │ NAT Gateway │◀──│────│───│ nginx:8080 │ │ │ │
│ │ │ └──────────────┘ │ │ │ (static app) │ │ │ │
│ │ └──────────────────────┘ │ └────────────────┘ │ │ │
│ │ └────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌──────────────────────────────────────┐ │
│ │ ECR │ │ Managed by ECS Express Mode: │ │
│ │ (images) │ │ • Auto-scaling (request-count based) │ │
│ └─────────────┘ │ • TLS certificates (ACM) │ │
│ │ • Target groups & health checks │ │
│ │ • Canary deployments │ │
│ │ • CloudWatch Logs │ │
│ └──────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
tfplanbuilder/
├── .kiro/ # Kiro IDE configuration
│ ├── steering/ # Project rules & conventions
│ │ ├── project-conventions.md # Always-on coding standards
│ │ ├── terraform-patterns.md # Active when editing *.tf files
│ │ └── docker-guidelines.md # Active when editing Dockerfiles
│ └── specs/tfplanbuilder/ # Spec-driven development docs
│ ├── requirements.md # Functional & non-functional reqs
│ ├── design.md # Architecture & component design
│ └── tasks.md # 52 implementation tasks
│
├── app/ # Container application
│ ├── Dockerfile # nginx:alpine, non-root, health check
│ ├── nginx.conf # Production static server + /ping
│ ├── index.html # The skyline visualization
│ └── .dockerignore
│
├── cli/ # CLI tool (npx tfplanbuilder)
│ ├── bin/tfplanbuilder.js # Zero-dependency Node.js CLI
│ ├── web/index.html # Same visualization, auto-loads plan
│ ├── examples/sample-plan.json # 12-resource sample plan
│ ├── package.json # npm package config
│ └── README.md
│
├── infra/ # Terraform infrastructure
│ ├── main.tf # Root config — wires modules
│ ├── variables.tf # All inputs with validation
│ ├── outputs.tf # Service URL, ECR URL, cluster
│ ├── versions.tf # Provider constraints + S3 backend
│ ├── terraform.tfvars.example # Copy → terraform.tfvars
│ └── modules/
│ ├── networking/ # VPC, subnets, NAT, route tables
│ ├── ecr/ # Container registry + lifecycle
│ └── ecs-express/ # ECS Express Gateway + IAM roles
│
├── .github/workflows/deploy.yml # CI/CD: build → ECR → plan → apply
├── Makefile # Developer commands
├── .gitignore
└── BLOG.md # Companion blog post
# Run with the included sample using npx (from the cli/ directory)
cd cli
npx . --file examples/sample-plan.json
# Or run directly with node
node cli/bin/tfplanbuilder.js --file cli/examples/sample-plan.jsonPipe a real terraform plan:
cd infra
terraform plan -out=plan.tfplan
terraform show -json plan.tfplan | npx ../cliInstall globally (so tfplanbuilder works anywhere):
cd cli
npm linkThen use it directly:
terraform show -json plan.tfplan | tfplanbuilder
tfplanbuilder --file plan.jsonBrowser opens at http://127.0.0.1:3333 with the visualization auto-playing.
make run
# → http://localhost:8080 — paste any plan text or JSONcd infra
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars
terraform init
terraform apply
# Push the app image
cd .. && make push IMAGE_TAG=v1.0.0
# Deploy with the new image
cd infra && terraform apply -var="container_image_tag=v1.0.0"
# Get the URL
terraform output service_endpointtfplanbuilder — Visualize terraform plans as an animated city skyline
USAGE:
terraform show -json plan.tfplan | tfplanbuilder
tfplanbuilder --file plan.json
OPTIONS:
--file <path> Read plan JSON from a file instead of stdin
--port <num> Port for the local server (default: 3333)
--no-open Don't auto-open the browser
-h, --help Show this help
Aliases: tfplanbuilder, tfpb
| Action | Animation | Color |
|---|---|---|
| Create | Crane lifts a new building | Green |
| Update | Scaffolding wraps the building | Amber |
| Replace | Demolished then rebuilt | Amber |
| Destroy | Wrecking ball, dust, rubble | Red |
Provider colors: AWS (orange), Azure (blue), GCP (green), Other (gray)
Click any building to open the inspector panel showing:
- Resource address, type, provider, module path
- Attribute diff (old → new values) when using JSON plan input
This project uses ECS Express Mode (launched Nov 2025) — you provide a container image and two IAM roles, and Express Mode handles everything else:
- Application Load Balancer with HTTPS/TLS
- Auto-scaling (request-count, CPU, or memory based)
- Security groups and target groups
- Canary deployments
- CloudWatch Logs
The Terraform is modular:
modules/networking— VPC with public/private subnets across 2 AZsmodules/ecr— Container registry with lifecycle policies and scan-on-pushmodules/ecs-express— ECS cluster, IAM roles, Express Gateway Service
The GitHub Actions workflow (.github/workflows/deploy.yml) runs on push to main:
- Build — Docker image from
app/ - Push — To ECR with
sha-<commit>tag - Plan —
terraform planwith the new image tag - Apply — Deploys to ECS Express (main branch only)
On PRs, it runs plan-only so reviewers can see infrastructure changes.
Required secret: AWS_DEPLOY_ROLE_ARN (GitHub OIDC federation — no long-lived credentials)
make help # Show all commands
make build # Build Docker image locally
make run # Run on localhost:8080
make plan # Terraform plan
make apply # Terraform apply
make push # Build + push to ECR
make destroy # Tear down infrastructure
make fmt # Format Terraform files
make lint # Validate Terraform
make clean # Remove local artifacts| Resource | Monthly Cost |
|---|---|
| ECS Fargate (512 CPU / 1GB, 1 task) | ~$15 |
| NAT Gateway | ~$32 + data |
| ALB (shared, managed by Express Mode) | ~$0 incremental |
| ECR | < $1 |
Set enable_nat_gateway = false for demos to save ~$32/month.
This entire project — architecture, infrastructure, application, CLI tool, and CI/CD — was designed and implemented in a single Kiro session. Read the companion blog post for the full story.
make destroy
# or
cd infra && terraform destroy