Terraform: error redeploying API gateway stage when mapped to custom domain path

Created on 12 Dec 2016  ยท  10Comments  ยท  Source: hashicorp/terraform

When redeploying an aws_api_gateway_deployment to the same stage and that stage is mapped to an aws_api_gateway_base_path_mapping, the deployment fails with error:

aws_api_gateway_deployment.deployment: BadRequestException: Active stages pointing to this deployment must be moved or deleted

Terraform Version

7.11

Affected Resource(s)

  • aws_api_gateway_deployment

Terraform Configuration Files

# INPUTS
variable "api_stage" {
  default = "v1"
}

variable "domain_name" {
  default = "example.domain.com"
}

variable "domain_base_path" {
  default = "examplepath"
}


# API
resource "aws_api_gateway_rest_api" "api" {
  name = "my api"
  description = "example api for bug"
}

# API Deployment
resource "aws_api_gateway_deployment" "deployment" {
  rest_api_id = "${aws_api_gateway_rest_api.api.id}"
  stage_name = "${var.api_stage}"
  variables = {
    "functionAlias" = "${var.api_stage}"
    #this is to force a new API deployment on every 'terraform apply'
    "deploymentGUID" = "${uuid()}"
  }
}

# Custom domain path mapping
resource "aws_api_gateway_base_path_mapping" "path_mapping" {
  depends_on=[
    "aws_api_gateway_deployment.deployment"
  ]
  api_id      = "${aws_api_gateway_rest_api.api.id}"
  domain_name = "${var.domain_name}"
  base_path = "${var.domain_base_path}",
  stage_name = "${var.api_stage}"
}

Expected Behavior

API redeployed to the stage and the base path mapping still pointed to that stage.

Actual Behavior

API deployment failed with error:

Error applying plan:


1 error(s) occurred:

* aws_api_gateway_deployment.deployment: BadRequestException: Active stages pointing to this deployment must be moved or deleted

2016/12/12 16:26:58 [DEBUG] plugin: waiting for all plugin processes to complete...
    status code: 400, request id: cd69598e-c087-11e6-b7ec-1d35a1dd5635

Steps to Reproduce

  1. terraform apply

note: first run of terraform apply may pass. It's when redeploying that the issue occurs.

Important Factoids

I am forcing a new API deployment on every run of apply by using the uuid() method in an API deployment variable.

bug provideaws

Most helpful comment

I found that using lifecycle "create_before_destroy" on the aws_api_gateway_deployment solves the problem; e.g.

resource "aws_api_gateway_deployment" "ApiDeploymentDev" {
  rest_api_id = "${module.api.api_id}"
  description = "Deployed at ${timestamp()}"
  stage_name  = "dev"
  stage_description = "Deployed at ${timestamp()}"

  lifecycle {
    create_before_destroy = true
  }
}

All 10 comments

@mitchellh: I've got the same problem. If I don't add a variable to to the API Gateway deployment, I can't then get a republish of the API to the target stage every time. I've basically added a script that does a manual terraform destroy of the resource beforehand - but it's very frustrating from a tooling perspective to figure out why the destroy isn't happening organically.

Hi @mitchellh, @steve-gray, we came across this too.

We have a aws_api_gateway_deployment which includes a variable in it's description and stage_description which changes with each run.

When we try to deploy, we got the same error as OP.

Our workaround currently is to execute a terraform taint on the corresponding aws_api_gateway_base_path_mapping - this has solved our problem for now, but it's a workaround and we'd love a more permanent solution.

Hope our workaround helps others too.

This is also an issue for Terraform 0.9.2. Could it be related to the fact that there is no aws_api_gateway_stage ?

I found that using lifecycle "create_before_destroy" on the aws_api_gateway_deployment solves the problem; e.g.

resource "aws_api_gateway_deployment" "ApiDeploymentDev" {
  rest_api_id = "${module.api.api_id}"
  description = "Deployed at ${timestamp()}"
  stage_name  = "dev"
  stage_description = "Deployed at ${timestamp()}"

  lifecycle {
    create_before_destroy = true
  }
}

@4dz I tried this fix and it didn't work if I was also using aws_api_gateway_base_path_mapping with a wide open base path.

It would be great for Terraform to understand that it needs to destroy the mapping first.

I ended up solving it by adding a unique variable to the deployment reflecting all of my API Gateway resources. Since change in variables forces a new resource, this reliably keeps my API Gateway Deployment up-to-date.

locals {
  lambda_integrations = [
    "${module.foo_resource.resource_id}",
    "${module.bar_resource.resource_id}",
    "${module.baz_resource.resource_id}",
  ]
}

resource "aws_api_gateway_deployment" "example" {
  # ...
  variables = {
    integrations = "${join(",", local.lambda_integrations)}"
  }
  # ...
}

@kylelaverty did you solve the issue? I have the same problem that you.

@safv12 I am no longer on the team that was encountering the issue. But before I left we didn't solve it and instead had to manually deploy that part.

@kylelaverty @safv12 I had the same issue with a wide open base path mapping.

It finally worked by explicitly specifying an aws_api_gateway_stage instead of the one created by the deployment itself. (cf https://www.terraform.io/docs/providers/aws/r/api_gateway_stage.html)
And that stage having an explicit depends_on = ["aws_api_gateway_deployment.deploy_api"]
I've also added depends_on = ["aws_api_gateway_stage.deployment_stage"] to my aws_api_gateway_base_path_mapping. Not sure if it helps or not...

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 have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings