Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

fix(aws-alb): DuplicateListener on 2nd up #3035

Merged
merged 2 commits into from
Mar 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/3035.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
plugin/alb: Handle DuplicateListener errors from aws-alb releaser
```
55 changes: 53 additions & 2 deletions builtin/aws/alb/releaser.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,15 +372,15 @@ func (r *Releaser) resourceListenerCreate(

tgs := []*elbv2.TargetGroupTuple{
{
TargetGroupArn: &target.Arn,
TargetGroupArn: aws.String(target.Arn),
Weight: aws.Int64(100),
},
}

if shouldCreateListener {
// create the listener to forward traffic to the target group
lo, err := elbsrv.CreateListener(&elbv2.CreateListenerInput{
LoadBalancerArn: &lbState.Arn,
LoadBalancerArn: aws.String(lbState.Arn),
Port: aws.Int64(port),
Protocol: aws.String(protocol),
Certificates: certs,
Expand All @@ -394,6 +394,57 @@ func (r *Releaser) resourceListenerCreate(
},
})
if err != nil {
log.Warn("error creating listener", "error", err)
if aerr, ok := err.(awserr.Error); ok {
// CreateListener is idempotent, but if params change, such as `DefaultActions`,
// it will return a DuplicateListener error
switch aerr.Code() {
case elbv2.ErrCodeDuplicateListenerException:
// if DuplicateListener, we actually want to ModifyListener to use
// the newly created TargetGroup & Target pair.
//
// this requires us to fetch the listener ARN from the load balancer
log.Info("duplicate listener found, attempting to modify listener")
dlo, err := elbsrv.DescribeListeners(&elbv2.DescribeListenersInput{
LoadBalancerArn: aws.String(lbState.Arn),
})
if err != nil {
return err
}

// find the listener on our port
for _, ln := range dlo.Listeners {
if *ln.Port == port {
listener = ln
}
}

mlo, err := elbsrv.ModifyListener(&elbv2.ModifyListenerInput{
ListenerArn: listener.ListenerArn,
Port: aws.Int64(port),
Protocol: aws.String(protocol),
Certificates: certs,
DefaultActions: []*elbv2.Action{
{
ForwardConfig: &elbv2.ForwardActionConfig{
TargetGroups: tgs,
},
Type: aws.String("forward"),
},
},
})
if err != nil {
return err
}

listener = mlo.Listeners[0]
state.Arn = *listener.ListenerArn

log.Info("modified listener", "arn", state.Arn)
// exit
return nil
}
}
return err
}
listener = lo.Listeners[0]
Expand Down