관리 메뉴

근묵자흑

테라폼 로드밸런서 배포 본문

IaC/terraform

테라폼 로드밸런서 배포

Luuuuu 2024. 12. 22. 19:15

Terraform syntax & 기본 구성요소

Provider 설정

테라폼 provider 에 관한 블로그 글은 아래 정리돼 있습니다.

https://devstory.tistory.com/2

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-2"  # 서울 리전
}

Resource 정의

Resource 블록은 실제로 생성할 인프라 자원을 정의하는 핵심 구성요소입니다. 각 리소스는 고유한 식별자를 가지며, 해당 리소스의 모든 속성을 정의합니다.

  • 클라우드 리소스 생성 및 관리
  • 리소스 간 의존성 정의
  • 리소스 설정 및 속성 관리
  • 리소스 수명주기 관리

참조 : https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance


resource "리소스_타입" "리소스_이름" {
  설정_키 = 설정_값
}


resource "aws_instance" "example" {
  ami           = "ami-12345678"
  instance_type = "t2.micro"

  tags = {
    Name = "example-instance"
  }
}

Data Source 사용

Data Source는 이미 존재하는 리소스의 정보를 가져올 때 사용합니다.

  • 기존 리소스 정보 조회
  • 동적 데이터 참조
  • 외부 리소스와의 연동
data "데이터소스_타입" "데이터소스_이름" {
  필터_설정
}

data "aws_ami" "amazon_linux_2" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

변수와 출력

# Variable은 Terraform 코드를 유연하게 만들어주는 변수를 정의합니다.

variable "instance_type" {
  description = "EC2 인스턴스 타입"
  type        = string
  default     = "t2.micro"
}


# Output은 Terraform 실행 후 필요한 정보를 출력할 때 사용합니다.

output "instance_ip" {
  value       = aws_instance.example.public_ip
  description = "인스턴스의 공인 IP"
}

고급 기능

Count를 이용한 반복

resource "aws_instance" "server" {
  count = 3

  ami           = data.aws_ami.amazon_linux_2.id
  instance_type = var.instance_type

  tags = {
    Name = "server-${count.index + 1}"
  }
}

For Each를 이용한 반복

resource "aws_instance" "server" {
  for_each = {
    web = "t2.micro"
    app = "t2.small"
    db  = "t2.medium"
  }

  ami           = data.aws_ami.amazon_linux_2.id
  instance_type = each.value

  tags = {
    Name = "server-${each.key}"
  }
}

조건문 사용

resource "aws_instance" "example" {
  instance_type = var.environment == "prod" ? "t2.medium" : "t2.micro"

  tags = {
    Environment = var.environment
  }
}

Local Values

# Locals는 모듈 내에서 반복적으로 사용되는 값을 정의할 때 사용합니다.

locals {
  common_tags = {
    Environment = var.environment
    Project     = var.project_name
    ManagedBy   = "terraform"
  }
}

resource "aws_instance" "example" {
  # ... 다른 설정들 ...

  tags = merge(local.common_tags, {
    Name = "example-instance"
  })
}

로드밸런서 배포

프로젝트 구조

project/
├── main.tf      # 주요 리소스 정의
├── variables.tf # 변수 정의
├── outputs.tf   # 출력 정의
└── terraform.tfvars # 변수 값 설정

ALB 개요

각각 고유한 IP 주소를 가진 서버가 여러 개 있고 사용자에게는 일반적으로 하나의 IP 주소를 제공해야는 요구사항이 있다고 가정했을 때, 해답으로 로드 밸랜서를 제공할 수 있습니다.

Terraform graph

테라폼의 종속성은 resource, module 선언으로 프로비저닝되는 각 요소의 생성 순서를 구분 짓는다.

기본적으로 다른 리소스에서 값을 참조해 불러올 경우 생성 선후 관계에 따라 작업자가 의도하지는 않았지만 자동으로 연관 관계가 정의되는 암시적 종속성을 갖게 되고, 강제로 리소스 간 명시적 종속성을 부여할 경우에는 메타인수인 depends_on을 활용한다. 

  • 리스너(Listener)
    • 80 같은 특정 포트와 HTTP 같은 프로토콜을 수신합니다.
  • 리스너 규칙
    • 리스너에 들어오는 요청을 가져와 /foo 및 /bar 같은 특정 경로나 foo.example.com 및 bar.example.com 같은 호스트 이름과 일치하는 요청을 특정 대상 그룹으로 보냅니다.
  • 대상 그룹(Target groups)
    • 로드 밸런서에서 요청을 받는 하나 이상의 서버입니다. 대상 그룹은 서버의 상태를 확인하고 요청을 정상 노드로 보냅니다.
# Application Load Balancer 생성
# 트래픽 분산을 위한 로드 밸런서
resource "aws_lb" "example" {
  name               = var.alb_name              # ALB 이름
  load_balancer_type = "application"            # ALB 타입
  subnets            = aws_subnet.public[*].id   # 서브넷 ID 목록
  security_groups    = [aws_security_group.alb.id]  # 보안 그룹

  tags = {
    Name = "terraform-asg-example"
  }
}

# ALB 리스너 생성
# 들어오는 트래픽을 처리하는 규칙 정의
resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.example.arn  # ALB ARN
  port              = 80                  # 리스너 포트
  protocol          = "HTTP"              # 프로토콜

  # 기본 작업 (404 반환)
  default_action {
    type = "fixed-response"

    fixed_response {
      content_type = "text/plain"
      message_body = "404: page not found"
      status_code  = 404
    }
  }
}

# ALB 대상 그룹 생성
# 요청을 라우팅할 대상 정의
resource "aws_lb_target_group" "asg" {
  name     = var.alb_name        # 대상 그룹 이름
  port     = var.server_port     # 포트
  protocol = "HTTP"              # 프로토콜
  vpc_id   = aws_vpc.main.id     # VPC ID

  # 헬스 체크 설정
  health_check {
    path                = "/"      # 체크 경로
    protocol            = "HTTP"   # 프로토콜
    matcher             = "200"    # 성공 응답 코드
    interval            = 15       # 체크 간격
    timeout             = 3        # 타임아웃
    healthy_threshold   = 2        # 정상 임계값
    unhealthy_threshold = 2        # 비정상 임계값
  }
}

# ALB 리스너 규칙 생성
# 트래픽 라우팅 규칙 정의
resource "aws_lb_listener_rule" "asg" {
  listener_arn = aws_lb_listener.http.arn  # 리스너 ARN
  priority     = 100                       # 규칙 우선순위

  # 경로 패턴 조건
  condition {
    path_pattern {
      values = ["*"]  # 모든 경로 매칭
    }
  }

  # 작업 정의 (대상 그룹으로 전달)
  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.asg.arn
  }
}

 

실제 수행 가능한 코드는 아래 링크를 참조하시면 됩니다.

https://github.com/gs-kikim/terraform_up_and_running/tree/main/02.intro-to-terraform-syntax/2.6.webserver-cluster

 

'IaC > terraform' 카테고리의 다른 글

Terraform Module  (8) 2025.01.05
Terraform State  (3) 2024.12.29
왜 테라폼 인가?  (4) 2024.12.15
workflow  (7) 2024.11.05
Terraform provider  (7) 2024.10.20