{"id":18947638,"url":"https://github.com/yousafkhamza/terraform-alb","last_synced_at":"2026-02-27T00:32:05.860Z","repository":{"id":195965562,"uuid":"369297571","full_name":"yousafkhamza/terraform-alb","owner":"yousafkhamza","description":"Terraform is a tool for building infrastructure with various technologies including Amazon AWS, Microsoft Azure, Google Cloud, and vSphere. Here is a simple document on how to use Terraform to build an AWS ALB Application load balancer.","archived":false,"fork":false,"pushed_at":"2021-07-11T09:06:09.000Z","size":33,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-09T15:56:38.348Z","etag":null,"topics":["amazon-web-services","aws","terraform","terraform-module","terraform-modules"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yousafkhamza.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-05-20T18:06:56.000Z","updated_at":"2022-02-04T14:29:49.000Z","dependencies_parsed_at":"2023-09-20T19:52:55.019Z","dependency_job_id":"93541358-e400-4c67-bc7e-f8fe66c69191","html_url":"https://github.com/yousafkhamza/terraform-alb","commit_stats":null,"previous_names":["yousafkhamza/terraform-alb"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/yousafkhamza/terraform-alb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yousafkhamza%2Fterraform-alb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yousafkhamza%2Fterraform-alb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yousafkhamza%2Fterraform-alb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yousafkhamza%2Fterraform-alb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yousafkhamza","download_url":"https://codeload.github.com/yousafkhamza/terraform-alb/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yousafkhamza%2Fterraform-alb/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29879003,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-26T23:51:21.483Z","status":"ssl_error","status_checked_at":"2026-02-26T23:50:46.793Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amazon-web-services","aws","terraform","terraform-module","terraform-modules"],"created_at":"2024-11-08T13:10:49.096Z","updated_at":"2026-02-27T00:32:05.827Z","avatar_url":"https://github.com/yousafkhamza.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Creating Application Load Balancer using Terraform\n[![Builds](https://travis-ci.org/joemccann/dillinger.svg?branch=master)](https://travis-ci.org/joemccann/dillinger)\n\nTerraform is a tool for building infrastructure with various technologies including Amazon AWS, Microsoft Azure, Google Cloud, and vSphere.\nHere is a simple document on how to use Terraform to build an AWS ALB Application load balancer.\n\n## Features\n\n- Easy to customise with just a quick look with terrafrom code\n- AWS informations are defined using tfvars file and can easily changed\n- Project name is appended to the resources that are creating which will make easier to identify the resources.\n\n## Terraform Installation\n- Create an IAM user on your AWS console that have access to create the required resources.\n- Create a dedicated directory where you can create terraform configuration files.\n- Download Terrafom, click here [Terraform](https://www.terraform.io/downloads.html).\n- Install Terraform, click here [Terraform installation](https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started)\n\nUse the following command to install Terraform\n```sh\nwget https://releases.hashicorp.com/terraform/0.15.3/terraform_0.15.3_linux_amd64.zip\nunzip terraform_0.15.3_linux_amd64.zip \nls -l\n-rwxr-xr-x 1 root root 79991413 May  6 18:03 terraform  \u003c\u003c=======\n-rw-r--r-- 1 root root 32743141 May  6 18:50 terraform_0.15.3_linux_amd64.zip\nmv terraform /usr/bin/\nwhich terraform \n/usr/bin/terraform\n```\n#### Lets create a file for declaring the variables. \n\u003e Note : The terrafom files must be created with .tf extension. \n\nThis is used to declare the variable and pass values to terraform source code.\n```sh\nvim variable.tf\n```\n#### Declare the variables for initialising terraform (for terraform provider file )\n```sh\nvariable \"region\" {}\nvariable \"access_key\" {}\nvariable \"secret_key\" {}\nvariable \"project\" {}\nvariable \"vpc_cidr\" {}\n```\n#### Create the provider file\n\u003e Note : Terraform relies on plugins called \"providers\" to interact with remote systems. Terraform configurations must declare which providers they require, so that Terraform can install and use them. \nI'm using AWS as provider\n\n\n```sh\nvim provider.tf\n```\n```sh\nprovider \"aws\" {\n  region     = var.region\n  access_key = var.access_key\n  secret_key = var.secret_key\n}\n```\n\n#### Create a terraform.tfvars\n\u003e Note : A terraform.tfvars file is used to set the actual values of the variables.\n\n```sh\nvim terraform.tfvars\n```\n```sh\nregion = \"Desired region\"\naccess_key = \"IAM user access_key\"\nsecret_key = \"IAM user secret_key\"\nproject = \" Your project name\"\nvpc_cidr = \"VPC cidr block\"\n```\nThe Basic configuration for terraform aws is completed. Now we need to initialize the terraform using the loaded values\n\n## Creating Application Load Balancer\n\u003e A load balancer serves as the single point of contact for clients. The load balancer distributes incoming application traffic across multiple targets, such as EC2 instances, in multiple Availability Zones.\n\nThe main components of an Application load balancer are \n\n- [Listeners](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html) : A listener checks for connection requests from clients, using the protocol and port that you configure. The rules that you define for a listener determine how the load balancer routes requests to its registered targets. Each rule consists of a priority, one or more actions, and one or more conditions. When the conditions for a rule are met, then its actions are performed. You must define a default rule for each listener, and you can optionally define additional rules.\n\n- [Traget Group](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html) : Each target group routes requests to one or more registered targets, such as EC2 instances, using the protocol and port number that you specify. You can register a target with multiple target groups. You can configure health checks on a per target group basis. Health checks are performed on all targets registered to a target group that is specified in a listener rule for your load balancer.\n\nThe following diagram illustrates the basic components. \n\n![alt text](https://i.ibb.co/dQ7rc4k/Screenshot-from-2021-05-19-18-59-29.png)\n\n##### Get all subnet of new vpc\n\n```sh\ndata \"aws_subnet_ids\" \"default\" {\n  vpc_id = \"existing-vpc-id\"  \u003c===================== Please note that your existing VPC ID.\n  }\n```  \n\n##### Create a security group for load balancer \n\n```sh\nresource \"aws_security_group\" \"sg-web\" {\n  name        = \"sgweb\"\n  description = \"Allow 80,443,22\"\n  \n  ingress {\n    description      = \"HTTPS\"\n    from_port        = 80\n    to_port          = 80\n    protocol         = \"tcp\"\n   cidr_blocks      = [\"0.0.0.0/0\"]\n    ipv6_cidr_blocks = [\"::/0\"]\n  }\n  ingress {\n    description      = \"HTTPS\"\n    from_port        = 443\n    to_port          = 443\n    protocol         = \"tcp\"\n   cidr_blocks      = [\"0.0.0.0/0\"]\n    ipv6_cidr_blocks = [\"::/0\"]\n  }\n  ingress {\n    description      = \"SSH\"\n    from_port        = 22\n    to_port          = 22\n    protocol         = \"tcp\"\n   cidr_blocks      = [\"0.0.0.0/0\"]\n    ipv6_cidr_blocks = [\"::/0\"]\n  }\n\n  egress {\n    from_port        = 0\n    to_port          = 0\n    protocol         = \"-1\"\n    cidr_blocks      = [\"0.0.0.0/0\"]\n    ipv6_cidr_blocks = [\"::/0\"]\n  }\n\n  tags = {\n    Name = \"webserver\"\n  }\n    lifecycle {\n    create_before_destroy = true\n  }\n}\n```\n\n#### Create TargetGroup For Application LoadBalancer\n\u003e Lets's create 2 target group so that we can forward the traffic \n\n\u003e Target Group One\n```sh\nresource \"aws_lb_target_group\" \"tg-one\" {\n  name     = \"lb-tg-one\"\n  port     = 80\n  protocol = \"HTTP\"\n  vpc_id   = aws_vpc.vpc.id\n  load_balancing_algorithm_type = \"round_robin\"\n  deregistration_delay = 60\n  stickiness {\n    enabled = false\n    type    = \"lb_cookie\"\n    cookie_duration = 60\n  }\n\n  health_check {\n    healthy_threshold   = 2\n    unhealthy_threshold = 2\n    interval            = 30\n    path                = \"/\"\n    protocol            = \"HTTP\"\n    matcher             = 200\n    \n  }\n\n  lifecycle {\n    create_before_destroy = true\n  }\n}\n\n```\n\n\u003e Target Group Two\n\n```sh\nresource \"aws_lb_target_group\" \"tg-two\" {\n  name     = \"lb-tg-two\"\n  port     = 80\n  protocol = \"HTTP\"\n  vpc_id   = aws_vpc.vpc.id\n  load_balancing_algorithm_type = \"round_robin\"\n  deregistration_delay = 60\n  stickiness {\n    enabled = false\n    type    = \"lb_cookie\"\n    cookie_duration = 60\n  }\n\n  health_check {\n    healthy_threshold   = 2\n    unhealthy_threshold = 2\n    interval            = 30\n    path                = \"/\"\n    protocol            = \"HTTP\"\n    matcher             = 200\n\n  }\n\n  lifecycle {\n    create_before_destroy = true\n  }\n}\n```\n\n\u003e _Note : lifecycle is a nested block that can appear within a resource block._ \n\u003e _create_before_destroy is a meta-argument  that will create new replacement object first, and the prior object is destroyed after the replacement is created._\n\n##### Create Application LoadBalancer\n```sh\nresource \"aws_lb\" \"lb\" {\n  name               = \"lb\"\n  internal           = false\n  load_balancer_type = \"application\"\n  security_groups    = [aws_security_group.alltraffic.id]\n  subnets            = data.aws_subnet_ids.default.ids\n  enable_deletion_protection = false\n  depends_on = [ aws_lb_target_group.tg-one ]\n  tags = {\n     Name = \"${var.project}-lb\"\n   }\n}\n\noutput \"alb-endpoint\" {\n  value = aws_lb.lb.dns_name\n} \n```\n##### Creating http listener of application loadbalancer with default action.\n```sh\nresource \"aws_lb_listener\" \"listner\" {\n  \n  load_balancer_arn = aws_lb.lb.id\n  port              = 80\n  protocol          = \"HTTP\"\n  \n#-------------------------------------\n#defualt action of the target group.\n#-------------------------------------\n\n  default_action {\n    type = \"fixed-response\"\n    fixed_response {\n      content_type = \"text/plain\"\n      message_body = \" No such Site Found\"\n      status_code  = \"200\"\n   }\n}\n    \n  depends_on = [  aws_lb.mylb ]\n}\n```\n\u003e Note : Use the depends_on meta-argument to handle hidden resource or module dependencies that Terraform can't automatically infer.\n\n##### forward first hostname to targetgroup-one (eg: one-yousaf.com)\n```sh\n#-------------------------------------\n#First forwording rule\n#-------------------------------------\n\nresource \"aws_lb_listener_rule\" \"rule-one\" {\n\n  listener_arn = aws_lb_listener.listner.id\n  priority     = 5\n\n  action {\n    type             = \"forward\"\n    target_group_arn = aws_lb_target_group.tg-one.arn\n  }\n\n  condition {\n    host_header {\n      values = [\"first-host-name-\"]\n    }\n  }\n}\n```\n\n##### forward second hostname to targetgroup-two (eg: two-yousaf.com)\n```sh\nresource \"aws_lb_listener_rule\" \"rule-two\" {\n    \n  listener_arn = aws_lb_listener.listner.id\n  priority     = 5\n\n  action {\n    type             = \"forward\"\n    target_group_arn = aws_lb_target_group.tg-two.arn\n  }\n\n  condition {\n    host_header {\n      values = [\"-second-host-name-\"]\n    }\n  }\n}\n```\nNext, we need to create Launch configuration so that we can create Auto scaling group\n\n#####  Launch Configuration\n```sh\n#-------------------------------------\n#First Lauch Configuration\n#-------------------------------------\n\nresource \"aws_launch_configuration\" \"launch-one\" {\n  image_id          = \"-choose-a-AMI\"\n  instance_type     = \"-instance-type-\"\n  security_groups   = [ aws_security_group.sg-web.id ]\n  user_data         = file(\"launch-conf.sh\")\n\n  lifecycle {\n    create_before_destroy = true\n  }\n}\n\n#-------------------------------------\n#Second Lauch configuration\n#-------------------------------------\n\nresource \"aws_launch_configuration\" \"launch-two\" {\n  image_id        = \"-choose-a-AMI\"\n  instance_type   = \"-Instance-type\"\n  security_groups = [ aws_security_group.sg-web.id ]\n  user_data       = file(\"launch-conf.sh\")\n\n  lifecycle {\n    create_before_destroy = true\n  }\n}\n\n\n```\n\u003e Note : We are using file() to load user data.\n\n###### Create Auto Scaling Group One with Lauch configuration one to Target group one\n```sh\n#-------------------------------------\n#First ASG with Lauch configuration one\n#-------------------------------------\n\nresource \"aws_autoscaling_group\" \"asg-one\" {\n\n  launch_configuration    = aws_launch_configuration.launch-one.id\n  health_check_type       = \"EC2\"\n  min_size                = var.asg_count\n  max_size                = var.asg_count\n  desired_capacity        = var.asg_count\n  vpc_zone_identifier     = [-choose-public-subjet-one-,-choose-public-subjet-two-]\n  target_group_arns       = [ aws_lb_target_group.tg-one.arn ]\n  tag {\n    key = \"Name\"\n    propagate_at_launch = true\n    value = \"Asg-one\"\n  }\n\n  lifecycle {\n    create_before_destroy = true\n  }\n}\n```\n###### Create Auto Scaling Group two with Lauch configuration two to Target group two\n```sh\nresource \"aws_autoscaling_group\" \"asg-two\" {\n\n  launch_configuration    = aws_launch_configuration.launch-two.id\n  health_check_type       = \"EC2\"\n  min_size                = var.asg_count\n  max_size                = var.asg_count\n  desired_capacity        = var.asg_count\n  vpc_zone_identifier     = [-choose-public-subjet-one-,-choose-public-subjet-two-]\n  target_group_arns       = [ aws_lb_target_group.tg-two.arn ]\n  tag {\n    key = \"Name\"\n    propagate_at_launch = true\n    value = \"asg-two\"\n  }\n\n  lifecycle {\n    create_before_destroy = true\n  }\n}\n```\n\nNow we need to create a variable file for the autoscaling count\n```sh\nvim variable-asg.tf\n```\n```sh\n variable \"asg_count\" {\n  default = 2\n}                                          \n```\nWe need to create 2 user data for launch configuration. \n```sh\nvim launch-conf.sh\n```\n```sh\n#!/bin/bash\n\necho \"ClientAliveInterval 60\" \u003e\u003e /etc/ssh/sshd_config\necho \"LANG=en_US.utf-8\" \u003e\u003e /etc/environment\necho \"LC_ALL=en_US.utf-8\" \u003e\u003e /etc/environment\n\n\necho \"password123\" | passwd root --stdin\nsed  -i 's/#PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config\nsed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config\nservice sshd restart\n\nyum install http php git -y\nsystemctl start httpd\nsystemctl enable httpd\ngit clone https://github.com/yousafkhamza/aws-elb-site.git /var/website\ncp -r /var/website/*  /var/www/html/\nchown -R apache:apache /var/www/html/*\n```\n\n\u003e Note : I used the same launch configuration for both the ASG. However, I've inserted code so that it will show the hostname IP, so that we can identify from which target group it was loaded. \n\n#### Terraform Validation\n\u003e This will check for any errors on the source code\n\n```sh\nterraform validate\n```\n#### Terraform Plan\n\u003e The terraform plan command provides a preview of the actions that Terraform will take in order to configure resources per the configuration file. \n\n```sh\nterraform plan\n```\n#### Terraform apply\n\u003e This will execute the tf file we created\n\n```sh\nterraform apply\n```\n\n-----\n## Conclusion\n\nHere is a simple document on how to use Terraform to build an AWS ALB Application load balancer.\n\n#### ⚙️ Connect with Me\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"mailto:yousaf.k.hamza@gmail.com\"\u003e\u003cimg src=\"https://img.shields.io/badge/Gmail-D14836?style=for-the-badge\u0026logo=gmail\u0026logoColor=white\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://www.linkedin.com/in/yousafkhamza\"\u003e\u003cimg src=\"https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge\u0026logo=linkedin\u0026logoColor=white\"/\u003e\u003c/a\u003e \n\u003ca href=\"https://www.instagram.com/yousafkhamza\"\u003e\u003cimg src=\"https://img.shields.io/badge/Instagram-E4405F?style=for-the-badge\u0026logo=instagram\u0026logoColor=white\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://wa.me/%2B917736720639?text=This%20message%20from%20GitHub.\"\u003e\u003cimg src=\"https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge\u0026logo=whatsapp\u0026logoColor=white\"/\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyousafkhamza%2Fterraform-alb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyousafkhamza%2Fterraform-alb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyousafkhamza%2Fterraform-alb/lists"}