Skip to content

Commit

Permalink
provider/aws: Handle deleted CloudFormation stack during creation gra…
Browse files Browse the repository at this point in the history
…cefully
  • Loading branch information
radeksimko authored and Radek Simko committed Apr 4, 2016
1 parent 0e7671d commit 3599822
Showing 1 changed file with 51 additions and 2 deletions.
53 changes: 51 additions & 2 deletions builtin/providers/aws/resource_aws_cloudformation_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,46 @@ func resourceAwsCloudFormationStackCreate(d *schema.ResourceData, meta interface
}

d.SetId(*resp.StackId)
creationTime := time.Now()
var deletionReasons []string

wait := resource.StateChangeConf{
Pending: []string{"CREATE_IN_PROGRESS", "ROLLBACK_IN_PROGRESS", "ROLLBACK_COMPLETE"},
Pending: []string{
"CREATE_IN_PROGRESS",
"DELETE_IN_PROGRESS",
"DELETE_COMPLETE",
"ROLLBACK_IN_PROGRESS",
"ROLLBACK_COMPLETE",
},
Target: []string{"CREATE_COMPLETE"},
Timeout: time.Duration(retryTimeout) * time.Minute,
MinTimeout: 5 * time.Second,
MinTimeout: 1 * time.Second,
Refresh: func() (interface{}, string, error) {
resp, err := conn.DescribeStacks(&cloudformation.DescribeStacksInput{
StackName: aws.String(d.Get("name").(string)),
})
if len(resp.Stacks) == 0 {
if d.Get("on_failure").(string) == "DELETE" {
log.Printf("[DEBUG] Deleting CloudFormation stack %q (%q) because creation failed: %q",
d.Get("name").(string), d.Id(), deletionReasons)
d.SetId("")
return resp, "", fmt.Errorf(
"Creation of CloudFormation stack %q failed: %q",
d.Get("name").(string), deletionReasons)
} else {
// This shouldn't happen unless CloudFormation is inconsistent
// See https://github.com/hashicorp/terraform/issues/5487
log.Printf("[WARN] CloudFormation stack %q (%q) not found.\nresponse: %q\nfailures: %q",
d.Get("name").(string), d.Id(), resp, deletionReasons)
return resp, "", fmt.Errorf(
"CloudFormation stack %q vanished unexpectedly during creation.\n"+
"Unless you knowingly manually deleted the stack "+
"please report this as bug at https://github.com/hashicorp/terraform/issues\n"+
"along with the config & Terraform version & the details below:\n"+
"Full API response: %s\nCaptured reasons: %q\n",
d.Get("name").(string), resp, deletionReasons)
}
}
status := *resp.Stacks[0].StackStatus
log.Printf("[DEBUG] Current CloudFormation stack status: %q", status)

Expand All @@ -168,6 +198,18 @@ func resourceAwsCloudFormationStackCreate(d *schema.ResourceData, meta interface

return resp, "", fmt.Errorf("ROLLBACK_COMPLETE:\n%q", failures)
}

// There is a small chance we may not be able to catch this
// if stack becomes deleted in between retries
if status == "DELETE_IN_PROGRESS" {
failures, err := getCloudFormationFailures(aws.String(d.Get("name").(string)), creationTime, conn)
if err != nil {
return resp, "", fmt.Errorf(
"Failed getting details about deletion reasons: %q", err.Error())
}
deletionReasons = failures
}

return resp, status, err
},
}
Expand Down Expand Up @@ -485,3 +527,10 @@ func cfStackEventIsFailure(event *cloudformation.StackEvent, afterTime time.Time
return failRe.MatchString(*event.ResourceStatus) || rollbackRe.MatchString(*event.ResourceStatus) &&
event.Timestamp.After(afterTime) && event.ResourceStatusReason != nil
}

func cfStackEventIsStackDeletion(event *cloudformation.StackEvent, afterTime time.Time) bool {
return *event.ResourceStatus == "DELETE_IN_PROGRESS" &&
*event.ResourceType == "AWS::CloudFormation::Stack" &&
event.Timestamp.After(afterTime) &&
event.ResourceStatusReason != nil
}

0 comments on commit 3599822

Please sign in to comment.