From 06697eb32b97afd041e522a8a1917de29b121392 Mon Sep 17 00:00:00 2001 From: Julian Mehnle Date: Wed, 4 Oct 2017 17:40:33 +0000 Subject: [PATCH 1/2] r/aws_{ami,ami_copy,ami_from_instance}: Configurable timeouts. --- aws/resource_aws_ami.go | 22 ++++++++++++------- aws/resource_aws_ami_copy.go | 8 ++++++- aws/resource_aws_ami_from_instance.go | 8 ++++++- ...resource_aws_ami_launch_permission_test.go | 4 +++- website/docs/r/ami.html.markdown | 8 +++++++ website/docs/r/ami_copy.html.markdown | 8 +++++++ .../docs/r/ami_from_instance.html.markdown | 8 +++++++ 7 files changed, 55 insertions(+), 11 deletions(-) diff --git a/aws/resource_aws_ami.go b/aws/resource_aws_ami.go index f6b4ffb07714..1a1ae0d5d59e 100644 --- a/aws/resource_aws_ami.go +++ b/aws/resource_aws_ami.go @@ -31,6 +31,12 @@ func resourceAwsAmi() *schema.Resource { return &schema.Resource{ Create: resourceAwsAmiCreate, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(AWSAMIRetryTimeout), + Update: schema.DefaultTimeout(AWSAMIRetryTimeout), + Delete: schema.DefaultTimeout(AWSAMIDeleteRetryTimeout), + }, + Schema: resourceSchema, // The Read, Update and Delete operations are shared with aws_ami_copy @@ -117,7 +123,7 @@ func resourceAwsAmiCreate(d *schema.ResourceData, meta interface{}) error { d.SetPartial("manage_ebs_block_devices") d.Partial(false) - _, err = resourceAwsAmiWaitForAvailable(id, client) + _, err = resourceAwsAmiWaitForAvailable(d, id, client) if err != nil { return err } @@ -170,7 +176,7 @@ func resourceAwsAmiRead(d *schema.ResourceData, meta interface{}) error { // before we continue. We should never take this branch in normal // circumstances since we would've waited for availability during // the "Create" step. - image, err = resourceAwsAmiWaitForAvailable(id, client) + image, err = resourceAwsAmiWaitForAvailable(d, id, client) if err != nil { return err } @@ -302,7 +308,7 @@ func resourceAwsAmiDelete(d *schema.ResourceData, meta interface{}) error { } // Verify that the image is actually removed, if not we need to wait for it to be removed - if err := resourceAwsAmiWaitForDestroy(d.Id(), client); err != nil { + if err := resourceAwsAmiWaitForDestroy(d, d.Id(), client); err != nil { return err } @@ -335,16 +341,16 @@ func AMIStateRefreshFunc(client *ec2.EC2, id string) resource.StateRefreshFunc { } } -func resourceAwsAmiWaitForDestroy(id string, client *ec2.EC2) error { +func resourceAwsAmiWaitForDestroy(d *schema.ResourceData, id string, client *ec2.EC2) error { log.Printf("Waiting for AMI %s to be deleted...", id) stateConf := &resource.StateChangeConf{ Pending: []string{"available", "pending", "failed"}, Target: []string{"destroyed"}, Refresh: AMIStateRefreshFunc(client, id), - Timeout: AWSAMIDeleteRetryTimeout, + Timeout: d.Timeout(schema.TimeoutDelete), Delay: AWSAMIRetryDelay, - MinTimeout: AWSAMIRetryTimeout, + MinTimeout: AWSAMIRetryMinTimeout, } _, err := stateConf.WaitForState() @@ -355,14 +361,14 @@ func resourceAwsAmiWaitForDestroy(id string, client *ec2.EC2) error { return nil } -func resourceAwsAmiWaitForAvailable(id string, client *ec2.EC2) (*ec2.Image, error) { +func resourceAwsAmiWaitForAvailable(d *schema.ResourceData, id string, client *ec2.EC2) (*ec2.Image, error) { log.Printf("Waiting for AMI %s to become available...", id) stateConf := &resource.StateChangeConf{ Pending: []string{"pending"}, Target: []string{"available"}, Refresh: AMIStateRefreshFunc(client, id), - Timeout: AWSAMIRetryTimeout, + Timeout: d.Timeout(schema.TimeoutCreate), Delay: AWSAMIRetryDelay, MinTimeout: AWSAMIRetryMinTimeout, } diff --git a/aws/resource_aws_ami_copy.go b/aws/resource_aws_ami_copy.go index 3452d5b52874..14c18059ce81 100644 --- a/aws/resource_aws_ami_copy.go +++ b/aws/resource_aws_ami_copy.go @@ -42,6 +42,12 @@ func resourceAwsAmiCopy() *schema.Resource { return &schema.Resource{ Create: resourceAwsAmiCopyCreate, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(AWSAMIRetryTimeout), + Update: schema.DefaultTimeout(AWSAMIRetryTimeout), + Delete: schema.DefaultTimeout(AWSAMIDeleteRetryTimeout), + }, + Schema: resourceSchema, // The remaining operations are shared with the generic aws_ami resource, @@ -81,7 +87,7 @@ func resourceAwsAmiCopyCreate(d *schema.ResourceData, meta interface{}) error { d.SetPartial("manage_ebs_snapshots") d.Partial(false) - _, err = resourceAwsAmiWaitForAvailable(id, client) + _, err = resourceAwsAmiWaitForAvailable(d, id, client) if err != nil { return err } diff --git a/aws/resource_aws_ami_from_instance.go b/aws/resource_aws_ami_from_instance.go index cc272d3c15d0..ccf85ce11a1f 100644 --- a/aws/resource_aws_ami_from_instance.go +++ b/aws/resource_aws_ami_from_instance.go @@ -27,6 +27,12 @@ func resourceAwsAmiFromInstance() *schema.Resource { return &schema.Resource{ Create: resourceAwsAmiFromInstanceCreate, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(AWSAMIRetryTimeout), + Update: schema.DefaultTimeout(AWSAMIRetryTimeout), + Delete: schema.DefaultTimeout(AWSAMIDeleteRetryTimeout), + }, + Schema: resourceSchema, // The remaining operations are shared with the generic aws_ami resource, @@ -61,7 +67,7 @@ func resourceAwsAmiFromInstanceCreate(d *schema.ResourceData, meta interface{}) d.SetPartial("manage_ebs_snapshots") d.Partial(false) - _, err = resourceAwsAmiWaitForAvailable(id, client) + _, err = resourceAwsAmiWaitForAvailable(d, id, client) if err != nil { return err } diff --git a/aws/resource_aws_ami_launch_permission_test.go b/aws/resource_aws_ami_launch_permission_test.go index 4ccb35c7cb83..24ccedcb3b8b 100644 --- a/aws/resource_aws_ami_launch_permission_test.go +++ b/aws/resource_aws_ami_launch_permission_test.go @@ -117,7 +117,9 @@ func testAccAWSAMIDisappears(imageID *string) r.TestCheckFunc { return err } - if err := resourceAwsAmiWaitForDestroy(*imageID, conn); err != nil { + r := resourceAwsAmiLaunchPermission() // dummy resource + d := r.TestResourceData() + if err := resourceAwsAmiWaitForDestroy(d, *imageID, conn); err != nil { return err } return nil diff --git a/website/docs/r/ami.html.markdown b/website/docs/r/ami.html.markdown index 7c1a642980d8..8d7251abc4ba 100644 --- a/website/docs/r/ami.html.markdown +++ b/website/docs/r/ami.html.markdown @@ -93,6 +93,14 @@ Nested `ephemeral_block_device` blocks have the following structure: * `virtual_name` - (Required) A name for the ephemeral device, of the form "ephemeralN" where *N* is a volume number starting from zero. +### Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `create` - (Defaults to 40 mins) Used when creating the AMI +* `update` - (Defaults to 40 mins) Used when updating the AMI +* `delete` - (Defaults to 90 mins) Used when deregistering the AMI + ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/ami_copy.html.markdown b/website/docs/r/ami_copy.html.markdown index 67db233f0695..e29561fbb13c 100644 --- a/website/docs/r/ami_copy.html.markdown +++ b/website/docs/r/ami_copy.html.markdown @@ -49,6 +49,14 @@ The following arguments are supported: This resource also exposes the full set of arguments from the [`aws_ami`](ami.html) resource. +### Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `create` - (Defaults to 40 mins) Used when creating the AMI +* `update` - (Defaults to 40 mins) Used when updating the AMI +* `delete` - (Defaults to 90 mins) Used when deregistering the AMI + ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/ami_from_instance.html.markdown b/website/docs/r/ami_from_instance.html.markdown index 806cc3b3e905..d99312b2f127 100644 --- a/website/docs/r/ami_from_instance.html.markdown +++ b/website/docs/r/ami_from_instance.html.markdown @@ -46,6 +46,14 @@ The following arguments are supported: inconsistent filesystem state, but can be used to avoid downtime if the user otherwise guarantees that no filesystem writes will be underway at the time of snapshot. +### Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `create` - (Defaults to 40 mins) Used when creating the AMI +* `update` - (Defaults to 40 mins) Used when updating the AMI +* `delete` - (Defaults to 90 mins) Used when deregistering the AMI + ## Attributes Reference The following attributes are exported: From abe5d7682ff8872989af17014f7a184dfa79bc51 Mon Sep 17 00:00:00 2001 From: Julian Mehnle Date: Thu, 5 Oct 2017 15:52:06 +0000 Subject: [PATCH 2/2] r/aws_{ami,ami_copy,ami_from_instance}: Configurable timeouts: pass timeout directly rather than entire `ResourceData`. --- aws/resource_aws_ami.go | 14 +++++++------- aws/resource_aws_ami_copy.go | 2 +- aws/resource_aws_ami_from_instance.go | 2 +- aws/resource_aws_ami_launch_permission_test.go | 4 +--- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/aws/resource_aws_ami.go b/aws/resource_aws_ami.go index 1a1ae0d5d59e..7de68b511bd5 100644 --- a/aws/resource_aws_ami.go +++ b/aws/resource_aws_ami.go @@ -123,7 +123,7 @@ func resourceAwsAmiCreate(d *schema.ResourceData, meta interface{}) error { d.SetPartial("manage_ebs_block_devices") d.Partial(false) - _, err = resourceAwsAmiWaitForAvailable(d, id, client) + _, err = resourceAwsAmiWaitForAvailable(d.Timeout(schema.TimeoutCreate), id, client) if err != nil { return err } @@ -176,7 +176,7 @@ func resourceAwsAmiRead(d *schema.ResourceData, meta interface{}) error { // before we continue. We should never take this branch in normal // circumstances since we would've waited for availability during // the "Create" step. - image, err = resourceAwsAmiWaitForAvailable(d, id, client) + image, err = resourceAwsAmiWaitForAvailable(d.Timeout(schema.TimeoutCreate), id, client) if err != nil { return err } @@ -308,7 +308,7 @@ func resourceAwsAmiDelete(d *schema.ResourceData, meta interface{}) error { } // Verify that the image is actually removed, if not we need to wait for it to be removed - if err := resourceAwsAmiWaitForDestroy(d, d.Id(), client); err != nil { + if err := resourceAwsAmiWaitForDestroy(d.Timeout(schema.TimeoutDelete), d.Id(), client); err != nil { return err } @@ -341,14 +341,14 @@ func AMIStateRefreshFunc(client *ec2.EC2, id string) resource.StateRefreshFunc { } } -func resourceAwsAmiWaitForDestroy(d *schema.ResourceData, id string, client *ec2.EC2) error { +func resourceAwsAmiWaitForDestroy(timeout time.Duration, id string, client *ec2.EC2) error { log.Printf("Waiting for AMI %s to be deleted...", id) stateConf := &resource.StateChangeConf{ Pending: []string{"available", "pending", "failed"}, Target: []string{"destroyed"}, Refresh: AMIStateRefreshFunc(client, id), - Timeout: d.Timeout(schema.TimeoutDelete), + Timeout: timeout, Delay: AWSAMIRetryDelay, MinTimeout: AWSAMIRetryMinTimeout, } @@ -361,14 +361,14 @@ func resourceAwsAmiWaitForDestroy(d *schema.ResourceData, id string, client *ec2 return nil } -func resourceAwsAmiWaitForAvailable(d *schema.ResourceData, id string, client *ec2.EC2) (*ec2.Image, error) { +func resourceAwsAmiWaitForAvailable(timeout time.Duration, id string, client *ec2.EC2) (*ec2.Image, error) { log.Printf("Waiting for AMI %s to become available...", id) stateConf := &resource.StateChangeConf{ Pending: []string{"pending"}, Target: []string{"available"}, Refresh: AMIStateRefreshFunc(client, id), - Timeout: d.Timeout(schema.TimeoutCreate), + Timeout: timeout, Delay: AWSAMIRetryDelay, MinTimeout: AWSAMIRetryMinTimeout, } diff --git a/aws/resource_aws_ami_copy.go b/aws/resource_aws_ami_copy.go index 14c18059ce81..71db0b75fc9c 100644 --- a/aws/resource_aws_ami_copy.go +++ b/aws/resource_aws_ami_copy.go @@ -87,7 +87,7 @@ func resourceAwsAmiCopyCreate(d *schema.ResourceData, meta interface{}) error { d.SetPartial("manage_ebs_snapshots") d.Partial(false) - _, err = resourceAwsAmiWaitForAvailable(d, id, client) + _, err = resourceAwsAmiWaitForAvailable(d.Timeout(schema.TimeoutCreate), id, client) if err != nil { return err } diff --git a/aws/resource_aws_ami_from_instance.go b/aws/resource_aws_ami_from_instance.go index ccf85ce11a1f..9a1b88223f65 100644 --- a/aws/resource_aws_ami_from_instance.go +++ b/aws/resource_aws_ami_from_instance.go @@ -67,7 +67,7 @@ func resourceAwsAmiFromInstanceCreate(d *schema.ResourceData, meta interface{}) d.SetPartial("manage_ebs_snapshots") d.Partial(false) - _, err = resourceAwsAmiWaitForAvailable(d, id, client) + _, err = resourceAwsAmiWaitForAvailable(d.Timeout(schema.TimeoutCreate), id, client) if err != nil { return err } diff --git a/aws/resource_aws_ami_launch_permission_test.go b/aws/resource_aws_ami_launch_permission_test.go index 24ccedcb3b8b..23de0c66f9d0 100644 --- a/aws/resource_aws_ami_launch_permission_test.go +++ b/aws/resource_aws_ami_launch_permission_test.go @@ -117,9 +117,7 @@ func testAccAWSAMIDisappears(imageID *string) r.TestCheckFunc { return err } - r := resourceAwsAmiLaunchPermission() // dummy resource - d := r.TestResourceData() - if err := resourceAwsAmiWaitForDestroy(d, *imageID, conn); err != nil { + if err := resourceAwsAmiWaitForDestroy(AWSAMIDeleteRetryTimeout, *imageID, conn); err != nil { return err } return nil