Retry creation of IAM role depending on new IAM user (#7324)

This commit is contained in:
David Tolnay 2016-07-07 13:24:17 -07:00 committed by Clint
parent 96e90ec1f6
commit 2943a1c978
3 changed files with 40 additions and 18 deletions

View File

@ -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
}

View File

@ -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"
@ -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)
}

View File

@ -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)