AWS-ELB-ASG-Terraform





provider.tf

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
  }
}

provider "aws" {
  region     = "ap-south-1"
}

VPC.tf
resource "aws_vpc" "web-vpc" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "Terraform-VPC"
  }
}

Subnet.tf
resource "aws_subnet" "web-pub-sub-1a" {
  vpc_id                  = aws_vpc.web-vpc.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "ap-south-1a"
  map_public_ip_on_launch = true

  depends_on = [aws_internet_gateway.web-igw]

  tags = {
    Name = "Terraform-Public-1-Subnet"
  }
}

resource "aws_subnet" "web-pub-sub-1b" {
  vpc_id                  = aws_vpc.web-vpc.id
  cidr_block              = "10.0.2.0/24"
  availability_zone       = "ap-south-1b"
  map_public_ip_on_launch = true

  depends_on = [aws_internet_gateway.web-igw]

  tags = {
    Name = "Terraform-Public-2-Subnet"
  }
}

resource "aws_subnet" "web-prv-sub-1a" {
  vpc_id            = aws_vpc.web-vpc.id
  cidr_block        = "10.0.3.0/24"
  availability_zone = "ap-south-1a"

  depends_on = [aws_internet_gateway.web-igw]

  tags = {
    Name = "Terraform-Private-3-Subnet"
  }
}

resource "aws_subnet" "web-prv-sub-1b" {
  vpc_id            = aws_vpc.web-vpc.id
  cidr_block        = "10.0.4.0/24"
  availability_zone = "ap-south-1b"

  depends_on = [aws_internet_gateway.web-igw]

  tags = {
    Name = "Terraform-Private-4-Subnet"
  }
}

InternetGateway.tf
resource "aws_internet_gateway" "web-igw" {
  vpc_id = aws_vpc.web-vpc.id

  tags = {
    Name = "Terraform-IGW"
  }
}

RouteTable&Association.tf
resource "aws_route_table" "web-rt" {
  vpc_id = aws_vpc.web-vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.web-igw.id
  }

  tags = {
    Name = "Terraform-RT"
  }
}

resource "aws_route_table_association" "web-rta1" {
  subnet_id      = aws_subnet.web-pub-sub-1a.id
  route_table_id = aws_route_table.web-rt.id

}

resource "aws_route_table_association" "web-rta2" {
  subnet_id      = aws_subnet.web-pub-sub-1b.id
  route_table_id = aws_route_table.web-rt.id

}

SecurityGroup.tf
resource "aws_security_group" "web-sg" {
  name        = "Terraform-SG"
  description = "Terraform http & RDP allow"
  vpc_id      = aws_vpc.web-vpc.id

  tags = {
    Name = "Terraform"
  }
}

resource "aws_vpc_security_group_ingress_rule" "http_allow_all" {
  security_group_id = aws_security_group.web-sg.id
  cidr_ipv4         = "0.0.0.0/0"
  from_port         = 80
  ip_protocol       = "tcp"
  to_port           = 80
}

resource "aws_vpc_security_group_ingress_rule" "rdp_allow_ip" {
  security_group_id = aws_security_group.web-sg.id
  cidr_ipv4         = "103.163.248.19/32"
  from_port         = 3389
  ip_protocol       = "tcp"
  to_port           = 3389
}

resource "aws_vpc_security_group_egress_rule" "allow_all_egress" {
  security_group_id = aws_security_group.web-sg.id
  cidr_ipv4         = "0.0.0.0/0"
  ip_protocol       = "-1" # semantically equivalent to all ports
}

Template.tf
variable "html_content" {
  description = "list of contents into index.html"
  type        = list(string)
  default     = ["server 1", "server 2", "server 3"]
}

resource "aws_launch_template" "web-template" {
  name = "Terraform-Template"

  block_device_mappings {
    device_name = "/dev/sdf"

    ebs {
      volume_size = 20
    }
  }

  disable_api_stop        = false
  disable_api_termination = false

  image_id = "ami-0f26813c8d83a7f9f"

  instance_initiated_shutdown_behavior = "terminate"

  instance_type = "t2.micro"

  key_name = aws_key_pair.web-keypair.key_name

  monitoring {
    enabled = true
  }

  # network_interfaces {
  #   associate_public_ip_address = true
  # }

  vpc_security_group_ids = [aws_security_group.web-sg.id]

  tag_specifications {
    resource_type = "instance"

    tags = {
      Name = "Terraform-Template"
    }
  }

  user_data = base64encode(<<-EOF
    
    Install-WindowsFeature -name Web-Server -IncludeManagementTools
    $htmlContent = ${jsonencode(var.html_content)}
    $htmlPath = "C:\\inetpub\\wwwroot\\index.html"
    Set-Content -Path $htmlPath -Value $htmlContent
    foreach ($content in $htmlContent) {
        Add-Content -Path $htmlPath -Value $content
    }
    $newHostname = "IIS-WebServer"
    Rename-Computer -NewName $newHostname -Force -PassThru
    Restart-Computer -Force
    
  EOF
  )
}

TargetGroup.tf
resource "aws_lb_target_group" "web-tg" {
  name        = "Terraform-LB-TG"
  port        = 80
  protocol    = "HTTP"
  target_type = "instance"
  vpc_id      = aws_vpc.web-vpc.id
}

ApplicationLoadBalancer.tf
resource "aws_lb" "web-alb" {
  name               = "Terraform-ALB"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.web-sg.id]
  subnets            = [aws_subnet.web-pub-sub-1a.id, aws_subnet.web-pub-sub-1b.id]

  tags = {
    Environment = "Terraform-ALB"
  }
}

resource "aws_lb_listener" "web-alb-list" {
  load_balancer_arn = aws_lb.web-alb.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.web-tg.arn
  }
}

AutoScalingGroup.tf
resource "aws_autoscaling_group" "web-asg" {
  name = "Terraform-ASG"
  #availability_zones = ["ap-south-1a", "ap-south-1b"]
  desired_capacity = 2
  max_size         = 3
  min_size         = 2

  launch_template {
    id      = aws_launch_template.web-template.id
    version = "$Latest"
  }
  target_group_arns         = [aws_lb_target_group.web-tg.arn]
  health_check_grace_period = 300
  health_check_type         = "EC2"
  force_delete              = true
  vpc_zone_identifier       = [aws_subnet.web-pub-sub-1a.id, aws_subnet.web-pub-sub-1b.id]
}