Skip to content

Commit 0016fc8

Browse files
authored
resource/aws_subnet: Handle read-after-create eventual consistency (#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
1 parent 12912ee commit 0016fc8

3 files changed

Lines changed: 48 additions & 11 deletions

File tree

.changelog/18392.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
resource/aws_subnet: Handle EC2 eventual consistency errors on creation
3+
```

aws/internal/service/ec2/waiter/waiter.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ func SecurityGroupCreated(conn *ec2.EC2, id string, timeout time.Duration) (*ec2
270270
}
271271

272272
const (
273+
SubnetPropagationTimeout = 2 * time.Minute
273274
SubnetAttributePropagationTimeout = 5 * time.Minute
274275
)
275276

aws/resource_aws_subnet.go

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ import (
77

88
"github.com/aws/aws-sdk-go/aws"
99
"github.com/aws/aws-sdk-go/service/ec2"
10+
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
1011
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1112
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1213
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
14+
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/finder"
1315
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/waiter"
16+
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
1417
)
1518

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

235-
resp, err := conn.DescribeSubnets(&ec2.DescribeSubnetsInput{
236-
SubnetIds: []*string{aws.String(d.Id())},
237-
})
238+
var subnet *ec2.Subnet
238239

239-
if err != nil {
240-
if isAWSErr(err, "InvalidSubnetID.NotFound", "") {
241-
log.Printf("[WARN] Subnet (%s) not found, removing from state", d.Id())
242-
d.SetId("")
243-
return nil
240+
err := resource.Retry(waiter.SubnetPropagationTimeout, func() *resource.RetryError {
241+
var err error
242+
243+
subnet, err = finder.SubnetByID(conn, d.Id())
244+
245+
if d.IsNewResource() && tfawserr.ErrCodeEquals(err, "InvalidSubnetID.NotFound") {
246+
return resource.RetryableError(err)
244247
}
245-
return err
248+
249+
if err != nil {
250+
return resource.NonRetryableError(err)
251+
}
252+
253+
if d.IsNewResource() && subnet == nil {
254+
return resource.RetryableError(&resource.NotFoundError{
255+
LastError: fmt.Errorf("EC2 Subnet (%s) not found", d.Id()),
256+
})
257+
}
258+
259+
return nil
260+
})
261+
262+
if tfresource.TimedOut(err) {
263+
subnet, err = finder.SubnetByID(conn, d.Id())
246264
}
247-
if resp == nil {
265+
266+
if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, "InvalidSubnetID.NotFound") {
267+
log.Printf("[WARN] EC2 Subnet (%s) not found, removing from state", d.Id())
268+
d.SetId("")
248269
return nil
249270
}
250271

251-
subnet := resp.Subnets[0]
272+
if err != nil {
273+
return fmt.Errorf("error reading EC2 Subnet (%s): %w", d.Id(), err)
274+
}
275+
276+
if subnet == nil {
277+
if d.IsNewResource() {
278+
return fmt.Errorf("error reading EC2 Subnet (%s): not found after creation", d.Id())
279+
}
280+
281+
log.Printf("[WARN] EC2 Subnet (%s) not found, removing from state", d.Id())
282+
d.SetId("")
283+
return nil
284+
}
252285

253286
d.Set("vpc_id", subnet.VpcId)
254287
d.Set("availability_zone", subnet.AvailabilityZone)

0 commit comments

Comments
 (0)