From Zero to Deployed with an AI Agent
From Zero to Deployed with an AI Agent
Getting a new project deployed to AWS involves a lot of moving parts: VPC networking, ECS task definitions, load balancers, S3 buckets, CloudFront distributions, IAM policies, CI/CD pipelines, Docker builds. Each piece is individually straightforward, but wiring them all together correctly on the first try is where most people lose a few hours (or days).
This guide walks through using an AI agent with DevRamps to generate all of that from a single conversation, starting from an empty git repo and ending with a live app behind CloudFront.
Prerequisites
- An AWS account with admin access (or permission to create IAM roles and CloudFormation stacks)
- Node.js 18+
- An MCP-compatible AI coding agent (Claude Code, Cursor, Codex, Windsurf, or similar)
- Git and a GitHub repo (can be empty)
Set Up Agent Integration
Start with your repo cloned locally:
mkdir my-app && cd my-app
git init
Run:
npx @devramps/cli init-agent
This creates four files:
| File | Purpose |
|---|---|
.mcp.json |
Registers the DevRamps MCP server with your AI agent |
DEVRAMPS_AGENTS.md |
Rules the agent follows when generating infrastructure and pipelines |
CLAUDE.md |
References DEVRAMPS_AGENTS.md (loaded by Claude Code, Codex) |
AGENTS.md |
Same reference (loaded by Cursor, Windsurf, and others) |
DEVRAMPS_AGENTS.md is the important one. It contains constraints like “Terraform must include backend "s3" {}” and “CloudFront needs both an S3 origin and an ALB origin.” Left to its own devices, an AI agent will generate infrastructure that looks reasonable but breaks on first deploy. These rules prevent the common mistakes.
Start a Conversation
Open your AI coding agent in the project directory. Restart it so it picks up the new .mcp.json, then verify the DevRamps MCP server is connected (most agents have a way to list active MCP servers). Then:
Create a new app deployed to AWS — Node.js backend with a React frontend
The agent picks up the DevRamps tools and asks a few questions up front:
- Project name (suggests a default based on the directory)
- Stages — start with one, or set up staging + production?
- AWS account ID for each stage
- Region (defaults to us-east-1)
- Architecture tier — budget (~$30/mo), standard (~$80/mo), or high-availability (~$200/mo)
These are the only things the agent can’t figure out on its own. Everything else — deployment targets, artifact types, build commands, infrastructure topology — it determines from the architecture tier and the code it generates.
What Gets Generated
Terraform
The agent writes Terraform across separate files under infrastructure/:
infrastructure/
backend.tf # S3 remote state (empty backend block — configured during bootstrap)
providers.tf # AWS provider
variables.tf # region, account_id, env, app_name
outputs.tf # Cluster names, bucket names, distribution IDs
vpc.tf # Public + private subnets, NAT
security.tf # Security groups
ecs.tf # Fargate cluster, task definition, service
alb.tf # Load balancer, target group, listener
frontend.tf # S3 bucket for static assets
cloudfront.tf # CDN with S3 + ALB origins
The networking follows AWS best practices: ECS tasks run in private subnets with NAT for outbound access, the ALB sits in public subnets, and CloudFront handles ingress. The CloudFront distribution has two origins — static assets from S3 and API requests forwarded to the ALB — so both the React app and the Express API are served from the same domain.
The agent runs terraform validate after generating the files to catch syntax issues before presenting anything.
Cost estimate
Before proceeding, the agent shows a cost breakdown based on the architecture tier you picked:
| Resource | Est. Monthly Cost |
|---|---|
| ECS Fargate (0.25 vCPU, 0.5GB) | ~$9 |
| Application Load Balancer | ~$16 |
| NAT (t4g.nano / FCK-NAT) | ~$3 |
| S3 + CloudFront | ~$1 |
| CloudWatch Logs | ~$2 |
| Total | ~$31/mo |
It also lists a few optional upgrades with trade-offs and cost deltas — managed NAT Gateway for better availability, Multi-AZ RDS, larger task sizes. You can accept the defaults or ask for specific changes before moving on.
Pipeline
The pipeline definition goes to .devramps/my_app/pipeline.yaml. It defines the build and deploy sequence:
version: "1.0.0"
pipeline:
cloud_provider: AWS
pipeline_updates_require_approval: ALWAYS
stages:
- name: staging
account_id: "123456789012"
region: us-east-1
skip: ["Bake Period"]
vars:
env: staging
steps:
- name: Synthesize Infrastructure
id: infra
type: DEVRAMPS:TERRAFORM:SYNTHESIZE
params:
requires_approval: ALWAYS
source: /infrastructure
variables:
region: ${{ stage.region }}
aws_account_id: ${{ stage.account_id }}
env: ${{ vars.env }}
- name: Deploy Backend
type: DEVRAMPS:ECS:DEPLOY
goes_after: ["Synthesize Infrastructure"]
params:
cluster_name: ${{ steps.infra.ecs_cluster_name }}
service_name: ${{ steps.infra.ecs_service_name }}
reference_task_definition: ${{ steps.infra.task_definition }}
images:
- container_name: service
image: ${{ stage.artifacts.backend.image_url }}
- name: Deploy Frontend
type: DEVRAMPS:S3:UPLOAD
goes_after: ["Synthesize Infrastructure"]
params:
source_s3_url: ${{ stage.artifacts.frontend.s3_url }}
bucket: ${{ steps.infra.frontend_bucket_name }}
decompress: true
clean: true
- name: Invalidate Cache
type: DEVRAMPS:CLOUDFRONT:INVALIDATE
goes_after: ["Deploy Frontend"]
params:
distribution_id: ${{ steps.infra.cloudfront_distribution_id }}
paths: ["/*"]
- name: Bake Period
type: DEVRAMPS:APPROVAL:BAKE
params:
duration_minutes: 5
artifacts:
Backend Image:
id: backend
type: DEVRAMPS:DOCKER:BUILD
rebuild_when_changed: [/services/backend]
params:
dockerfile: /services/backend/Dockerfile
Frontend Bundle:
id: frontend
type: DEVRAMPS:BUNDLE:BUILD
per_stage: true
rebuild_when_changed: [/services/frontend]
dependencies: ["node.22"]
params:
build_commands: |
cd services/frontend
npm install && npm run build
zip -r ../../bundle.zip ./dist
file_path: /bundle.zip
The ${{ steps.infra.* }} expressions reference Terraform output names. The agent verifies that every expression has a matching output block in outputs.tf — a mismatch would cause a runtime failure.
IAM policies
The generate-iam-policies tool scans the Terraform files and produces .devramps/my_app/aws_additional_iam_policies.json. It detects both direct resource blocks and well-known Terraform modules (like terraform-aws-modules/vpc/aws) and maps them to the required IAM actions. The output is grouped by AWS service — one statement for EC2, one for ECS, one for S3, and so on.
Validation and application code
The agent validates the pipeline definition (checking step types, dependency references, stage names) and generates starter application code: an Express server with a health check at /health and a simple API at /api/hello, plus a React + Vite frontend that calls it.
Review and Bootstrap
Look through the generated files. The Terraform is worth reviewing most carefully — VPC CIDR ranges, instance sizes, security group ingress rules. Everything is standard code in your repo. Change whatever you want.
When it looks right:
npx @devramps/cli bootstrap
This authenticates via the browser, then deploys CloudFormation stacks to your AWS account. It provisions IAM roles, ECR repositories, S3 buckets for build artifacts, and a Terraform state bucket. It shows you exactly what it will create and asks for confirmation first.
Push and Deploy
Connect the repo in the DevRamps dashboard, then push:
git add .
git commit -m "Initial project setup"
git push origin main
The push triggers the pipeline. In the dashboard you’ll see it move through each step:
- Synthesize Infrastructure —
terraform planthenterraform apply - Build artifacts — Docker image for the backend, zipped Vite bundle for the frontend
- Deploy Backend — ECS service update with the new image
- Deploy Frontend — bundle uploaded to S3, CloudFront cache invalidated
The first run takes a few minutes since Terraform is creating all the resources. After that, deploys only touch what changed.
When the pipeline finishes, find the CloudFront domain in the dashboard or in the Terraform outputs. Open it in a browser — you’ll see the React app, fetching data from the Express API through the same CloudFront distribution.
Where to Go Next
This setup is a single staging environment. Some things to consider adding:
A production stage. Add another stage to the pipeline with a separate AWS account or region. The bake period gives you a window to verify staging before production deploys. See the stages documentation.
Ephemeral environments. An ephemeral_environments block in the pipeline gives you a fresh deployment per pull request. It spins up on PR open and tears down on merge. More on this in the ephemeral environments guide.
Slack notifications. A notifications block sends alerts on failures, required approvals, and rollbacks. Three lines of YAML.
Custom domain. Add an ACM certificate and Route 53 record to the Terraform. Update CloudFront’s viewer_certificate block and add an alias. ACM certificates are free.
Database migrations. The DEVRAMPS:DATABASE:MIGRATE step type runs migrations as part of the deploy, after infrastructure synthesis.
Auto-rollback. Set auto_rollback_alarm_name on a stage and point it at a CloudWatch alarm. If the alarm fires post-deploy, the stage rolls back automatically.
Full documentation at devramps.com/docs.