From 644837b6528625eaa214224a08a2e3f7c6fdad4e Mon Sep 17 00:00:00 2001 From: Raihaan Shouhell Date: Thu, 27 Jun 2019 14:17:21 +0800 Subject: [PATCH 1/3] Add timeouts for create and delete and refactor to use isAWSerr This contribution is made by Autodesk Inc. under the terms of the Mozilla Public License (MPL) version 2.0. --- aws/resource_aws_ebs_snapshot.go | 33 +++++++++++++++------------ aws/resource_aws_ebs_snapshot_test.go | 5 ++++ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/aws/resource_aws_ebs_snapshot.go b/aws/resource_aws_ebs_snapshot.go index 7821ece72962..687bc6a56d91 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, @@ -157,16 +161,9 @@ 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) }) } @@ -174,9 +171,17 @@ func resourceAwsEbsSnapshotDelete(d *schema.ResourceData, meta interface{}) erro func resourceAwsEbsSnapshotWaitForAvailable(id string, conn *ec2.EC2) error { log.Printf("Waiting for Snapshot %s to become available...", id) - req := &ec2.DescribeSnapshotsInput{ - SnapshotIds: []*string{aws.String(id)}, - } - err := conn.WaitUntilSnapshotCompleted(req) - return err + return resource.Retry(5*time.Minute, func() *resource.RetryError { + req := &ec2.DescribeSnapshotsInput{ + SnapshotIds: []*string{aws.String(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) } From 05ad737eb7060f631b6130b4eea8b77142ceb977 Mon Sep 17 00:00:00 2001 From: Raihaan Shouhell Date: Thu, 27 Jun 2019 15:29:44 +0800 Subject: [PATCH 2/3] Missed setting the timeout --- aws/resource_aws_ebs_snapshot.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_ebs_snapshot.go b/aws/resource_aws_ebs_snapshot.go index 687bc6a56d91..e145a3f54321 100644 --- a/aws/resource_aws_ebs_snapshot.go +++ b/aws/resource_aws_ebs_snapshot.go @@ -99,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 } @@ -153,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()), } @@ -168,12 +168,12 @@ func resourceAwsEbsSnapshotDelete(d *schema.ResourceData, meta interface{}) erro }) } -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()) - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { req := &ec2.DescribeSnapshotsInput{ - SnapshotIds: []*string{aws.String(id)}, + SnapshotIds: []*string{aws.String(d.Id())}, } err := conn.WaitUntilSnapshotCompleted(req) if err == nil { From 688b5f1a8d5d8627ee0df2fc242b22513c8e4fa1 Mon Sep 17 00:00:00 2001 From: Raihaan Shouhell Date: Wed, 3 Jul 2019 15:11:32 +0800 Subject: [PATCH 3/3] Updated ebs snapshot documentation --- website/docs/r/ebs_snapshot.html.markdown | 7 +++++++ 1 file changed, 7 insertions(+) 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