# lb-standard

Creates an Application or Network Load Balancer with target groups, listeners, and target attachments.

Provisions a single load balancer along with its target groups, listeners, and target group attachments, supporting both ALB and NLB through one interface. Cross-variable checks enforce the constraints each load balancer type imposes: NLB does not support redirect actions or WAF association, and ALB/NLB differ on which target group protocols and stickiness types are valid. Security groups are supported on both ALB and NLB (NLB security groups govern traffic into the load balancer's ENIs — target-side security groups on the backend instances are managed separately, outside this module).

## Usage

### Application Load Balancer

```hcl
module "lb_standard" {
  source  = "hcassc.jfrog.io/iac-tf-modules-virtual__compute/lb-standard/aws"
  version = "0.1.0"

  name_prefix = "acme-prod-web"
  name_suffix = "public"

  load_balancer_type = "application"
  subnet_ids          = ["subnet-0aaa111122223333", "subnet-0bbb444455556666"]
  security_group_ids  = ["sg-0123456789abcdef0"]

  target_groups = {
    web = {
      name_suffix = "web"
      port        = 443
      protocol    = "HTTPS"
      vpc_id      = "vpc-0123456789abcdef0"
    }
  }

  listeners = {
    https = {
      port              = 443
      protocol          = "HTTPS"
      certificate_arn   = "arn:aws:acm:ap-south-1:123456789012:certificate/example"
      target_group_key  = "web"
    }
  }
}
```

### Network Load Balancer with target attachments

```hcl
module "lb_standard" {
  source  = "hcassc.jfrog.io/iac-tf-modules-virtual__compute/lb-standard/aws"
  version = "0.1.0"

  name_prefix = "acme-prod-dc"
  name_suffix = "ldaps"

  load_balancer_type = "network"
  internal            = true
  subnet_ids          = ["subnet-0aaa111122223333", "subnet-0bbb444455556666"]
  security_group_ids  = ["sg-0123456789abcdef0"]

  cross_zone_load_balancing = true

  target_groups = {
    ldaps = {
      name_suffix = "ldaps"
      port        = 636
      protocol    = "TCP"
      target_type = "ip"
      vpc_id      = "vpc-0123456789abcdef0"

      targets = {
        dc1 = { id = "10.0.1.10", port = 636 }
        dc2 = { id = "10.0.2.10", port = 636 }
      }

      health_check = {
        protocol            = "TCP"
        interval            = 10
        healthy_threshold   = 3
        unhealthy_threshold = 3
      }
    }
  }

  listeners = {
    ldaps_636 = {
      port              = 636
      protocol          = "TCP"
      target_group_key  = "ldaps"
    }
  }
}
```

## Notes

- **Target attachments** are declared inline under each target group's `targets` map (`id` + optional `port`). `id` is an instance ID when `target_type = "instance"`, or an IP address when `target_type = "ip"`. `port` is required per-target when `target_type = "ip"` — enforced by a `check` block at plan time.
- **Security groups**: this module does not create security groups. `security_group_ids` attaches existing groups to the load balancer's ENIs. Target-side rules (allowing the load balancer's traffic into backend instances) belong to whatever manages those instances, not this module.
- **GWLB is out of scope** for this module — see `lb-gateway` for Gateway Load Balancer support.

<!-- BEGIN_TF_DOCS — DO NOT EDIT BELOW THIS LINE -->

## Requirements

| Name                                                                     | Version            |
| ------------------------------------------------------------------------ | ------------------ |
| <a name="requirement_terraform"></a> [terraform](#requirement_terraform) | >= 1.15.0, < 2.0.0 |
| <a name="requirement_aws"></a> [aws](#requirement_aws)                   | >= 6.0, < 7.0      |

## Providers

| Name                                             | Version       |
| ------------------------------------------------ | ------------- |
| <a name="provider_aws"></a> [aws](#provider_aws) | >= 6.0, < 7.0 |

## Resources

| Name                                                                                                                                          | Type     |
| --------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| [aws_lb.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb)                                                 | resource |
| [aws_lb_listener.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener)                               | resource |
| [aws_lb_target_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group)                       | resource |
| [aws_lb_target_group_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group_attachment) | resource |
| [aws_wafv2_web_acl_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_association)   | resource |

## Inputs

| Name                                                                                                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | Type                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Default         | Required |
| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | :------: |
| <a name="input_name_prefix"></a> [name_prefix](#input_name_prefix)                                           | Prefix prepended to resource names created by this module.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `string`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | n/a             |   yes    |
| <a name="input_name_suffix"></a> [name_suffix](#input_name_suffix)                                           | Suffix appended to the load balancer resource name to distinguish it within name_prefix.                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `string`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | n/a             |   yes    |
| <a name="input_subnet_ids"></a> [subnet_ids](#input_subnet_ids)                                              | Subnet IDs for the load balancer. Must span at least two AZs.                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `list(string)`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | n/a             |   yes    |
| <a name="input_access_logs_bucket"></a> [access_logs_bucket](#input_access_logs_bucket)                      | S3 bucket for access logs (optional).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | `string`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `null`          |    no    |
| <a name="input_access_logs_prefix"></a> [access_logs_prefix](#input_access_logs_prefix)                      | S3 prefix for access logs.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `string`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `"lb"`          |    no    |
| <a name="input_cross_zone_load_balancing"></a> [cross_zone_load_balancing](#input_cross_zone_load_balancing) | Enable cross-zone load balancing. Valid for NLB only — ALB always has this enabled and it is not configurable.                                                                                                                                                                                                                                                                                                                                                                                                                              | `bool`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `true`          |    no    |
| <a name="input_deletion_protection"></a> [deletion_protection](#input_deletion_protection)                   | Enable deletion protection.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `bool`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `true`          |    no    |
| <a name="input_idle_timeout"></a> [idle_timeout](#input_idle_timeout)                                        | Idle timeout in seconds. Valid for ALB only — NLB connections do not have a configurable idle timeout.                                                                                                                                                                                                                                                                                                                                                                                                                                      | `number`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `60`            |    no    |
| <a name="input_internal"></a> [internal](#input_internal)                                                    | Create an internal (non-internet-facing) load balancer.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `bool`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `false`         |    no    |
| <a name="input_listeners"></a> [listeners](#input_listeners)                                                 | Map of load balancer listener definitions.<br/><br/>- redirect actions are only valid on ALB listeners — NLB does not support the redirect action type.<br/>- certificate_arn is only meaningful for HTTPS/TLS protocol listeners.                                                                                                                                                                                                                                                                                                          | <pre>map(object({<br/> port = number<br/> protocol = string<br/> certificate_arn = optional(string, null)<br/> ssl_policy = optional(string, "ELBSecurityPolicy-TLS13-1-2-2021-06")<br/> default_action_type = optional(string, "forward")<br/> target_group_key = optional(string, null)<br/> redirect = optional(object({<br/> port = optional(string, "443")<br/> protocol = optional(string, "HTTPS")<br/> status_code = optional(string, "HTTP_301")<br/> }), null)<br/> }))</pre>                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `{}`            |    no    |
| <a name="input_load_balancer_type"></a> [load_balancer_type](#input_load_balancer_type)                      | Load balancer type — application or network.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `string`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `"application"` |    no    |
| <a name="input_security_group_ids"></a> [security_group_ids](#input_security_group_ids)                      | Security group IDs to attach to the load balancer's ENIs. Supported on ALB always, and on NLB in regions/accounts with the 2023 NLB security groups feature enabled.                                                                                                                                                                                                                                                                                                                                                                        | `list(string)`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `[]`            |    no    |
| <a name="input_tags"></a> [tags](#input_tags)                                                                | Tags applied to all resources in this module.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `map(string)`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `{}`            |    no    |
| <a name="input_target_groups"></a> [target_groups](#input_target_groups)                                     | Map of target group definitions.<br/><br/>- name_suffix is combined with name_prefix and region to build the target group name.<br/>- protocol must be TCP/UDP/TCP_UDP for NLB target groups, HTTP/HTTPS for ALB.<br/>- stickiness.type must be source_ip for NLB, lb_cookie or app_cookie for ALB.<br/>- targets is a map of instance IDs (target_type = "instance") or IP addresses<br/> (target_type = "ip") to attach. port overrides the target group's port for<br/> that specific target; leave null to use the target group's port. | <pre>map(object({<br/> name_suffix = string<br/> port = number<br/> protocol = string<br/> target_type = optional(string, "instance")<br/> vpc_id = string<br/> deregistration_delay = optional(number, 30)<br/> tags = optional(map(string), {})<br/> targets = optional(map(object({<br/> id = string<br/> port = optional(number, null)<br/> })), {})<br/> health_check = optional(object({<br/> enabled = optional(bool, true)<br/> path = optional(string, "/health")<br/> protocol = optional(string, "HTTP")<br/> matcher = optional(string, "200")<br/> interval = optional(number, 30)<br/> timeout = optional(number, 5)<br/> healthy_threshold = optional(number, 2)<br/> unhealthy_threshold = optional(number, 2)<br/> }), {})<br/> stickiness = optional(object({<br/> enabled = optional(bool, false)<br/> cookie_duration = optional(number, 86400)<br/> type = optional(string, "lb_cookie")<br/> }), null)<br/> }))</pre> | `{}`            |    no    |
| <a name="input_waf_web_acl_arn"></a> [waf_web_acl_arn](#input_waf_web_acl_arn)                               | WAF Web ACL ARN to associate with the load balancer. Valid for ALB only — WAFv2 does not support NLB as an association target.                                                                                                                                                                                                                                                                                                                                                                                                              | `string`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `null`          |    no    |

## Outputs

| Name                                                                                                              | Description                                                                                                                             |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| <a name="output_arn"></a> [arn](#output_arn)                                                                      | Load balancer ARN.                                                                                                                      |
| <a name="output_dns_name"></a> [dns_name](#output_dns_name)                                                       | DNS name of the load balancer.                                                                                                          |
| <a name="output_id"></a> [id](#output_id)                                                                         | Load balancer ID.                                                                                                                       |
| <a name="output_listener_arns"></a> [listener_arns](#output_listener_arns)                                        | Map of listener logical key to ARN.                                                                                                     |
| <a name="output_name"></a> [name](#output_name)                                                                   | Generated load balancer name.                                                                                                           |
| <a name="output_target_attachment_ids"></a> [target_attachment_ids](#output_target_attachment_ids)                | Map of flattened attachment key (target_group_key-target_key) to the target_id that was attached.                                       |
| <a name="output_target_group_arns"></a> [target_group_arns](#output_target_group_arns)                            | Map of target group logical key to ARN.                                                                                                 |
| <a name="output_target_group_health_checks"></a> [target_group_health_checks](#output_target_group_health_checks) | Map of target group logical key to its resolved health check config, for troubleshooting unhealthy targets without opening the console. |
| <a name="output_target_group_names"></a> [target_group_names](#output_target_group_names)                         | Map of target group logical key to generated name.                                                                                      |
| <a name="output_zone_id"></a> [zone_id](#output_zone_id)                                                          | Hosted zone ID of the load balancer (for Route53 alias records).                                                                        |

<!-- END_TF_DOCS — DO NOT EDIT ABOVE THIS LINE -->
