Skip to main content

AWS Overview

Cloud Infrastructure Architecture

Amply runs on Amazon Web Services (AWS) for reliable, scalable, and secure hosting.

AWS Account Structure

Amply AWS Organisation
├── amply-production # Production workloads
├── amply-staging # Pre-production testing
├── amply-sandbox # Integrator testing environment
└── amply-shared-services # Shared resources (CI/CD, monitoring)

Region Strategy

Primary Region: eu-central-1 (Frankfurt)

  • EU data residency requirements
  • Good latency for European users
  • Full service availability

Future: Multi-region for global availability

Architecture Diagram

                              ┌─────────────────┐
│ Route 53 │
│ DNS │
└────────┬────────┘

┌────────▼────────┐
│ CloudFront │
│ CDN │
└────────┬────────┘

┌──────────────────────────────┼──────────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────────┐ ┌───────────────┐
│ S3 │ │ Application │ │ S3 │
│ (Static) │ │ Load Balancer │ │ (Widgets) │
│ │ │ │ │ │
│ React Frontend│ └─────────┬─────────┘ │ Widget Bundle │
└───────────────┘ │ └───────────────┘

┌──────────▼──────────┐
│ │
│ ECS Fargate │
│ (API + Workers) │
│ │
└──┬─────┬─────┬─────┬┘
│ │ │ │
┌──────────────────┤ │ │ ├──────────────────┐
│ │ │ │ │ │
▼ ▼ │ ▼ ▼ ▼
┌───────────┐ ┌───────────┐│┌───────────┐ ┌───────────┐
│ RDS │ │ElastiCache││| SQS │ │ S3 │
│PostgreSQL │ │ Redis │││ Queues │ │ Storage │
└───────────┘ └───────────┘│└───────────┘ └───────────┘


┌───────────┐
│ SES │
│ Email │
└───────────┘

Service Summary

ServicePurposeDocumentation
ECS FargateAPI containersecs.md
RDSPostgreSQL databaserds.md
ElastiCacheRedis for caching/sessionselasticache.md
S3Object storage, checkpointss3.md
SQSMessage queue (future - Celery)sqs.md
SESTransactional emailses.md
CloudFrontCDNcloudfront.md
Route 53DNS managementroute53.md
Secrets ManagerCredential storagesecrets-manager.md
CloudWatchMonitoring and loggingnot yet documented

VPC Architecture

VPC: 10.0.0.0/16
├── Public Subnets (2 AZs)
│ ├── 10.0.1.0/24 (eu-central-1a) - ALB, NAT Gateway
│ └── 10.0.2.0/24 (eu-central-1b) - ALB, NAT Gateway

├── Private Subnets (2 AZs)
│ ├── 10.0.10.0/24 (eu-central-1a) - ECS, RDS
│ └── 10.0.20.0/24 (eu-central-1b) - ECS, RDS

└── Isolated Subnets (2 AZs)
├── 10.0.100.0/24 (eu-central-1a) - RDS (multi-AZ)
└── 10.0.200.0/24 (eu-central-1b) - RDS (multi-AZ)

Security Groups

┌─────────────────────────────────────────────────────────────┐
│ Internet │
└─────────────────────────────┬───────────────────────────────┘
│ HTTPS (443)

┌─────────────────────────────────────────────────────────────┐
│ sg-alb: Application Load Balancer │
│ Inbound: 443 from 0.0.0.0/0 │
│ Outbound: 8000 to sg-ecs │
└─────────────────────────────┬───────────────────────────────┘
│ 8000

┌─────────────────────────────────────────────────────────────┐
│ sg-ecs: ECS Tasks │
│ Inbound: 8000 from sg-alb │
│ Outbound: 5432 to sg-rds, 6379 to sg-redis, 443 to 0.0.0.0 │
└─────────────────────────────┬───────────────────────────────┘

┌─────────────────────┼─────────────────────┐
│ 5432 │ 6379 │ 443
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ sg-rds │ │ sg-redis │ │ External │
│ Inbound: 5432 │ │ Inbound: 6379 │ │ (Stripe, │
│ from sg-ecs │ │ from sg-ecs │ │ SES, S3) │
└───────────────┘ └───────────────┘ └───────────────┘

IAM Structure

Roles

ECS Task Execution Role
├── AmazonECSTaskExecutionRolePolicy
├── SecretsManager read access
└── CloudWatch Logs write access

ECS Task Role (application)
├── S3 read/write (amply-storage-*)
├── SQS send/receive (amply-*)
├── SES send email
├── Secrets Manager read
└── CloudWatch metrics/logs

CI/CD Role (GitHub Actions)
├── ECR push
├── ECS deploy
├── S3 deploy (frontend)
└── CloudFront invalidate

Policies

Least-privilege policies for each service:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::amply-storage-prod/*"
}
]
}

Cost Estimation

ServiceConfigurationEst. Monthly Cost
ECS Fargate2 × 0.5 vCPU, 1GB~$30
RDSdb.t3.small, Multi-AZ~$50
ElastiCachecache.t3.micro~$15
S3100GB storage~$3
CloudFront100GB transfer~$10
SQS1M requests~$0.40
SES10k emails~$1
Route 531 hosted zone~$0.50
Secrets Manager10 secrets~$4
Total~$115/month

Estimates for initial scale. Costs increase with usage.

Terraform Structure

Infrastructure as Code using Terraform:

amply-infrastructure/
├── terraform/
│ ├── environments/
│ │ ├── production/
│ │ │ ├── main.tf
│ │ │ ├── variables.tf
│ │ │ └── terraform.tfvars
│ │ ├── staging/
│ │ └── sandbox/
│ │
│ └── modules/
│ ├── vpc/
│ ├── ecs/
│ ├── rds/
│ ├── elasticache/
│ ├── s3/
│ ├── cloudfront/
│ └── monitoring/

├── .github/
│ └── workflows/
│ └── terraform.yml

└── README.md

Deployment Pipeline

GitHub Push


GitHub Actions

├── Build Docker image
├── Push to ECR
├── Run Terraform plan
├── (on main) Apply Terraform
└── Deploy to ECS

Monitoring & Alerting

  • CloudWatch Dashboards: Key metrics visualisation
  • CloudWatch Alarms: Alert on thresholds
  • CloudWatch Logs: Centralised logging
  • Sentry: Application errors (see sentry.md)

Backup Strategy

ResourceBackup MethodRetention
RDSAutomated snapshots7 days
RDSManual snapshotsMonthly, 1 year
S3VersioningForever
S3Cross-region replicationCritical buckets

Disaster Recovery

RTO (Recovery Time Objective): 4 hours RPO (Recovery Point Objective): 1 hour

  • Multi-AZ for RDS and ElastiCache
  • S3 cross-region replication for critical data
  • Infrastructure as Code for quick rebuilds
  • Documented runbooks

Related: