Solution Architecture · Cloud Infrastructure · Pickles Asia - 2025

AWS Production Infrastructure
Ad-Hoc Cloud → Production-Grade Architecture

Pickles Asia's AWS infrastructure had grown ad-hoc since 2019 - workloads in the default VPC, overly permissive security groups, single-AZ RDS, secrets hardcoded as environment variables, no WAF, no formal DR plan, and no cost attribution model. I designed the full production infrastructure architecture for the Malaysia region launch: a multi-AZ VPC topology with private subnets for all workloads, ECS Fargate compute, RDS Multi-AZ with read replicas, ElastiCache cluster, CloudFront with WAF, Secrets Manager, structured IAM permission model, observability stack, and a CDK-based IaC baseline. The design also included a tiered disaster recovery framework with documented RPO/RTO targets and runbooks per failure scenario.

vpc.ap-southeast-5Deployed
3-AZ
Availability
100%
IaC
<60s
RDS RTO
0
Public subs
multi-az · 100% iac coverage ↑
The Starting Point

6 years of ad-hoc AWS. No architecture. Real security gaps.

Pickles Asia's AWS account had been provisioned in 2019 and expanded incrementally without a defined infrastructure architecture. By 2025, workloads were running in the default VPC with public and private resources mixed without a consistent subnet strategy. EC2 instances and ECS services sat behind security groups that had been widened over time to fix connectivity issues and never tightened. RDS was deployed as a single-AZ instance - a live auction platform with no database failover capability.

The Malaysia region launch created an opportunity and an obligation: stand up the new region properly, not as a clone of the existing ad-hoc setup. This required designing a proper infrastructure architecture that the team could deploy repeatably, understand fully, and operate with confidence.

  • Workloads in the default VPC - no documented network topology, public and private traffic mixed
  • Security groups with overly broad inbound rules - some with 0.0.0.0/0 on non-web ports
  • RDS single-AZ - any instance failure meant manual restore from snapshot with 30–60 minute downtime
  • Secrets hardcoded as Lambda/ECS environment variables in the AWS console - no rotation, no audit trail
  • No WAF - web-facing ALBs exposed directly to the internet without OWASP layer protection
  • No tagging policy - impossible to attribute costs by service, environment, or team
  • Infrastructure deployed entirely via console - no IaC, no reproducibility, no CI/CD for infra changes
  • No formal disaster recovery plan - no defined RPO/RTO targets, no runbooks for common failure scenarios

infra.baseline_auditNo Architecture
1
AZ (no HA)
0%
IaC coverage
None
WAF / DR plan
ComponentState
VPC topologyDefault VPC
RDSSingle-AZ
Secrets managementEnv vars in console
WAFNone
IaCNone
Disaster recoveryNo plan
Cost attributionNo tags
infrastructure audit · ap-southeast-1 baseline
The Architecture Design

7 design pillars. Built to be operated by a team of 5.

1
VPC topology - 3 AZs, strict subnet tiers - designed a /16 VPC split across 3 AZs. Three subnet tiers per AZ: Public (ALB only); Private App (ECS Fargate tasks, Lambda functions); Private Data (RDS, ElastiCache - no internet egress path). NAT Gateway per AZ. VPC Endpoints for S3 and DynamoDB. All security groups scoped to specific CIDR ranges - zero 0.0.0.0/0 on non-web ports.
2
Compute - ECS Fargate with auto-scaling - ECS Fargate for all containerised workloads. Two ECS clusters: production and staging with strict IAM boundary separation. Service auto-scaling based on ALB request count and CPU utilisation. Task definition managed via CDK. Circuit-breaker deployment rollback enabled on all services to auto-revert failed deployments without manual intervention.
3
Data layer - RDS Multi-AZ + ElastiCache cluster + S3 - RDS MySQL with Multi-AZ enabled: automatic failover to standby replica in a separate AZ in <60 seconds. One read replica for reporting workloads. ElastiCache Redis in cluster mode across 2 AZs. S3 + CloudFront for all static assets and vehicle media - signed URLs for access-controlled content. Automated daily RDS snapshots with 30-day retention.
4
Security posture - WAF, Secrets Manager, GuardDuty - AWS WAF deployed on CloudFront with managed rule set covering OWASP Top 10, bot protection, and rate limiting (500 req/5min per IP). AWS Secrets Manager for all credentials with automatic rotation. IAM roles designed with least-privilege per ECS task and Lambda function - no wildcard ARNs. GuardDuty enabled. VPC Flow Logs with 30-day retention. CloudTrail enabled for all regions.
5
Observability stack - structured logs, tracing, alerting - all ECS and Lambda workloads emit structured JSON logs to CloudWatch Logs. AWS X-Ray distributed tracing enabled. Per-service CloudWatch dashboards with four golden signals: latency (p50/p99), request rate, error rate, saturation. PagerDuty integration for P1 alerts. SNS topics for P2/P3 alerts routed to Slack.
6
Infrastructure as Code - AWS CDK (TypeScript) - all infrastructure defined in AWS CDK TypeScript. Stack structure: NetworkStack (VPC, subnets, NAT), ComputeStack (ECS clusters, task definitions), DataStack (RDS, ElastiCache), SecurityStack (WAF, Secrets Manager, GuardDuty). CI/CD pipeline in GitHub Actions: PR triggers cdk diff for plan review; merge triggers cdk deploy to staging; production deployment requires manual approval gate.
7
Disaster recovery framework - tiered RPO/RTO by service - classified all services into 3 DR tiers. Tier 1 (Critical): Live auction engine + bidding - RPO: 0 min, RTO: <5 min. Tier 2 (Important): User auth + vehicle catalogue - RPO: <5 min, RTO: <15 min. Tier 3 (Standard): Reporting + media - RPO: <1 hr, RTO: <1 hr. Per-scenario runbooks: AZ failure, region degradation, RDS failover, DDoS event, accidental data deletion.
Infrastructure Architecture (ap-southeast-5)
Edge
CloudFront CDN · WAF (OWASP Top 10) · Route 53
↓ HTTPS · Signed URLs for media
Public Subnets (3 AZs)
Application Load Balancer · ALB only - no compute
↓ Target Groups → ECS tasks
Private App Subnets
ECS Fargate
Lambda
NAT GW
↓ Secrets Manager · IAM task roles
Private Data Subnets
RDS Multi-AZ
ElastiCache
↓ No internet path
Observability
CloudWatch
X-Ray
GuardDuty
CloudTrail
IaC Stack Structure (CDK)
NetworkStack
SecurityStack
↓ depends on
DataStack
ComputeStack
↓ CI/CD: PR → diff · Merge → deploy staging · Approval → prod
The Results

Production-grade infrastructure. Reproducible. Operable. Secure.

3-AZ HA
Zero single points of failure

Every critical workload distributed across 3 AZs. RDS Multi-AZ automatic failover confirmed <60 seconds RTO. ECS circuit-breaker deployment rollback auto-reverts any failed container deployment. No single AZ loss can take the platform down.

100%
Infrastructure as Code

Every AWS resource defined in CDK TypeScript. Staging and production environments are identical reproductions - no configuration drift. New environments can be deployed from scratch with a single cdk deploy. Console-based infrastructure changes are blocked via SCPs.

0
Public subnets for workloads

All ECS tasks, Lambda functions, and database instances run in private subnets with no direct internet exposure. ALBs in public subnets are the only internet-facing layer. Security groups scoped to specific CIDR ranges. WAF blocks malicious requests at the CloudFront layer before they reach the application.

DR Tiers
Formal disaster recovery framework

All services classified into 3 DR tiers with defined RPO/RTO targets. Runbooks written for AZ failure, region degradation, RDS failover, DDoS event, and accidental data deletion. The team knows exactly what to do and in what order when any infrastructure failure occurs.

Security Architecture Decisions

Security designed in, not bolted on

Secrets Manager over environment variables

All credentials (DB passwords, API keys, third-party tokens) stored in AWS Secrets Manager with automatic rotation via Lambda rotation functions for RDS. Environment variables in ECS task definitions reference Secrets Manager ARNs - no plaintext secrets in CDK code, CI/CD pipelines, or CloudWatch logs. Rotation events logged to CloudTrail. Zero console-set environment variable credentials in the new infrastructure.

Least-privilege IAM per ECS task

Every ECS task and Lambda function has a dedicated IAM execution role scoped to exactly the AWS resources it needs - specific S3 bucket ARNs, specific DynamoDB tables, specific Secrets Manager secret ARNs. No wildcard ARNs. IAM roles reviewed and approved as part of the CDK PR process - any IAM change triggers a required security review label on the PR. Permission Boundaries applied to all application roles to prevent privilege escalation.

WAF rule strategy - managed + custom

AWS Managed Rules covering OWASP Top 10 (SQLi, XSS, common exploits), AWS Bot Control (blocking scrapers and scanners), and Amazon IP Reputation list. Custom rate limiting rule: 500 requests per 5-minute window per IP before CAPTCHA challenge, 2,000 requests before block. Geo-restriction not applied - Pickles Asia operates internationally. WAF metrics exported to CloudWatch with per-rule dashboards. All blocked requests logged to S3 for post-incident analysis.

SCP enforcement - no console deployments

AWS Service Control Policies applied at the AWS Organization level to prevent manual console-based creation or modification of core infrastructure resources (VPCs, ECS services, RDS instances, Lambda functions). All changes must flow through the CDK CI/CD pipeline with PR review. This eliminates the pattern that created the original ad-hoc environment - console fixes that become permanent undocumented infrastructure.

Engineering Decisions

Architectural choices, tradeoffs, and what nearly broke production

Multi-AZ active, not standby failover

Why not simpler single-AZ with regional failover?

Multi-AZ within a single region provides <60s automatic failover with zero configuration. It's built into RDS, ALB, and ECS. Cross-region failover adds operational complexity (DNS propagation, data replication lag). For an auction platform, <60s RDS recovery beats minutes-long cross-region cutover.

CDK over CloudFormation templates

Why AWS CDK instead of raw CloudFormation YAML?

CDK is a programming model on top of CloudFormation - it eliminates boilerplate and enables programmatic composition. You write TypeScript instead of maintaining 3000-line YAML. The CDK constructs encode AWS best practices (e.g., RDS defaults to encrypted, multi-AZ). Easier to version control and test.

What nearly failed: ElastiCache partition strategy

What architectural decision caused production issues?

Initially, we designed Redis as a single node. First load test showed it bottlenecked at ~20k ops/sec. We scaled to a cluster with 3 shards, but the hashing strategy for session keys wasn't optimal. A deploy that redistributed hash keys caused connection pool misses during peak bidding. Fixed by pinning Redis config and testing under realistic concurrency.

Lesson: Caching architectures hide performance issues until production load. Test at 3x expected peak capacity during design validation.

IAM principle of least privilege - strict

How did you balance security with developer velocity?

Built IAM roles with specific action + resource scopes. ECS tasks can only PutObject to their specific S3 bucket prefix, not the entire bucket. This prevented accidental data leaks and lateral movement if a container was compromised. Dev velocity improved because developers understood exactly what permissions they had.

THE TRADEOFFS

Cost · Risk · Tradeoffs

Estimated values based on production metrics and monitoring data

Cost Impact
~$8k → $6.2k
AWS monthly cost
Optimized instance sizing and Reserved Instances reduced 2025 spend vs legacy setup; 100% cost visibility with tagging
Risk Reduction
instance failure → 0 impact
Availability risk
Multi-AZ automatic failover and zero-downtime deployments via rolling restarts
>30 min → <60s
Recovery time (RDS failure)
Multi-AZ RDS failover happens automatically; manual recovery is no longer a path
Technical Tradeoff
increased
Infrastructure expertise required
Trade: team needs to understand CDK, VPC, RDS clusters. Mitigated by runbooks and design docs
Before vs After

Transformative Results: Before vs After

✕Before
  • Workloads in default VPCSecurity gaps
  • No IaC - manual setupError-prone
  • Single-AZ RDSNo failover
  • Overly permissive IAMSecurity risk
→
✓After
  • Multi-AZ VPC topologyHigh availability
  • 100% CDK IaC coverageReproducible
  • RDS Multi-AZ + read replicas<60s failover
  • Least-privilege IAM + WAFSecure by design
⇪Business Impact
3-AZ availability zones
<60s RDS failover RTO
100% IaC coverage
Tech Stack

What was used

IaCAWS CDK (TypeScript)
ComputeECS Fargate · AWS Lambda
NetworkingVPC · ALB · CloudFront · NAT GW
DatabaseRDS MySQL Multi-AZ · Read Replica
CacheElastiCache Redis (cluster mode)
SecurityWAF · Secrets Manager · GuardDuty
IAMLeast-privilege task roles · SCPs · Permission Boundaries
ObservabilityCloudWatch · X-Ray · CloudTrail · VPC Flow Logs
CDN / MediaS3 · CloudFront · Signed URLs
DNSRoute 53 · ACM (TLS)
CI/CD (Infra)GitHub Actions · cdk diff / deploy
Target regionap-southeast-5 (Malaysia)

Need to design production-grade cloud infrastructure from scratch?

I design AWS architectures that are secure by default, fully reproducible via IaC, and operable by real teams - not just impressive on paper.