Elastic Load Balancing automatically distributes your incoming traffic across multiple targets, such as EC2 instances, containers, and IP addresses, in one or more Availability Zones. It monitors the health of its registered targets, and routes traffic only to the healthy targets. Elastic Load Balancing scales your load balancer capacity automatically in response to changes in incoming traffic.
There are 3 types of load balancer service:
In this lab, I will setup an Application Load Balancer in our VPC and route traffic to ASG’s instances. The ALB has internet-facing, so it will be deployed on public subnets and have Security Group allow route traffic to instance’s Security Group.
This script creates a Application Load Balancer, target group to ASG and listener rule for HTTP traffic from internet, S3 bucket to save access logs, which helps you trace the logs later.
############### Application Load Balancer ###############
resource "aws_lb" "lab_alb" {
name = "lab-alb"
internal = false
load_balancer_type = "application"
security_groups = [module.alb_sg.security_group_id]
subnets = module.vpc.public_subnets
enable_deletion_protection = true
access_logs {
bucket = module.s3_bucket_for_logs.s3_bucket_id
prefix = ""
enabled = true
}
}
resource "aws_lb_target_group" "lab_instance" {
name = "lab-instance"
port = 80
protocol = "HTTP"
vpc_id = module.vpc.vpc_id
}
resource "aws_lb_listener" "demo-alb-listener" {
load_balancer_arn = aws_lb.lab_alb.arn
port = 80
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.lab_instance.arn
}
}
resource "aws_autoscaling_attachment" "web_asg_attachment" {
autoscaling_group_name = aws_autoscaling_group.web_asg.id
lb_target_group_arn = aws_lb_target_group.lab_instance.arn
}
For S3 bucket log, the resource.random_pet block will create a random name, which help you create a unique name for your bucket, sometimes the bucket name can be overlapped, you can explicit set the name.
S3 bucket
############### S3 ###############
resource "random_pet" "s3_bucket" {}
module "s3_bucket_for_logs" {
source = "terraform-aws-modules/s3-bucket/aws"
bucket = "my-s3-bucket-for-logs-lab-${random_pet.s3_bucket.id}"
acl = "log-delivery-write"
# Allow deletion of non-empty bucket
force_destroy = true
control_object_ownership = true
object_ownership = "ObjectWriter"
attach_elb_log_delivery_policy = true # Required for ALB logs
attach_lb_log_delivery_policy = true # Required for ALB/NLB logs
}
Note: attach_elb_log_delivery_policy and attach_lb_log_delivery_policy are predefined rules for allowing ALB permission to write log to S3 bucket.
which policy you can see in Console:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ELBRegionUs-East-1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::127311923021:root"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-s3-bucket-for-logs-lab-concise-snapper/*"
},
{
"Effect": "Allow",
"Principal": {
"Service": "logdelivery.elasticloadbalancing.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-s3-bucket-for-logs-lab-concise-snapper/*"
},
{
"Sid": "AWSLogDeliveryWrite",
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-s3-bucket-for-logs-lab-concise-snapper/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Sid": "AWSLogDeliveryAclCheck",
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": [
"s3:ListBucket",
"s3:GetBucketAcl"
],
"Resource": "arn:aws:s3:::my-s3-bucket-for-logs-lab-concise-snapper"
}
]
}
Result in Console:
