diff --git a/aws/internal/service/ec2/finder/finder.go b/aws/internal/service/ec2/finder/finder.go index 5d00fb05322..8754c22f2e0 100644 --- a/aws/internal/service/ec2/finder/finder.go +++ b/aws/internal/service/ec2/finder/finder.go @@ -5,6 +5,8 @@ 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" tfnet "github.com/terraform-providers/terraform-provider-aws/aws/internal/net" tfec2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2" ) @@ -97,31 +99,46 @@ func InstanceByID(conn *ec2.EC2, id string) (*ec2.Instance, error) { } // RouteTableByID returns the route table corresponding to the specified identifier. -// Returns nil if no route table is found. +// Returns NotFoundError if no route table is found. func RouteTableByID(conn *ec2.EC2, routeTableID string) (*ec2.RouteTable, error) { input := &ec2.DescribeRouteTablesInput{ RouteTableIds: aws.StringSlice([]string{routeTableID}), } + return RouteTable(conn, input) +} + +func RouteTable(conn *ec2.EC2, input *ec2.DescribeRouteTablesInput) (*ec2.RouteTable, error) { output, err := conn.DescribeRouteTables(input) + if tfawserr.ErrCodeEquals(err, tfec2.ErrCodeInvalidRouteTableIDNotFound) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + if err != nil { return nil, err } - if output == nil || len(output.RouteTables) == 0 { - return nil, nil + if output == nil || len(output.RouteTables) == 0 || output.RouteTables[0] == nil { + return nil, &resource.NotFoundError{ + Message: "Empty result", + LastRequest: input, + LastResponse: output, + } } return output.RouteTables[0], nil } // RouteFinder returns the route corresponding to the specified destination. -// Returns nil if no route is found. +// Returns NotFoundError if no route is found. type RouteFinder func(*ec2.EC2, string, string) (*ec2.Route, error) // RouteByIPv4Destination returns the route corresponding to the specified IPv4 destination. -// Returns nil if no route is found. +// Returns NotFoundError if no route is found. func RouteByIPv4Destination(conn *ec2.EC2, routeTableID, destinationCidr string) (*ec2.Route, error) { routeTable, err := RouteTableByID(conn, routeTableID) if err != nil { @@ -134,11 +151,11 @@ func RouteByIPv4Destination(conn *ec2.EC2, routeTableID, destinationCidr string) } } - return nil, nil + return nil, &resource.NotFoundError{} } // RouteByIPv6Destination returns the route corresponding to the specified IPv6 destination. -// Returns nil if no route is found. +// Returns NotFoundError if no route is found. func RouteByIPv6Destination(conn *ec2.EC2, routeTableID, destinationIpv6Cidr string) (*ec2.Route, error) { routeTable, err := RouteTableByID(conn, routeTableID) if err != nil { @@ -151,7 +168,7 @@ func RouteByIPv6Destination(conn *ec2.EC2, routeTableID, destinationIpv6Cidr str } } - return nil, nil + return nil, &resource.NotFoundError{} } // SecurityGroupByID looks up a security group by ID. When not found, returns nil and potentially an API error. diff --git a/aws/resource_aws_route.go b/aws/resource_aws_route.go index 325f2314b9e..f319ce3a125 100644 --- a/aws/resource_aws_route.go +++ b/aws/resource_aws_route.go @@ -252,16 +252,14 @@ func resourceAwsRouteCreate(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error creating Route for Route Table (%s) with destination (%s): %w", routeTableID, destination, err) } - var route *ec2.Route - err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { - route, err = routeFinder(conn, routeTableID, destination) + _, err = routeFinder(conn, routeTableID, destination) if err != nil { return resource.RetryableError(err) } - if route == nil { + if tfresource.NotFound(err) { return resource.RetryableError(fmt.Errorf("route not found")) } @@ -269,14 +267,14 @@ func resourceAwsRouteCreate(d *schema.ResourceData, meta interface{}) error { }) if tfresource.TimedOut(err) { - route, err = routeFinder(conn, routeTableID, destination) + _, err = routeFinder(conn, routeTableID, destination) } if err != nil { return fmt.Errorf("error reading Route for Route Table (%s) with destination (%s): %w", routeTableID, destination, err) } - if route == nil { + if tfresource.NotFound(err) { return fmt.Errorf("Route in Route Table (%s) with destination (%s) not found", routeTableID, destination) } @@ -309,8 +307,8 @@ func resourceAwsRouteRead(d *schema.ResourceData, meta interface{}) error { route, err := routeFinder(conn, routeTableID, destination) - if tfawserr.ErrCodeEquals(err, tfec2.ErrCodeInvalidRouteTableIDNotFound) { - log.Printf("[WARN] Route Table (%s) not found, removing from state", routeTableID) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Route in Route Table (%s) with destination (%s) not found, removing from state", routeTableID, destination) d.SetId("") return nil } @@ -319,12 +317,6 @@ func resourceAwsRouteRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error reading Route for Route Table (%s) with destination (%s): %w", routeTableID, destination, err) } - if route == nil { - log.Printf("[WARN] Route in Route Table (%s) with destination (%s) not found, removing from state", routeTableID, destination) - d.SetId("") - return nil - } - d.Set("destination_cidr_block", route.DestinationCidrBlock) d.Set("destination_ipv6_cidr_block", route.DestinationIpv6CidrBlock) d.Set("destination_prefix_list_id", route.DestinationPrefixListId)