AWS CloudFormation provides users with a simple way to create and manage a collection of Amazon Web Services (AWS) resources by provisioning and updating them in a predictable way. AWS CloudFormation enables you to manage your complete infrastructure or AWS resources in a text file.

Here we are deploying a simple php application with elastic load balancer and autoscaling group using cloudformation.

A stack is a collection of AWS resources that you can manage as a single unit. In other words, you can create, update, or delete a collection of resources by creating, updating, or deleting stacks. All the resources in a stack are defined by the stack's AWS CloudFormation template

First we are creating a stack using cloudformation template.

A) creat a test.yaml file and save the below contents.

AWSTemplateFormatVersion: 2010-09-09
Description: 'AWS CloudFormation Sample Template UpdateTutorial Part 5: Sample template
  that can be used to test EC2 updates convert a single instance deployment into an
  Auto Scaled, Load Balanced solutio. **WARNING** This template creates an Amazon
  Ec2 Instance. You will be billed for the AWS resources used if you create a stack
  from this template.'
  
Parameters:

  LinuxAmiId:
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'

  ENV:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - prod


  VPCId:
    Description: VPC ID of the Lab VPC
    Type: String

  VPCPublicSubnetId:
    Description: Subnet ID of the public subnet within the Lab VPC
    Type: String

  VPCPublicSubnetAZ:
    Description: AZ of the public subnet within the Lab VPC
    Type: String

Mappings:
  EC2TypeConfig:
    prod:
      InstanceType: t2.small
    dev:
      InstanceType: t2.micro

Resources:
  WebServerInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - ec2-role
  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP
      VpcId: !Ref VPCId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

  ElasticLoadBalancer:
    Type: AWS::ElasticLoadBalancing::LoadBalancer
    Properties:
      Subnets:
        - !Ref VPCPublicSubnetId
      SecurityGroups:
        - !Ref WebServerSecurityGroup
      Listeners:
        - LoadBalancerPort: 80
          InstancePort: 80
          Protocol: HTTP
      HealthCheck:
        Target: HTTP:80/
        HealthyThreshold: 3
        UnhealthyThreshold: 5
        Interval: 30
        Timeout: 5

  WebServerGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      AvailabilityZones:
        - !Ref VPCPublicSubnetAZ
      LaunchConfigurationName: !Ref WebServerConfig
      MinSize: 2
      MaxSize: 3
      LoadBalancerNames:
        - !Ref ElasticLoadBalancer
      VPCZoneIdentifier:
        - !Ref VPCPublicSubnetId

  WebServerConfig:
    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M
    Type: AWS::AutoScaling::LaunchConfiguration
    Metadata:
      Comment: Install a simple PHP application
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
              php: []
          files:
            /var/www/html/index.php:
              content: |
                <?php
                echo '<h1>AWS CloudFormation sample PHP application</h1>';
                echo 'Highly available, load balanced stack updated version via UpdateStack';
                 ?>
              mode: 000644
              owner: apache
              group: apache
          services:
            sysvinit:
              httpd:
                enabled: true
                ensureRunning: true
              sendmail:
                enabled: false
                ensureRunning: false

    Properties:
      ImageId: !Ref LinuxAmiId
      InstanceType: !FindInMap [EC2TypeConfig, !Ref ENV, InstanceType]
      SecurityGroups:
        - !Ref WebServerSecurityGroup
      IamInstanceProfile: !Ref WebServerInstanceProfile
      UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash
            yum update -y aws-cfn-bootstrap
            /opt/aws/bin/cfn-init -s ${AWS::StackName} -r WebServerConfig --region ${AWS::Region}

            /opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'

            /opt/aws/bin/cfn-signal --exit-code $? --stack ${AWS::StackName} --resource WebServerConfig --region ${AWS::Region}
Outputs:
  WebsiteURL:
    Value: !Sub http://${ElasticLoadBalancer.DNSName}
    Description: Application URL

B)  we want to create a IAM role for cloudformation named as ec2-role.Login to IAM and create role for cloudformation and give name as ec2-role with administrator access.

Login into aws console and cloudformation.

C) Create stack

D) Click choose file and upload test.yaml and Next

E) Type a stack name and give VPCid, VPCPublicSubnetAZ, VPCPublic subnetid which we can get from our VPC dashboard. You want to choose a VPC and a availability zone and a subnet in that availability zone,here i choose my default vpc.

Click Next

F) Select the IAM role that we created previously. Then Next,

G)  Finally create stack

H) Wait few times and stack resuources will be created and you can see a stack called test(my stack name).Go to the output section click the link thats your ELB DNS name

I)  You can see your web contents .

J)  If you have domain and want to route domain to this ELB, login into Route53 and  create a Hosted zone and you will get NS records , then login to your domain registar and change your domain NS to those records . After this your domain's DNS is with aws, now you can create a simple A record and point to that ELB.

1) create hosted zone and give your domain name  and  click create hosted zone.

2) you will get NS and SOA records(optional)

3)Login to your domain portal and change NS

4) Add A records in Route53 and route traffic to our ELB.

choose your region

and select your elb  and click create records thats all, Open your browser and type your doman , yaaa it working.

We deployed simple php application with autoscaling group and elb, we did'nt specify ec2 key here so we can't login to our ec2, if you want to login to your ec2 then specify key as properties(refer aws documents ) in autoscaling group launch configuration section in test.yaml.