diff --git a/builtin/providers/aws/resource_aws_lambda_event_source_mapping.go b/builtin/providers/aws/resource_aws_lambda_event_source_mapping.go index 70ca3a01c..053b2adaf 100644 --- a/builtin/providers/aws/resource_aws_lambda_event_source_mapping.go +++ b/builtin/providers/aws/resource_aws_lambda_event_source_mapping.go @@ -3,10 +3,13 @@ package aws import ( "fmt" "log" + "time" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/lambda" + "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" ) @@ -88,14 +91,35 @@ func resourceAwsLambdaEventSourceMappingCreate(d *schema.ResourceData, meta inte Enabled: aws.Bool(d.Get("enabled").(bool)), } - eventSourceMappingConfiguration, err := conn.CreateEventSourceMapping(params) + // IAM profiles and roles can take some time to propagate in AWS: + // http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role-console + // Error creating Lambda function: InvalidParameterValueException: The + // function defined for the task cannot be assumed by Lambda. + // + // The role may exist, but the permissions may not have propagated, so we + // retry + err := resource.Retry(1*time.Minute, func() error { + eventSourceMappingConfiguration, err := conn.CreateEventSourceMapping(params) + if err != nil { + if awserr, ok := err.(awserr.Error); ok { + if awserr.Code() == "InvalidParameterValueException" { + // Retryable + return awserr + } + } + // Not retryable + return resource.RetryError{Err: err} + } + // No error + d.Set("uuid", eventSourceMappingConfiguration.UUID) + d.SetId(*eventSourceMappingConfiguration.UUID) + return nil + }) + if err != nil { return fmt.Errorf("Error creating Lambda event source mapping: %s", err) } - d.Set("uuid", eventSourceMappingConfiguration.UUID) - d.SetId(*eventSourceMappingConfiguration.UUID) - return resourceAwsLambdaEventSourceMappingRead(d, meta) } @@ -162,7 +186,22 @@ func resourceAwsLambdaEventSourceMappingUpdate(d *schema.ResourceData, meta inte Enabled: aws.Bool(d.Get("enabled").(bool)), } - _, err := conn.UpdateEventSourceMapping(params) + err := resource.Retry(1*time.Minute, func() error { + _, err := conn.UpdateEventSourceMapping(params) + if err != nil { + if awserr, ok := err.(awserr.Error); ok { + if awserr.Code() == "InvalidParameterValueException" { + // Retryable + return awserr + } + } + // Not retryable + return resource.RetryError{Err: err} + } + // No error + return nil + }) + if err != nil { return fmt.Errorf("Error updating Lambda event source mapping: %s", err) } diff --git a/builtin/providers/aws/resource_aws_lambda_function.go b/builtin/providers/aws/resource_aws_lambda_function.go index 324016455..4cce32f4d 100644 --- a/builtin/providers/aws/resource_aws_lambda_function.go +++ b/builtin/providers/aws/resource_aws_lambda_function.go @@ -5,7 +5,6 @@ import ( "fmt" "io/ioutil" "log" - "strings" "time" "github.com/aws/aws-sdk-go/aws" @@ -15,6 +14,7 @@ import ( "errors" + "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" ) @@ -149,22 +149,24 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e Timeout: aws.Int64(int64(d.Get("timeout").(int))), } - var err error - for i := 0; i < 5; i++ { - _, err = conn.CreateFunction(params) - 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 - // Error creating Lambda function: InvalidParameterValueException: The role defined for the task cannot be assumed by Lambda. - if awsErr.Code() == "InvalidParameterValueException" && strings.Contains(awsErr.Message(), "The role defined for the task cannot be assumed by Lambda.") { - log.Printf("[DEBUG] Invalid IAM Instance Profile referenced, retrying...") - time.Sleep(2 * time.Second) - continue + // 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 + // Error creating Lambda function: InvalidParameterValueException: The role defined for the task cannot be assumed by Lambda. + err := resource.Retry(1*time.Minute, func() error { + _, err := conn.CreateFunction(params) + if err != nil { + if awserr, ok := err.(awserr.Error); ok { + if awserr.Code() == "InvalidParameterValueException" { + // Retryable + return awserr + } } + // Not retryable + return resource.RetryError{Err: err} } - break - } + // No error + return nil + }) if err != nil { return fmt.Errorf("Error creating Lambda function: %s", err) }