Repository: zalando-incubator/kube-ingress-aws-controller
Pull request #463 (2022-01-26 13:57:30)

default NLB with internal annotation should fallback to ALB
default NLB with internal annotation should fallback to ALB, because of https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-troubleshooting.html#intermittent-connection-failure that we also found in a small production incident

Signed-off-by: Sandor Szücs <sandor.szuecs@zalando.de>

mikkeloscar: This should probably also be noted in the docs/README
mikkeloscar: :+1: 
AlexanderYastrebov: :+1: 

Patch:
diff --git a/README.md b/README.md
index f89c11c..dfdc9e6 100644
--- a/README.md
+++ b/README.md
@@ -344,7 +344,17 @@ spec:
           servicePort: main-port
 ```
 
-You can only select from `internet-facing` (default) and `internal` options.
+You can only select from `internet-facing` (default) and `internal`
+options.
+
+If you run the controller with `--load-balancer-type=network` and
+create an `internal` load balancer, the controller will create an
+Application Load Balancer instead of a Network Load Balancer, because
+it can create [hard to debug issues](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-troubleshooting.html#intermittent-connection-failure),
+that we want to prevent as default. If you know what you are doing you
+can enforce to create a Network Load Balancer by setting annotation
+`zalando.org/aws-load-balancer-type: nlb`.
+
 
 #### Omit to create a Load Balancer for cluster internal domains
 
diff --git a/kubernetes/adapter.go b/kubernetes/adapter.go
index 1f73f25..952c5c4 100644
--- a/kubernetes/adapter.go
+++ b/kubernetes/adapter.go
@@ -201,7 +201,13 @@ func (a *Adapter) newIngress(typ ingressType, metadata kubeItemMetadata, host st
 
 	loadBalancerType, hasLB := annotations[ingressLoadBalancerTypeAnnotation]
 	if !hasLB {
-		loadBalancerType = a.ingressDefaultLoadBalancerType
+		// internal load balancers should be ALB if user do not override the decision
+		// https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-troubleshooting.html#intermittent-connection-failure
+		if scheme == elbv2.LoadBalancerSchemeEnumInternal {
+			loadBalancerType = loadBalancerTypeALB
+		} else {
+			loadBalancerType = a.ingressDefaultLoadBalancerType
+		}
 	}
 
 	securityGroup, hasSG := annotations[ingressSecurityGroupAnnotation]


Test patch:
diff --git a/kubernetes/adapter_test.go b/kubernetes/adapter_test.go
index 66be33c..0b10047 100644
--- a/kubernetes/adapter_test.go
+++ b/kubernetes/adapter_test.go
@@ -293,6 +293,75 @@ func TestNewIngressFromKube(tt *testing.T) {
 				},
 			},
 		},
+		{
+			msg:                     "test default NLB with internal annotations fallbacks to ALB",
+			defaultLoadBalancerType: aws.LoadBalancerTypeNetwork,
+			ingress: &Ingress{
+				resourceType:     ingressTypeIngress,
+				Namespace:        "default",
+				Name:             "foo",
+				Hostname:         "bar",
+				Scheme:           "internal",
+				Shared:           true,
+				HTTP2:            true,
+				ClusterLocal:     true,
+				SSLPolicy:        testSSLPolicy,
+				IPAddressType:    aws.IPAddressTypeIPV4,
+				LoadBalancerType: aws.LoadBalancerTypeApplication,
+				SecurityGroup:    testIngressDefaultSecurityGroup,
+			},
+			kubeIngress: &ingress{
+				Metadata: kubeItemMetadata{
+					Namespace: "default",
+					Name:      "foo",
+					Annotations: map[string]string{
+						ingressSchemeAnnotation: "internal",
+					},
+				},
+				Status: ingressStatus{
+					LoadBalancer: ingressLoadBalancerStatus{
+						Ingress: []ingressLoadBalancer{
+							{Hostname: "bar"},
+						},
+					},
+				},
+			},
+		},
+		{
+			msg:                     "test default ALB with lb type annotation nlb and internal annotation uses NLB",
+			defaultLoadBalancerType: aws.LoadBalancerTypeApplication,
+			ingress: &Ingress{
+				resourceType:     ingressTypeIngress,
+				Namespace:        "default",
+				Name:             "foo",
+				Hostname:         "bar",
+				Scheme:           "internal",
+				Shared:           true,
+				HTTP2:            true,
+				ClusterLocal:     true,
+				SSLPolicy:        testSSLPolicy,
+				IPAddressType:    aws.IPAddressTypeIPV4,
+				LoadBalancerType: aws.LoadBalancerTypeNetwork,
+				SecurityGroup:    testIngressDefaultSecurityGroup,
+			},
+			kubeIngress: &ingress{
+				Metadata: kubeItemMetadata{
+					Namespace: "default",
+					Name:      "foo",
+					Annotations: map[string]string{
+						ingressSchemeAnnotation:           "internal",
+						ingressLoadBalancerTypeAnnotation: "nlb",
+					},
+				},
+				Status: ingressStatus{
+					LoadBalancer: ingressLoadBalancerStatus{
+						Ingress: []ingressLoadBalancer{
+							{Hostname: "bar"},
+						},
+					},
+				},
+			},
+		},
 		{
 			msg:                     "test default NLB with WAF fallbacks to ALB",
 			defaultLoadBalancerType: aws.LoadBalancerTypeNetwork,