Auto Scaling Web Tier
AWS architecture template · SAA-C03: ALB → Auto Scaling EC2 fleet + EBS volumes → RDS + ElastiCache
Auto Scaling Web Tier is a free AWS architecture template built with Auto Scaling, EBS, EC2, ElastiCache, Load Balancer and RDS. Open it in TheArchitect to edit the diagram, estimate monthly cost, and export the CloudFormation or Terraform that deploys it.
AWS services in this template
- Auto Scaling
- EBS
- EC2
- ElastiCache
- Load Balancer
- RDS
Deployment notes
Needs input
- Add a Launch Template with a valid AMI to the Auto Scaling group before deployment.
- Uses demo VPC with public/private subnets and managed RDS password.
Generated CloudFormation — 38 resources
| Logical ID | Resource type |
|---|---|
| AutoScalingVPC10100016vpc | AWS::EC2::VPC |
| AutoScalingVPC10100016vpcedgewebsgSecurityGroup | AWS::EC2::SecurityGroup |
| AutoScalingVPC10100016vpcappruntimesgSecurityGroup | AWS::EC2::SecurityGroup |
| AutoScalingVPC10100016vpcappruntimesgSecurityGroupIngressRule | AWS::EC2::SecurityGroupIngress |
| AutoScalingVPC10100016vpcworkersgSecurityGroup | AWS::EC2::SecurityGroup |
| AutoScalingVPC10100016vpcdatastoresgSecurityGroup | AWS::EC2::SecurityGroup |
| AutoScalingVPC10100016vpcdatastoresgSecurityGroupIngressRule | AWS::EC2::SecurityGroupIngress |
| AutoScalingVPC10100016vpccontrolplanesgSecurityGroup | AWS::EC2::SecurityGroup |
| AutoScalingVPC10100016vpcPublicSubnet1 | AWS::EC2::Subnet |
| AutoScalingVPC10100016vpcPublicSubnet2 | AWS::EC2::Subnet |
| AutoScalingVPC10100016vpcPrivateSubnet1 | AWS::EC2::Subnet |
| AutoScalingVPC10100016vpcPrivateSubnet2 | AWS::EC2::Subnet |
| AutoScalingVPC10100016vpcPrivateSubnet3 | AWS::EC2::Subnet |
| AutoScalingVPC10100016vpcPrivateSubnet4 | AWS::EC2::Subnet |
| AutoScalingVPC10100016vpcInternetGateway | AWS::EC2::InternetGateway |
| AutoScalingVPC10100016vpcGatewayAttachment | AWS::EC2::VPCGatewayAttachment |
| AutoScalingVPC10100016vpcPublicRouteTable | AWS::EC2::RouteTable |
| AutoScalingVPC10100016vpcPublicRoute | AWS::EC2::Route |
| AutoScalingVPC10100016vpcPublicSubnet1RTA | AWS::EC2::SubnetRouteTableAssociation |
| AutoScalingVPC10100016vpcPublicSubnet2RTA | AWS::EC2::SubnetRouteTableAssociation |
| AutoScalingVPC10100016vpcNatEIP | AWS::EC2::EIP |
| AutoScalingVPC10100016vpcNatGateway | AWS::EC2::NatGateway |
| AutoScalingVPC10100016vpcPrivateRouteTable | AWS::EC2::RouteTable |
| AutoScalingVPC10100016vpcPrivateRoute | AWS::EC2::Route |
| AutoScalingVPC10100016vpcPrivateSubnet1RTA | AWS::EC2::SubnetRouteTableAssociation |
| AutoScalingVPC10100016vpcPrivateSubnet2RTA | AWS::EC2::SubnetRouteTableAssociation |
| AutoScalingVPC10100016vpcPrivateSubnet3RTA | AWS::EC2::SubnetRouteTableAssociation |
| AutoScalingVPC10100016vpcPrivateSubnet4RTA | AWS::EC2::SubnetRouteTableAssociation |
| AutoScalingVPC10100016vpcDbSubnetGroup | AWS::RDS::DBSubnetGroup |
| AutoScalingVPC10100016vpcCacheSubnetGroup | AWS::ElastiCache::SubnetGroup |
| WebALBelb | AWS::ElasticLoadBalancingV2::LoadBalancer |
| WebASGautoscaling | AWS::AutoScaling::AutoScalingGroup |
| WebInstanceec2 | AWS::EC2::Instance |
| AppVolumeebs | AWS::EC2::Volume |
| PostgreSQLDBrds | AWS::RDS::DBInstance |
| RedisCacheelasticache | AWS::ElastiCache::CacheCluster |
| PostgreSQLDBrdsIngressSG | AWS::EC2::SecurityGroup |
| RedisCacheelasticacheIngressSG | AWS::EC2::SecurityGroup |
View the full CloudFormation template
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Generated by TheArchitect — https://www.thecloudarchitect.dev",
"Metadata": {
"TheArchitect": {
"Edges": [
{
"From": "WebALBelb",
"To": "WebASGautoscaling"
},
{
"From": "WebInstanceec2",
"To": "PostgreSQLDBrds",
"Label": "SQL"
},
{
"From": "WebInstanceec2",
"To": "RedisCacheelasticache",
"Label": "cache"
}
]
}
},
"Resources": {
"AutoScalingVPC10100016vpc": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.10.0.0/16",
"EnableDnsHostnames": true,
"EnableDnsSupport": true,
"Tags": [
{
"Key": "Name",
"Value": "saa-asg-vpc"
}
]
}
},
"AutoScalingVPC10100016vpcedgewebsgSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupName": "edge-web-sg",
"GroupDescription": "Allow HTTPS from the internet to public load balancers",
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"Tags": [
{
"Key": "Name",
"Value": "edge-web-sg"
}
],
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": 443,
"ToPort": 443,
"CidrIp": "0.0.0.0/0"
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "-1",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"AutoScalingVPC10100016vpcappruntimesgSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupName": "app-runtime-sg",
"GroupDescription": "Allow application traffic from the edge tier",
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"Tags": [
{
"Key": "Name",
"Value": "app-runtime-sg"
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "-1",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"AutoScalingVPC10100016vpcappruntimesgSecurityGroupIngressRule": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": {
"Ref": "AutoScalingVPC10100016vpcappruntimesgSecurityGroup"
},
"IpProtocol": "tcp",
"FromPort": 80,
"ToPort": 80,
"SourceSecurityGroupId": {
"Ref": "AutoScalingVPC10100016vpcedgewebsgSecurityGroup"
}
}
},
"AutoScalingVPC10100016vpcworkersgSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupName": "worker-sg",
"GroupDescription": "Private worker runtime egress only",
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"Tags": [
{
"Key": "Name",
"Value": "worker-sg"
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "-1",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"AutoScalingVPC10100016vpcdatastoresgSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupName": "data-store-sg",
"GroupDescription": "Allow PostgreSQL from application runtimes",
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"Tags": [
{
"Key": "Name",
"Value": "data-store-sg"
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "-1",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"AutoScalingVPC10100016vpcdatastoresgSecurityGroupIngressRule": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": {
"Ref": "AutoScalingVPC10100016vpcdatastoresgSecurityGroup"
},
"IpProtocol": "tcp",
"FromPort": 5432,
"ToPort": 5432,
"SourceSecurityGroupId": {
"Ref": "AutoScalingVPC10100016vpcappruntimesgSecurityGroup"
}
}
},
"AutoScalingVPC10100016vpccontrolplanesgSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupName": "control-plane-sg",
"GroupDescription": "Private EKS control plane attachment group",
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"Tags": [
{
"Key": "Name",
"Value": "control-plane-sg"
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "-1",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"AutoScalingVPC10100016vpcPublicSubnet1": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"CidrBlock": "10.10.1.0/24",
"AvailabilityZone": "us-east-1a",
"MapPublicIpOnLaunch": true,
"Tags": [
{
"Key": "Name",
"Value": "public-edge-a"
}
]
}
},
"AutoScalingVPC10100016vpcPublicSubnet2": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"CidrBlock": "10.10.2.0/24",
"AvailabilityZone": "us-east-1b",
"MapPublicIpOnLaunch": true,
"Tags": [
{
"Key": "Name",
"Value": "public-edge-b"
}
]
}
},
"AutoScalingVPC10100016vpcPrivateSubnet1": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"CidrBlock": "10.10.11.0/24",
"AvailabilityZone": "us-east-1a",
"MapPublicIpOnLaunch": false,
"Tags": [
{
"Key": "Name",
"Value": "private-app-a"
}
]
}
},
"AutoScalingVPC10100016vpcPrivateSubnet2": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"CidrBlock": "10.10.12.0/24",
"AvailabilityZone": "us-east-1b",
"MapPublicIpOnLaunch": false,
"Tags": [
{
"Key": "Name",
"Value": "private-app-b"
}
]
}
},
"AutoScalingVPC10100016vpcPrivateSubnet3": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"CidrBlock": "10.10.21.0/24",
"AvailabilityZone": "us-east-1a",
"MapPublicIpOnLaunch": false,
"Tags": [
{
"Key": "Name",
"Value": "private-data-a"
}
]
}
},
"AutoScalingVPC10100016vpcPrivateSubnet4": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"CidrBlock": "10.10.22.0/24",
"AvailabilityZone": "us-east-1b",
"MapPublicIpOnLaunch": false,
"Tags": [
{
"Key": "Name",
"Value": "private-data-b"
}
]
}
},
"AutoScalingVPC10100016vpcInternetGateway": {
"Type": "AWS::EC2::InternetGateway",
"Properties": {
"Tags": [
{
"Key": "Name",
"Value": "saa-asg-vpc-igw"
}
]
}
},
"AutoScalingVPC10100016vpcGatewayAttachment": {
"Type": "AWS::EC2::VPCGatewayAttachment",
"Properties": {
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"InternetGatewayId": {
"Ref": "AutoScalingVPC10100016vpcInternetGateway"
}
}
},
"AutoScalingVPC10100016vpcPublicRouteTable": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"Tags": [
{
"Key": "Name",
"Value": "saa-asg-vpc-public-rt"
}
]
}
},
"AutoScalingVPC10100016vpcPublicRoute": {
"Type": "AWS::EC2::Route",
"DependsOn": [
"AutoScalingVPC10100016vpcGatewayAttachment"
],
"Properties": {
"RouteTableId": {
"Ref": "AutoScalingVPC10100016vpcPublicRouteTable"
},
"DestinationCidrBlock": "0.0.0.0/0",
"GatewayId": {
"Ref": "AutoScalingVPC10100016vpcInternetGateway"
}
}
},
"AutoScalingVPC10100016vpcPublicSubnet1RTA": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": {
"Ref": "AutoScalingVPC10100016vpcPublicSubnet1"
},
"RouteTableId": {
"Ref": "AutoScalingVPC10100016vpcPublicRouteTable"
}
}
},
"AutoScalingVPC10100016vpcPublicSubnet2RTA": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": {
"Ref": "AutoScalingVPC10100016vpcPublicSubnet2"
},
"RouteTableId": {
"Ref": "AutoScalingVPC10100016vpcPublicRouteTable"
}
}
},
"AutoScalingVPC10100016vpcNatEIP": {
"Type": "AWS::EC2::EIP",
"DependsOn": [
"AutoScalingVPC10100016vpcGatewayAttachment"
],
"Properties": {
"Domain": "vpc"
}
},
"AutoScalingVPC10100016vpcNatGateway": {
"Type": "AWS::EC2::NatGateway",
"Properties": {
"AllocationId": {
"Fn::GetAtt": [
"AutoScalingVPC10100016vpcNatEIP",
"AllocationId"
]
},
"SubnetId": {
"Ref": "AutoScalingVPC10100016vpcPublicSubnet1"
},
"Tags": [
{
"Key": "Name",
"Value": "saa-asg-vpc-nat"
}
]
}
},
"AutoScalingVPC10100016vpcPrivateRouteTable": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
},
"Tags": [
{
"Key": "Name",
"Value": "saa-asg-vpc-private-rt"
}
]
}
},
"AutoScalingVPC10100016vpcPrivateRoute": {
"Type": "AWS::EC2::Route",
"Properties": {
"RouteTableId": {
"Ref": "AutoScalingVPC10100016vpcPrivateRouteTable"
},
"DestinationCidrBlock": "0.0.0.0/0",
"NatGatewayId": {
"Ref": "AutoScalingVPC10100016vpcNatGateway"
}
}
},
"AutoScalingVPC10100016vpcPrivateSubnet1RTA": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": {
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet1"
},
"RouteTableId": {
"Ref": "AutoScalingVPC10100016vpcPrivateRouteTable"
}
}
},
"AutoScalingVPC10100016vpcPrivateSubnet2RTA": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": {
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet2"
},
"RouteTableId": {
"Ref": "AutoScalingVPC10100016vpcPrivateRouteTable"
}
}
},
"AutoScalingVPC10100016vpcPrivateSubnet3RTA": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": {
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet3"
},
"RouteTableId": {
"Ref": "AutoScalingVPC10100016vpcPrivateRouteTable"
}
}
},
"AutoScalingVPC10100016vpcPrivateSubnet4RTA": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": {
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet4"
},
"RouteTableId": {
"Ref": "AutoScalingVPC10100016vpcPrivateRouteTable"
}
}
},
"AutoScalingVPC10100016vpcDbSubnetGroup": {
"Type": "AWS::RDS::DBSubnetGroup",
"Properties": {
"DBSubnetGroupDescription": "Private subnets for saa-asg-vpc",
"SubnetIds": [
{
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet1"
},
{
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet2"
},
{
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet3"
},
{
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet4"
}
],
"Tags": [
{
"Key": "Name",
"Value": "saa-asg-vpc-db-subnet-group"
}
]
}
},
"AutoScalingVPC10100016vpcCacheSubnetGroup": {
"Type": "AWS::ElastiCache::SubnetGroup",
"Properties": {
"Description": "Private subnets for saa-asg-vpc",
"SubnetIds": [
{
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet1"
},
{
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet2"
},
{
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet3"
},
{
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet4"
}
],
"Tags": [
{
"Key": "Name",
"Value": "saa-asg-vpc-cache-subnet-group"
}
]
}
},
"WebALBelb": {
"Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
"Properties": {
"Name": "saa-asg-web-alb",
"Type": "application",
"Scheme": "internet-facing",
"IpAddressType": "ipv4",
"Subnets": [
{
"Ref": "AutoScalingVPC10100016vpcPublicSubnet1"
},
{
"Ref": "AutoScalingVPC10100016vpcPublicSubnet2"
}
],
"SecurityGroups": [
{
"Ref": "AutoScalingVPC10100016vpcedgewebsgSecurityGroup"
}
]
}
},
"WebASGautoscaling": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"Properties": {
"AutoScalingGroupName": "saa-asg-web-fleet",
"MinSize": "2",
"MaxSize": "20",
"DesiredCapacity": "2",
"HealthCheckType": "ELB",
"HealthCheckGracePeriod": 300,
"VPCZoneIdentifier": [
{
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet1"
},
{
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet2"
}
]
}
},
"WebInstanceec2": {
"Type": "AWS::EC2::Instance",
"Properties": {
"InstanceType": "t3.medium",
"Tags": [
{
"Key": "Name",
"Value": "saa-asg-web-instance"
}
],
"SubnetId": {
"Ref": "AutoScalingVPC10100016vpcPrivateSubnet1"
},
"SecurityGroupIds": [
{
"Ref": "AutoScalingVPC10100016vpcappruntimesgSecurityGroup"
}
],
"MetadataOptions": {
"HttpTokens": "required"
}
}
},
"AppVolumeebs": {
"Type": "AWS::EC2::Volume",
"Properties": {
"AvailabilityZone": "us-east-1a",
"Size": 20,
"VolumeType": "gp3",
"Throughput": 125,
"Encrypted": true
}
},
"PostgreSQLDBrds": {
"Type": "AWS::RDS::DBInstance",
"Properties": {
"DBInstanceIdentifier": "saa-asg-appdb",
"Engine": "postgres",
"DBName": "appdb",
"DBInstanceClass": "db.t4g.micro",
"DBSubnetGroupName": {
"Ref": "AutoScalingVPC10100016vpcDbSubnetGroup"
},
"VPCSecurityGroups": [
{
"Ref": "AutoScalingVPC10100016vpcdatastoresgSecurityGroup"
},
{
"Ref": "PostgreSQLDBrdsIngressSG"
}
],
"PubliclyAccessible": false,
"AllocatedStorage": "20",
"MaxAllocatedStorage": 100,
"StorageType": "gp3",
"MasterUsername": "appadmin",
"ManageMasterUserPassword": true,
"StorageEncrypted": true,
"BackupRetentionPeriod": 7
}
},
"RedisCacheelasticache": {
"Type": "AWS::ElastiCache::CacheCluster",
"Properties": {
"ClusterName": "saa-asg-cache",
"Engine": "redis",
"CacheNodeType": "cache.t4g.micro",
"NumCacheNodes": 1,
"CacheSubnetGroupName": {
"Ref": "AutoScalingVPC10100016vpcCacheSubnetGroup"
},
"VpcSecurityGroupIds": [
{
"Fn::GetAtt": [
"AutoScalingVPC10100016vpc",
"DefaultSecurityGroup"
]
},
{
"Ref": "RedisCacheelasticacheIngressSG"
}
]
}
},
"PostgreSQLDBrdsIngressSG": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Allow connected compute to RDS postgres on port 5432",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": 5432,
"ToPort": 5432,
"SourceSecurityGroupId": {
"Ref": "AutoScalingVPC10100016vpcappruntimesgSecurityGroup"
}
}
],
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
}
}
},
"RedisCacheelasticacheIngressSG": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Allow connected compute to ElastiCache redis on port 6379",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": 6379,
"ToPort": 6379,
"SourceSecurityGroupId": {
"Ref": "AutoScalingVPC10100016vpcappruntimesgSecurityGroup"
}
}
],
"VpcId": {
"Ref": "AutoScalingVPC10100016vpc"
}
}
}
}
}Generated by TheArchitect from the diagram above. Review values such as names, CIDR ranges and instance sizes before deploying to your account.