# 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
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://isurus.gitbook.io/infrastructure-and-platform-notes/terraform-15/terraform-aws/15.elb.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
