> For the complete documentation index, see [llms.txt](https://terraform201.devart.tv/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://terraform201.devart.tv/2./2.3-aws-alb-and-nlb.md).

# AWS ALB and NLB 생성하기

## Load Balancer 생성

Load Balancer는 여러 인스턴스에 트래픽을 분배해주기 위해서 반드시 필요한 리소스입니다. EC2 위에 올라가 있는 대부분의 서비스는 LB를 앞 단에 두는 것이 보통인데, LB의 경우에는 설정할 것이 상당히 많아 코드로 한 번 정리해놓으면 편리하게 생성/관리하실 수 있습니다.

Load Balancer는 NLB/ALB 선택해서 생성하시면 됩니다.

* **ALB (Application Load Balancer)**: Layer 7 로드밸런서로,  Security Group으로 접근제어가 가능하며, URI 별로 라우팅을 할 수 있습니다.
* **NLB (Network Load Balancer)**: Layer 4 로드밸런서로, ALB보다 전송 속도는 빠르지만 Security Group으로 과거에는 접근제어가 되지 않았지만, 현재는 가능합니다.

실습에서 생성할 리소스는 아래와 같습니다.

* Load Balancer
* Target Group
  * https(443) : redirect to instance
  * http(80) : redirect to 443
* Route53 Record
  * A record for ELB

### Module 구성

보통 서비스를 위한 리소스는 환경별로 동일하게 생성하는 경우가 많습니다. 따라서 같은 코드를 변수만 바꿔서 사용할 수 있도록 Module을 이용하여 생성합니다.

{% hint style="info" %}
Module을 사용할 때는 최대한 고유 명사를 없애고 변수처리하는 것이 좋습니다. 고유 명사를 변수로 대체하면 이후에 다른 서비스를&#x20;
{% endhint %}

`_module` 폴더의 구조는 아래와 같습니다.&#x20;

* **outputs.tf** : 모듈내에서의 output.
* **service.tf** : ALB 및 SG 와 관련된 리소스가 포함된 파일
* **var\_lb.tf** : Load Balancer 관련 변수 정의 파일
* **var\_sg.tf** : Security Group 관련 변수 정의 파일
* **variables.tf** : 기타 변수 정의 파일

```
$ tree
.
└── hello
    ├── outputs.tf
    ├── alb.tf
    ├── var_lb.tf
    ├── var_sg.tf
    └── variables.tf 
```

### ALB 리소스 생성

ALB 생성을 위한 리소스는 `terraform/services/hello/_module/hello/alb.tf` 에 있습니다. ALB 생성을 위해서는 일단 LB에 붙일 Security Group(보안 그룹)과 Load Balancer, 그리고 Target group입니다.

{% code title="vim terraform/services/hello/\_module/hello/alb.tf" %}

```hcl
############ Security Group For External LB
resource "aws_security_group" "external_lb" {
  name        = "${var.service_name}-${var.vpc_name}-ext"
  description = "${var.service_name} external LB SG"
  vpc_id      = var.target_vpc

  # Only allow access from IPs or SGs you specifiy in ext_lb_ingress_cidrs variables
  # If you don't want to use HTTPS then remove this block
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = var.ext_lb_ingress_cidrs
    description = "External service https port"
  }


  # Allow 80 port
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = var.ext_lb_ingress_cidrs
    description = "External service http port"
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["10.0.0.0/8"]
    description = "Internal outbound any traffic"
  }

  tags = var.sg_variables.external_lb.tags[var.shard_id]
}

#################### External ALB
resource "aws_lb" "external" {
  name     = "${var.service_name}-${var.shard_id}-ext"
  subnets  = var.public_subnets
  internal = false

  # For external LB,
  # Home SG (Includes Office IPs) could be added if this service is internal service.
  security_groups = [
    aws_security_group.external_lb.id,
  ]

  # For HTTP service, application LB is recommended.
  # You could use other load_balancer_type if you want.
  load_balancer_type = "application"

  tags = var.lb_variables.external_lb.tags[var.shard_id]
}

#################### External LB Target Group
resource "aws_lb_target_group" "external" {
  name                 = "${var.service_name}-${var.shard_id}-ext"
  port                 = var.service_port
  protocol             = "HTTP"
  vpc_id               = var.target_vpc
  slow_start           = var.lb_variables.target_group_slow_start[var.shard_id]
  deregistration_delay = var.lb_variables.target_group_deregistration_delay[var.shard_id]

  # Change the health check setting
  health_check {
    interval            = 15
    port                = var.healthcheck_port
    path                = "/"
    timeout             = 3
    healthy_threshold   = 3
    unhealthy_threshold = 2
    matcher             = "200"
  }

  tags = var.lb_variables.external_lb_tg.tags[var.shard_id]
}


#################### Listener for HTTP service
resource "aws_lb_listener" "internal_80" {
  load_balancer_arn = aws_lb.external.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    target_group_arn = aws_lb_target_group.external.arn
    type             = "forward"
  }
}
```

{% endcode %}

### ALB 관련 태그 및 설정

위 리소스를 생성하기 위해서는 기본적인 설정과 태그가 필요합니다.&#x20;

```hcl
# terraform/application/hello/_module/hello/var_lb.tf
variable "lb_variables" {
  default = {

    target_group_slow_start = {}

    target_group_deregistration_delay = {}

    internal_lb = {
      tags = {}
    }

    internal_lb_tg = {
      tags = {}
    }

    external_lb = {
      tags = {}
    }

    external_lb_tg = {
      tags = {}
    }
  }
}
```

실제 설정값은 아래와 같습니다.

```bash
# terraform/application/hello/devartd_apnortheast2/var_lb.tf
variable "lb_variables" {
  default = {

    target_group_slow_start = {
      devartdapne2   = 0
      artdapne2   = 0
      artpapne2   = 0
    }

    target_group_deregistration_delay = {
      devartdapne2   = 0
      artdapne2    = 60
      artpapne2    = 60
    }

    external_lb = {
      tags = {
        devartdapne2 = {
          Name    = "hello-devartd_apnortheast2-external-lb"
          app     = "hello"
          project = "hello"
          env     = "dev"
          stack   = "devartd_apnortheast2"
        },      
      
        artdapne2 = {
          Name    = "hello-artd_apnortheast2-external-lb"
          app     = "hello"
          project = "hello"
          env     = "dev"
          stack   = "artd_apnortheast2"
        },

        artpapne2 = {
          Name    = "hello-artp_apnortheast2-external-lb"
          app     = "hello"
          project = "hello"
          env     = "prod"
          stack   = "artp_apnortheast2"
        }
      }
    }

    external_lb_tg = {
      tags = {
      
        devartdapne2 = {
          Name    = "hello-devartd_apnortheast2-external-tg"
          app     = "hello"
          project = "hello"
          env     = "dev"
          stack   = "devartd_apnortheast2"
        },
        
        artdapne2 = {
          Name    = "hello-artd_apnortheast2-external-tg"
          app     = "hello"
          project = "hello"
          env     = "dev"
          stack   = "artd_apnortheast2"
        },

        artpapne2 = {
          Name    = "hello-artp_apnortheast2-external-tg"
          app     = "hello"
          project = "hello"
          env     = "prod"
          stack   = "artp_apnortheast2"
        }
      }
    }
  }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://terraform201.devart.tv/2./2.3-aws-alb-and-nlb.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
