I try to create a VPC with 4 subnets(2 public, 2 private) with 2 ALBs, 2ASG, 2 NATGateways and 4 EC2 instances(2 in public and 2 in private) using cloudformation. Everything works fine except one of the instance in private subnet always failed to pass the health check with timeout error. I checked quite a few times for the code and could not find out what went wrong. Please help to point out what I have done wrong. I tried several time, always the instance in privatesubnetB(10.0.4.0) failed the health check Here is the code.
Parameters:
NumberofAZs:
Type: Number
AllowedValues:
- 1
- 2
Default: 2
Description: How many AZ do you want to utilize
PrivateSubnet:
Type: String
AllowedValues:
- True
- False
Default: True
Description: Do you want to build private subnet
NumberofPrivateSubnets:
Type: Number
AllowedValues:
- 1
- 2
Default: 1
Description: How many private subnet do you want to create
NatGateway:
Type: String
AllowedValues:
- True
- False
Default: True
Description: Do you want to create NAT Gateway for private subnet
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Conditions:
Build2Public: !Not [!Equals [!Ref NumberofAZs, 1]]
Build3Public: !Equals [!Ref NumberofAZs, 3]
BuildPrivateSubnet: !Equals [!Ref PrivateSubnet, True]
BuildOnePrivateSubnet: !And [!Equals [!Ref PrivateSubnet, True],!Equals [!Ref NumberofPrivateSubnets, 1]]
BuildTwoPrivateSubnet: !And [!Equals [!Ref PrivateSubnet, True], !Equals [!Ref NumberofPrivateSubnets, 2]]
BuildNatGateway: !Equals [!Ref NatGateway, True]
Resources:
myVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/21
Tags:
- Key: Name
Value: myVPC1
mySecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: allow8000
GroupDescription: Allow 80 8000 to client host
VpcId: !Ref myVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 8000
ToPort: 8000
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
myOwnACL:
Type: AWS::EC2::NetworkAcl
Properties:
VpcId: !Ref myVPC
Tags:
- Key: Name
Value: allow8000
InboundRule:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref myOwnACL
RuleNumber: 100
Protocol: 6
RuleAction: allow
CidrBlock: 172.16.0.0/24
PortRange:
From: 8000
To: 8000
OutboundRule:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref myOwnACL
RuleNumber: 100
Protocol: -1
Egress: true
RuleAction: allow
CidrBlock: 0.0.0.0/0
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref myVPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [ 0, !GetAZs ]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-Public-A
PublicSubnetB:
Type: AWS::EC2::Subnet
Condition: Build2Public
Properties:
VpcId: !Ref myVPC
CidrBlock: 10.0.2.0/24
AvailabilityZone: !Select [ 1, !GetAZs ]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-Public-B
PrivateSubnetA:
Type: AWS::EC2::Subnet
Condition: BuildPrivateSubnet
Properties:
VpcId: !Ref myVPC
CidrBlock: 10.0.3.0/24
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-Private-A
PrivateSubnetB:
Type: AWS::EC2::Subnet
Condition: BuildTwoPrivateSubnet
Properties:
VpcId: !Ref myVPC
CidrBlock: 10.0.4.0/24
AvailabilityZone: !Select [ 1, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-Private-B
mySubnetNetworkAclAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Condition: BuildTwoPrivateSubnet
Properties:
SubnetId: !Ref PrivateSubnetB
NetworkAclId: !Ref myOwnACL
InternetGateway:
Type: AWS::EC2::InternetGateway
DependsOn: myVPC
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref myVPC
InternetGatewayId: !Ref InternetGateway
NATGateway:
Condition: BuildNatGateway
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt ElasticIPAddress.AllocationId
SubnetId: !Ref PublicSubnetA
ConnectivityType: public
Tags:
- Key: Name
Value: !Sub NAT-${AWS::StackName}
NATGatewayB:
Condition: BuildNatGateway
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt ElasticIPAddress2.AllocationId
SubnetId: !Ref PublicSubnetB
ConnectivityType: public
Tags:
- Key: Name
Value: !Sub NAT-${AWS::StackName}-B
ElasticIPAddress:
Type: AWS::EC2::EIP
Condition: BuildPrivateSubnet
Properties:
Domain: VPC
ElasticIPAddress2:
Type: AWS::EC2::EIP
Condition: BuildPrivateSubnet
Properties:
Domain: VPC
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref myVPC
Tags:
- Key: Name
Value: Public
PublicRoute1:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Condition: BuildPrivateSubnet
Properties:
VpcId: !Ref myVPC
Tags:
- Key: Name
Value: Private
PrivateRoute1:
Type: AWS::EC2::Route
Condition: BuildNatGateway
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGateway
PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Condition: BuildPrivateSubnet
Properties:
VpcId: !Ref myVPC
Tags:
- Key: Name
Value: Private
PrivateRoute2:
Type: AWS::EC2::Route
Condition: BuildNatGateway
Properties:
RouteTableId: !Ref PrivateRouteTable2
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGatewayB
PublicSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref PublicRouteTable
PublicSubnetBRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: Build2Public
Properties:
SubnetId: !Ref PublicSubnetB
RouteTableId: !Ref PublicRouteTable
PrivateSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: BuildPrivateSubnet
Properties:
SubnetId: !Ref PrivateSubnetA
RouteTableId: !Ref PrivateRouteTable
PrivateSubnetBRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: BuildTwoPrivateSubnet
Properties:
SubnetId: !Ref PrivateSubnetB
RouteTableId: !Ref PrivateRouteTable2
MyEC2LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateData:
ImageId: ami-05064bb33b40c33a2
InstanceType: t2.micro
KeyName: !Ref KeyName
Monitoring:
Enabled: true
SecurityGroupIds:
- !Ref mySecurityGroup
DisableApiTermination: true
InstanceInitiatedShutdownBehavior: terminate
HibernationOptions:
Configured: true
BlockDeviceMappings:
- Ebs:
VolumeSize: 8
VolumeType: gp2
DeleteOnTermination: true
Encrypted: true
DeviceName: /dev/xvda
UserData:
Fn::Base64:
!Sub |
#!/bin/bash -ex
sudo yum install -y httpd;
sudo echo "<html><h1>Hello CloudFormation A!!<h1></html>" > /var/www/html/index.html;
cd /var/www/html;
sudo chmod 755 index.html;
sudo service httpd start;
sudo chkconfig httpd on;
MyASG:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MinSize: '1'
MaxSize: '3'
DesiredCapacity: '2'
TargetGroupARNs:
- !Ref MyTargetGroup
LaunchTemplate:
LaunchTemplateId: !Ref MyEC2LaunchTemplate
Version: !GetAtt MyEC2LaunchTemplate.LatestVersionNumber
VPCZoneIdentifier:
- !Ref PrivateSubnetA
- !Ref PrivateSubnetB
####### Target group
MyTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: MyTargets
TargetType: instance
Protocol: HTTP
Port: 80
VpcId: !Ref myVPC
HealthCheckIntervalSeconds: 30
HealthCheckPath: /
HealthCheckPort: 80
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
############# Internal ALB
myInternalALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
IpAddressType: ipv4
Name: testALB
Scheme: internal
SecurityGroups:
- !Ref mySecurityGroup
Subnets:
- !Ref PrivateSubnetA
- !Ref PrivateSubnetB
Type: application
myInternalALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref MyTargetGroup
LoadBalancerArn: !Ref myInternalALB
Port: '80'
Protocol: HTTP
exASG:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MinSize: '1'
MaxSize: '3'
DesiredCapacity: '2'
TargetGroupARNs:
- !Ref MyexTargetGroup
LaunchTemplate:
LaunchTemplateId: !Ref MyEC2LaunchTemplate
Version: !GetAtt MyEC2LaunchTemplate.LatestVersionNumber
VPCZoneIdentifier:
- !Ref PublicSubnetA
- !Ref PublicSubnetB
# CreationPolicy:
# ResourceSignal:
# Count: 2
# Timeout: 'PT10M'
####### Target group for public subnets
MyexTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: MyexTargets
TargetType: instance
Protocol: HTTP
Port: 80
VpcId: !Ref myVPC
HealthCheckIntervalSeconds: 30
HealthCheckPath: /
HealthCheckPort: 80
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 10
############# External ALB
myExternalALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
IpAddressType: ipv4
Name: testExALB
Scheme: internet-facing
SecurityGroups:
- !Ref mySecurityGroup
Subnets:
- !Ref PublicSubnetA
- !Ref PublicSubnetB
Type: application
myExternalALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref MyexTargetGroup
LoadBalancerArn: !Ref myExternalALB
Port: '80'
Protocol: HTTP
Your myOwnACL
is misconfigured and only used in Private-B
subnet. Your website is on port 80, not 8000. Also why do you have
CidrBlock: 172.16.0.0/24
if your vpc is 10.0.0.0/16?
Just remove your custom ACL, and use default ACLs.