Skip to content
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

resource/aws_api_gateway_deployment: Do not delete stages in use by other deployments #3896

Merged
merged 2 commits into from
Oct 2, 2018

Conversation

mdlavin
Copy link
Contributor

@mdlavin mdlavin commented Mar 23, 2018

When a deployment has been updated in a way that forces a create/delete, the newly deployed deployment can be left in a bad state. Here how the code used to work:

  1. A new deployment is created that points to stage 'test'
  2. The old deployment is marked for deletion and was associated with 'test'
  3. The 'test' stage is deleted
  4. The deposed deployment is deleted
  5. The new deployment is now pointing at a stage that does not exist

Here is how the code works now:

  1. A new deployment is created that points to stage 'test'
  2. The old deployment is marked for deletion and was associated with 'test'
  3. The 'test' stage is not deleted because it is no longer associated with the deposed deployment
  4. The deposed deployment is deleted
  5. The new deployment is still happy =)

@ghost ghost added the size/L Managed by automation to categorize the size of a PR. label Mar 23, 2018
@bflad bflad added bug Addresses a defect in current functionality. service/apigateway Issues and PRs that pertain to the apigateway service. labels Mar 23, 2018
@mdlavin
Copy link
Contributor Author

mdlavin commented May 31, 2018

I just double checked and this PR still cleanly applies to master and passes the tests. Any chance of a merge soon before a conflict appears?

@mdlavin
Copy link
Contributor Author

mdlavin commented Jun 1, 2018

If anybody is interested in testing out this feature in a patched v1.21.0 version, I've made some Alpine Linux x64 binaries available here: https://github.com/lifeomic/terraform-provider-aws/releases/tag/v1.21.0_patched_5f7d0def

@mdlavin
Copy link
Contributor Author

mdlavin commented Sep 7, 2018

@bflad is there anything I can do to help this get merged into an official release?

@mdlavin
Copy link
Contributor Author

mdlavin commented Sep 13, 2018

If anybody is interested in testing out this feature in a patched v1.36.0 version, I've made some Alpine Linux x64 binaries available here: https://github.com/lifeomic/terraform-provider-aws/releases/tag/v1.36.0_patched_f2d0f833c

@bflad
Copy link
Contributor

bflad commented Sep 13, 2018

At first glance, I believe this change seems appropriate. We don't have too much precedent of resources that create other unmanaged resources though. 😅

More forward looking: I am not convinced that we should allow the deployment resource to create stages at all (and hence delete them too), as it leaves Terraform management in a precarious state with unmanaged resources or resources that need to be imported. Unfortunately, I do not believe the API Gateway API provides any mechanism to prevent this behavior beyond only sending the deployment to the "default" stage.

Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial comments below -- please reach out with any questions!

return nil
})
if err != nil {
return resource.RetryableError(err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few notes:

  • It seems like we should not retry on errors calling GetStage, especially any error
  • As its fairly unexpected that the deletion of a resource is requiring a read call to begin with, we should also return a helpful message here, e.g. return fmt.Errorf("error getting referenced stage: %s", err)
  • Seems like we should skip deleting the stage if its not found, instead of returning the stage not found error

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll make the changes you suggest

// If the stage has been updated to point at a different deployment, then
// the stage should not be removed then this deployment is deleted.
var shouldDeleteStage = true
if *stage.DeploymentId != d.Id() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To prevent potential panics, this should perform a nil check and use the SDK helper function for the string value:

if stage == nil || aws.StringValue(stage.DeploymentId) != d.Id() {
  shouldDeleteState = false
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I'll make that change

return func(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).apigateway

restApiId := aws.String(s.RootModule().Resources["aws_api_gateway_rest_api.test"].Primary.ID)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: Instead of hardcoding this reference, we should prefer to pass into the function (any of these):

  • The REST API resource name
  • The actual apigateway.RestApi object (e.g. from testAccCheckAWSAPIGatewayRestAPIExists())
  • The deployment resource name, then reference its rest_api_id attribute

Personally, I'd go with the last option since this is explicitly named with Deployment. 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll see how hard the last bullet is. Seems like a good approach to me

@ghost ghost added size/L Managed by automation to categorize the size of a PR. service/apigateway Issues and PRs that pertain to the apigateway service. tests PRs: expanded test coverage. Issues: expanded coverage, enhancements to test infrastructure. labels Sep 18, 2018
@mdlavin
Copy link
Contributor Author

mdlavin commented Sep 18, 2018

@bflad I believe that I have addressed all of your feedback. Let me know if there is anything else I should change.

Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mdlavin 🚀 Two non-blocking nits (which I'll fix on merge), but otherwise LGTM.

--- PASS: TestAccAWSAPIGatewayDeployment_basic (5.56s)
--- PASS: TestAccAWSAPIGatewayDeployment_createBeforeDestoryUpdate (40.73s)

restApiId := aws.String(deploymentResource.Primary.Attributes["rest_api_id"])

req := &apigateway.GetStageInput{
StageName: &stageName,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: the stage name can be fetched from attributes as well (deploymentResource.Primary.Attributes["stage_name"]) instead of a parameter passed in from the acceptance test

if err != nil {
// If the stage is already deleted then there is no need to attempt deletion
apigatewayErr, _ := err.(awserr.Error)
if apigatewayErr.Code() == "NotFoundException" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: we have a helper function for this type of logic and prefer the AWS Go SDK constants, e.g. isAWSErr(err, apigateway.ErrCodeNotFoundException, "")

@bflad bflad added this to the v1.39.0 milestone Oct 2, 2018
@bflad bflad merged commit f9829c3 into hashicorp:master Oct 2, 2018
bflad added a commit that referenced this pull request Oct 2, 2018
bflad added a commit that referenced this pull request Oct 2, 2018
```
--- PASS: TestAccAWSAPIGatewayDeployment_basic (20.41s)
--- PASS: TestAccAWSAPIGatewayDeployment_createBeforeDestoryUpdate (33.28s)
```
@ghost
Copy link

ghost commented Apr 3, 2020

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.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@ghost ghost locked and limited conversation to collaborators Apr 3, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Addresses a defect in current functionality. service/apigateway Issues and PRs that pertain to the apigateway service. size/L Managed by automation to categorize the size of a PR. tests PRs: expanded test coverage. Issues: expanded coverage, enhancements to test infrastructure.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants