{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "AWS CloudFormation Sample Template multi-tier-web-app-in-vpc.template: Sample template showing how to create a multi-tier web application in a VPC with multiple subnets. The first subnet is public and contains and internet facing load balancer, a NAT device for internet access from the private subnet and a bastion host to allow SSH access to the hosts in the private subnet. The second subnet is private and contains a Frontend fleet of EC2 instances, an internal load balancer and a Backend fleet of EC2 instances. **WARNING** This template creates Elastic Load Balancers and Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template.", "Parameters" : { "KeyName": { "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances", "Type": "String", "MinLength": "1", "MaxLength": "255", "AllowedPattern" : "[\\x20-\\x7E]*", "ConstraintDescription" : "can contain only ASCII characters." }, "SSHLocation" : { "Description" : "Lockdown SSH access to the bastion host (default can be accessed from anywhere)", "Type" : "String", "MinLength": "9", "MaxLength": "18", "Default" : "0.0.0.0/0", "AllowedPattern" : "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription" : "must be a valid CIDR range of the form x.x.x.x/x." }, "FrontendInstanceType" : { "Description" : "Frontend Server EC2 instance type", "Type" : "String", "Default" : "m1.small", "AllowedValues" : [ "t1.micro","m1.small","m1.medium","m1.large","m1.xlarge","m2.xlarge","m2.2xlarge","m2.4xlarge","m3.xlarge","m3.2xlarge","c1.medium","c1.xlarge","cc1.4xlarge","cc2.8xlarge","cg1.4xlarge"], "ConstraintDescription" : "must be a valid EC2 instance type." }, "FrontendSize" : { "Description" : "Number of EC2 instances to launch for the Frontend server", "Type" : "Number", "Default" : "1" }, "BackendInstanceType" : { "Description" : "Backend Server EC2 instance type", "Type" : "String", "Default" : "m1.small", "AllowedValues" : [ "t1.micro","m1.small","m1.medium","m1.large","m1.xlarge","m2.xlarge","m2.2xlarge","m2.4xlarge","m3.xlarge","m3.2xlarge","c1.medium","c1.xlarge","cc1.4xlarge","cc2.8xlarge","cg1.4xlarge"], "ConstraintDescription" : "must be a valid EC2 instance type." }, "BackendSize" : { "Description" : "Number of EC2 instances to launch for the backend server", "Type" : "Number", "Default" : "1" }, "BastionInstanceType" : { "Description" : "Bastion Host EC2 instance type", "Type" : "String", "Default" : "m1.small", "AllowedValues" : [ "t1.micro","m1.small","m1.medium","m1.large","m1.xlarge","m2.xlarge","m2.2xlarge","m2.4xlarge","m3.xlarge","m3.2xlarge","c1.medium","c1.xlarge","cc1.4xlarge","cc2.8xlarge","cg1.4xlarge"], "ConstraintDescription" : "must be a valid EC2 instance type." }, "NATInstanceType" : { "Description" : "NET Device EC2 instance type", "Type" : "String", "Default" : "m1.small", "AllowedValues" : [ "t1.micro","m1.small","m1.medium","m1.large","m1.xlarge","m2.xlarge","m2.2xlarge","m2.4xlarge","m3.xlarge","m3.2xlarge","c1.medium","c1.xlarge","cc1.4xlarge","cc2.8xlarge","cg1.4xlarge"], "ConstraintDescription" : "must be a valid EC2 instance type." } }, "Mappings" : { "AWSNATAMI" : { "us-east-1" : { "AMI" : "ami-c6699baf" }, "us-west-2" : { "AMI" : "ami-52ff7262" }, "us-west-1" : { "AMI" : "ami-3bcc9e7e" }, "eu-west-1" : { "AMI" : "ami-0b5b6c7f" }, "ap-southeast-1" : { "AMI" : "ami-02eb9350" }, "ap-southeast-2" : { "AMI" : "ami-ab990e91" }, "ap-northeast-1" : { "AMI" : "ami-14d86d15" }, "sa-east-1" : { "AMI" : "ami-0439e619" } }, "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "64" }, "m1.small" : { "Arch" : "64" }, "m1.medium" : { "Arch" : "64" }, "m1.large" : { "Arch" : "64" }, "m1.xlarge" : { "Arch" : "64" }, "m2.xlarge" : { "Arch" : "64" }, "m2.2xlarge" : { "Arch" : "64" }, "m2.4xlarge" : { "Arch" : "64" }, "m3.xlarge" : { "Arch" : "64" }, "m3.2xlarge" : { "Arch" : "64" }, "c1.medium" : { "Arch" : "64" }, "c1.xlarge" : { "Arch" : "64" }, "cc1.4xlarge" : { "Arch" : "64Cluster" }, "cc2.8xlarge" : { "Arch" : "64Cluster" }, "cg1.4xlarge" : { "Arch" : "64GPU" } }, "AWSRegionArch2AMI" : { "us-east-1" : { "32" : "ami-a0cd60c9", "64" : "ami-aecd60c7", "64Cluster" : "ami-a8cd60c1", "64GPU" : "ami-eccf6285" }, "us-west-2" : { "32" : "ami-46da5576", "64" : "ami-48da5578", "64Cluster" : "NOT_YET_SUPPORTED", "64GPU" : "NOT_YET_SUPPORTED" }, "us-west-1" : { "32" : "ami-7d4c6938", "64" : "ami-734c6936", "64Cluster" : "NOT_YET_SUPPORTED", "64GPU" : "NOT_YET_SUPPORTED" }, "eu-west-1" : { "32" : "ami-61555115", "64" : "ami-6d555119", "64Cluster" : "ami-67555113", "64GPU" : "NOT_YET_SUPPORTED" }, "ap-southeast-1" : { "32" : "ami-220b4a70", "64" : "ami-3c0b4a6e", "64Cluster" : "NOT_YET_SUPPORTED", "64GPU" : "NOT_YET_SUPPORTED" }, "ap-southeast-2" : { "32" : "ami-b3990e89", "64" : "ami-bd990e87", "64Cluster" : "NOT_YET_SUPPORTED", "64GPU" : "NOT_YET_SUPPORTED" }, "ap-northeast-1" : { "32" : "ami-2a19aa2b", "64" : "ami-2819aa29", "64Cluster" : "NOT_YET_SUPPORTED", "64GPU" : "NOT_YET_SUPPORTED" }, "sa-east-1" : { "32" : "ami-f836e8e5", "64" : "ami-fe36e8e3", "64Cluster" : "NOT_YET_SUPPORTED", "64GPU" : "NOT_YET_SUPPORTED" } }, "SubnetConfig" : { "VPC" : { "CIDR" : "10.0.0.0/16" }, "Public" : { "CIDR" : "10.0.0.0/24" }, "Private" : { "CIDR" : "10.0.1.0/24" } } }, "Resources" : { "VPC" : { "Type" : "AWS::EC2::VPC", "Properties" : { "CidrBlock" : { "Fn::FindInMap" : [ "SubnetConfig", "VPC", "CIDR" ]}, "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackId" } }, { "Key" : "Network", "Value" : "Public" } ] } }, "PublicSubnet" : { "Type" : "AWS::EC2::Subnet", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "CidrBlock" : { "Fn::FindInMap" : [ "SubnetConfig", "Public", "CIDR" ]}, "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackId" } }, { "Key" : "Network", "Value" : "Public" } ] } }, "InternetGateway" : { "Type" : "AWS::EC2::InternetGateway", "Properties" : { "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackId" } }, { "Key" : "Network", "Value" : "Public" } ] } }, "GatewayToInternet" : { "Type" : "AWS::EC2::VPCGatewayAttachment", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "InternetGatewayId" : { "Ref" : "InternetGateway" } } }, "PublicRouteTable" : { "Type" : "AWS::EC2::RouteTable", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackId" } }, { "Key" : "Network", "Value" : "Public" } ] } }, "PublicRoute" : { "Type" : "AWS::EC2::Route", "DependsOn" : "GatewayToInternet", "Properties" : { "RouteTableId" : { "Ref" : "PublicRouteTable" }, "DestinationCidrBlock" : "0.0.0.0/0", "GatewayId" : { "Ref" : "InternetGateway" } } }, "PublicSubnetRouteTableAssociation" : { "Type" : "AWS::EC2::SubnetRouteTableAssociation", "Properties" : { "SubnetId" : { "Ref" : "PublicSubnet" }, "RouteTableId" : { "Ref" : "PublicRouteTable" } } }, "PublicNetworkAcl" : { "Type" : "AWS::EC2::NetworkAcl", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackId" } }, { "Key" : "Network", "Value" : "Public" } ] } }, "InboundHTTPPublicNetworkAclEntry" : { "Type" : "AWS::EC2::NetworkAclEntry", "Properties" : { "NetworkAclId" : { "Ref" : "PublicNetworkAcl" }, "RuleNumber" : "100", "Protocol" : "6", "RuleAction" : "allow", "Egress" : "false", "CidrBlock" : "0.0.0.0/0", "PortRange" : { "From" : "80", "To" : "80" } } }, "InboundHTTPSPublicNetworkAclEntry" : { "Type" : "AWS::EC2::NetworkAclEntry", "Properties" : { "NetworkAclId" : { "Ref" : "PublicNetworkAcl" }, "RuleNumber" : "101", "Protocol" : "6", "RuleAction" : "allow", "Egress" : "false", "CidrBlock" : "0.0.0.0/0", "PortRange" : { "From" : "443", "To" : "443" } } }, "InboundSSHPublicNetworkAclEntry" : { "Type" : "AWS::EC2::NetworkAclEntry", "Properties" : { "NetworkAclId" : { "Ref" : "PublicNetworkAcl" }, "RuleNumber" : "102", "Protocol" : "6", "RuleAction" : "allow", "Egress" : "false", "CidrBlock" : { "Ref" : "SSHLocation" }, "PortRange" : { "From" : "22", "To" : "22" } } }, "InboundEmphemeralPublicNetworkAclEntry" : { "Type" : "AWS::EC2::NetworkAclEntry", "Properties" : { "NetworkAclId" : { "Ref" : "PublicNetworkAcl" }, "RuleNumber" : "103", "Protocol" : "6", "RuleAction" : "allow", "Egress" : "false", "CidrBlock" : "0.0.0.0/0", "PortRange" : { "From" : "1024", "To" : "65535" } } }, "OutboundPublicNetworkAclEntry" : { "Type" : "AWS::EC2::NetworkAclEntry", "Properties" : { "NetworkAclId" : { "Ref" : "PublicNetworkAcl" }, "RuleNumber" : "100", "Protocol" : "6", "RuleAction" : "allow", "Egress" : "true", "CidrBlock" : "0.0.0.0/0", "PortRange" : { "From" : "0", "To" : "65535" } } }, "PublicSubnetNetworkAclAssociation" : { "Type" : "AWS::EC2::SubnetNetworkAclAssociation", "Properties" : { "SubnetId" : { "Ref" : "PublicSubnet" }, "NetworkAclId" : { "Ref" : "PublicNetworkAcl" } } }, "PrivateSubnet" : { "Type" : "AWS::EC2::Subnet", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "CidrBlock" : { "Fn::FindInMap" : [ "SubnetConfig", "Private", "CIDR" ]}, "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackId" } }, { "Key" : "Network", "Value" : "Private" } ] } }, "PrivateRouteTable" : { "Type" : "AWS::EC2::RouteTable", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackId" } }, { "Key" : "Network", "Value" : "Private" } ] } }, "PrivateSubnetRouteTableAssociation" : { "Type" : "AWS::EC2::SubnetRouteTableAssociation", "Properties" : { "SubnetId" : { "Ref" : "PrivateSubnet" }, "RouteTableId" : { "Ref" : "PrivateRouteTable" } } }, "PrivateRoute" : { "Type" : "AWS::EC2::Route", "Properties" : { "RouteTableId" : { "Ref" : "PrivateRouteTable" }, "DestinationCidrBlock" : "0.0.0.0/0", "InstanceId" : { "Ref" : "NATDevice" } } }, "PrivateNetworkAcl" : { "Type" : "AWS::EC2::NetworkAcl", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackId" } }, { "Key" : "Network", "Value" : "Private" } ] } }, "InboundPrivateNetworkAclEntry" : { "Type" : "AWS::EC2::NetworkAclEntry", "Properties" : { "NetworkAclId" : { "Ref" : "PrivateNetworkAcl" }, "RuleNumber" : "100", "Protocol" : "6", "RuleAction" : "allow", "Egress" : "false", "CidrBlock" : "0.0.0.0/0", "PortRange" : { "From" : "0", "To" : "65535" } } }, "OutBoundPrivateNetworkAclEntry" : { "Type" : "AWS::EC2::NetworkAclEntry", "Properties" : { "NetworkAclId" : { "Ref" : "PrivateNetworkAcl" }, "RuleNumber" : "100", "Protocol" : "6", "RuleAction" : "allow", "Egress" : "true", "CidrBlock" : "0.0.0.0/0", "PortRange" : { "From" : "0", "To" : "65535" } } }, "PrivateSubnetNetworkAclAssociation" : { "Type" : "AWS::EC2::SubnetNetworkAclAssociation", "Properties" : { "SubnetId" : { "Ref" : "PrivateSubnet" }, "NetworkAclId" : { "Ref" : "PrivateNetworkAcl" } } }, "NATIPAddress" : { "Type" : "AWS::EC2::EIP", "DependsOn" : "GatewayToInternet", "Properties" : { "Domain" : "vpc", "InstanceId" : { "Ref" : "NATDevice" } } }, "NATDevice" : { "Type" : "AWS::EC2::Instance", "Properties" : { "InstanceType" : { "Ref" : "NATInstanceType" }, "KeyName" : { "Ref" : "KeyName" }, "SubnetId" : { "Ref" : "PublicSubnet" }, "SourceDestCheck" : "false", "ImageId" : { "Fn::FindInMap" : [ "AWSNATAMI", { "Ref" : "AWS::Region" }, "AMI" ]}, "SecurityGroupIds" : [{ "Ref" : "NATSecurityGroup" }] } }, "NATSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable internal access to the NAT device", "VpcId" : { "Ref" : "VPC" }, "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"} , { "IpProtocol" : "tcp", "FromPort" : "443", "ToPort" : "443", "CidrIp" : "0.0.0.0/0"} , { "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation" }} ], "SecurityGroupEgress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"} , { "IpProtocol" : "tcp", "FromPort" : "443", "ToPort" : "443", "CidrIp" : "0.0.0.0/0"} ] } }, "BastionIPAddress" : { "Type" : "AWS::EC2::EIP", "DependsOn" : "GatewayToInternet", "Properties" : { "Domain" : "vpc", "InstanceId" : { "Ref" : "BastionHost" } } }, "BastionHost" : { "Type" : "AWS::EC2::Instance", "Properties" : { "InstanceType" : { "Ref" : "BastionInstanceType" }, "KeyName" : { "Ref" : "KeyName" }, "SubnetId" : { "Ref" : "PublicSubnet" }, "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "BastionInstanceType" }, "Arch" ] } ] }, "SecurityGroupIds" : [{ "Ref" : "BastionSecurityGroup" }] } }, "BastionSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable access to the Bastion host", "VpcId" : { "Ref" : "VPC" }, "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation" }} ], "SecurityGroupEgress" : [ { "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Fn::FindInMap" : [ "SubnetConfig", "Private", "CIDR" ]}}] } }, "PublicElasticLoadBalancer" : { "Type" : "AWS::ElasticLoadBalancing::LoadBalancer", "Properties" : { "SecurityGroups" : [ { "Ref" : "PublicLoadBalancerSecurityGroup" } ], "Subnets" : [ { "Ref" : "PublicSubnet" } ], "Listeners" : [ { "LoadBalancerPort" : "80", "InstancePort" : "80", "Protocol" : "HTTP" } ], "HealthCheck" : { "Target" : "HTTP:80/", "HealthyThreshold" : "3", "UnhealthyThreshold" : "5", "Interval" : "90", "Timeout" : "60" } } }, "PublicLoadBalancerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Public ELB Security Group with HTTP access on port 80 from the internet", "VpcId" : { "Ref" : "VPC" }, "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"} ], "SecurityGroupEgress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"} ] } }, "FrontendFleet" : { "Type" : "AWS::AutoScaling::AutoScalingGroup", "Properties" : { "AvailabilityZones" : [{ "Fn::GetAtt" : [ "PrivateSubnet", "AvailabilityZone" ] }], "VPCZoneIdentifier" : [{ "Ref" : "PrivateSubnet" }], "LaunchConfigurationName" : { "Ref" : "FrontendServerLaunchConfig" }, "MinSize" : "1", "MaxSize" : "10", "DesiredCapacity" : { "Ref" : "FrontendSize" }, "LoadBalancerNames" : [ { "Ref" : "PublicElasticLoadBalancer" } ], "Tags" : [ { "Key" : "Network", "Value" : "Public", "PropagateAtLaunch" : "true" } ] } }, "FrontendServerLaunchConfig" : { "Type" : "AWS::AutoScaling::LaunchConfiguration", "Metadata" : { "Comment1" : "Configure the FrontendServer to forward /backend requests to the backend servers", "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "httpd" : [] } }, "files" : { "/var/www/html/index.html" : { "content" : { "Fn::Join" : ["\n", [ "", "
This is a multi-tier web application launched in an Amazon Virtual Private Cloud (Amazon VPC) with multiple subnets. The first subnet is public and contains and internet facing load balancer, a NAT device for internet access from the private subnet and a bastion host to allow SSH access to the hosts in the private subnet. The second subnet is private and contains a Frontend fleet of EC2 instances, an internal load balancer and a Backend fleet of EC2 instances.", "
To serve a web page from the backend service, click here.
" ]]}, "mode" : "000644", "owner" : "root", "group" : "root" }, "/etc/httpd/conf.d/maptobackend.conf" : { "content" : { "Fn::Join" : ["", [ "ProxyPass /backend http://", { "Fn::GetAtt" : [ "PrivateElasticLoadBalancer", "DNSName" ]}, "\n", "ProxyPassReverse /backend http://", { "Fn::GetAtt" : [ "PrivateElasticLoadBalancer", "DNSName" ]}, "\n" ]]}, "mode" : "000644", "owner" : "root", "group" : "root" } }, "services" : { "sysvinit" : { "httpd" : { "enabled" : "true", "ensureRunning" : "true", "files" : [ "/etc/httpd/conf.d/maptobackend.conf", "/var/www/html/index.html" ] } } } } } }, "Properties" : { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "FrontendInstanceType" }, "Arch" ] } ] }, "SecurityGroups" : [ { "Ref" : "FrontendSecurityGroup" } ], "InstanceType" : { "Ref" : "FrontendInstanceType" }, "KeyName" : { "Ref" : "KeyName" }, "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash -v\n", "yum update -y aws-cfn-bootstrap\n", "# Install Apache and configure as a reverse Frontend\n", "/opt/aws/bin/cfn-init --stack ", { "Ref" : "AWS::StackId" }, " --resource FrontendServerLaunchConfig ", " --region ", { "Ref" : "AWS::Region" }, "\n", "# Signal completion\n", "/opt/aws/bin/cfn-signal -e $? -r \"Frontend setup done\" '", { "Ref" : "FrontendWaitHandle" }, "'\n" ]]}} } }, "FrontendSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Allow access from load balancer and bastion as well as outbound HTTP and HTTPS traffic", "VpcId" : { "Ref" : "VPC" }, "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "SourceSecurityGroupId" : { "Ref" : "PublicLoadBalancerSecurityGroup" } } , { "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "SourceSecurityGroupId" : { "Ref" : "BastionSecurityGroup" } } ], "SecurityGroupEgress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0" } , { "IpProtocol" : "tcp", "FromPort" : "443", "ToPort" : "443", "CidrIp" : "0.0.0.0/0" } ] } }, "FrontendWaitHandle" : { "Type" : "AWS::CloudFormation::WaitConditionHandle" }, "FrontendWaitCondition" : { "Type" : "AWS::CloudFormation::WaitCondition", "DependsOn" : "FrontendFleet", "Properties" : { "Handle" : { "Ref" : "FrontendWaitHandle" }, "Timeout" : "300", "Count" : { "Ref" : "FrontendSize" } } }, "PrivateElasticLoadBalancer" : { "Type" : "AWS::ElasticLoadBalancing::LoadBalancer", "Properties" : { "SecurityGroups" : [ { "Ref" : "PrivateLoadBalancerSecurityGroup" } ], "Subnets" : [ { "Ref" : "PrivateSubnet" } ], "Listeners" : [ { "LoadBalancerPort" : "80", "InstancePort" : "80", "Protocol" : "HTTP" } ], "Scheme" : "internal", "HealthCheck" : { "Target" : "HTTP:80/", "HealthyThreshold" : "3", "UnhealthyThreshold" : "5", "Interval" : "90", "Timeout" : "60" } } }, "PrivateLoadBalancerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Private ELB Security Group with HTTP access on port 80 from the Frontend Fleet only", "VpcId" : { "Ref" : "VPC" }, "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "SourceSecurityGroupId" : { "Ref" : "FrontendSecurityGroup" } } ], "SecurityGroupEgress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0" } ] } }, "BackendFleet" : { "Type" : "AWS::AutoScaling::AutoScalingGroup", "Properties" : { "AvailabilityZones" : [{ "Fn::GetAtt" : [ "PrivateSubnet", "AvailabilityZone" ] }], "VPCZoneIdentifier" : [{ "Ref" : "PrivateSubnet" }], "LaunchConfigurationName" : { "Ref" : "BackendLaunchConfig" }, "MinSize" : "1", "MaxSize" : "10", "DesiredCapacity" : { "Ref" : "BackendSize" }, "LoadBalancerNames" : [ { "Ref" : "PrivateElasticLoadBalancer" } ], "Tags" : [ { "Key" : "Network", "Value" : "Private", "PropagateAtLaunch" : "true" } ] } }, "BackendLaunchConfig" : { "Type" : "AWS::AutoScaling::LaunchConfiguration", "Metadata" : { "Comment1" : "Configure the Backend server to respond to requests", "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "httpd" : [] } }, "files" : { "/var/www/html/index.html" : { "content" : { "Fn::Join" : ["\n", [ "", "