From 7a94534716d0dbe1d6000cd14a6d3ad17b72ca2a Mon Sep 17 00:00:00 2001 From: Khiem Do Date: Thu, 17 Dec 2020 10:54:42 +0700 Subject: [PATCH 1/2] resource/aws_eip_association: fix eventual consistency issue when associating EIP --- aws/resource_aws_eip_association.go | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_eip_association.go b/aws/resource_aws_eip_association.go index 01cc47aba138..b10b7c79c74b 100644 --- a/aws/resource_aws_eip_association.go +++ b/aws/resource_aws_eip_association.go @@ -157,7 +157,30 @@ func resourceAwsEipAssociationRead(d *schema.ResourceData, meta interface{}) err return err } - response, err := conn.DescribeAddresses(request) + var response *ec2.DescribeAddressesOutput + err = resource.Retry(2*time.Minute, func() *resource.RetryError { + var err error + response, err = conn.DescribeAddresses(request) + + if tfawserr.ErrCodeEquals(err, "InvalidAssociationID.NotFound") { + return resource.RetryableError(err) + } + + if d.IsNewResource() && (response.Addresses == nil || len(response.Addresses) == 0) { + return resource.RetryableError(&resource.NotFoundError{}) + } + + if err != nil { + return resource.NonRetryableError(err) + } + + return nil + }) + + if isResourceTimeoutError(err) { + response, err = conn.DescribeAddresses(request) + } + if err != nil { return fmt.Errorf("Error reading EC2 Elastic IP %s: %#v", d.Get("allocation_id").(string), err) } From 84b090e97615d52f5833f95e2a20df27d5b88eac Mon Sep 17 00:00:00 2001 From: Khiem Do Date: Fri, 18 Dec 2020 10:33:54 +0700 Subject: [PATCH 2/2] Update aws_eip_association for eventual consistency issue + add EC2 general PropagationTimeout --- aws/internal/service/ec2/waiter/waiter.go | 3 +++ aws/resource_aws_eip_association.go | 14 ++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/aws/internal/service/ec2/waiter/waiter.go b/aws/internal/service/ec2/waiter/waiter.go index 08dc760bd27f..e912e908b3db 100644 --- a/aws/internal/service/ec2/waiter/waiter.go +++ b/aws/internal/service/ec2/waiter/waiter.go @@ -11,6 +11,9 @@ import ( const ( // Maximum amount of time to wait for EC2 Instance attribute modifications to propagate InstanceAttributePropagationTimeout = 2 * time.Minute + + // General timeout for EC2 resource creations to propagate + PropagationTimeout = 2 * time.Minute ) const ( diff --git a/aws/resource_aws_eip_association.go b/aws/resource_aws_eip_association.go index b10b7c79c74b..9496721b7095 100644 --- a/aws/resource_aws_eip_association.go +++ b/aws/resource_aws_eip_association.go @@ -4,13 +4,13 @@ import ( "fmt" "log" "net" - "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/waiter" ) func resourceAwsEipAssociation() *schema.Resource { @@ -94,7 +94,7 @@ func resourceAwsEipAssociationCreate(d *schema.ResourceData, meta interface{}) e log.Printf("[DEBUG] EIP association configuration: %#v", request) var resp *ec2.AssociateAddressOutput - err := resource.Retry(2*time.Minute, func() *resource.RetryError { + err := resource.Retry(waiter.PropagationTimeout, func() *resource.RetryError { var err error resp, err = conn.AssociateAddress(request) @@ -158,11 +158,11 @@ func resourceAwsEipAssociationRead(d *schema.ResourceData, meta interface{}) err } var response *ec2.DescribeAddressesOutput - err = resource.Retry(2*time.Minute, func() *resource.RetryError { + err = resource.Retry(waiter.PropagationTimeout, func() *resource.RetryError { var err error response, err = conn.DescribeAddresses(request) - if tfawserr.ErrCodeEquals(err, "InvalidAssociationID.NotFound") { + if d.IsNewResource() && tfawserr.ErrCodeEquals(err, "InvalidAssociationID.NotFound") { return resource.RetryableError(err) } @@ -181,6 +181,12 @@ func resourceAwsEipAssociationRead(d *schema.ResourceData, meta interface{}) err response, err = conn.DescribeAddresses(request) } + if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, "InvalidAssociationID.NotFound") { + log.Printf("[WARN] EIP Association (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + if err != nil { return fmt.Errorf("Error reading EC2 Elastic IP %s: %#v", d.Get("allocation_id").(string), err) }