Skip to content

Commit

Permalink
resource/aws_subnet: Handle read-after-create eventual consistency (#…
Browse files Browse the repository at this point in the history
…18392)

* resource/aws_subnet: Handle read-after-create eventual consistency

Reference: #12829
Reference: #16796

Output from acceptance testing in AWS Commercial:

```
--- PASS: TestAccAWSSubnet_availabilityZoneId (53.74s)
--- PASS: TestAccAWSSubnet_basic (52.50s)
--- PASS: TestAccAWSSubnet_defaultAndIgnoreTags (80.26s)
--- PASS: TestAccAWSSubnet_defaultTags_providerAndResource_duplicateTag (6.45s)
--- PASS: TestAccAWSSubnet_defaultTags_providerAndResource_nonOverlappingTag (84.84s)
--- PASS: TestAccAWSSubnet_defaultTags_providerAndResource_overlappingTag (86.61s)
--- PASS: TestAccAWSSubnet_defaultTags_providerOnly (87.99s)
--- PASS: TestAccAWSSubnet_defaultTags_updateToProviderOnly (69.48s)
--- PASS: TestAccAWSSubnet_defaultTags_updateToResourceOnly (72.12s)
--- PASS: TestAccAWSSubnet_disappears (41.08s)
--- PASS: TestAccAWSSubnet_enableIpv6 (109.36s)
--- PASS: TestAccAWSSubnet_ignoreTags (81.13s)
--- PASS: TestAccAWSSubnet_ipv6 (118.69s)
--- PASS: TestAccAWSSubnet_MapPublicIpOnLaunch (118.55s)
--- PASS: TestAccAWSSubnet_tags (106.25s)
--- SKIP: TestAccAWSSubnet_CustomerOwnedIpv4Pool (1.44s)
--- SKIP: TestAccAWSSubnet_MapCustomerOwnedIpOnLaunch (1.40s)
--- SKIP: TestAccAWSSubnet_outpost (1.70s)
```

Output from acceptance testing in AWS GovCloud (US):

```
--- PASS: TestAccAWSSubnet_availabilityZoneId (55.41s)
--- PASS: TestAccAWSSubnet_basic (55.46s)
--- PASS: TestAccAWSSubnet_defaultAndIgnoreTags (85.95s)
--- PASS: TestAccAWSSubnet_defaultTags_providerAndResource_duplicateTag (6.64s)
--- PASS: TestAccAWSSubnet_defaultTags_providerAndResource_nonOverlappingTag (82.23s)
--- PASS: TestAccAWSSubnet_defaultTags_providerAndResource_overlappingTag (84.95s)
--- PASS: TestAccAWSSubnet_defaultTags_providerOnly (86.26s)
--- PASS: TestAccAWSSubnet_defaultTags_updateToProviderOnly (69.05s)
--- PASS: TestAccAWSSubnet_defaultTags_updateToResourceOnly (73.74s)
--- PASS: TestAccAWSSubnet_disappears (42.78s)
--- PASS: TestAccAWSSubnet_enableIpv6 (117.40s)
--- PASS: TestAccAWSSubnet_ignoreTags (83.74s)
--- PASS: TestAccAWSSubnet_ipv6 (126.25s)
--- PASS: TestAccAWSSubnet_MapPublicIpOnLaunch (124.27s)
--- PASS: TestAccAWSSubnet_tags (115.31s)
--- SKIP: TestAccAWSSubnet_CustomerOwnedIpv4Pool (6.95s)
--- SKIP: TestAccAWSSubnet_MapCustomerOwnedIpOnLaunch (2.60s)
--- SKIP: TestAccAWSSubnet_outpost (2.14s)
```

* Update CHANGELOG for #18392
  • Loading branch information
bflad committed Mar 25, 2021
1 parent 12912ee commit 0016fc8
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
3 changes: 3 additions & 0 deletions .changelog/18392.txt
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_subnet: Handle EC2 eventual consistency errors on creation
```
1 change: 1 addition & 0 deletions aws/internal/service/ec2/waiter/waiter.go
Expand Up @@ -270,6 +270,7 @@ func SecurityGroupCreated(conn *ec2.EC2, id string, timeout time.Duration) (*ec2
}

const (
SubnetPropagationTimeout = 2 * time.Minute
SubnetAttributePropagationTimeout = 5 * time.Minute
)

Expand Down
55 changes: 44 additions & 11 deletions aws/resource_aws_subnet.go
Expand Up @@ -7,10 +7,13 @@ import (

"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/keyvaluetags"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/finder"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/waiter"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

func resourceAwsSubnet() *schema.Resource {
Expand Down Expand Up @@ -232,23 +235,53 @@ func resourceAwsSubnetRead(d *schema.ResourceData, meta interface{}) error {
defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig
ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

resp, err := conn.DescribeSubnets(&ec2.DescribeSubnetsInput{
SubnetIds: []*string{aws.String(d.Id())},
})
var subnet *ec2.Subnet

if err != nil {
if isAWSErr(err, "InvalidSubnetID.NotFound", "") {
log.Printf("[WARN] Subnet (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
err := resource.Retry(waiter.SubnetPropagationTimeout, func() *resource.RetryError {
var err error

subnet, err = finder.SubnetByID(conn, d.Id())

if d.IsNewResource() && tfawserr.ErrCodeEquals(err, "InvalidSubnetID.NotFound") {
return resource.RetryableError(err)
}
return err

if err != nil {
return resource.NonRetryableError(err)
}

if d.IsNewResource() && subnet == nil {
return resource.RetryableError(&resource.NotFoundError{
LastError: fmt.Errorf("EC2 Subnet (%s) not found", d.Id()),
})
}

return nil
})

if tfresource.TimedOut(err) {
subnet, err = finder.SubnetByID(conn, d.Id())
}
if resp == nil {

if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, "InvalidSubnetID.NotFound") {
log.Printf("[WARN] EC2 Subnet (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

subnet := resp.Subnets[0]
if err != nil {
return fmt.Errorf("error reading EC2 Subnet (%s): %w", d.Id(), err)
}

if subnet == nil {
if d.IsNewResource() {
return fmt.Errorf("error reading EC2 Subnet (%s): not found after creation", d.Id())
}

log.Printf("[WARN] EC2 Subnet (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

d.Set("vpc_id", subnet.VpcId)
d.Set("availability_zone", subnet.AvailabilityZone)
Expand Down

0 comments on commit 0016fc8

Please sign in to comment.