hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.84k stars 9.19k forks source link

Cannot remove function + attached resolver #15480

Open andrewp-sf opened 4 years ago

andrewp-sf commented 4 years ago

Community Note

Terraform CLI and Terraform AWS Provider Version

Terraform v0.12.28 AWS provider v2.70.0

Affected Resource(s)

Description

Terraform correctly creates above resources and sets up implicit dependency from resolver to function, when pipeline_config is created. However due to AWS limitations of this relation, destroying those two resources at same run/deployment is resulting in a failure. Before there are comments of 'did you try on 0.13' - no I haven't, that's a luxury I can't afford at this moment as infrastructure that I'm working on is big and mature, we have upgrade in roadmap but not anytime soon.

I'm looking for a solution or a workaround that will solve this, or at least will be solved once we upgrade.

Terraform Configuration Files

Note: incomplete and dummy part of code, but should give an idea of a problem

resource "aws_appsync_resolver" "dummy_resolver" {
  kind              = "PIPELINE"
  api_id            = aws_appsync_graphql_api.dummy.id
  field             = "dummyField"
  type              = "Query"
  request_template  = "SOME_TEMPLATE"
  response_template = "SOME_TEMPLATE"
  depends_on = [
    aws_appsync_graphql_api.dummy,
  ]
  pipeline_config {
    functions = [
      "${aws_appsync_function.dummy.function_id}"
    ]
  }
}

resource "aws_appsync_function" "dummy" {
  api_id                    = aws_appsync_graphql_api.dummy.id
  data_source               = aws_appsync_datasource.dummy.name
  name                      = "dummyField"
  request_mapping_template  = "SOME_TEMPLATE"
  response_mapping_template = "SOME_TEMPLATE"
}

resource "aws_appsync_datasource" "dummy" {
  api_id = aws_appsync_graphql_api.dummy.id
  name   = "dummy_datasource"
  type   = "NONE"
}

Panic Output

Error: Error deleting AppSync Function .....: BadRequestException: Cannot delete a function which is currently used by a resolver. Resolver type: Query, field: ....

Error: BadRequestException: Data source is still in use by functions: [....]

Expected Behavior

There has to be reversed dependency when it comes to destroying/updating. Resolver MUST be updated/removed before function, this is AWS requirement. On creation however it stays as it is right now, function has to be created before it is attached to resolver.

Actual Behavior

Because of implicit dependency, on destroy function is deleted first, and it can't as it's attached to resolver configuration. Adding explicit dependency results in cycle error.

Steps to Reproduce

Create any resolver and function in pipeline_config setup, then remove them from hcl code and run terraform to destroy them.

ewoelfel commented 2 years ago

I guess this is more an aws issue than a terraform one (see: https://github.com/aws/aws-appsync-community/issues/146)

klaucode commented 1 year ago

Is it something new according this issue? We have a same error msg., when TF apply, then rename some function, which is linked to resolver and then TF apply again.

tested on TF 1.3.4 with aws prov. 4.38.0, 1.3.7 with 4.49.0 and alpha1.4.0 20221207 with 4.49.0, still the same error

mleziva commented 3 months ago

I encountered a similar issue when changing a function data source and removing the previous referenced datasource in the same apply.

Error: deleting Appsync Data Source (widgsvnwtrddjihrjcvgsdfz4y-http_call): operation error AppSync: DeleteDataSource, https response error StatusCode: 400, RequestID: d5a1f331-e48f-47e2-9416-f32719315436, BadRequestException: Data source is still in use by functions: [lknmme342nbd7iy33xz4xkpld4]

Example:

Existing resources:
Data source a
Function a (using data source a)

Proposed changes:
data source a (remove)
data source b (create)
function a (remove data source a and use data source b)

Error: Data source a is attempted to be removed before the function is updated and cannot be removed because it is still in use

To fix this, I added the create_before_destroy lifecycle argument so that the function is updated before dependent resources are destroyed