Elastic Load Balancers (ELB)

Once we have placed autoscaling for our EC2 instances, we might want to put load balancing for these instances. That is where ELB comes in. ELB automatically distributes incoming traffic across multiple EC2 instances. It scales up and down according to the receiving traffic. When there are multiple EC2 instances running behind ELB, it will perform periodic health checks and terminate traffic flow if these health checks get failed. In case of a autoscaling group taking care of EC2 instances and it adds a new instance, ELB will automatically notice the new instance and will start health checks.

In addtion to health checks, ELB also can use to SSL termination, where it will offload the certificates and allow unencrypted traffic to flow inside the subnets.

ELBs can be spread accross multiple availability zones for higher fault tolerance.

In this example I will create an ELB to manage traffic flow to an EC2 instance provisioned using an autoscaling group.

Let me first declare our autoscaling group in autoscaling.tf,

resource "aws_launch_configuration" "example-launchconfig" {
  name_prefix     = "example-launchconfig"
  image_id        = var.AMIS[var.AWS_REGION]
  instance_type   = "t2.micro"
  key_name        = aws_key_pair.mykeypair.key_name
  security_groups = [aws_security_group.myinstance.id]
  user_data       = "#!/bin/bash\napt-get update\napt-get -y install net-tools nginx\nMYIP=`ifconfig | grep -E '(inet 10)|(addr:10)' | awk '{ print $2 }' | cut -d ':' -f2`\necho 'this is: '$MYIP > /var/www/html/index.html"
  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_autoscaling_group" "example-autoscaling" {
  name                      = "example-autoscaling"
  vpc_zone_identifier       = [aws_subnet.main-public-1.id, aws_subnet.main-public-2.id]
  launch_configuration      = aws_launch_configuration.example-launchconfig.name
  min_size                  = 2
  max_size                  = 2
  health_check_grace_period = 300
  health_check_type         = "ELB"
  load_balancers            = [aws_elb.my-elb.name]
  force_delete              = true

  tag {
    key                 = "Name"
    value               = "ec2 instance"
    propagate_at_launch = true
  }
}

Next I'm creating elb.tf file to declare the ELB instance,

resource "aws_elb" "my-elb" {
  name            = "my-elb"
  subnets         = [aws_subnet.main-public-1.id, aws_subnet.main-public-2.id]
  security_groups = [aws_security_group.elb-securitygroup.id]
  listener {
    instance_port     = 80
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  }
  health_check {
    healthy_threshold   = 2
    unhealthy_threshold = 2
    timeout             = 3
    target              = "HTTP:80/"
    interval            = 30
  }

  cross_zone_load_balancing   = true
  connection_draining         = true
  connection_draining_timeout = 400
  tags = {
    Name = "my-elb"
  }
}

Generate ssh keys,

$ ssh-keygen -f mykey

Initialize the providers,

$ terraform init

Apply the changes,

$ terraform apply

Don't forget to clean up once experiments are done,

$ terraform destroy

Last updated