Skip to content

Commit

Permalink
Cleanup AWS EC2 eventual consistency warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
Ciprian Hacman committed Jul 28, 2020
1 parent 9c8dee2 commit 75c5c34
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 37 deletions.
18 changes: 12 additions & 6 deletions upup/pkg/fi/cloudup/awstasks/autoscalinggroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ import (
"strconv"
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/aws/aws-sdk-go/service/ec2"

"k8s.io/klog"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
"k8s.io/kops/upup/pkg/fi/cloudup/cloudformation"
"k8s.io/kops/upup/pkg/fi/cloudup/terraform"
"k8s.io/kops/util/pkg/maps"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/aws/aws-sdk-go/service/ec2"
"k8s.io/klog"
)

// CloudTagInstanceGroupRolePrefix is a cloud tag that defines the instance role
Expand Down Expand Up @@ -299,7 +299,13 @@ func (v *AutoscalingGroup) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Autos

// @step: attempt to create the autoscaling group for us
if _, err := t.Cloud.Autoscaling().CreateAutoScalingGroup(request); err != nil {
return fmt.Errorf("error creating AutoscalingGroup: %v", err)
code := awsup.AWSErrorCode(err)
message := awsup.AWSErrorMessage(err)
if code == "ValidationError" && strings.Contains(message, "Invalid IAM Instance Profile name") {
klog.V(4).Infof("error creating AutoscalingGroup: %s", message)
return fi.NewTryAgainLaterError("Waiting for IAM Instance Profile to be propagated")
}
return fmt.Errorf("error creating AutoScalingGroup: %s", message)
}

// @step: attempt to enable the metrics for us
Expand Down
34 changes: 5 additions & 29 deletions upup/pkg/fi/cloudup/awstasks/launchtemplate_target_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ import (
"fmt"
"sort"
"strings"
"time"

"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"

"k8s.io/klog"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
)

// RenderAWS is responsible for performing creating / updating the launch template
Expand Down Expand Up @@ -142,31 +141,8 @@ func (t *LaunchTemplate) RenderAWS(c *awsup.AWSAPITarget, a, ep, changes *Launch
}
}
// @step: attempt to create the launch template
err = func() error {
for attempt := 0; attempt < 10; attempt++ {
if _, err = c.Cloud.EC2().CreateLaunchTemplate(input); err == nil {
return nil
}

if awsup.AWSErrorCode(err) == "ValidationError" {
message := awsup.AWSErrorMessage(err)
if strings.Contains(message, "not authorized") || strings.Contains(message, "Invalid IamInstance") {
if attempt > 10 {
return fmt.Errorf("IAM instance profile not yet created/propagated (original error: %v)", message)
}
klog.V(4).Infof("got an error indicating that the IAM instance profile %q is not ready: %q", fi.StringValue(ep.IAMInstanceProfile.Name), message)

time.Sleep(5 * time.Second)
continue
}
klog.V(4).Infof("ErrorCode=%q, Message=%q", awsup.AWSErrorCode(err), awsup.AWSErrorMessage(err))
}
}

return err
}()
if err != nil {
return fmt.Errorf("failed to create aws launch template: %s", err)
if _, err = c.Cloud.EC2().CreateLaunchTemplate(input); err != nil {
return fmt.Errorf("error creating LaunchTemplate: %v", err)
}

ep.ID = fi.String(name)
Expand Down
15 changes: 15 additions & 0 deletions upup/pkg/fi/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,18 @@ func NewExistsAndWarnIfChangesError(message string) *ExistsAndWarnIfChangesError

// ExistsAndWarnIfChangesError implementation of the error interface.
func (e *ExistsAndWarnIfChangesError) Error() string { return e.msg }

// TryAgainLaterError is the custom used when a task needs to fail validation with a message and try again later
type TryAgainLaterError struct {
msg string
}

// NewTryAgainLaterError is a builder for TryAgainLaterError.
func NewTryAgainLaterError(message string) *TryAgainLaterError {
return &TryAgainLaterError{
msg: message,
}
}

// TryAgainLaterError implementation of the error interface.
func (e *TryAgainLaterError) Error() string { return e.msg }
8 changes: 6 additions & 2 deletions upup/pkg/fi/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,11 @@ func (e *executor) RunTasks(taskMap map[string]Task) error {
}

remaining := time.Second * time.Duration(int(time.Until(ts.deadline).Seconds()))
klog.Warningf("error running task %q (%v remaining to succeed): %v", ts.key, remaining, err)
if _, ok := err.(*TryAgainLaterError); ok {
klog.Infof("Task %q not ready: %v", ts.key, err)
} else {
klog.Warningf("error running task %q (%v remaining to succeed): %v", ts.key, remaining, err)
}
errors = append(errors, err)
ts.lastError = err
} else {
Expand All @@ -140,7 +144,7 @@ func (e *executor) RunTasks(taskMap map[string]Task) error {
// Logic error!
panic("did not make progress executing tasks; but no errors reported")
}
klog.Infof("No progress made, sleeping before retrying %d failed task(s)", len(errors))
klog.Infof("No progress made, sleeping before retrying %d task(s)", len(errors))
time.Sleep(e.options.WaitAfterAllTasksFailed)
}
}
Expand Down

0 comments on commit 75c5c34

Please sign in to comment.