brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Oct 24. 2022

19탄-6. 테라폼-AWS-로드밸런서

다음은 주말 CloudNet 테라폼 스터디 내용 참고하여  정리한 부분입니다.

https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863



<1> ALB 생성 - alb.tf

<2> ALB와 ASG 연동 - asg.tf

<3> aws_lb_listener_rule 리소스를 사용해 리스너 규칙을 생성하여 연결 -  alb.tf

<4> 도전 과제



<1> ALB 생성 - alb.tf


1

ALB 배포


cat <<EOT > alb.tf

resource "aws_lb" "myalb" {

  name               = "t101-alb"

  load_balancer_type = "application"

  subnets            = [aws_subnet.mysubnet1.id, aws_subnet.mysubnet2.id]

  security_groups = [aws_security_group.mysg.id]


  tags = {

    Name = "t101-alb"

  }

}


output "myalb_dns" {

  value       = aws_lb.myalb.dns_name

  description = "The DNS Address of the ALB"

}


EOT




2

terraform plan && terraform apply -auto-approve


3

terraform state list


4

ALB 정보 확인

aws elbv2 describe-load-balancers --output table

aws elbv2 describe-load-balancers | jq


5

terraform output -raw myalb_dns


6.

ALBDNS=$(terraform output -raw myalb_dns)

while true; do curl --connect-timeout 1  http://$ALBDNS/ ; echo; echo "------------------------------"; date; sleep 1; done


------------------------------

Tue Oct 25 07:36:16 UTC 2022

curl: (7) Failed to connect to t101-alb-1965989833.ap-northeast-2.elb.amazonaws.com port 80 after 322 ms: Connection refused






7

alb 리스너 생성


cat <<EOT > alb.tf

resource "aws_lb" "myalb" {

  name               = "t101-alb"

  load_balancer_type = "application"

  subnets            = [aws_subnet.mysubnet1.id, aws_subnet.mysubnet2.id]

  security_groups = [aws_security_group.mysg.id]


  tags = {

    Name = "t101-alb"

  }

}


resource "aws_lb_listener" "myhttp" {

  load_balancer_arn = aws_lb.myalb.arn

  port              = 80

  protocol          = "HTTP"


  # By default, return a simple 404 page

  default_action {

    type = "fixed-response"


    fixed_response {

      content_type = "text/plain"

      message_body = "404: page not found - T101 Study"

      status_code  = 404

    }

  }

}


output "myalb_dns" {

  value       = aws_lb.myalb.dns_name

  description = "The DNS Address of the ALB"

}

EOT



8

terraform plan && terraform apply -auto-approve


9

# ALB DNS 주소 curl 접속 확인


ALBDNS=$(terraform output -raw myalb_dns)

while true; do curl --connect-timeout 1  http://$ALBDNS/ ; echo; echo "------------------------------"; date; sleep 1; done


404 나오면 정상

------------------------------

Tue Oct 25 07:33:09 UTC 2022

404: page not found - T101 Study




10

aws_lb_target_group 리소스를 사용하여 ASG의 대상 그룹을 생성

대상그룹 만들기~~~


cat <<EOT > alb.tf

resource "aws_lb" "myalb" {

  name               = "t101-alb"

  load_balancer_type = "application"

  subnets            = [aws_subnet.mysubnet1.id, aws_subnet.mysubnet2.id]

  security_groups = [aws_security_group.mysg.id]


  tags = {

    Name = "t101-alb"

  }

}


resource "aws_lb_listener" "myhttp" {

  load_balancer_arn = aws_lb.myalb.arn

  port              = 80

  protocol          = "HTTP"


  # By default, return a simple 404 page

  default_action {

    type = "fixed-response"


    fixed_response {

      content_type = "text/plain"

      message_body = "404: page not found - T101 Study"

      status_code  = 404

    }

  }

}


resource "aws_lb_target_group" "myalbtg" {

  name = "t101-alb-tg"

  port     = 80

  protocol = "HTTP"

  vpc_id   = aws_vpc.myvpc.id


  health_check {

    path                = "/"

    protocol            = "HTTP"

    matcher             = "200-299"

    interval            = 5

    timeout             = 3

    healthy_threshold   = 2

    unhealthy_threshold = 2

  }

}


output "myalb_dns" {

  value       = aws_lb.myalb.dns_name

  description = "The DNS Address of the ALB"

}

EOT



11

terraform plan && terraform apply -auto-approve

// 대상 그룹이 만들어 진다. 콘솔에서 확인!!!

// ALB 대상 그룹 확인 : 아직은 타켓 대상(EC2) 없음





<2> ALB와 ASG 연동 - asg.tf


1

대상서버 추가


cat <<EOT > asg.tf

data "aws_ami" "my_amazonlinux2" {

  most_recent = true

  filter {

    name   = "owner-alias"

    values = ["amazon"]

  }


  filter {

    name   = "name"

    values = ["amzn2-ami-hvm-*-x86_64-ebs"]

  }


  owners = ["amazon"]

}


resource "aws_launch_configuration" "mylauchconfig" {

  name_prefix     = "t101-lauchconfig-"

  image_id        = data.aws_ami.my_amazonlinux2.id

  instance_type   = "t2.micro"

  security_groups = [aws_security_group.mysg.id]

  associate_public_ip_address = true


  user_data = <<-EOF

              #!/bin/bash

              wget https://busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/busybox-x86_64

              mv busybox-x86_64 busybox

              chmod +x busybox

              RZAZ=\$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone-id)

              IID=\$(curl 169.254.169.254/latest/meta-data/instance-id)

              LIP=\$(curl 169.254.169.254/latest/meta-data/local-ipv4)

              echo "<h1>RegionAz(\$RZAZ) : Instance ID(\$IID) : Private IP(\$LIP) : Web Server</h1>" > index.html

              nohup ./busybox httpd -f -p 80 &

              EOF


  # Required when using a launch configuration with an auto scaling group.

  lifecycle {

    create_before_destroy = true

  }

}


resource "aws_autoscaling_group" "myasg" {

  name                 = "myasg"

  launch_configuration = aws_launch_configuration.mylauchconfig.name

  vpc_zone_identifier  = [aws_subnet.mysubnet1.id, aws_subnet.mysubnet2.id]

  min_size = 2

  max_size = 10

  health_check_type = "ELB"

  target_group_arns = [aws_lb_target_group.myalbtg.arn]


  tag {

    key                 = "Name"

    value               = "terraform-asg"

    propagate_at_launch = true

  }

}

EOT



//  health_check_type = "ELB"

  target_group_arns = [aws_lb_target_group.myalbtg.arn]



2

terraform plan && terraform apply -auto-approve


3

확인

타겟그룹에 EC2가 추가됨.

콘솔 확인




<3> aws_lb_listener_rule 리소스를 사용해 리스너 규칙을 생성하여 연결 -  alb.tf


1


cat <<EOT > alb.tf

resource "aws_lb" "myalb" {

  name               = "t101-alb"

  load_balancer_type = "application"

  subnets            = [aws_subnet.mysubnet1.id, aws_subnet.mysubnet2.id]

  security_groups = [aws_security_group.mysg.id]


  tags = {

    Name = "t101-alb"

  }

}


resource "aws_lb_listener" "myhttp" {

  load_balancer_arn = aws_lb.myalb.arn

  port              = 80

  protocol          = "HTTP"


  # By default, return a simple 404 page

  default_action {

    type = "fixed-response"


    fixed_response {

      content_type = "text/plain"

      message_body = "404: page not found - T101 Study"

      status_code  = 404

    }

  }

}


resource "aws_lb_target_group" "myalbtg" {

  name = "t101-alb-tg"

  port     = 80

  protocol = "HTTP"

  vpc_id   = aws_vpc.myvpc.id


  health_check {

    path                = "/"

    protocol            = "HTTP"

    matcher             = "200-299"

    interval            = 5

    timeout             = 3

    healthy_threshold   = 2

    unhealthy_threshold = 2

  }

}


resource "aws_lb_listener_rule" "myalbrule" {

  listener_arn = aws_lb_listener.myhttp.arn

  priority     = 100


  condition {

    path_pattern {

      values = ["*"]

    }

  }


  action {

    type             = "forward"

    target_group_arn = aws_lb_target_group.myalbtg.arn

  }

}


output "myalb_dns" {

  value       = aws_lb.myalb.dns_name

  description = "The DNS Address of the ALB"

}

EOT




2


배포 완료 후 curl 접속 확인


# 배포

terraform plan && terraform apply -auto-approve


결과

-----------------------------

Tue Oct 25 07:48:45 UTC 2022

<h1>RegionAz(apne2-az3) : Instance ID(i-0fa1d7e022b755d82) : Private IP(10.10.2.18) : Web Server</h1>

------------------------------

Tue Oct 25 07:48:46 UTC 2022

<h1>RegionAz(apne2-az1) : Instance ID(i-0e644930def8bf5ad) : Private IP(10.10.1.93) : Web Server</h1>

------------------------------

Tue Oct 25 07:48:47 UTC 2022

<h1>RegionAz(apne2-az1) : Instance ID(i-0e644930def8bf5ad) : Private IP(10.10.1.93) : Web Server</h1>

------------------------------

Tue Oct 25 07:48:48 UTC 2022



3

테스트


# ALB DNS주소로 curl 접속 확인 

ALBDNS=$(terraform output -raw myalb_dns)

for i in {1..100}; do curl -s http://$ALBDNS/ ; done | sort | uniq -c | sort -nr


vpc]# for i in {1..100}; do curl -s http://$ALBDNS/ ; done | sort | uniq -c | sort -nr

  53 <h1>RegionAz(apne2-az1) : Instance ID(i-0e644930def8bf5ad) : Private IP(10.10.1.93) : Web Server</h1>

  47 <h1>RegionAz(apne2-az3) : Instance ID(i-0fa1d7e022b755d82) : Private IP(10.10.2.18) : Web Server</h1>

53대 47로 분산 되고 있음.



4

# EC2 최소 2대 => 3대로 증가 수정

sed -i -e 's/min_size = 2/min_size = 3/g' asg.tf


# 배포

terraform plan && terraform apply -auto-approve


5

생성에 2~3분 걸리니  콘솔에서 생성 확인후 확인

# ALB DNS주소로 curl 접속 확인 

for i in {1..100}; do curl -s http://$ALBDNS/ ; done | sort | uniq -c | sort -nr


vpc]# for i in {1..100}; do curl -s http://$ALBDNS/ ; done | sort | uniq -c | sort -nr

     36 <h1>RegionAz(apne2-az1) : Instance ID(i-077fb0f43675b6849) : Private IP(10.10.1.176) : Web Server</h1>

     33 <h1>RegionAz(apne2-az1) : Instance ID(i-0e644930def8bf5ad) : Private IP(10.10.1.93) : Web Server</h1>

     31 <h1>RegionAz(apne2-az3) : Instance ID(i-0fa1d7e022b755d82) : Private IP(10.10.2.18) : Web Server</h1>



6

삭제: 

terraform destroy -auto-approve





<4> 과제와 도전 과제


1

과제

위 내용 코드와 스크린샷


[root@ip-172-31-61-209 vpc]# ls

alb.tf  asg.tf  sg.tf  terraform.tfstate  terraform.tfstate.backup  vpc.tf




2

도전 과제


변수로 처리

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb#network-load-balancer


ALB 에 HTTPS(ACM 인증서) 리스너 설정하여 SSL Offload(HTTPS → HTTP로 타켓 대상 연결) 연결하는 테라폼 코드 작성 및 실습해보기

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/acm_certificate


nlb

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb#network-load-balancer




다음과정

https://brunch.co.kr/@topasvga/2768






https://brunch.co.kr/@topasvga/2421

감사합니다.



브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari