Skip to content

Commit b99d383

Browse files
committed
Wait for rollback completion on update failures
Instead of immediately failing on the first UPDATE_FAILED event that likely caused the stack update failure, delay returning until the stack reaches a terminal failure state. This reduces the chance of another workflow starting while the stack still rolls back. Closes #1
1 parent da009ad commit b99d383

File tree

1 file changed

+6
-3
lines changed

1 file changed

+6
-3
lines changed

main.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"cmp"
45
"context"
56
"crypto/rand"
67
"encoding/hex"
@@ -104,6 +105,7 @@ func run(ctx context.Context, stackName string, args []string) error {
104105
log.Print("polling for stack updates until it's ready, this may take a while")
105106
oldEventsCutoff := time.Now().Add(-time.Hour)
106107
ticker := time.NewTicker(20 * time.Second)
108+
var likelyRootCause error
107109
defer ticker.Stop()
108110
for {
109111
select {
@@ -125,15 +127,16 @@ func run(ctx context.Context, stackName string, args []string) error {
125127
if evt.ClientRequestToken == nil || *evt.ClientRequestToken != token {
126128
continue
127129
}
128-
if evt.ResourceStatus == types.ResourceStatusUpdateFailed && unptr(evt.ResourceStatusReason) != "Resource update cancelled" {
129-
return fmt.Errorf("%s %v: %s", unptr(evt.LogicalResourceId), evt.ResourceStatus, unptr(evt.ResourceStatusReason))
130+
if likelyRootCause == nil && evt.ResourceStatus == types.ResourceStatusUpdateFailed && unptr(evt.ResourceStatusReason) != "Resource update cancelled" {
131+
likelyRootCause = fmt.Errorf("%s %v: %s", unptr(evt.LogicalResourceId), evt.ResourceStatus, unptr(evt.ResourceStatusReason))
132+
debugf("likely root cause: %v", likelyRootCause)
130133
}
131134
debugf("%s\t%s\t%v", unptr(evt.ResourceType), unptr(evt.LogicalResourceId), evt.ResourceStatus)
132135
if unptr(evt.LogicalResourceId) == stackName && unptr(evt.ResourceType) == "AWS::CloudFormation::Stack" {
133136
switch evt.ResourceStatus {
134137
case types.ResourceStatusUpdateRollbackComplete,
135138
types.ResourceStatusRollbackFailed:
136-
return fmt.Errorf("%v, see AWS CloudFormation Console for more details", evt.ResourceStatus)
139+
return cmp.Or(likelyRootCause, fmt.Errorf("%v, see AWS CloudFormation Console for more details", evt.ResourceStatus))
137140
case types.ResourceStatusUpdateComplete:
138141
return nil
139142
}

0 commit comments

Comments
 (0)