Deploy 3-tier app lên AWS nghe có vẻ phức tạp — VPC, ALB, ECS, RDS, Redis mỗi thứ một kiểu. Nhưng với CDK, bạn có thể định nghĩa toàn bộ kiến trúc trong 40 dòng code. Mình chọn T4G.MEDIUM cho RDS vì ARM rẻ hơn Intel khoảng 20% cho cùng performance.
flowchart TB
subgraph "Tier 1: Public"
ALB["ALB · HTTPS"]
end
subgraph "Tier 2: Private App"
ECS["ECS Fargate · 3 tasks"]
end
subgraph "Tier 3: Isolated Data"
RDS["RDS PostgreSQL · Multi-AZ"]
Redis["ElastiCache Redis"]
end
Internet --> ALB
ALB --> ECS
ECS --> RDS
ECS --> Redis
const vpc = new ec2.Vpc(this, "VPC", {
maxAzs: 2,
natGateways: 1,
subnetConfiguration: [
{ name: "public", subnetType: ec2.SubnetType.PUBLIC },
{ name: "app", subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
{ name: "data", subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
],
});
// natGateways: 1 để tiết kiệm chi phí, production nên để 2 cho HA.
// Gateway Endpoint cho S3 và DynamoDB miễn phí, không cần NAT.
vpc.addGatewayEndpoint("S3Endpoint", {
service: ec2.GatewayVpcEndpointAwsService.S3,
});
vpc.addGatewayEndpoint("DynamoDBEndpoint", {
service: ec2.GatewayVpcEndpointAwsService.DYNAMODB,
});
// Ba tầng này là kiến trúc phổ biến nhất trên AWS, và với CDK bạn có thể replicate từ dev lên production chỉ bằng cách đổi vài parameter.
const db = new rds.DatabaseInstance(this, "DB", {
engine: rds.DatabaseInstanceEngine.postgres({
version: rds.PostgresEngineVersion.VER_17,
}),
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.T4G,
ec2.InstanceSize.MEDIUM
),
vpc,
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
multiAz: true,
backupRetention: cdk.Duration.days(14),
storageEncrypted: true,
deletionProtection: true,
});
const service = new ecsPatterns.ApplicationLoadBalancedFargateService(
this,
"App",
{
cluster,
cpu: 512,
memoryLimitMiB: 1024,
desiredCount: 3,
taskSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
publicLoadBalancer: true,
}
);
Bài sau: Phần 38: Cost optimization