3

I am deploying an AWS CloudFormation Template. I am deploying a Load Balancer pointing to an Auto Scaling Group. I could deploy my template successfully. But when I access the website using Load Balancer's DNS, it just keeps loading, loading and loading.

This is my template.

AWSTemplateFormatVersion: '2010-09-09'
Description: "Simple 3 tier web application template"
Parameters:
  KeyName:
    Default: 'MyanEatTesting2'
    Type: String
  VpcCidr:
    Default: '10.1.0.0/16'
    Type: String
    AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})'
  InstanceType:
    Default: 't2.micro'
    Type: String
  SSHLocation:
    Description: The IP address range that can be used to SSH to the EC2 instances
    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 IP CIDR range of the form x.x.x.x/x
Mappings:
  AWSInstanceType2Arch:
    t1.micro:
      Arch: HVM64
    t2.nano:
      Arch: HVM64
    t2.micro:
      Arch: HVM64
    t2.small:
      Arch: HVM64
    t2.medium:
      Arch: HVM64
    t2.large:
      Arch: HVM64
    m1.small:
      Arch: HVM64
    m1.medium:
      Arch: HVM64
    m1.large:
      Arch: HVM64
    m1.xlarge:
      Arch: HVM64
    m2.xlarge:
      Arch: HVM64
    m2.2xlarge:
      Arch: HVM64
    m2.4xlarge:
      Arch: HVM64
    m3.medium:
      Arch: HVM64
    m3.large:
      Arch: HVM64
    m3.xlarge:
      Arch: HVM64
    m3.2xlarge:
      Arch: HVM64
    m4.large:
      Arch: HVM64
    m4.xlarge:
      Arch: HVM64
    m4.2xlarge:
      Arch: HVM64
    m4.4xlarge:
      Arch: HVM64
    m4.10xlarge:
      Arch: HVM64
    c1.medium:
      Arch: HVM64
    c1.xlarge:
      Arch: HVM64
    c3.large:
      Arch: HVM64
    c3.xlarge:
      Arch: HVM64
    c3.2xlarge:
      Arch: HVM64
    c3.4xlarge:
      Arch: HVM64
    c3.8xlarge:
      Arch: HVM64
    c4.large:
      Arch: HVM64
    c4.xlarge:
      Arch: HVM64
    c4.2xlarge:
      Arch: HVM64
    c4.4xlarge:
      Arch: HVM64
    c4.8xlarge:
      Arch: HVM64
    g2.2xlarge:
      Arch: HVMG2
    g2.8xlarge:
      Arch: HVMG2
    r3.large:
      Arch: HVM64
    r3.xlarge:
      Arch: HVM64
    r3.2xlarge:
      Arch: HVM64
    r3.4xlarge:
      Arch: HVM64
    r3.8xlarge:
      Arch: HVM64
    i2.xlarge:
      Arch: HVM64
    i2.2xlarge:
      Arch: HVM64
    i2.4xlarge:
      Arch: HVM64
    i2.8xlarge:
      Arch: HVM64
    d2.xlarge:
      Arch: HVM64
    d2.2xlarge:
      Arch: HVM64
    d2.4xlarge:
      Arch: HVM64
    d2.8xlarge:
      Arch: HVM64
    hi1.4xlarge:
      Arch: HVM64
    hs1.8xlarge:
      Arch: HVM64
    cr1.8xlarge:
      Arch: HVM64
    cc2.8xlarge:
      Arch: HVM64
  AWSRegionArch2AMI:
    us-east-1:
      HVM64: ami-0ff8a91507f77f867
      HVMG2: ami-0a584ac55a7631c0c
    us-west-2:
      HVM64: ami-a0cfeed8
      HVMG2: ami-0e09505bc235aa82d
    us-west-1:
      HVM64: ami-0bdb828fd58c52235
      HVMG2: ami-066ee5fd4a9ef77f1
    eu-west-1:
      HVM64: ami-047bb4163c506cd98
      HVMG2: ami-0a7c483d527806435
    eu-west-2:
      HVM64: ami-f976839e
      HVMG2: NOT_SUPPORTED
    eu-west-3:
      HVM64: ami-0ebc281c20e89ba4b
      HVMG2: NOT_SUPPORTED
    eu-central-1:
      HVM64: ami-0233214e13e500f77
      HVMG2: ami-06223d46a6d0661c7
    ap-northeast-1:
      HVM64: ami-06cd52961ce9f0d85
      HVMG2: ami-053cdd503598e4a9d
    ap-northeast-2:
      HVM64: ami-0a10b2721688ce9d2
      HVMG2: NOT_SUPPORTED
    ap-northeast-3:
      HVM64: ami-0d98120a9fb693f07
      HVMG2: NOT_SUPPORTED
    ap-southeast-1:
      HVM64: ami-08569b978cc4dfa10
      HVMG2: ami-0be9df32ae9f92309
    ap-southeast-2:
      HVM64: ami-09b42976632b27e9b
      HVMG2: ami-0a9ce9fecc3d1daf8
    ap-south-1:
      HVM64: ami-0912f71e06545ad88
      HVMG2: ami-097b15e89dbdcfcf4
    us-east-2:
      HVM64: ami-0b59bfac6be064b78
      HVMG2: NOT_SUPPORTED
    ca-central-1:
      HVM64: ami-0b18956f
      HVMG2: NOT_SUPPORTED
    sa-east-1:
      HVM64: ami-07b14488da8ea02a0
      HVMG2: NOT_SUPPORTED
    cn-north-1:
      HVM64: ami-0a4eaf6c4454eda75
      HVMG2: NOT_SUPPORTED
    cn-northwest-1:
      HVM64: ami-6b6a7d09
      HVMG2: NOT_SUPPORTED
Resources:
  Vpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsHostnames: True
      EnableDnsSupport: True
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 0, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: True
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref AWS::Region
  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 1, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: True
      AvailabilityZone: !Select
        - 1
        - Fn::GetAZs: !Ref AWS::Region
  PublicSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 2, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: True
      AvailabilityZone: !Select
        - 2
        - Fn::GetAZs: !Ref AWS::Region
  DatabaseSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 3, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref AWS::Region
  DatabaseSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 4, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      AvailabilityZone: !Select
        - 1
        - Fn::GetAZs: !Ref AWS::Region
  MiddlewareSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 5, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: False
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref AWS::Region
  MiddlewareSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 6, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: False
      AvailabilityZone: !Select
        - 1
        - Fn::GetAZs: !Ref AWS::Region
  MiddlewareSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 7, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: False
      AvailabilityZone: !Select
        - 2
        - Fn::GetAZs: !Ref AWS::Region
  InternetGateway:
    Type: AWS::EC2::InternetGateway
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref Vpc
      InternetGatewayId: !Ref InternetGateway
  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref Vpc
  Route:
    Type: AWS::EC2::Route
    DependsOn: InternetGateway
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  SubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref RouteTable
  SubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref RouteTable
  SubnetRouteTableAssociation3:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref RouteTable
  AsgLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateName: !Sub ${AWS::StackName}-launch-template
      LaunchTemplateData:
        CreditSpecification:
          CpuCredits: Unlimited
        ImageId:
          Fn::FindInMap:
            - AWSRegionArch2AMI
            - Ref: AWS::Region
            - Fn::FindInMap:
                - AWSInstanceType2Arch
                - Ref: InstanceType
                - Arch
        InstanceType: !Ref InstanceType
        KeyName: !Ref KeyName
        Monitoring:
          Enabled: True
        SecurityGroupIds:
          - !Ref WebServerSecurityGroup
        UserData:
          Fn::Base64: !Sub |
            #!/bin/bash -xe
            cd /tmp
            yum update -y
            yum install -y httpd24
            echo "Welcome from the instance" > /var/www/html/index.html
            sudo -u root service httpd start
  ApplicationAsg:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      AutoScalingGroupName: ApplicationAsg
      MinSize: '1'
      MaxSize: '5'
      DesiredCapacity: '2'
      HealthCheckGracePeriod: 300
      LaunchTemplate:
        LaunchTemplateId: !Ref AsgLaunchTemplate
        Version: !GetAtt AsgLaunchTemplate.LatestVersionNumber
      VPCZoneIdentifier:
        - !Ref MiddlewareSubnet1
        - !Ref MiddlewareSubnet2
        - !Ref MiddlewareSubnet3
      LoadBalancerNames:
        - !Ref LoadBalancer
  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access via port 80
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp:
            Ref: SSHLocation
      VpcId: !Ref Vpc
  LoadBalancer:
    Type: AWS::ElasticLoadBalancing::LoadBalancer
    Properties:
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
        - !Ref PublicSubnet3
      CrossZone: 'true'
      Listeners:
        - LoadBalancerPort: '80'
          InstancePort: '80'
          Protocol: HTTP
      HealthCheck:
        Target: HTTP:80/
        HealthyThreshold: '3'
        UnhealthyThreshold: '5'
        Interval: '30'
        Timeout: '5'

What is missing in my template and how can I fix it?

Wai Yan Hein
  • 13,651
  • 35
  • 180
  • 372

2 Answers2

2

I launched your template in my sandbox account.

It deploys, but due to lack of AWS::EC2::NatGateway and associated EIP, route tables, the instances are not able to connect to the internet to download http24 in run UserData successfully.

I also fixed (or maybe improved) your UserData, missing security group for the ELB, and added DependsOn to your ASG.

You can check the following. I verified that it works in us-east-1:

AWSTemplateFormatVersion: '2010-09-09'
Description: "Simple 3 tier web application template"
Parameters:
  KeyName:
    Default: 'MyanEatTesting2'
    Type: String
  VpcCidr:
    Default: '10.1.0.0/16'
    Type: String
    AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})'
  InstanceType:
    Default: 't2.micro'
    Type: String
  SSHLocation:
    Description: The IP address range that can be used to SSH to the EC2 instances
    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 IP CIDR range of the form x.x.x.x/x
Mappings:
  AWSInstanceType2Arch:
    t1.micro:
      Arch: HVM64
    t2.nano:
      Arch: HVM64
    t2.micro:
      Arch: HVM64
    t2.small:
      Arch: HVM64
    t2.medium:
      Arch: HVM64
    t2.large:
      Arch: HVM64
    m1.small:
      Arch: HVM64
    m1.medium:
      Arch: HVM64
    m1.large:
      Arch: HVM64
    m1.xlarge:
      Arch: HVM64
    m2.xlarge:
      Arch: HVM64
    m2.2xlarge:
      Arch: HVM64
    m2.4xlarge:
      Arch: HVM64
    m3.medium:
      Arch: HVM64
    m3.large:
      Arch: HVM64
    m3.xlarge:
      Arch: HVM64
    m3.2xlarge:
      Arch: HVM64
    m4.large:
      Arch: HVM64
    m4.xlarge:
      Arch: HVM64
    m4.2xlarge:
      Arch: HVM64
    m4.4xlarge:
      Arch: HVM64
    m4.10xlarge:
      Arch: HVM64
    c1.medium:
      Arch: HVM64
    c1.xlarge:
      Arch: HVM64
    c3.large:
      Arch: HVM64
    c3.xlarge:
      Arch: HVM64
    c3.2xlarge:
      Arch: HVM64
    c3.4xlarge:
      Arch: HVM64
    c3.8xlarge:
      Arch: HVM64
    c4.large:
      Arch: HVM64
    c4.xlarge:
      Arch: HVM64
    c4.2xlarge:
      Arch: HVM64
    c4.4xlarge:
      Arch: HVM64
    c4.8xlarge:
      Arch: HVM64
    g2.2xlarge:
      Arch: HVMG2
    g2.8xlarge:
      Arch: HVMG2
    r3.large:
      Arch: HVM64
    r3.xlarge:
      Arch: HVM64
    r3.2xlarge:
      Arch: HVM64
    r3.4xlarge:
      Arch: HVM64
    r3.8xlarge:
      Arch: HVM64
    i2.xlarge:
      Arch: HVM64
    i2.2xlarge:
      Arch: HVM64
    i2.4xlarge:
      Arch: HVM64
    i2.8xlarge:
      Arch: HVM64
    d2.xlarge:
      Arch: HVM64
    d2.2xlarge:
      Arch: HVM64
    d2.4xlarge:
      Arch: HVM64
    d2.8xlarge:
      Arch: HVM64
    hi1.4xlarge:
      Arch: HVM64
    hs1.8xlarge:
      Arch: HVM64
    cr1.8xlarge:
      Arch: HVM64
    cc2.8xlarge:
      Arch: HVM64
  AWSRegionArch2AMI:
    us-east-1:
      HVM64: ami-0ff8a91507f77f867
      HVMG2: ami-0a584ac55a7631c0c
    us-west-2:
      HVM64: ami-a0cfeed8
      HVMG2: ami-0e09505bc235aa82d
    us-west-1:
      HVM64: ami-0bdb828fd58c52235
      HVMG2: ami-066ee5fd4a9ef77f1
    eu-west-1:
      HVM64: ami-047bb4163c506cd98
      HVMG2: ami-0a7c483d527806435
    eu-west-2:
      HVM64: ami-f976839e
      HVMG2: NOT_SUPPORTED
    eu-west-3:
      HVM64: ami-0ebc281c20e89ba4b
      HVMG2: NOT_SUPPORTED
    eu-central-1:
      HVM64: ami-0233214e13e500f77
      HVMG2: ami-06223d46a6d0661c7
    ap-northeast-1:
      HVM64: ami-06cd52961ce9f0d85
      HVMG2: ami-053cdd503598e4a9d
    ap-northeast-2:
      HVM64: ami-0a10b2721688ce9d2
      HVMG2: NOT_SUPPORTED
    ap-northeast-3:
      HVM64: ami-0d98120a9fb693f07
      HVMG2: NOT_SUPPORTED
    ap-southeast-1:
      HVM64: ami-08569b978cc4dfa10
      HVMG2: ami-0be9df32ae9f92309
    ap-southeast-2:
      HVM64: ami-09b42976632b27e9b
      HVMG2: ami-0a9ce9fecc3d1daf8
    ap-south-1:
      HVM64: ami-0912f71e06545ad88
      HVMG2: ami-097b15e89dbdcfcf4
    us-east-2:
      HVM64: ami-0b59bfac6be064b78
      HVMG2: NOT_SUPPORTED
    ca-central-1:
      HVM64: ami-0b18956f
      HVMG2: NOT_SUPPORTED
    sa-east-1:
      HVM64: ami-07b14488da8ea02a0
      HVMG2: NOT_SUPPORTED
    cn-north-1:
      HVM64: ami-0a4eaf6c4454eda75
      HVMG2: NOT_SUPPORTED
    cn-northwest-1:
      HVM64: ami-6b6a7d09
      HVMG2: NOT_SUPPORTED
Resources:
  Vpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsHostnames: True
      EnableDnsSupport: True
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 0, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: True
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref AWS::Region
  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 1, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: True
      AvailabilityZone: !Select
        - 1
        - Fn::GetAZs: !Ref AWS::Region
  PublicSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 2, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: True
      AvailabilityZone: !Select
        - 2
        - Fn::GetAZs: !Ref AWS::Region
  DatabaseSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 3, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref AWS::Region
  DatabaseSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 4, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      AvailabilityZone: !Select
        - 1
        - Fn::GetAZs: !Ref AWS::Region
  MiddlewareSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 5, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: False
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref AWS::Region
  MiddlewareSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 6, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: False
      AvailabilityZone: !Select
        - 1
        - Fn::GetAZs: !Ref AWS::Region
  MiddlewareSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 7, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: False
      AvailabilityZone: !Select
        - 2
        - Fn::GetAZs: !Ref AWS::Region
  InternetGateway:
    Type: AWS::EC2::InternetGateway
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref Vpc
      InternetGatewayId: !Ref InternetGateway
  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref Vpc
  Route:
    Type: AWS::EC2::Route
    DependsOn: InternetGateway
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  SubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref RouteTable
  SubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref RouteTable
  SubnetRouteTableAssociation3:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet3
      RouteTableId: !Ref RouteTable
  AsgLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateName: !Sub ${AWS::StackName}-launch-template
      LaunchTemplateData:
        CreditSpecification:
          CpuCredits: Unlimited
        ImageId:
          Fn::FindInMap:
            - AWSRegionArch2AMI
            - Ref: AWS::Region
            - Fn::FindInMap:
                - AWSInstanceType2Arch
                - Ref: InstanceType
                - Arch
        InstanceType: !Ref InstanceType
        KeyName: !Ref KeyName
        Monitoring:
          Enabled: True
        SecurityGroupIds:
          - !Ref WebServerSecurityGroup
        UserData:
          Fn::Base64: |
            #!/bin/bash -xe
   
            yum update -y
            yum install -y httpd24
            echo "Welcome from the instance $(hostname -f)" > /var/www/html/index.html
            service httpd start


  MyEIP:
    Type: AWS::EC2::EIP
    DependsOn: AttachGateway
    Properties: {}

  MyNAT:
    Type: AWS::EC2::NatGateway
    Properties: 
      AllocationId: !GetAtt MyEIP.AllocationId
      SubnetId: !Ref PublicSubnet1

  RouteToNat:
    Type: AWS::EC2::Route
    DependsOn: InternetGateway
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref MyNAT  

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref Vpc

  PrivateSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref MiddlewareSubnet1
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref MiddlewareSubnet2
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnetRouteTableAssociation3:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref MiddlewareSubnet3
      RouteTableId: !Ref PrivateRouteTable

  ELBWebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access via port 80
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
      VpcId: !Ref Vpc



  ApplicationAsg:
    Type: AWS::AutoScaling::AutoScalingGroup
    DependsOn: 
        - RouteToNat
        - PrivateSubnetRouteTableAssociation1
        - PrivateSubnetRouteTableAssociation2
        - PrivateSubnetRouteTableAssociation3
    Properties:
      AutoScalingGroupName: ApplicationAsg
      MinSize: '1'
      MaxSize: '5'
      DesiredCapacity: '2'
      HealthCheckGracePeriod: 300
      LaunchTemplate:
        LaunchTemplateId: !Ref AsgLaunchTemplate
        Version: !GetAtt AsgLaunchTemplate.LatestVersionNumber
      VPCZoneIdentifier:
        - !Ref MiddlewareSubnet1
        - !Ref MiddlewareSubnet2
        - !Ref MiddlewareSubnet3
      LoadBalancerNames:
        - !Ref LoadBalancer
  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access via port 80
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp:
            Ref: SSHLocation
      VpcId: !Ref Vpc

  LoadBalancer:
    Type: AWS::ElasticLoadBalancing::LoadBalancer
    Properties:
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
        - !Ref PublicSubnet3
      CrossZone: 'true'
      Listeners:
        - LoadBalancerPort: '80'
          InstancePort: '80'
          Protocol: HTTP
      HealthCheck:
        Target: HTTP:80/
        HealthyThreshold: '3'
        UnhealthyThreshold: '5'
        Interval: '30'
        Timeout: '5'
      SecurityGroups:
        - !Ref ELBWebServerSecurityGroup    

Marcin
  • 215,873
  • 14
  • 235
  • 294
  • @WaiYanHein I just updated the template and can confirm now it works. – Marcin Jul 27 '20 at 23:09
  • Hi. Thanks a lot. I will try with the new template then. I tried the previous one. It kept loading. – Wai Yan Hein Jul 27 '20 at 23:12
  • @WaiYanHein Yes, there was mistake in UserData :-(. But now it works, at least for me. But it takes a while till all UserData scripts run. Lots of updates to install. – Marcin Jul 27 '20 at 23:14
  • 1
    HI @Marcin, thanks a lot. It is working for me too. I got another question. Now we attach only one Nat to a public subnet. Should we not attach a separate nat to each public subnet also creating an Elastic IP for each? – Wai Yan Hein Jul 27 '20 at 23:27
  • @WaiYanHein No problem. You don't have to, but for high availability its recommended to do that. But you are limited to 5 EIPs. So if you use 3 EIPs for this VPC ( 1 EIP per NAT), you will be left with only 2. – Marcin Jul 28 '20 at 00:35
  • Hi @Marcin, thanks for getting back. I assign all the public subnets to load balancer. So it should not be the issue. Right? – Wai Yan Hein Jul 28 '20 at 00:52
  • @WaiYanHein If you use this only one VPC, this is not a problem. But lets say, you want to have second VPC, also with three NATs. Thus it total you will require 6 EIPs, and the limit is 5. – Marcin Jul 28 '20 at 00:54
  • 1
    Got it. Thank you so much. – Wai Yan Hein Jul 28 '20 at 01:16
  • @WaiYanHein There are still mistakes in the template. Check `SubnetRouteTableAssociation3`. It has incorrect `SubnetId`. I fixed that now in the answer. – Marcin Jul 28 '20 at 02:09
  • Hi @Marcin, another question is that why do we need to attach EIP for Nat gateway? Is it necessary? Can you please explain? – Wai Yan Hein Oct 09 '20 at 19:35
  • @WaiYanHein Hi. I don't know technical reasons for that. But one benefit of it is that instances, lambdas and more, in private subnets will static IP address connecting to the internet. This makes it easy to whiteliist such an address in other web services. – Marcin Oct 09 '20 at 22:35
  • Thanks @Marcin. So is it optional to attach an EIP to the Nat gateway then? – Wai Yan Hein Oct 10 '20 at 16:52
  • @WaiYanHein EIP is required. You can't create NAT without EIP. – Marcin Oct 11 '20 at 04:16
1

This is ultimately coming down to the health check failing due to no web server running on your hosts.

The hosts are private in subnets that have neither a NAT Gateway or NAT instance. Without this they are not able to setup apache and serve traffic.

To rectify this perform one of the following actions:

  • Add a NAT to the route table of the subnets for the private instances.
  • Create a pre baked AMI which already contains your configuration, then reference this AMI in your launch configuration.
  • Launch the instances as public (only if neither of the above scenarios work for you)
Chris Williams
  • 32,215
  • 4
  • 30
  • 68