terraform-provider-aws: Terraform cannot destroy VPC Links to API Gateway because of a dependency issue
I’m trying to destroy an API Gateway application which has a VPC link and it’s constantly and consistently failing to do so and I’m unable to automate this in a way which consistently functions. It appears that terraform doesn’t know how to destroy these resources.
Terraform version: v0.12.8 AWS Provider: v2.48.0
The error that I’m getting from the Terraform CLI is:
module.service.module.ecs_passthrough.aws_api_gateway_vpc_link.vpc_link: Refreshing state... [id=ox6a0g]
module.service.module.ecs_passthrough.aws_api_gateway_vpc_link.vpc_link: Destroying... [id=ox6a0g]
Error: error deleting API Gateway VPC Link (ox6a0g): BadRequestException: Cannot delete vpc link. Vpc link 'ox6a0g', is referenced in [ANY:kx106x:dev] in format of [Method:Resource:Stage].
I don’t think I’m doing anything out of the ordinary in terms of the API Gateway, but the VPC parts of it look like this
resource "aws_api_gateway_vpc_link" "vpc_link" {
name = "${var.name}_vpc_link"
target_arns = ["${var.load_balancer.arn}"]
}
resource "aws_api_gateway_integration" "request_method_integration" {
rest_api_id = "${var.api_id}"
resource_id = "${var.resource_id}"
http_method = "${aws_api_gateway_method.request_method.http_method}"
integration_http_method = "${aws_api_gateway_method.request_method.http_method}"
type = "${var.invoke_type}"
uri = "http://${var.load_balancer.dns_name}/{proxy}/"
credentials = "${var.gateway_credentials}"
request_parameters = "${var.integration_request_params}"
connection_type = "VPC_LINK"
connection_id = "${aws_api_gateway_vpc_link.vpc_link.id}"
}
I don’t know what I can do since if I can’t bring up and reliably pull down an application, then I’m stuck, maybe I can force the order of terraform resources to make it work in the way that will enable this to start working again?
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 6
- Comments: 16 (1 by maintainers)
Hi,
I also stumbled across this error. I tried the suggestion to use the lifecycle hook “create_before_destory”, but unfortunately without success. After some research, I came across a note in the AWS doc (https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html) which says that the VPC link should not be referenced directly, but instead a stage variable should be used as a reference. I set this up and can now reliably delete VPC links.
I think this is the real problem here. I’ve been doing some testing and found that the crossed dependencies make nearly imposible to change parameters on resources that trigger a recreation of that resource.
While trying to find a way to past the VPC_LINK problem I tried to change the integration_type that is refering that VPC_LINK to MOCK. This change is triggering a recreation of the integration object but is failing because it’s a required dependency for the route that is using it.
I’m trying to play with the
depends_onmeta parameter from terraform but without luck so far 😦EDIT: To make things even worse, you cannot define two different vpc-links to the same subnets even with different security-groups. This is an AWS API limitation:
As the VPC-LINK is creating ENIs attached to those subnets seems that it can only attach one per subnet.
So you cannot create a new one with the configuration you need and then switch the integration to the new one so you don’t have downtime.
It appears the problem is that API Gateways are “compiled” and deployed instances of what the console is representing. This is a problem that I experienced in the past because you would change the API Gateway using the console and the API Gateway wouldn’t respond to the updated changes until you “deploy api” and this takes your definition in the console, builds a distribution and pushes it to cloudfront.
If you look in the cloudfront console, there is no distribution since API Gateway cloudfront distributions are hidden and only accessible through API Gateways Console interface.
So the problem is, that terraform wants to delete/recreate/change a VPC Link, so it tries to do that, but there is a connection to this “object” in the cloudfront distribution and this blocks modification of the VPC Link.
So even if you delete the resources in API Gateways interface, but don’t deploy it, you still can’t modify this VPC Link, because the link is being referenced in the compiled, distributed version that is installed on cloudfront.
If you remove the methods and integrations from your API Gateway and remove the reference to the VPC link, then deploy api, THEN you can delete the vpc link.
Terraform apparently doesn’t know how to do this, but there are no mechanisms that I’m aware of other than scripting to make a sequence of actions that will do the following
This sequence of actions in theory would work. However I can’t see any way to do them using terraform primatives. Anybody has any ideas how you’d do this in pure terraform.tf files?
Figured out a solution! The aws_api_gateway_deployment resource documentation has a note talking about adding a create_before_destroy lifecycle block. This allows the VPC Link to connect to the new API Gateway Deployment first before destroying the old API Gateway Deployment, so at all times the VPC Link is attached and prevents the downtime.
lifecycle { create_before_destroy = true }Oh you’re new to this? First time? (Movie quote bonus! +1)
Don’t worry, the problem will disappear and then come back, at least that’s what it does with me 😃 On 17. Jul 2020, 13:53 +0200, Steven Massaro notifications@github.com, wrote: