diff --git a/aws/resource_aws_ebs_snapshot.go b/aws/resource_aws_ebs_snapshot.go index 7821ece72962..e145a3f54321 100644 --- a/aws/resource_aws_ebs_snapshot.go +++ b/aws/resource_aws_ebs_snapshot.go @@ -6,7 +6,6 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -18,6 +17,11 @@ func resourceAwsEbsSnapshot() *schema.Resource { Read: resourceAwsEbsSnapshotRead, Delete: resourceAwsEbsSnapshotDelete, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + Schema: map[string]*schema.Schema{ "volume_id": { Type: schema.TypeString, @@ -95,7 +99,7 @@ func resourceAwsEbsSnapshotCreate(d *schema.ResourceData, meta interface{}) erro d.SetId(*res.SnapshotId) - err = resourceAwsEbsSnapshotWaitForAvailable(d.Id(), conn) + err = resourceAwsEbsSnapshotWaitForAvailable(d, conn) if err != nil { return err } @@ -149,7 +153,7 @@ func resourceAwsEbsSnapshotRead(d *schema.ResourceData, meta interface{}) error func resourceAwsEbsSnapshotDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { request := &ec2.DeleteSnapshotInput{ SnapshotId: aws.String(d.Id()), } @@ -157,26 +161,27 @@ func resourceAwsEbsSnapshotDelete(d *schema.ResourceData, meta interface{}) erro if err == nil { return nil } - - ebsErr, ok := err.(awserr.Error) - if ebsErr.Code() == "SnapshotInUse" { + if isAWSErr(err, "SnapshotInUse", "") { return resource.RetryableError(fmt.Errorf("EBS SnapshotInUse - trying again while it detaches")) } - - if !ok { - return resource.NonRetryableError(err) - } - return resource.NonRetryableError(err) }) } -func resourceAwsEbsSnapshotWaitForAvailable(id string, conn *ec2.EC2) error { - log.Printf("Waiting for Snapshot %s to become available...", id) +func resourceAwsEbsSnapshotWaitForAvailable(d *schema.ResourceData, conn *ec2.EC2) error { + log.Printf("Waiting for Snapshot %s to become available...", d.Id()) - req := &ec2.DescribeSnapshotsInput{ - SnapshotIds: []*string{aws.String(id)}, - } - err := conn.WaitUntilSnapshotCompleted(req) - return err + return resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + req := &ec2.DescribeSnapshotsInput{ + SnapshotIds: []*string{aws.String(d.Id())}, + } + err := conn.WaitUntilSnapshotCompleted(req) + if err == nil { + return nil + } + if isAWSErr(err, "ResourceNotReady", "") { + return resource.RetryableError(fmt.Errorf("EBS CreatingSnapshot - waiting for snapshot to become available")) + } + return resource.NonRetryableError(err) + }) } diff --git a/aws/resource_aws_ebs_snapshot_test.go b/aws/resource_aws_ebs_snapshot_test.go index fdd1b08e1aac..bc84d7815f0c 100644 --- a/aws/resource_aws_ebs_snapshot_test.go +++ b/aws/resource_aws_ebs_snapshot_test.go @@ -173,6 +173,11 @@ resource "aws_ebs_snapshot" "test" { tags = { Name = "%s" } + + timeouts { + create = "10m" + delete = "10m" + } } `, rName) } diff --git a/website/docs/r/ebs_snapshot.html.markdown b/website/docs/r/ebs_snapshot.html.markdown index a8ee09129416..17e3e4ad5a2f 100644 --- a/website/docs/r/ebs_snapshot.html.markdown +++ b/website/docs/r/ebs_snapshot.html.markdown @@ -39,6 +39,13 @@ The following arguments are supported: * `description` - (Optional) A description of what the snapshot is. * `tags` - (Optional) A mapping of tags to assign to the snapshot +### Timeouts + +`aws_ebs_snapshot` provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - (Default `10 minutes`) Used for creating the ebs snapshot +- `delete` - (Default `10 minutes`) Used for deleting the ebs snapshot ## Attributes Reference