@@ -112,6 +112,12 @@ func (s *Service) reconcileV2LB(lbSpec *infrav1.AWSLoadBalancerSpec) error {
112
112
// set up the type for later processing
113
113
lb .LoadBalancerType = lbSpec .LoadBalancerType
114
114
if lb .IsManaged (s .scope .Name ()) {
115
+ // Reconcile the target groups and listeners from the spec and the ones currently attached to the load balancer.
116
+ _ , err := s .reconcileTargetGroupsAndListeners (lb , lbSpec )
117
+ if err != nil {
118
+ return errors .Wrapf (err , "failed to create target groups/listeners for load balancer %q" , lb .Name )
119
+ }
120
+
115
121
if ! cmp .Equal (spec .ELBAttributes , lb .ELBAttributes ) {
116
122
if err := s .configureLBAttributes (lb .ARN , spec .ELBAttributes ); err != nil {
117
123
return err
@@ -147,6 +153,7 @@ func (s *Service) reconcileV2LB(lbSpec *infrav1.AWSLoadBalancerSpec) error {
147
153
return errors .Wrapf (err , "failed to apply security groups to load balancer %q" , lb .Name )
148
154
}
149
155
}
156
+
150
157
} else {
151
158
s .scope .Trace ("Unmanaged control plane load balancer, skipping load balancer configuration" , "api-server-elb" , lb )
152
159
}
@@ -388,89 +395,7 @@ func (s *Service) createLB(spec *infrav1.LoadBalancer, lbSpec *infrav1.AWSLoadBa
388
395
return nil , errors .New ("no new network load balancer was created; the returned list is empty" )
389
396
}
390
397
391
- // TODO(Skarlso): Add options to set up SSL.
392
- // https://github.com/kubernetes-sigs/cluster-api-provider-aws/issues/3899
393
- for _ , ln := range spec .ELBListeners {
394
- // create the target group first
395
- targetGroupInput := & elbv2.CreateTargetGroupInput {
396
- Name : aws .String (ln .TargetGroup .Name ),
397
- Port : aws .Int64 (ln .TargetGroup .Port ),
398
- Protocol : aws .String (ln .TargetGroup .Protocol .String ()),
399
- VpcId : aws .String (ln .TargetGroup .VpcID ),
400
- Tags : input .Tags ,
401
- HealthCheckIntervalSeconds : aws .Int64 (infrav1 .DefaultAPIServerHealthCheckIntervalSec ),
402
- HealthCheckTimeoutSeconds : aws .Int64 (infrav1 .DefaultAPIServerHealthCheckTimeoutSec ),
403
- HealthyThresholdCount : aws .Int64 (infrav1 .DefaultAPIServerHealthThresholdCount ),
404
- UnhealthyThresholdCount : aws .Int64 (infrav1 .DefaultAPIServerUnhealthThresholdCount ),
405
- }
406
- if s .scope .VPC ().IsIPv6Enabled () {
407
- targetGroupInput .IpAddressType = aws .String ("ipv6" )
408
- }
409
- if ln .TargetGroup .HealthCheck != nil {
410
- targetGroupInput .HealthCheckEnabled = aws .Bool (true )
411
- targetGroupInput .HealthCheckProtocol = ln .TargetGroup .HealthCheck .Protocol
412
- targetGroupInput .HealthCheckPort = ln .TargetGroup .HealthCheck .Port
413
- if ln .TargetGroup .HealthCheck .Path != nil {
414
- targetGroupInput .HealthCheckPath = ln .TargetGroup .HealthCheck .Path
415
- }
416
- if ln .TargetGroup .HealthCheck .IntervalSeconds != nil {
417
- targetGroupInput .HealthCheckIntervalSeconds = ln .TargetGroup .HealthCheck .IntervalSeconds
418
- }
419
- if ln .TargetGroup .HealthCheck .TimeoutSeconds != nil {
420
- targetGroupInput .HealthCheckTimeoutSeconds = ln .TargetGroup .HealthCheck .TimeoutSeconds
421
- }
422
- if ln .TargetGroup .HealthCheck .ThresholdCount != nil {
423
- targetGroupInput .HealthyThresholdCount = ln .TargetGroup .HealthCheck .ThresholdCount
424
- }
425
- if ln .TargetGroup .HealthCheck .UnhealthyThresholdCount != nil {
426
- targetGroupInput .UnhealthyThresholdCount = ln .TargetGroup .HealthCheck .UnhealthyThresholdCount
427
- }
428
- }
429
- s .scope .Debug ("creating target group" , "group" , targetGroupInput , "listener" , ln )
430
- group , err := s .ELBV2Client .CreateTargetGroup (targetGroupInput )
431
- if err != nil {
432
- return nil , errors .Wrapf (err , "failed to create target group for load balancer" )
433
- }
434
- if len (group .TargetGroups ) == 0 {
435
- return nil , errors .New ("no target group was created; the returned list is empty" )
436
- }
437
-
438
- if ! lbSpec .PreserveClientIP {
439
- targetGroupAttributeInput := & elbv2.ModifyTargetGroupAttributesInput {
440
- TargetGroupArn : group .TargetGroups [0 ].TargetGroupArn ,
441
- Attributes : []* elbv2.TargetGroupAttribute {
442
- {
443
- Key : aws .String (infrav1 .TargetGroupAttributeEnablePreserveClientIP ),
444
- Value : aws .String ("false" ),
445
- },
446
- },
447
- }
448
- if _ , err := s .ELBV2Client .ModifyTargetGroupAttributes (targetGroupAttributeInput ); err != nil {
449
- return nil , errors .Wrapf (err , "failed to modify target group attribute" )
450
- }
451
- }
452
-
453
- listenerInput := & elbv2.CreateListenerInput {
454
- DefaultActions : []* elbv2.Action {
455
- {
456
- TargetGroupArn : group .TargetGroups [0 ].TargetGroupArn ,
457
- Type : aws .String (elbv2 .ActionTypeEnumForward ),
458
- },
459
- },
460
- LoadBalancerArn : out .LoadBalancers [0 ].LoadBalancerArn ,
461
- Port : aws .Int64 (ln .Port ),
462
- Protocol : aws .String (string (ln .Protocol )),
463
- Tags : converters .MapToV2Tags (spec .Tags ),
464
- }
465
- // Create ClassicELBListeners
466
- listener , err := s .ELBV2Client .CreateListener (listenerInput )
467
- if err != nil {
468
- return nil , errors .Wrap (err , "failed to create listener" )
469
- }
470
- if len (listener .Listeners ) == 0 {
471
- return nil , errors .New ("no listener was created; the returned list is empty" )
472
- }
473
- }
398
+ // Target Groups and listeners will be reconciled separately
474
399
475
400
s .scope .Info ("Created network load balancer" , "dns-name" , * out .LoadBalancers [0 ].DNSName )
476
401
@@ -1604,6 +1529,113 @@ func (s *Service) reconcileV2LBTags(lb *infrav1.LoadBalancer, desiredTags map[st
1604
1529
return nil
1605
1530
}
1606
1531
1532
+ func (s * Service ) reconcileTargetGroupsAndListeners (spec * infrav1.LoadBalancer , lbSpec * infrav1.AWSLoadBalancerSpec ) ([]* elbv2.TargetGroup , error ) {
1533
+
1534
+ describeInput := & elbv2.DescribeTargetGroupsInput {
1535
+ LoadBalancerArn : aws .String (spec .ARN ),
1536
+ }
1537
+ targetGroups , err := s .ELBV2Client .DescribeTargetGroups (describeInput )
1538
+ if err != nil {
1539
+ s .scope .Error (err , "could not describe target groups for load balancer" , "arn" , spec .ARN )
1540
+ return nil , err
1541
+ }
1542
+
1543
+ // Target Groups already exist, no need to do additional work.
1544
+ // TODO(nrb): This will need to match the infrav1.Listener type
1545
+ if len (targetGroups .TargetGroups ) > 0 {
1546
+ return targetGroups .TargetGroups , nil
1547
+ }
1548
+
1549
+ groups := make ([]* elbv2.TargetGroup , len (spec .ELBListeners ))
1550
+
1551
+ // TODO(Skarlso): Add options to set up SSL.
1552
+ // https://github.com/kubernetes-sigs/cluster-api-provider-aws/issues/3899
1553
+ for _ , ln := range spec .ELBListeners {
1554
+ // create the target group first
1555
+ targetGroupInput := & elbv2.CreateTargetGroupInput {
1556
+ Name : aws .String (ln .TargetGroup .Name ),
1557
+ Port : aws .Int64 (ln .TargetGroup .Port ),
1558
+ Protocol : aws .String (ln .TargetGroup .Protocol .String ()),
1559
+ VpcId : aws .String (ln .TargetGroup .VpcID ),
1560
+ Tags : converters .MapToV2Tags (spec .Tags ),
1561
+ HealthCheckIntervalSeconds : aws .Int64 (infrav1 .DefaultAPIServerHealthCheckIntervalSec ),
1562
+ HealthCheckTimeoutSeconds : aws .Int64 (infrav1 .DefaultAPIServerHealthCheckTimeoutSec ),
1563
+ HealthyThresholdCount : aws .Int64 (infrav1 .DefaultAPIServerHealthThresholdCount ),
1564
+ UnhealthyThresholdCount : aws .Int64 (infrav1 .DefaultAPIServerUnhealthThresholdCount ),
1565
+ }
1566
+ if s .scope .VPC ().IsIPv6Enabled () {
1567
+ targetGroupInput .IpAddressType = aws .String ("ipv6" )
1568
+ }
1569
+ if ln .TargetGroup .HealthCheck != nil {
1570
+ targetGroupInput .HealthCheckEnabled = aws .Bool (true )
1571
+ targetGroupInput .HealthCheckProtocol = ln .TargetGroup .HealthCheck .Protocol
1572
+ targetGroupInput .HealthCheckPort = ln .TargetGroup .HealthCheck .Port
1573
+ if ln .TargetGroup .HealthCheck .Path != nil {
1574
+ targetGroupInput .HealthCheckPath = ln .TargetGroup .HealthCheck .Path
1575
+ }
1576
+ if ln .TargetGroup .HealthCheck .IntervalSeconds != nil {
1577
+ targetGroupInput .HealthCheckIntervalSeconds = ln .TargetGroup .HealthCheck .IntervalSeconds
1578
+ }
1579
+ if ln .TargetGroup .HealthCheck .TimeoutSeconds != nil {
1580
+ targetGroupInput .HealthCheckTimeoutSeconds = ln .TargetGroup .HealthCheck .TimeoutSeconds
1581
+ }
1582
+ if ln .TargetGroup .HealthCheck .ThresholdCount != nil {
1583
+ targetGroupInput .HealthyThresholdCount = ln .TargetGroup .HealthCheck .ThresholdCount
1584
+ }
1585
+ if ln .TargetGroup .HealthCheck .UnhealthyThresholdCount != nil {
1586
+ targetGroupInput .UnhealthyThresholdCount = ln .TargetGroup .HealthCheck .UnhealthyThresholdCount
1587
+ }
1588
+ }
1589
+ s .scope .Debug ("creating target group" , "group" , targetGroupInput , "listener" , ln )
1590
+ group , err := s .ELBV2Client .CreateTargetGroup (targetGroupInput )
1591
+ if err != nil {
1592
+ return nil , errors .Wrapf (err , "failed to create target group for load balancer" )
1593
+ }
1594
+ if len (group .TargetGroups ) == 0 {
1595
+ return nil , errors .New ("no target group was created; the returned list is empty" )
1596
+ }
1597
+ groups = append (groups , group .TargetGroups ... )
1598
+
1599
+ if ! lbSpec .PreserveClientIP {
1600
+ targetGroupAttributeInput := & elbv2.ModifyTargetGroupAttributesInput {
1601
+ TargetGroupArn : group .TargetGroups [0 ].TargetGroupArn ,
1602
+ Attributes : []* elbv2.TargetGroupAttribute {
1603
+ {
1604
+ Key : aws .String (infrav1 .TargetGroupAttributeEnablePreserveClientIP ),
1605
+ Value : aws .String ("false" ),
1606
+ },
1607
+ },
1608
+ }
1609
+ if _ , err := s .ELBV2Client .ModifyTargetGroupAttributes (targetGroupAttributeInput ); err != nil {
1610
+ return nil , errors .Wrapf (err , "failed to modify target group attribute" )
1611
+ }
1612
+ }
1613
+
1614
+ listenerInput := & elbv2.CreateListenerInput {
1615
+ DefaultActions : []* elbv2.Action {
1616
+ {
1617
+ TargetGroupArn : group .TargetGroups [0 ].TargetGroupArn ,
1618
+ Type : aws .String (elbv2 .ActionTypeEnumForward ),
1619
+ },
1620
+ },
1621
+ LoadBalancerArn : aws .String (spec .ARN ),
1622
+ Port : aws .Int64 (ln .Port ),
1623
+ Protocol : aws .String (string (ln .Protocol )),
1624
+ Tags : converters .MapToV2Tags (spec .Tags ),
1625
+ }
1626
+ // Create ClassicELBListeners
1627
+ listener , err := s .ELBV2Client .CreateListener (listenerInput )
1628
+ if err != nil {
1629
+ return nil , errors .Wrap (err , "failed to create listener" )
1630
+ }
1631
+ if len (listener .Listeners ) == 0 {
1632
+ return nil , errors .New ("no listener was created; the returned list is empty" )
1633
+ }
1634
+ }
1635
+
1636
+ return groups , nil
1637
+ }
1638
+
1607
1639
func (s * Service ) getHealthCheckTarget () string {
1608
1640
controlPlaneELB := s .scope .ControlPlaneLoadBalancer ()
1609
1641
protocol := & infrav1 .ELBProtocolSSL
0 commit comments