Skip to content

Commit

Permalink
Retry creation of IAM role depending on new IAM user (#7324)
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay authored and catsby committed Jul 7, 2016
1 parent 96e90ec commit 2943a1c
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 18 deletions.
14 changes: 14 additions & 0 deletions builtin/providers/aws/awserr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package aws

import (
"strings"

"github.com/aws/aws-sdk-go/aws/awserr"
)

func isAWSErr(err error, code string, message string) bool {
if err, ok := err.(awserr.Error); ok {
return err.Code() == code && strings.Contains(err.Message(), message)
}
return false
}
13 changes: 12 additions & 1 deletion builtin/providers/aws/resource_aws_iam_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package aws
import (
"fmt"
"regexp"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
Expand Down Expand Up @@ -103,7 +104,17 @@ func resourceAwsIamRoleCreate(d *schema.ResourceData, meta interface{}) error {
AssumeRolePolicyDocument: aws.String(d.Get("assume_role_policy").(string)),
}

createResp, err := iamconn.CreateRole(request)
var createResp *iam.CreateRoleOutput
err := resource.Retry(10*time.Second, func() *resource.RetryError {
var err error
createResp, err = iamconn.CreateRole(request)
// IAM roles can take ~10 seconds to propagate in AWS:
// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role-console
if isAWSErr(err, "MalformedPolicyDocument", "Invalid principal in policy") {
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
})
if err != nil {
return fmt.Errorf("Error creating IAM Role %s: %s", name, err)
}
Expand Down
31 changes: 14 additions & 17 deletions builtin/providers/aws/resource_aws_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,25 +361,22 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] Run configuration: %s", runOpts)

var runResp *ec2.Reservation
for i := 0; i < 5; i++ {
err = resource.Retry(10*time.Second, func() *resource.RetryError {
var err error
runResp, err = conn.RunInstances(runOpts)
if awsErr, ok := err.(awserr.Error); ok {
// IAM profiles can take ~10 seconds to propagate in AWS:
// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role-console
if awsErr.Code() == "InvalidParameterValue" && strings.Contains(awsErr.Message(), "Invalid IAM Instance Profile") {
log.Printf("[DEBUG] Invalid IAM Instance Profile referenced, retrying...")
time.Sleep(2 * time.Second)
continue
}

// Warn if the AWS Error involves group ids, to help identify situation
// where a user uses group ids in security_groups for the Default VPC.
// See https://github.com/hashicorp/terraform/issues/3798
if awsErr.Code() == "InvalidParameterValue" && strings.Contains(awsErr.Message(), "groupId is invalid") {
return fmt.Errorf("Error launching instance, possible mismatch of Security Group IDs and Names. See AWS Instance docs here: %s.\n\n\tAWS Error: %s", "https://terraform.io/docs/providers/aws/r/instance.html", awsErr.Message())
}
// IAM profiles can take ~10 seconds to propagate in AWS:
// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role-console
if isAWSErr(err, "InvalidParameterValue", "Invalid IAM Instance Profile") {
log.Printf("[DEBUG] Invalid IAM Instance Profile referenced, retrying...")
return resource.RetryableError(err)
}
break
return resource.NonRetryableError(err)
})
// Warn if the AWS Error involves group ids, to help identify situation
// where a user uses group ids in security_groups for the Default VPC.
// See https://github.com/hashicorp/terraform/issues/3798
if isAWSErr(err, "InvalidParameterValue", "groupId is invalid") {
return fmt.Errorf("Error launching instance, possible mismatch of Security Group IDs and Names. See AWS Instance docs here: %s.\n\n\tAWS Error: %s", "https://terraform.io/docs/providers/aws/r/instance.html", err.(awserr.Error).Message())
}
if err != nil {
return fmt.Errorf("Error launching source instance: %s", err)
Expand Down

0 comments on commit 2943a1c

Please sign in to comment.