-
Notifications
You must be signed in to change notification settings - Fork 9.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PLACEHOLDER] Consistent Resource Not Found Error Handling #15945
Comments
…ssing Hosted Zone or VPC association Reference: #15945 Reference: #17016 Reference: https://docs.aws.amazon.com/Route53/latest/APIReference/API_DisassociateVPCFromHostedZone.html#API_DisassociateVPCFromHostedZone_Errors This is a best effort fix for the errors returned by the Route 53 `DisassociateVPCFromHostedZone` API, which are unrelated to the potential errors during the `Read` function that uses the `ListHostedZonesByVPC` API. The acceptance testing framework does not lend itself well to testing this situation and this highlights a case where #15945 would need special handling. Output from acceptance testing in AWS Commercial: ``` --- PASS: TestAccAWSRoute53ZoneAssociation_disappears_Zone (146.44s) --- PASS: TestAccAWSRoute53ZoneAssociation_disappears (147.22s) --- PASS: TestAccAWSRoute53ZoneAssociation_disappears_VPC (147.31s) --- PASS: TestAccAWSRoute53ZoneAssociation_CrossRegion (149.84s) --- PASS: TestAccAWSRoute53ZoneAssociation_basic (150.01s) --- PASS: TestAccAWSRoute53ZoneAssociation_CrossAccount (507.91s) ```
…ssing Hosted Zone or VPC association (#17023) Reference: #15945 Reference: #17016 Reference: https://docs.aws.amazon.com/Route53/latest/APIReference/API_DisassociateVPCFromHostedZone.html#API_DisassociateVPCFromHostedZone_Errors This is a best effort fix for the errors returned by the Route 53 `DisassociateVPCFromHostedZone` API, which are unrelated to the potential errors during the `Read` function that uses the `ListHostedZonesByVPC` API. The acceptance testing framework does not lend itself well to testing this situation and this highlights a case where #15945 would need special handling. Output from acceptance testing in AWS Commercial: ``` --- PASS: TestAccAWSRoute53ZoneAssociation_disappears_Zone (146.44s) --- PASS: TestAccAWSRoute53ZoneAssociation_disappears (147.22s) --- PASS: TestAccAWSRoute53ZoneAssociation_disappears_VPC (147.31s) --- PASS: TestAccAWSRoute53ZoneAssociation_CrossRegion (149.84s) --- PASS: TestAccAWSRoute53ZoneAssociation_basic (150.01s) --- PASS: TestAccAWSRoute53ZoneAssociation_CrossAccount (507.91s) ```
…und (hashicorp#15945). r/aws_route: Implement 'd.IsNewResource()' checksin 'resourceAwsRouteRead' (hashicorp#16796). Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSRoute_basic\|TestAccAWSRoute_disappears' ACCTEST_PARALLELISM=2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 2 -run=TestAccAWSRoute_basic\|TestAccAWSRoute_disappears -timeout 120m === RUN TestAccAWSRoute_basic === PAUSE TestAccAWSRoute_basic === RUN TestAccAWSRoute_disappears === PAUSE TestAccAWSRoute_disappears === RUN TestAccAWSRoute_disappears_RouteTable === PAUSE TestAccAWSRoute_disappears_RouteTable === CONT TestAccAWSRoute_basic === CONT TestAccAWSRoute_disappears_RouteTable --- PASS: TestAccAWSRoute_disappears_RouteTable (34.67s) === CONT TestAccAWSRoute_disappears --- PASS: TestAccAWSRoute_basic (36.39s) --- PASS: TestAccAWSRoute_disappears (31.85s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 66.620s
This comment has been minimized.
This comment has been minimized.
Some initial thoughts on what this could look like. Returning
|
Some conclusions and considerations from the initial thoughts above:
r := resourceAwsExampleThing()
d := r.Data(nil)
d.SetId(...)
err = r.Delete(d, client) form then there is usually only a single place that the resource deletion API method is called |
…f 'nil' when no application found (hashicorp#15945). r/aws_kinesis_analytics_application: Implement 'd.IsNewResource()' checks in 'resourceAwsKinesisAnalyticsApplicationRead' (hashicorp#16796). Acceptance test output: $ make testacc TEST=./aws/ TESTARGS='-run=TestAccAWSKinesisAnalyticsApplication_basic\|TestAccAWSKinesisAnalyticsApplication_disappears' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSKinesisAnalyticsApplication_basic\|TestAccAWSKinesisAnalyticsApplication_disappears -timeout 120m === RUN TestAccAWSKinesisAnalyticsApplication_basic === PAUSE TestAccAWSKinesisAnalyticsApplication_basic === RUN TestAccAWSKinesisAnalyticsApplication_disappears === PAUSE TestAccAWSKinesisAnalyticsApplication_disappears === CONT TestAccAWSKinesisAnalyticsApplication_basic === CONT TestAccAWSKinesisAnalyticsApplication_disappears --- PASS: TestAccAWSKinesisAnalyticsApplication_basic (15.29s) --- PASS: TestAccAWSKinesisAnalyticsApplication_disappears (18.26s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 18.344s
Testing the Resource Not Found error on resource deletion can be done by adding a second call to func TestAccAWSVpc_disappears(t *testing.T) {
var vpc ec2.Vpc
resourceName := "aws_vpc.test"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckVpcDestroy,
Steps: []resource.TestStep{
{
Config: testAccVpcConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckVpcExists(resourceName, &vpc),
testAccCheckResourceDisappears(testAccProvider, resourceAwsVpc(), resourceName),
// Deletion of deleted resource.
testAccCheckResourceDisappears(testAccProvider, resourceAwsVpc(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
} |
…und (hashicorp#15945). r/aws_route: Implement 'd.IsNewResource()' checksin 'resourceAwsRouteRead' (hashicorp#16796). Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSRoute_basic\|TestAccAWSRoute_disappears' ACCTEST_PARALLELISM=2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 2 -run=TestAccAWSRoute_basic\|TestAccAWSRoute_disappears -timeout 120m === RUN TestAccAWSRoute_basic === PAUSE TestAccAWSRoute_basic === RUN TestAccAWSRoute_disappears === PAUSE TestAccAWSRoute_disappears === RUN TestAccAWSRoute_disappears_RouteTable === PAUSE TestAccAWSRoute_disappears_RouteTable === CONT TestAccAWSRoute_basic === CONT TestAccAWSRoute_disappears_RouteTable --- PASS: TestAccAWSRoute_disappears_RouteTable (34.67s) === CONT TestAccAWSRoute_disappears --- PASS: TestAccAWSRoute_basic (36.39s) --- PASS: TestAccAWSRoute_disappears (31.85s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 66.620s
…of 'nil' when no application found (hashicorp#15945). Acceptance test output: $ make testacc TEST=./aws/ TESTARGS='-run=TestAccAWSKinesisAnalyticsV2Application_' ACCTEST_PARALLELISM=3 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 3 -run=TestAccAWSKinesisAnalyticsV2Application_ -timeout 120m === RUN TestAccAWSKinesisAnalyticsV2Application_basicFlinkApplication === PAUSE TestAccAWSKinesisAnalyticsV2Application_basicFlinkApplication === RUN TestAccAWSKinesisAnalyticsV2Application_basicSQLApplication === PAUSE TestAccAWSKinesisAnalyticsV2Application_basicSQLApplication === RUN TestAccAWSKinesisAnalyticsV2Application_disappears === PAUSE TestAccAWSKinesisAnalyticsV2Application_disappears === RUN TestAccAWSKinesisAnalyticsV2Application_Tags === PAUSE TestAccAWSKinesisAnalyticsV2Application_Tags === RUN TestAccAWSKinesisAnalyticsV2Application_ApplicationCodeConfiguration_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_ApplicationCodeConfiguration_Update === RUN TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Add === PAUSE TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Add === RUN TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Delete === PAUSE TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Delete === RUN TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Update === RUN TestAccAWSKinesisAnalyticsV2Application_EnvironmentProperties_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_EnvironmentProperties_Update === RUN TestAccAWSKinesisAnalyticsV2Application_FlinkApplicationConfiguration_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_FlinkApplicationConfiguration_Update === RUN TestAccAWSKinesisAnalyticsV2Application_FlinkApplicationConfiguration_EnvironmentProperties_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_FlinkApplicationConfiguration_EnvironmentProperties_Update === RUN TestAccAWSKinesisAnalyticsV2Application_ServiceExecutionRole_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_ServiceExecutionRole_Update === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Input_Add === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Input_Add === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Input_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Input_Update === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Add === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Add === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Delete === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Delete === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Update === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Multiple_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Multiple_Update === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Output_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Output_Update === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Add === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Add === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Delete === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Delete === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Update === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Add === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Add === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Delete === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Delete === RUN TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Update === PAUSE TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Update === CONT TestAccAWSKinesisAnalyticsV2Application_basicFlinkApplication === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Input_Update === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Update --- PASS: TestAccAWSKinesisAnalyticsV2Application_basicFlinkApplication (54.58s) === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Delete --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Update (74.66s) === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Add --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Input_Update (117.92s) === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Update --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Delete (67.58s) === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Delete --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_VPCConfiguration_Add (68.71s) === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Add --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Add (103.54s) === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Output_Update --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Delete (129.15s) === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Multiple_Update --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_ReferenceDataSource_Update (135.56s) === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Update --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Multiple_Update (108.99s) === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Delete --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Update (113.14s) === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Add --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Output_Update (126.17s) === CONT TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Update --- PASS: TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Update (41.51s) === CONT TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Input_Add --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Add (97.33s) === CONT TestAccAWSKinesisAnalyticsV2Application_ServiceExecutionRole_Update --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_InputProcessingConfiguration_Delete (106.22s) === CONT TestAccAWSKinesisAnalyticsV2Application_FlinkApplicationConfiguration_EnvironmentProperties_Update --- PASS: TestAccAWSKinesisAnalyticsV2Application_ServiceExecutionRole_Update (42.77s) === CONT TestAccAWSKinesisAnalyticsV2Application_FlinkApplicationConfiguration_Update --- PASS: TestAccAWSKinesisAnalyticsV2Application_FlinkApplicationConfiguration_EnvironmentProperties_Update (66.21s) === CONT TestAccAWSKinesisAnalyticsV2Application_EnvironmentProperties_Update --- PASS: TestAccAWSKinesisAnalyticsV2Application_SQLApplicationConfiguration_Input_Add (118.86s) === CONT TestAccAWSKinesisAnalyticsV2Application_ApplicationCodeConfiguration_Update --- PASS: TestAccAWSKinesisAnalyticsV2Application_ApplicationCodeConfiguration_Update (52.50s) === CONT TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Delete --- PASS: TestAccAWSKinesisAnalyticsV2Application_FlinkApplicationConfiguration_Update (80.04s) === CONT TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Add --- PASS: TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Delete (42.49s) === CONT TestAccAWSKinesisAnalyticsV2Application_disappears --- PASS: TestAccAWSKinesisAnalyticsV2Application_EnvironmentProperties_Update (103.32s) === CONT TestAccAWSKinesisAnalyticsV2Application_Tags --- PASS: TestAccAWSKinesisAnalyticsV2Application_CloudWatchLoggingOptions_Add (52.77s) === CONT TestAccAWSKinesisAnalyticsV2Application_basicSQLApplication --- PASS: TestAccAWSKinesisAnalyticsV2Application_disappears (35.36s) --- PASS: TestAccAWSKinesisAnalyticsV2Application_basicSQLApplication (36.17s) --- PASS: TestAccAWSKinesisAnalyticsV2Application_Tags (59.22s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 695.388s
Acceptance test output: % make testacc TEST=./aws TESTARGS='-run=TestAccAWSAmplifyApp_disappears' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAmplifyApp_disappears -timeout 180m === RUN TestAccAWSAmplifyApp_disappears === PAUSE TestAccAWSAmplifyApp_disappears === CONT TestAccAWSAmplifyApp_disappears --- PASS: TestAccAWSAmplifyApp_disappears (10.95s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 14.084s
Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label. If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you! |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. |
Community Note
Background
Placeholder Note: This issue contains details for a potential future project, but it has not been agreed upon in principle/design and is currently only here to track various issue/pull request references as they appear along with broad proposals.
The general goal behind this project would be to standardize resource error handling when the resource is not found. Resources today can use the following methodology for handling resource disappearance:
Read
function: Warning log (likely warning diagnostic in future), remove resource from state, return no errorDelete
function: Return no error (resource is already automatically removed from state)CheckDestroy
function: Continue resource checking loop (we got what we wanted already)While there are some efforts to implement disappears testing across the provider codebase, it is not consistent or necessarily enforced during reviews so it is easy to miss. Without disappears testing, there are higher chances of
Read
handling to be missing. Handling of these errors in theDelete
function are often missed because there is not an easy way in the Terraform Plugin SDK acceptance testing framework to trigger a deletion without refresh.CheckDestroy
handling is almost always implemented for at least some of the errors as the testing will not pass at all without it.Another challenge here is that there can be considerable "distance" between where the API/SDK call occurs and the resource code which would be checking for the resource not found error. For example, some resources use
finder
andwaiter
packages for delegating read or wait for removal API functionality in a more consistent (and potentially automatically generated in the future) method, while others have manually implemented similar but disparate equivalents in other resource functions. Especially for those custom implementations, some go through efforts toreturn nil
instead of resource not found errors. These types of inconsistencies should be smoothed over through this proposal.Proposal 1
Create a standard method for converting AWS Go SDK errors with specific error codes and messages to the Terraform Plugin SDK
helper/resource.NotFoundError
. We could then use static analysis to ensure this type of error is always handled in theRead
/Delete
/CheckDestroy
functions.Very roughly:
nil
) or wrapping it inresource.NotFoundError
††Read
,Delete
, andCheckDestroy
function, add a conditional withresource.NotFoundError
checking and remove any existing resource not found error checkingRead
,Delete
, andCheckDestroy
function contains a conditional withresource.NotFoundError
checking† Or implement a new "Terraform AWS Provider resource" type and this as a new receiver method -- although if this is remotely a path forward, then this should really be thought about in the context of the "service packages" project.
†† This can (should?) be further simplified into "provide a list of error checking functions that return a boolean" whether this should be wrapped. Very related to what would likely be good for #9223 as well.
Proposal 2
Always create wrapper functions for AWS Go SDK API calls and
return nil
for resource not found errors immediately after they occur.References
Related Efforts:
Related Issues:
The text was updated successfully, but these errors were encountered: