Over a million developers have joined DZone.

AWS/Terraform Workshop #3: ELB, SNS, and Auto Scaling

DZone 's Guide to

AWS/Terraform Workshop #3: ELB, SNS, and Auto Scaling

Now that you know your way around AWS and Terraform, let's set up elastic load balancing, SNS communication, and Auto Scaling groups.

· Cloud Zone ·
Free Resource

If you're just joining us for this series, we're seeing how AWS and Terraform can work together to enhance your environment and infrastructure. Before we dive in, you should make sure you take a look at the following:

AWS Elastic Load Balancing (ELB)

AWS ELB automatically distributes incoming application traffic across multiple Amazon EC2 instances. It detects unhealthy instances and reroutes traffic to healthy instances until the unhealthy instances have been restored. Elastic Load Balancing automatically scales its request-handling capacity in response to incoming traffic.

Health checks: To discover the availability of your EC2 instances, the load balancer periodically sends pings, attempts connections, or sends requests to test the EC2 instances. These tests are called health checks. The status of the instances that are healthy at the time of the health check is InService. The status of any instances that are unhealthy at the time of the health check is OutOfService. The load balancer performs health checks on all registered instances, whether the instance is in a healthy state or an unhealthy state.

ELB Listener defines frontend and backend protocol/port for proxy connections. In case the frontend protocol it HTTPS, you will need to specify SSL certificates and ciphers.

ELB Security Group acts as a firewall that controls the traffic allowed to and from one or more ELBs or instances.

Additional ELB configurations:

  • To ensure that the load balancer stops sending requests to instances that are de-registering or unhealthy, while keeping the existing connections open, use connection draining. This enables the load balancer to complete in-flight requests made to instances that are de-registering or unhealthy.
  • By default, your load balancer distributes incoming requests evenly across its enabled Availability Zones. To ensure that your load balancer distributes incoming requests evenly across all back-end instances, regardless of the Availability Zone that they are in, enable cross-zone load balancing.
  • Elastic Load Balancing provides access logs that capture detailed information about all requests sent to your load balancer. Each log contains information such as the time the request was received, the client’s IP address, latencies, request paths, and server responses. You can use these access logs to analyze traffic patterns and to troubleshoot issues.

An Auto Scaling group (ASG) integrates with Elastic Load Balancing to enable you to attach one or more load balancers to an existing Auto Scaling group. After you attach the load balancer, it automatically registers the instances in the group and distributes incoming traffic across the instances.

By default, an ASG determines the health state of each instance by periodically checking the results of the EC2 instance status checks. If an instance fails the EC2 instance status checks, Auto Scaling marks the instance as unhealthy and replaces the instance. However, if you have attached one or more load balancers to your Auto Scaling group and the instance fails the Elastic Load Balancing health checks, Auto Scaling does not replace the instance by default. You can configure your Auto Scaling group to use both EC2 instance status checks and Elastic Load Balancing health checks to determine the health status of your instances.

If connection draining is enabled for your load balancer, Auto Scaling waits for the in-flight requests to complete or for the maximum timeout to expire, whichever comes first, before terminating instances due to a scaling event or health check replacement.

Read more:

AWS Simple Notification Service

AWS SNS is a web service that coordinates and manages the delivery or sending of messages to subscribing endpoints or clients. In Amazon SNS, there are two types of clients — publishers and subscribers — also referred to as producers and consumers. Publishers communicate asynchronously with subscribers by producing and sending a message to a topic, which is a logical access point and communication channel. Subscribers (i.e., web servers, email addresses etc) consume or receive the message or notification over one of the supported protocols (HTTP/S, email) when they are subscribed to the topic.

SNS is a common way to enable communication between AWS components and part of infrastructure placed outside AWS, for example:

  • You can configure an AWS CloudWatch alarm to send ALARM action to SNS and subscribe to it via email to get notifications.
  • ASG dynamic scaling requires CloudWatch alarms to trigger ASG scale policies, communication between CloudWatch and ASG is done via SNS.
  • Using SNS, you can trigger AWS Lambda functions (covered in later workshops).

Read more:

Hands On

  1. Go to the w3 directory in the cloned Smartling/aws-terraform-workshops git repository.

  2. Specify the actual IDs of AWS VPC, the subnet, and the Availability Zone into your terraform.tfvars file.

    Note: Follow the instructions in the Hands On section of Workshop #2 or just copy the terraform.tfvars file from it.

  3. Add your public SSH key to user-data.txt.

  4. Create an Auto Scaling group:

    • Configure your security group for instances in ASG to accept incoming connections via TCP ports 22 and 80 from

      Note: This is generally a bad idea from a security perspective — please avoid such a setup in configurations other than a workshop.

    • Add these missing arguments for ASG in your autoscaling.tf file:

      • Min instances limit = 2, max instances = 2
      • Instance type t2.nano
      • Add references between AWS resources: Attach ASG launch configuration to the ASG, etc.

        Note: Be prepared for the intential mistakes made in the Terraform configuration – just fix them.
    • Apply the Terraform configuration.

    • Check newly created AWS resources in the AWS web console.

  5. Create your AWS ELB and attach it to the ASG created before.

    • Uncomment resources in elb.tf and add the final configurations.

    • Configure the ELB Listener to accept HTTP connections on port 80, then forward them to port 80.

    • Enable connection draining.

    • Configure ELB health checks:

      1. Ping Target: "HTTP:80/"
      2. Healthy threshold = 3
      3. Unhealthy threshold = 3
      4. Timeout = 2
      5. Interval = 5
    • Put ELB in the same Security Group as your instances in the ASG.

    • Apply the Terraform configuration.

    • Attach ELB to ASG:

      1. Update the ASG configuration in Terraform
      2. Configure ASG to use ELB metrics instead of EC2
    • Find the ELB endpoint and open it in your browser – you should see an Nginx welcome page.

  6. Create SNS topic to receive ASG scaling notifications to email.

    • a. Uncomment the SNS topic resource in the sns.tf file.

    • Apply the Terraform configuration.

    • Go to the AWS SNS web console, find the newly created SNS topic, and create a subscription to your email address.

    • Update the ASG configuration to send its scaling events to the SNS topic.

    • Apply the Terraform configuration.

    • Log into one of the EC2 instances via SSH and stop docker using sudo service docker stop. ASG will detect that the instance is unhealthy (as it doesn't reply to health checks). Then, it will terminate it and create a new one.

    • Make sure you received notifications from ASG in your email.

  7. Destroy your AWS resources.

There you have it! Now, ELB and your ASGs are ready to go. This post is part of AWS/Terraform Workshops series that we share with you along with our vision of Service Oriented Architecture (SOA). Check out the introductory workshop and new posts at the Smartling Engineering Blog.

terraform ,autoscaling ,elastic load balancing ,tutorial ,cloud

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}