From c44409795fb889a2f97f020da66cc37e361574e8 Mon Sep 17 00:00:00 2001 From: mikutas <23391543+mikutas@users.noreply.github.com> Date: Thu, 28 Nov 2024 22:02:46 +0900 Subject: [PATCH 1/2] Add WAFv2ACLArn field to IngressClassParams --- apis/elbv2/v1beta1/ingressclassparams_types.go | 4 ++++ config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml | 3 +++ docs/guide/ingress/ingress_class.md | 7 +++++++ helm/aws-load-balancer-controller/crds/crds.yaml | 3 +++ pkg/ingress/model_build_load_balancer_addons.go | 5 +++++ 5 files changed, 22 insertions(+) diff --git a/apis/elbv2/v1beta1/ingressclassparams_types.go b/apis/elbv2/v1beta1/ingressclassparams_types.go index d872ff5bce..9306836d5d 100644 --- a/apis/elbv2/v1beta1/ingressclassparams_types.go +++ b/apis/elbv2/v1beta1/ingressclassparams_types.go @@ -174,6 +174,10 @@ type IngressClassParamsSpec struct { // PrefixListsIDs defines the security group prefix lists for all Ingresses that belong to IngressClass with this IngressClassParams. PrefixListsIDs []string `json:"PrefixListsIDs,omitempty"` + + // WAFv2ACLArn specifies ARN for the Amazon WAFv2 web ACL. + // +optional + WAFv2ACLArn string `json:"wafv2AclArn"` } // +kubebuilder:object:root=true diff --git a/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml b/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml index d33ee151aa..eb04b22d57 100644 --- a/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml +++ b/config/crd/bases/elbv2.k8s.aws_ingressclassparams.yaml @@ -268,6 +268,9 @@ spec: - instance - ip type: string + wafv2AclArn: + description: WAFv2ACLArn specifies ARN for the Amazon WAFv2 web ACL. + type: string type: object type: object served: true diff --git a/docs/guide/ingress/ingress_class.md b/docs/guide/ingress/ingress_class.md index 899f9e0d61..b273fd962b 100644 --- a/docs/guide/ingress/ingress_class.md +++ b/docs/guide/ingress/ingress_class.md @@ -202,6 +202,7 @@ Cluster administrators can use the optional `inboundCIDRs` field to specify the If the field is specified, LBC will ignore the `alb.ingress.kubernetes.io/inbound-cidrs` annotation. #### spec.certificateArn + Cluster administrators can use the optional `certificateARN` field to specify the ARN of the certificates for all Ingresses that belong to IngressClass with this IngressClassParams. If the field is specified, LBC will ignore the `alb.ingress.kubernetes.io/certificate-arn` annotation. @@ -289,3 +290,9 @@ Cluster administrators can use `PrefixListsIDs` field to specify the managed pre 1. If `PrefixListsIDs` is set, the prefix lists defined will be applied to the load balancer that belong to this IngressClass. If you specify invalid prefix list IDs, the controller will fail to reconcile ingresses belonging to the particular ingress class. 2. If `PrefixListsIDs` un-specified, Ingresses with this IngressClass can continue to use `alb.ingress.kubernetes.io/security-group-prefix-lists` annotation to specify the load balancer prefix lists. + +#### spec.wafv2AclArn + +Cluster administrators can use the optional `wafv2AclArn` field to specify ARN for the Amazon WAFv2 web ACL. +Only Regional WAFv2 is supported. +When this annotation is absent or empty, the controller will keep LoadBalancer WAFv2 settings unchanged. To disable WAFv2, explicitly set the annotation value to 'none'. diff --git a/helm/aws-load-balancer-controller/crds/crds.yaml b/helm/aws-load-balancer-controller/crds/crds.yaml index cbb3256576..64392ff0f2 100644 --- a/helm/aws-load-balancer-controller/crds/crds.yaml +++ b/helm/aws-load-balancer-controller/crds/crds.yaml @@ -267,6 +267,9 @@ spec: - instance - ip type: string + wafv2AclArn: + description: WAFv2ACLArn specifies ARN for the Amazon WAFv2 web ACL. + type: string type: object type: object served: true diff --git a/pkg/ingress/model_build_load_balancer_addons.go b/pkg/ingress/model_build_load_balancer_addons.go index dde8c7595c..f8bca68c14 100644 --- a/pkg/ingress/model_build_load_balancer_addons.go +++ b/pkg/ingress/model_build_load_balancer_addons.go @@ -2,6 +2,7 @@ package ingress import ( "context" + "github.com/pkg/errors" "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/aws-load-balancer-controller/pkg/annotations" @@ -39,6 +40,10 @@ func (t *defaultModelBuildTask) buildWAFv2WebACLAssociation(_ context.Context, l if rawWebACLARN != "" { explicitWebACLARNs.Insert(rawWebACLARN) } + params := member.IngClassConfig.IngClassParams + if params != nil && params.Spec.WAFv2ACLArn != "" { + explicitWebACLARNs.Insert(params.Spec.WAFv2ACLArn) + } } if len(explicitWebACLARNs) == 0 { return nil, nil From 0ca2e1d9a7b2ac1717385dd024b1291374bcb260 Mon Sep 17 00:00:00 2001 From: mikutas <23391543+mikutas@users.noreply.github.com> Date: Fri, 2 May 2025 10:19:42 +0900 Subject: [PATCH 2/2] Add a test --- pkg/ingress/model_builder_test.go | 103 ++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/pkg/ingress/model_builder_test.go b/pkg/ingress/model_builder_test.go index 1d8348c8e8..dabb214142 100644 --- a/pkg/ingress/model_builder_test.go +++ b/pkg/ingress/model_builder_test.go @@ -2743,6 +2743,109 @@ func Test_defaultModelBuilder_Build(t *testing.T) { } } } +}`, + }, + { + name: "Ingress - wafv2AclArn in IngressClassParams", + env: env{ + svcs: []*corev1.Service{ns_1_svc_1, ns_1_svc_2, ns_1_svc_3}, + }, + fields: fields{ + resolveViaDiscoveryCalls: []resolveViaDiscoveryCall{resolveViaDiscoveryCallForInternalLB}, + listLoadBalancersCalls: []listLoadBalancersCall{listLoadBalancerCallForEmptyLB}, + enableBackendSG: true, + }, + args: args{ + ingGroup: Group{ + ID: GroupID{Namespace: "ns-1", Name: "ing-1"}, + Members: []ClassifiedIngress{ + { + IngClassConfig: ClassConfiguration{ + IngClassParams: &v1beta1.IngressClassParams{ + Spec: v1beta1.IngressClassParamsSpec{ + WAFv2ACLArn: "alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:us-west-2:xxxxx:regional/webacl/xxxxxxx/3ab78708-85b0-49d3-b4e1-7a9615a6613b", + }, + }, + }, + Ing: &networking.Ingress{ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns-1", + Name: "ing-1", + }, + Spec: networking.IngressSpec{ + Rules: []networking.IngressRule{ + { + Host: "app-1.example.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: "/svc-1", + Backend: networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: ns_1_svc_1.Name, + Port: networking.ServiceBackendPort{ + Name: "http", + }, + }, + }, + }, + { + Path: "/svc-2", + Backend: networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: ns_1_svc_2.Name, + Port: networking.ServiceBackendPort{ + Name: "http", + }, + }, + }, + }, + }, + }, + }, + }, + { + Host: "app-2.example.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: "/svc-3", + Backend: networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: ns_1_svc_3.Name, + Port: networking.ServiceBackendPort{ + Name: "https", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + wantStackPatch: ` +{ + "id":"ns-1/ing-1", + "resources":{ + "AWS::WAFv2::WebACLAssociation":{ + "LoadBalancer":{ + "spec":{ + "resourceARN":{ + "$ref":"#/resources/AWS::ElasticLoadBalancingV2::LoadBalancer/LoadBalancer/status/loadBalancerARN" + }, + "webACLARN":"alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:us-west-2:xxxxx:regional/webacl/xxxxxxx/3ab78708-85b0-49d3-b4e1-7a9615a6613b" + } + } + } + } }`, }, {