Application Load Balancer
ALB with HTTPS listeners, target groups, listener rules, and access logging — drop-in for ECS/EC2/Lambda targets.
Verification
Live-testedReally deployed, verified, idempotent and destroyed in a cloud sandbox.
Conformance
- Static validation (fmt · validate · tflint)
- Security scan: findings disclosed (Checkov)
- Plan tests (mocked: validation rules · outputs)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live-tested — applied, verified, destroyed
Last verified 2026-06-19 · how we verify
Documentation
aws-alb — Application Load Balancer
ALB with HTTPS listeners, target groups, listener rules, and access logging — drop-in for ECS/EC2/Lambda targets. Hand it an ACM certificate and you get a TLS 1.3 (1.2-floor) HTTPS listener with automatic HTTP→HTTPS 301 redirect; define target groups as a simple map and route to them with host/path listener rules. Hardened defaults: invalid-header dropping, desync mitigation, and deletion protection are all on.
Works with Terraform and OpenTofu (>= 1.6), AWS provider >= 6.0, < 7.0.
Usage
module "alb" {
source = "./aws-alb"
name = "web"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.public_subnet_ids
security_group_ids = [module.alb_sg.security_group_id]
certificate_arn = aws_acm_certificate.site.arn
target_groups = {
app = { port = 8080, target_type = "ip" } # ECS/Fargate
api = { port = 3000, target_type = "ip", health_check = { path = "/healthz" } }
}
default_target_group_key = "app"
listener_rules = {
api = { priority = 10, target_group_key = "api", path_patterns = ["/api/*"] }
}
access_logs_bucket = module.logs_bucket.bucket_id
tags = { Environment = "prod" }
}
No certificate_arn? The module degrades to a plain HTTP :80 ALB (useful for
internal tooling); add the cert later and the redirect wires itself up.
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
name | string | — | LB name, ≤ 24 chars (prefixes TG names) (required) |
vpc_id | string | — | VPC for target groups (required) |
subnet_ids | list(string) | — | ≥ 2 subnets in different AZs (required) |
security_group_ids | list(string) | — | ≥ 1 security group (required) |
target_groups | map(object) | — | TGs keyed by short name (≤ 7 chars): { port?, protocol?, target_type?, deregistration_delay?, slow_start?, stickiness_enabled?, stickiness_duration?, health_check? } (required) |
default_target_group_key | string | — | TG receiving unmatched traffic (required) |
internal | bool | false | Internal instead of internet-facing |
certificate_arn | string | null | ACM cert; enables the HTTPS :443 listener |
additional_certificate_arns | set(string) | [] | Extra SNI certs on the HTTPS listener |
ssl_policy | string | ELBSecurityPolicy-TLS13-1-2-2021-06 | TLS policy |
create_http_listener | bool | true | Create the HTTP :80 listener |
redirect_http_to_https | bool | true | 301 HTTP→HTTPS when a cert is set |
listener_rules | map(object) | {} | { priority, target_group_key, host_headers?, path_patterns? } on the primary listener |
enable_deletion_protection | bool | true | Set false in dev/test so destroy works |
drop_invalid_header_fields | bool | true | Security hardening |
enable_http2 | bool | true | HTTP/2 |
idle_timeout | number | 60 | Idle timeout seconds |
desync_mitigation_mode | string | "defensive" | monitor / defensive / strictest |
access_logs_bucket | string | null | S3 bucket for access logs (null = off) |
access_logs_prefix | string | null | Log key prefix |
tags | map(string) | {} | Tags applied to all resources |
Outputs
| Name | Description |
|---|---|
lb_arn, lb_dns_name, lb_zone_id, lb_arn_suffix | LB identifiers (zone ID for Route 53 aliases) |
target_group_arns, target_group_arn_suffixes, target_group_names | TG maps keyed by your short names |
https_listener_arn, http_listener_arn | Listener ARNs (null when not created) |
listener_rule_arns | Rule key => ARN map |
Notes
- Access logs: the S3 bucket must carry the regional ELB log-delivery
bucket policy (
logdelivery.elasticloadbalancing.amazonaws.com/ the regional ELB account principal), or the ALB API rejects the config. - Lambda targets: set
target_type = "lambda"— port/protocol/health-check are automatically omitted; register the function and addaws_lambda_permissionoutside the module. - Deletion protection defaults on;
terraform destroyrequires flippingenable_deletion_protection = falseand applying first. - ALBs bill hourly + LCU; this module creates one ALB regardless of how many target groups/rules you define.
Requirements
- Terraform or OpenTofu
>= 1.6 hashicorp/aws>= 6.0, < 7.0
Verification
Static-validated (fmt, validate, tflint). Live apply/destroy testing pending cloud sandbox availability — see catalog status.
License
Commercial — IaC Bazaar EULA. © IaC Bazaar. Original work (not derived from a third-party module).