diff --git a/aws/resource_aws_cloudwatch_event_permission.go b/aws/resource_aws_cloudwatch_event_permission.go index e72b8c5d6ed1..be61ac40bdca 100644 --- a/aws/resource_aws_cloudwatch_event_permission.go +++ b/aws/resource_aws_cloudwatch_event_permission.go @@ -99,42 +99,35 @@ func resourceAwsCloudWatchEventPermissionCreate(d *schema.ResourceData, meta int func resourceAwsCloudWatchEventPermissionRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn input := events.DescribeEventBusInput{} - var policyDoc CloudWatchEventPermissionPolicyDoc + var output *events.DescribeEventBusOutput var policyStatement *CloudWatchEventPermissionPolicyStatement // Especially with concurrent PutPermission calls there can be a slight delay err := resource.Retry(1*time.Minute, func() *resource.RetryError { log.Printf("[DEBUG] Reading CloudWatch Events bus: %s", input) - debo, err := conn.DescribeEventBus(&input) + output, err := conn.DescribeEventBus(&input) if err != nil { return resource.NonRetryableError(fmt.Errorf("Reading CloudWatch Events permission '%s' failed: %s", d.Id(), err.Error())) } - if debo.Policy == nil { - return resource.RetryableError(&resource.NotFoundError{ - Message: fmt.Sprintf("CloudWatch Events permission %q not found"+ - "in given results from DescribeEventBus", d.Id()), - LastResponse: debo, - LastRequest: input, - }) - } + policyStatement, err = getPolicyStatement(output, d.Id()) + return resource.RetryableError(err) + }) - err = json.Unmarshal([]byte(*debo.Policy), &policyDoc) - if err != nil { - return resource.NonRetryableError(fmt.Errorf("Reading CloudWatch Events permission '%s' failed: %s", d.Id(), err.Error())) + if isResourceTimeoutError(err) { + output, err = conn.DescribeEventBus(&input) + if output != nil { + policyStatement, err = getPolicyStatement(output, d.Id()) } + } - policyStatement, err = findCloudWatchEventPermissionPolicyStatementByID(&policyDoc, d.Id()) - return resource.RetryableError(err) - }) + if isResourceNotFoundError(err) { + log.Printf("[WARN] %s", err) + d.SetId("") + return nil + } if err != nil { // Missing statement inside valid policy - if nfErr, ok := err.(*resource.NotFoundError); ok { - log.Printf("[WARN] %s", nfErr) - d.SetId("") - return nil - } - return err } @@ -151,7 +144,7 @@ func resourceAwsCloudWatchEventPermissionRead(d *schema.ResourceData, meta inter principalMap := policyStatement.Principal.(map[string]interface{}) policyARN, err := arn.Parse(principalMap["AWS"].(string)) if err != nil { - return fmt.Errorf("Reading CloudWatch Events permission '%s' failed: %s", d.Id(), err.Error()) + return fmt.Errorf("Reading CloudWatch Events permission '%s' failed: %s", d.Id(), err) } d.Set("principal", policyARN.AccountID) } @@ -160,6 +153,25 @@ func resourceAwsCloudWatchEventPermissionRead(d *schema.ResourceData, meta inter return nil } +func getPolicyStatement(output *events.DescribeEventBusOutput, statementID string) (*CloudWatchEventPermissionPolicyStatement, error) { + var policyDoc CloudWatchEventPermissionPolicyDoc + + if output == nil || output.Policy == nil { + return nil, &resource.NotFoundError{ + Message: fmt.Sprintf("CloudWatch Events permission %q not found"+ + "in given results from DescribeEventBus", statementID), + LastResponse: output, + } + } + + err := json.Unmarshal([]byte(*output.Policy), &policyDoc) + if err != nil { + return nil, fmt.Errorf("Reading CloudWatch Events permission '%s' failed: %s", statementID, err) + } + + return findCloudWatchEventPermissionPolicyStatementByID(&policyDoc, statementID) +} + func resourceAwsCloudWatchEventPermissionUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn diff --git a/aws/resource_aws_cloudwatch_event_rule.go b/aws/resource_aws_cloudwatch_event_rule.go index 853830ed7115..200af79efc2d 100644 --- a/aws/resource_aws_cloudwatch_event_rule.go +++ b/aws/resource_aws_cloudwatch_event_rule.go @@ -3,7 +3,6 @@ package aws import ( "fmt" "log" - "regexp" "time" "github.com/aws/aws-sdk-go/aws" @@ -99,22 +98,23 @@ func resourceAwsCloudWatchEventRuleCreate(d *schema.ResourceData, meta interface // IAM Roles take some time to propagate var out *events.PutRuleOutput err = resource.Retry(30*time.Second, func() *resource.RetryError { - var err error out, err = conn.PutRule(input) - pattern := regexp.MustCompile(`cannot be assumed by principal '[a-z]+\.amazonaws\.com'\.$`) + + if isAWSErr(err, "ValidationException", "cannot be assumed by principal") { + log.Printf("[DEBUG] Retrying update of CloudWatch Event Rule %q", *input.Name) + return resource.RetryableError(err) + } if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - if awsErr.Code() == "ValidationException" && pattern.MatchString(awsErr.Message()) { - log.Printf("[DEBUG] Retrying creation of CloudWatch Event Rule %q", *input.Name) - return resource.RetryableError(err) - } - } return resource.NonRetryableError(err) } return nil }) + if isResourceTimeoutError(err) { + _, err = conn.PutRule(input) + } + if err != nil { - return fmt.Errorf("Creating CloudWatch Event Rule failed: %s", err) + return fmt.Errorf("Updating CloudWatch Event Rule failed: %s", err) } d.Set("arn", out.RuleArn) @@ -197,18 +197,20 @@ func resourceAwsCloudWatchEventRuleUpdate(d *schema.ResourceData, meta interface // IAM Roles take some time to propagate err = resource.Retry(30*time.Second, func() *resource.RetryError { _, err := conn.PutRule(input) - pattern := regexp.MustCompile(`cannot be assumed by principal '[a-z]+\.amazonaws\.com'\.$`) + + if isAWSErr(err, "ValidationException", "cannot be assumed by principal") { + log.Printf("[DEBUG] Retrying update of CloudWatch Event Rule %q", *input.Name) + return resource.RetryableError(err) + } if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - if awsErr.Code() == "ValidationException" && pattern.MatchString(awsErr.Message()) { - log.Printf("[DEBUG] Retrying update of CloudWatch Event Rule %q", *input.Name) - return resource.RetryableError(err) - } - } return resource.NonRetryableError(err) } return nil }) + if isResourceTimeoutError(err) { + _, err = conn.PutRule(input) + } + if err != nil { return fmt.Errorf("Updating CloudWatch Event Rule failed: %s", err) } diff --git a/aws/resource_aws_cloudwatch_log_destination.go b/aws/resource_aws_cloudwatch_log_destination.go index e995cf62e168..ab2eda1abbfb 100644 --- a/aws/resource_aws_cloudwatch_log_destination.go +++ b/aws/resource_aws_cloudwatch_log_destination.go @@ -2,11 +2,9 @@ package aws import ( "fmt" - "strings" "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/cloudwatchlogs" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -64,28 +62,28 @@ func resourceAwsCloudWatchLogDestinationPut(d *schema.ResourceData, meta interfa TargetArn: aws.String(target_arn), } - return resource.Retry(3*time.Minute, func() *resource.RetryError { - resp, err := conn.PutDestination(params) + var resp *cloudwatchlogs.PutDestinationOutput + var err error + err = resource.Retry(3*time.Minute, func() *resource.RetryError { + resp, err = conn.PutDestination(params) - if err == nil { - d.SetId(name) - d.Set("arn", *resp.Destination.Arn) - } - - awsErr, ok := err.(awserr.Error) - if !ok { + if isAWSErr(err, cloudwatchlogs.ErrCodeInvalidParameterException, "Could not deliver test message to specified") { return resource.RetryableError(err) } - - if awsErr.Code() == "InvalidParameterException" { - if strings.Contains(awsErr.Message(), "Could not deliver test message to specified") { - return resource.RetryableError(err) - } + if err != nil { return resource.NonRetryableError(err) } - - return resource.NonRetryableError(err) + return nil }) + if isResourceTimeoutError(err) { + resp, err = conn.PutDestination(params) + } + if err != nil { + return fmt.Errorf("Error putting cloudwatch log destination: %s", err) + } + d.SetId(name) + d.Set("arn", resp.Destination.Arn) + return nil } func resourceAwsCloudWatchLogDestinationRead(d *schema.ResourceData, meta interface{}) error { diff --git a/aws/resource_aws_cloudwatch_log_subscription_filter.go b/aws/resource_aws_cloudwatch_log_subscription_filter.go index fa6985d57d53..acbafac3a1f1 100644 --- a/aws/resource_aws_cloudwatch_log_subscription_filter.go +++ b/aws/resource_aws_cloudwatch_log_subscription_filter.go @@ -64,32 +64,32 @@ func resourceAwsCloudwatchLogSubscriptionFilterCreate(d *schema.ResourceData, me params := getAwsCloudWatchLogsSubscriptionFilterInput(d) log.Printf("[DEBUG] Creating SubscriptionFilter %#v", params) - return resource.Retry(5*time.Minute, func() *resource.RetryError { + err := resource.Retry(5*time.Minute, func() *resource.RetryError { _, err := conn.PutSubscriptionFilter(¶ms) - if err == nil { - d.SetId(cloudwatchLogsSubscriptionFilterId(d.Get("log_group_name").(string))) - log.Printf("[DEBUG] Cloudwatch logs subscription %q created", d.Id()) + if isAWSErr(err, cloudwatchlogs.ErrCodeInvalidParameterException, "Could not deliver test message to specified") { + return resource.RetryableError(err) } - - awsErr, ok := err.(awserr.Error) - if !ok { + if isAWSErr(err, cloudwatchlogs.ErrCodeInvalidParameterException, "Could not execute the lambda function") { return resource.RetryableError(err) } - - if awsErr.Code() == "InvalidParameterException" { - log.Printf("[DEBUG] Caught message: %q, code: %q: Retrying", awsErr.Message(), awsErr.Code()) - if strings.Contains(awsErr.Message(), "Could not deliver test message to specified") { - return resource.RetryableError(err) - } - if strings.Contains(awsErr.Message(), "Could not execute the lambda function") { - return resource.RetryableError(err) - } - resource.NonRetryableError(err) + if err != nil { + return resource.NonRetryableError(err) } - - return resource.NonRetryableError(err) + return nil }) + + if isResourceTimeoutError(err) { + _, err = conn.PutSubscriptionFilter(¶ms) + } + + if err != nil { + return fmt.Errorf("Error creating Cloudwatch log subscription filter: %s", err) + } + + d.SetId(cloudwatchLogsSubscriptionFilterId(d.Get("log_group_name").(string))) + log.Printf("[DEBUG] Cloudwatch logs subscription %q created", d.Id()) + return nil } func resourceAwsCloudwatchLogSubscriptionFilterUpdate(d *schema.ResourceData, meta interface{}) error {