AWS Deployment Workflow Demo

From architecture diagram to production-ready CloudFormation stack — fully automated by pAiCoder.

AWS Deployment Workflow Diagram

Goal

This system serves a modern web application using a split architecture: static content (HTML/JS/CSS) is delivered globally through a CloudFront-fronted S3 origin, while dynamic content is served through a separate API endpoint backed by serverless compute. This separation lets the static front-end scale and cache at the edge for low latency and low cost, while dynamic business logic runs on-demand in Lambda with access to multiple persistence and caching backends. The design supports a public website (www.example.com) and a distinct API surface (api.example.com) so the two concerns can evolve, cache, and scale independently.

Architecture

A user opens a web browser and requests one of two hostnames. The two requests take entirely different paths through the system.

Static path (www.example.com)

The browser resolves www.example.com to an Amazon CloudFront Distribution. CloudFront serves cached static website content (HTML/JS/CSS) at the edge. On a cache miss, CloudFront fetches the object from its origin, an Amazon S3 bucket that holds the static website assets. This gives the front-end global distribution and edge caching without running any servers.

Dynamic path (https://api.example.com)

The browser calls https://api.example.com, which resolves to Amazon API Gateway. API Gateway is the single managed entry point for all dynamic requests. It invokes AWS Lambda Functions (the business-logic tier) via native Lambda proxy integration over HTTPS. The Lambda functions run inside a VPC so they can reach VPC-scoped data stores.

From Lambda, requests fan out to the data tier depending on the operation:

So the overall flow is: browser → (CloudFront → S3 static) for the site shell, and browser → API Gateway → Lambda (in VPC) → {DynamoDB, RDS, ElastiCache, S3} for all live data operations. The static and dynamic paths never cross; they share only the browser as a common client.

Architecture Diagram

Static content path:

    [web browser]
         │  www.example.com (HTTP/HTTPS)
         ▼
    [Amazon CloudFront Distribution]
         │  origin fetch (cache miss)
         ▼
    [Amazon S3 — static website bucket]
       (HTML / JS / CSS)

Dynamic content path:

    [web browser]
         │  https://api.example.com (HTTPS)
         ▼
    [Amazon API Gateway]
         │  Lambda proxy integration
         ▼
    ┌─────────────── VPC ────────────────────────────┐
    │        [AWS Lambda Functions]                   │
    │           │      │      │       │               │
    │   ┌───────┘      │      │       └────────┐      │
    │   ▼              ▼      ▼                ▼       │
    │ [Amazon      [Amazon  [Amazon      [Amazon S3   │
    │  RDS]      ElastiCache] DynamoDB]   app-data]    │
    │                                   🔒 (TLS/SSE)   │
    └─────────────────────────────────────────────────┘

AWS Components

Estimated Cost

Assumption: 100k dynamic API requests/month, ~50 GB CloudFront transfer, small RDS/ElastiCache instances, modest DynamoDB and S3 usage.

ComponentEst. monthly costNotes
CloudFront~$5~50 GB egress + requests; 1 TB free tier first year
S3 (static + app)~$1Storage + requests; 5 GB free tier
API Gateway~$0.35~$3.50 per million REST requests
Lambda~$0 (free tier)First 1M requests + 400k GB-s free
DynamoDB~$1On-demand at low volume; 25 GB free tier
Amazon RDS~$15Single db.t3.micro; 750 hrs free tier first year
ElastiCache~$12Single cache.t3.micro node
VPC endpoints / NAT~$0–$32$0 if using gateway endpoints only

Rough total: ~$35–$65/month depending on RDS/ElastiCache sizing and whether a NAT Gateway is used.

IAM Permissions Required

cloudformation:*
s3:*
cloudfront:*
apigateway:*
lambda:*
dynamodb:*
rds:*
elasticache:*
ec2:CreateVpc, ec2:CreateSubnet, ec2:CreateSecurityGroup,
ec2:AuthorizeSecurityGroupIngress, ec2:CreateVpcEndpoint,
ec2:DescribeVpcs, ec2:DescribeSubnets, ec2:DescribeSecurityGroups,
ec2:CreateRouteTable, ec2:CreateRoute, ec2:CreateInternetGateway,
ec2:CreateNatGateway, ec2:AllocateAddress
iam:CreateRole, iam:AttachRolePolicy, iam:PutRolePolicy, iam:PassRole,
iam:CreatePolicy, iam:GetRole
logs:CreateLogGroup, logs:PutRetentionPolicy, logs:CreateLogStream
acm:RequestCertificate, acm:DescribeCertificate
cognito-idp:*

Pre-Deployment Checklist

  1. AWS credentials configured (aws configure or environment variables).
  2. Region decided — update AWS_REGION in configs.py and parameters.json.
  3. Stack name decided — update STACK_NAME in configs.py.
  4. Secrets filled in — open .env and replace all YOUR_*_HERE values.
  5. Domain registered and hosted in Route 53.
  6. ACM certificates requested for both www.example.com (us-east-1) and api.example.com.
  7. VPC CIDR / subnet choices decided in parameters.json.
  8. Decide whether Lambda needs internet egress (NAT Gateway) or only VPC endpoints — set the EnableNatGateway parameter accordingly.

Implementation Phases

Phase 1: CloudFormation Infrastructure

Files: aws/cloud/stack.yaml, aws/cloud/parameters.json

The complete CloudFormation template defining ALL resources: the static S3 bucket + CloudFront distribution (with OAC to the bucket), API Gateway REST API + custom domain, Lambda functions with their execution role, VPC with private/public subnets, security groups, RDS instance, ElastiCache cluster, DynamoDB table, the app-data S3 bucket, and VPC gateway/interface endpoints for S3 and DynamoDB. All resource names and ARNs must be internally consistent, and parameters.json must have an entry for every Parameter in stack.yaml (region, VPC CIDR, subnet CIDRs, RDS credentials, instance classes, certificate ARNs, domain names, EnableNatGateway).

Phase 2: Operational Files

Files: aws/cloud/deploy.sh, aws/cloud/destroy.sh, aws/cloud/README.md, .env, configs.py

deploy.sh runs aws cloudformation deploy with --capabilities CAPABILITY_NAMED_IAM and the parameters file. destroy.sh runs aws cloudformation delete-stack and waits for completion. It first empties both S3 buckets (static + app-data), since CloudFormation cannot delete non-empty buckets. README.md explains setup and deploy steps.

Deployment Files

amazon-s3-hosted-websites/
  SPEC.md                     — this specification (source of truth)
  .env                        — AWS secrets (YOUR_*_HERE placeholders)
  configs.py                  — non-secret config (region, stack name, env)
  aws/
    cloud/
      stack.yaml              — CloudFormation template
      parameters.json         — stack parameters
      deploy.sh               — local deployment script
      README.md               — deployment notes
    AWS-DEPLOYMENT.md         — architecture overview

Deployment Notes

Unknowns

UnknownImpactResolution
Authentication/authorization layer?Diagram shows no Cognito or authorizerAmazon Cognito User Pool + API Gateway JWT authorizer
Which datastore is authoritative?Diagram wires Lambda to bothDynamoDB primary; RDS for relational; ElastiCache cache-only
Does Lambda need outbound internet?NAT Gateway adds ~$32/moVPC gateway endpoints only (no NAT)
ElastiCache engine?Affects cluster configRedis (single node)
Multi-AZ / high availability?Affects RDS and ElastiCache costSingle-AZ (cost-optimized)

Assumptions

Notes