From bbee2da7f30c29e845755ffd219a2e5994d6c06f Mon Sep 17 00:00:00 2001 From: Brice Figureau Date: Wed, 30 Jan 2019 16:01:22 +0100 Subject: [PATCH] Fix #73479 AWS NLB target groups missing tags `elbv2.AddTags` doesn't seem to support assigning the same set of tags to multiple resources at once leading to the following error: Error adding tags after modifying load balancer targets: "ValidationError: Only one resource can be tagged at a time" This can happen when using AWS NLB with multiple listeners pointing to different node ports. When k8s creates a NLB it creates a target group per listener along with installing security group ingress rules allowing the traffic to reach the k8s nodes. Unfortunately if those target groups are not tagged, k8s will not manage them, thinking it is not the owner. This small changes assigns tags one resource at a time instead of batching them as before. Signed-off-by: Brice Figureau --- .../providers/aws/aws_loadbalancer.go | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/pkg/cloudprovider/providers/aws/aws_loadbalancer.go b/pkg/cloudprovider/providers/aws/aws_loadbalancer.go index 7a79e3d8fd4..1a9339b4c2d 100644 --- a/pkg/cloudprovider/providers/aws/aws_loadbalancer.go +++ b/pkg/cloudprovider/providers/aws/aws_loadbalancer.go @@ -143,10 +143,7 @@ func (c *Cloud) ensureLoadBalancerv2(namespacedName types.NamespacedName, loadBa loadBalancer = createResponse.LoadBalancers[0] // Create Target Groups - addTagsInput := &elbv2.AddTagsInput{ - ResourceArns: []*string{}, - Tags: []*elbv2.Tag{}, - } + resourceArns := make([]*string, 0, len(mappings)) for i := range mappings { // It is easier to keep track of updates by having possibly @@ -155,20 +152,28 @@ func (c *Cloud) ensureLoadBalancerv2(namespacedName types.NamespacedName, loadBa if err != nil { return nil, fmt.Errorf("Error creating listener: %q", err) } - addTagsInput.ResourceArns = append(addTagsInput.ResourceArns, targetGroupArn) + resourceArns = append(resourceArns, targetGroupArn) } // Add tags to targets + targetGroupTags := make([]*elbv2.Tag, 0, len(tags)) + for k, v := range tags { - addTagsInput.Tags = append(addTagsInput.Tags, &elbv2.Tag{ + targetGroupTags = append(targetGroupTags, &elbv2.Tag{ Key: aws.String(k), Value: aws.String(v), }) } - if len(addTagsInput.ResourceArns) > 0 && len(addTagsInput.Tags) > 0 { - _, err = c.elbv2.AddTags(addTagsInput) - if err != nil { - return nil, fmt.Errorf("Error adding tags after creating Load Balancer: %q", err) + if len(resourceArns) > 0 && len(targetGroupTags) > 0 { + // elbv2.AddTags doesn't allow to tag multiple resources at once + for _, arn := range resourceArns { + _, err = c.elbv2.AddTags(&elbv2.AddTagsInput{ + ResourceArns: []*string{arn}, + Tags: targetGroupTags, + }) + if err != nil { + return nil, fmt.Errorf("Error adding tags after creating Load Balancer: %q", err) + } } } } else {