AWS Load Balancer Controller and Terraform ALB Module for aws_lb

The AWS ecosystem for Kubernetes load balancing spans two closely related surfaces: the AWS Load Balancer Controller that reconciles Kubernetes Service, Ingress and Gateway resources into Elastic Load Balancers, and the Terraform AWS ALB module that provisions Application and Network Load Balancer resources with declarative configuration. Both converge on the awslb resource and its supporting listener, target group and security group constructs, and both expose configuration through annotations and module variables that must be understood together to operate awslb safely in production.

The AWS Load Balancer Controller is a controller to help manage Elastic Load Balancers for a Kubernetes cluster. It satisfies Kubernetes Ingress resources by provisioning Application Load Balancers. It satisfies Kubernetes Service resources by provisioning Network Load Balancers. It satisfies Kubernetes Gateway resources by provisioning Network Load Balancers and Application Load Balancers. This project was formerly known as "AWS ALB Ingress Controller", we rebranded it to be "AWS Load Balancer Controller".

The Terraform module which creates Application and Network Load Balancer resources on AWS provides a Terraform wrapper around the aws_lb resource and related AWS resources. When you're using ALB Listener rules, make sure that every rule's actions block ends in a forward, redirect, or fixed-response action so that every rule will resolve to some sort of an HTTP response.

AWS Load Balancer Controller Overview

AWS Load Balancer Controller is a controller to help manage Elastic Load Balancers for a Kubernetes cluster.

The controller's primary reconciliation targets are:

  • Kubernetes Ingress resources by provisioning Application Load Balancers
  • Kubernetes Service resources by provisioning Network Load Balancers
  • Kubernetes Gateway resources by provisioning Network Load Balancers and Application Load Balancers

This project was formerly known as "AWS ALB Ingress Controller", we rebranded it to be "AWS Load Balancer Controller".

Origin and governance

AWS ALB Ingress Controller was originated by Ticketmaster and CoreOS as part of Ticketmaster's move to AWS and CoreOS Tectonic. Learn more about Ticketmaster's Kubernetes initiative from Justin Dean's video at Tectonic Summit.

AWS ALB Ingress Controller was donated to Kubernetes SIG-AWS to allow AWS, CoreOS, Ticketmaster and other SIG-AWS contributors to officially maintain the project. SIG-AWS reached this consensus on June 1, 2018.

The controller is open for contributions. We welcome contributions! For non-trivial changes (new features, API changes, refactors), please open an issue or discussion before submitting a PR so the maintainers can provide early feedback. See CONTRIBUTING.md for full details.

Terraform AWS ALB Module Overview

The module referenced in the reference material is terraform-aws-modules/alb/aws. Terraform module which creates Application and Network Load Balancer resources on AWS.

Version constraints captured in the reference material:

Name Version
terraform >= 1.5.7
aws >= 6.28

The module creates the following resources as documented:

Name Type
awslambdapermission.this resource
aws_lb.this resource
awslblistener.this resource
awslblistener_certificate.this resource
awslblistener_rule.this resource
awslbtarget_group.this resource
awslbtargetgroupattachment.additional resource
awslbtargetgroupattachment.this resource
awsroute53record.this resource
awssecuritygroup.this resource
awsvpcsecuritygroupegress_rule.this resource
awsvpcsecuritygroupingress_rule.this resource
awswafv2webaclassociation.this resource
aws_partition.current data source

Module Configuration Example

A representative module invocation is shown in the reference facts:

hcl module "alb" { source = "terraform-aws-modules/alb/aws" name = "my-alb" vpc_id = "vpc-abcde012" subnets = ["subnet-abcde012", "subnet-bcde012a"] security_group_ingress_rules = { all_http = { from_port = 80 to_port = 80 ip_protocol = "tcp" description = "HTTP web traffic" cidr_ipv4 = "0.0.0.0/0" } all_https = { from_port = 443 to_port = 443 ip_protocol = "tcp" description = "HTTPS web traffic" cidr_ipv4 = "0.0.0.0/0" } } security_group_egress_rules = { all = { ip_protocol = "-1" cidr_ipv4 = "10.0.0.0/16" } } access_logs = { bucket = "my-alb-logs" } listeners = { ex-http-https-redirect = { port = 80 protocol = "HTTP" redirect = { port = "443" protocol = "HTTPS" status_code = "HTTP_301" } } ex-https = { port = 443 protocol = "HTTPS" certificate_arn = "arn:aws:iam::123456789012:server-certificate/test_cert-123456789012" forward = { target_group_key = "ex-instance" } } } target_groups = { ex-instance = { name_prefix = "h1" protocol = "HTTP" port = 80 target_type = "instance" target_id = "i-0f6d38a07d50d080f" } } tags = { Environment = "Development" Project = "Example" } }

A second partial example shows the same listener pattern with an ex-cognito listener on port 444 with protocol HTTPS and certificate_arn.

The module documentation notes: When you're using ALB Listener rules, make sure that every rule's actions block ends in a forward, redirect, or fixed-response action so that every rule will resolve to some sort of an HTTP response.

Module Input Variables

The reference facts list the following input variables with partial descriptions.

Name Description Type Default Required
access_logs Map containing access logging configuration for load balancer object null no
additionaltargetgroup_attachments Map of additional target group attachments to create. Use targetgroupkey to attach to the target group created in target_groups map(object) null no
associatewebacl Indicates whether a Web Application Firewall (WAF) ACL should be associated with the load balancer bool false no
clientkeepalive Client keep alive value in seconds. The valid range is 60-604800 seconds. Only valid for Load Balancers of type application. Default: 60 number null no
internal If true, the LB will be internal. Defaults to false bool null no
ipaddresstype The type of IP addresses used by the subnets for your load balancer. The possible values are ipv4 and dualstack string null no
ipam_pools The IPAM pools to use with the load balancer object null no
listeners Map of listener configurations to create map(object) {} no
loadbalancertype The type of load balancer to create. Possible values are application, gateway, or network. The default value is application string "application" no
minimumloadbalancer_capacity Minimum capacity for a load balancer. Only valid for Load Balancers of type application or network object null no
name The name of the LB. This name must be unique within your AWS account, can have a maximum of 32 characters, must contain only alphanumeric characters or hyphens, and must not begin or end with a hyphen string null no
name_prefix Creates a unique name beginning with the specified prefix. Conflicts with name string null no
preservehostheader Indicates whether the Application Load Balancer should preserve the Host header in the HTTP request and send it to the target without any change - - -

The module also documents:

  • Only valid for Load Balancers of type application. Default: 60
    • preserve client IP is disabled by default for IP targets - preserve client IP is enabled by default for instance targets
Additional guidance is available via See patterns.md for additional configuration snippets for common usage patterns.

Kubernetes Service Annotations for AWS Load Balancer Controller

The AWS Load Balancer Controller manages Kubernetes Services in a compatible way with the legacy aws cloud provider. The annotation service.beta.kubernetes.io/aws-load-balancer-type is used to determine which controller reconciles the service. If the annotation value is nlb-ip or external, legacy cloud provider ignores the service resource (provided it has the correct patch) so that the AWS Load Balancer controller can take over. For all other values of the annotation, the legacy cloud provider will handle the service. All other types below must be string-encoded, for example:

  • boolean: "true"
  • integer: "42"
  • stringList: "s1,s2,s3"
  • stringMap: "k1=v1,k2=v2"
  • json: "{ \"key\": \"value\" }"
  • boolean:
Annotations listed in the reference material:





































































































Name Type Default Notes
service.beta.kubernetes.io/load-balancer-source-ranges stringList
service.beta.kubernetes.io/aws-load-balancer-type string
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type string
service.beta.kubernetes.io/aws-load-balancer-name string
service.beta.kubernetes.io/aws-load-balancer-internal boolean false deprecated, in favor of aws-load-balancer-scheme
service.beta.kubernetes.io/aws-load-balancer-scheme string internal
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol string Set to "*" to enable
service.beta.kubernetes.io/aws-load-balancer-ip-address-type string ipv4 ipv4 dualstack
service.beta.kubernetes.io/aws-load-balancer-access-log-enabled boolean false
service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name string
service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix string
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled boolean false
service.beta.kubernetes.io/aws-load-balancer-ssl-cert stringList
service.beta.kubernetes.io/aws-load-balancer-ssl-ports stringList
service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy
Specific annotation behaviors captured:

  • service.beta.kubernetes.io/load-balancer-source-ranges: 10.0.0.0/24
  • service.beta.kubernetes.io/aws-load-balancer-scheme specifies whether the NLB will be internet-facing or internal. Valid values are internal, internet-facing. If not specified, default is internal.

    Example service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
  • service.beta.kubernetes.io/aws-load-balancer-internal specifies whether the NLB will be internet-facing or internal. deprecation note This annotation is deprecated starting v2.2.0 release in favor of the new aws-load-balancer-scheme annotation. It will will be supported, but in case of ties, the aws-load-balancer-scheme gets precedence.

    Example service.beta.kubernetes.io/aws-load-balancer-internal: "true"

Annotation Encoding and Legacy Compatibility

The annotation documentation notes that all other types below must be string-encoded. The reference facts illustrate encoding examples for boolean, integer, stringList, stringMap, json, and boolean. The legacy Cloud Provider interaction is explicitly handled through service.beta.kubernetes.io/aws-load-balancer-type. The controller takes over when the value is nlb-ip or external.

Integration Patterns Between Terraform Module and Controller

The Terraform module creates aws_lb.this and related aws_lb_listener, aws_lb_target_group resources directly via Terraform. The AWS Load Balancer Controller creates and manages aws_lb resources via Kubernetes reconciliation based on Service, Ingress and Gateway objects. When both are used in the same environment, separation of concerns is important:

  • Use the Terraform module for statically provisioned, infrastructure owned Application Load Balancers and Network Load Balancers with explicit listeners, target groups, security groups, access logs and WAF association.
  • Use the AWS Load Balancer Controller for dynamically provisioned load balancers driven by Kubernetes workloads, with configuration expressed through service annotations and Ingress/Gateway manifests.
The module variables internal, ip_address_type, load_balancer_type, client_keep_alive, preserve_host_header map to properties that can also be influenced by controller annotations such as service.beta.kubernetes.io/aws-load-balancer-scheme, service.beta.kubernetes.io/aws-load-balancer-ip-address-type, and service.beta.kubernetes.io/aws-load-balancer-access-log-enabled.

Operational Notes

  • The Terraform module supports loadbalancertype values application, gateway, or network with default application.
  • Security group ingress rules can be defined per port and protocol as shown in the example with allhttp and allhttps.
  • Security group egress rules can be defined with ipprotocol "-1" and cidripv4 range.
  • Access logging is configured via accesslogs bucket.
  • Listener redirect actions must terminate in forward, redirect, or fixed-response to resolve to an HTTP response.
  • Target group configuration includes nameprefix, protocol, port, targettype and targetid as demonstrated.

Conclusion

The aws_lb resource sits at the intersection of declarative Terraform provisioning and Kubernetes controller driven provisioning. The Terraform AWS ALB module provides a comprehensive, versioned interface to create Application and Network Load Balancers with listeners, target groups, security groups, access logs and WAF association, while the AWS Load Balancer Controller provides a Kubernetes native reconciliation path for Ingress, Service and Gateway resources into Elastic Load Balancers. Understanding the controller's history from AWS ALB Ingress Controller originated by Ticketmaster and CoreOS, donated to Kubernetes SIG-AWS on June 1, 2018, and rebranded to AWS Load Balancer Controller informs governance and contribution expectations. Understanding the Terraform module's input variables, resource set and listener rule requirements informs safe aws_lb construction. Understanding service annotations and their deprecation paths, notably service.beta.kubernetes.io/aws-load-balancer-internal deprecated in favor of service.beta.kubernetes.io/aws-load-balancer-scheme, informs correct Kubernetes Service configuration for NLB and ALB provisioning. Together, these surfaces provide authoritative, technically dense coverage of aws_lb creation and management in AWS with Kubernetes, with the Terraform module handling explicit infrastructure definitions and the AWS Load Balancer Controller handling dynamic workload driven load balancer lifecycle.

Sources

  1. kubernetes-sigs/aws-load-balancer-controller
  2. terraform-aws-modules/terraform-aws-alb
  3. kubernetes-sigs/aws-load-balancer-controller annotations guide

Related Posts