provider "aws" {
region = "ap-northeast-2"
}
# 최신 Amazon Linux 2 AMI
data "aws_ami" "amzn2" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
}
# 키페어
resource "aws_key_pair" "tf_keypair" {
key_name = "tf_keypair"
public_key = file("C:/ssh/tf_keypair.pub")
tags = {
Description = "TF-KeyPair"
}
}
# VPC, Subnet
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
availability_zone = "ap-northeast-2a"
}
# 인터넷 게이트웨이
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
}
resource "aws_route_table" "rt" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
}
resource "aws_route_table_association" "rt_assoc" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.rt.id
}
# 보안 그룹
resource "aws_security_group" "web_sg" {
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# EC2 인스턴스 2개
resource "aws_instance" "web1" {
ami = data.aws_ami.amzn2.id
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
key_name = aws_key_pair.tf_keypair.key_name
vpc_security_group_ids = [aws_security_group.web_sg.id]
user_data = <<-EOF
#!/bin/bash
echo "root:aws1234!" | chpasswd
sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart sshd
yum update -y
yum install -y httpd
sed -i 's/^Listen .*/Listen 0.0.0.0:80/' /etc/httpd/conf/httpd.conf
echo "<h1>Web Server 1</h1>" > /var/www/html/index.html
systemctl start httpd
systemctl enable httpd
EOF
}
resource "aws_instance" "web2" {
ami = data.aws_ami.amzn2.id
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
key_name = aws_key_pair.tf_keypair.key_name
vpc_security_group_ids = [aws_security_group.web_sg.id]
user_data = <<-EOF
#!/bin/bash
echo "root:aws1234!" | chpasswd
sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart sshd
yum update -y
yum install -y httpd
sed -i 's/^Listen .*/Listen 0.0.0.0:80/' /etc/httpd/conf/httpd.conf
echo "<h1>Web Server 2</h1>" > /var/www/html/index.html
systemctl start httpd
systemctl enable httpd
EOF
}
# NLB
resource "aws_lb" "nlb" {
name = "my-nlb"
internal = false
load_balancer_type = "network"
subnets = [aws_subnet.public.id]
}
resource "aws_lb_target_group" "tg" {
name = "nlb-tg"
port = 80
protocol = "TCP"
target_type = "instance"
vpc_id = aws_vpc.main.id
}
resource "aws_lb_target_group_attachment" "attach1" {
target_group_arn = aws_lb_target_group.tg.arn
target_id = aws_instance.web1.id
port = 80
}
resource "aws_lb_target_group_attachment" "attach2" {
target_group_arn = aws_lb_target_group.tg.arn
target_id = aws_instance.web2.id
port = 80
}
resource "aws_lb_listener" "listener" {
load_balancer_arn = aws_lb.nlb.arn
port = 80
protocol = "TCP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.tg.arn
}
}
# 출력
output "nlb_dns" {
value = aws_lb.nlb.dns_name
}
🔍 문제 원인 요약
✅ 1. NLB는 L4 (TCP) 기반
NLB는 HTTP 프로토콜을 이해하지 못하고, 단순히 TCP 포트만 로드밸런싱합니다.
브라우저는 HTTP 요청에 대해 **정상적인 응답 코드(200 등)**을 기대하지만, NLB는 그걸 보장하지 않음.
특히 웹서버가 부팅 후 포트 80이 열려 있더라도, Health Check 실패 시 트래픽 전달이 되지 않음.
✅ 2. NLB Target Group의 기본 상태 확인 방식은 TCP
EC2가 포트 80에 단순 TCP 응답만 하면 Healthy로 간주됨.
웹 서버가 아직 Apache 서비스를 띄우지 않았거나, yum update 지연 등으로 응답이 늦어지면 브라우저에서 응답 지연 또는 실패 발생 가능.
🔧 해결 방법
옵션 1: ALB 사용 (권장)
HTTP 기반 상태 확인 가능 (path = "/")
웹 브라우저와의 호환성이 뛰어남 (L7 레벨에서 동작)
로드밸런싱 동작이 눈에 보이게 확인 가능함
옵션 2: NLB에서 상태 확인과 딜레이 조정
NLB를 꼭 써야 한다면 아래처럼 health check를 잘 설정해줘야 합니다:
hcl
코드 복사
resource "aws_lb_target_group" "tg" {
name = "nlb-tg"
port = 80
protocol = "TCP"
target_type = "instance"
vpc_id = aws_vpc.main.id
health_check {
protocol = "TCP"
interval = 30
timeout = 10
healthy_threshold = 3
unhealthy_threshold = 3
}
}
'IT 엔지니어 > CLOUD' 카테고리의 다른 글
AWS - Transit GW (0) | 2025.06.16 |
---|---|
AWS - VPC Peering (0) | 2025.06.15 |
AWS - ALB (0) | 2025.06.13 |
AWS - troubleshooting (0) | 2025.06.12 |
AWS - Terraform -3 (0) | 2025.06.11 |