Terraform not deploying api gateway stage
Solution 1
TF does not deploy the API, this link might help you: https://medium.com/coryodaniel/til-forcing-terraform-to-deploy-a-aws-api-gateway-deployment-ed36a9f60c1a
I've fixed mine by adding the variable deployed_at:
resource "aws_api_gateway_deployment" "api_ingest_deployment" {
depends_on = ["aws_api_gateway_method.xxx",
"aws_api_gateway_integration.yyy",
"aws_api_gateway_integration.zzz",
"aws_api_gateway_integration.www",
]
rest_api_id = "${aws_api_gateway_rest_api.foo.id}"
stage_name = "${var.environment}"
variables {
deployed_at = "${timestamp()}"
}
}
the downside is that if done this way it will always deploy, even if there's no change
Solution 2
None of the other solutions here worked for me as I get this error:
BadRequestException: Active stages pointing to this deployment must be moved or deleted
This is the solution that worked for me:
resource "aws_api_gateway_deployment" "api_deployment" {
rest_api_id = aws_api_gateway_rest_api.api.id
stage_name = "default"
stage_description = "Deployed at ${timestamp()}"
lifecycle {
create_before_destroy = true
}
}
Tested on Terraform 0.12.24
Solution 3
From the aws_api_gateway_deployment:
resource "aws_api_gateway_deployment" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
triggers = {
# NOTE: The configuration below will satisfy ordering considerations,
# but not pick up all future REST API changes. More advanced patterns
# are possible, such as using the filesha1() function against the
# Terraform configuration file(s) or removing the .id references to
# calculate a hash against whole resources. Be aware that using whole
# resources will show a difference after the initial implementation.
# It will stabilize to only change when resources change afterwards.
redeployment = sha1(jsonencode([
aws_api_gateway_resource.example.id,
aws_api_gateway_method.example.id,
aws_api_gateway_integration.example.id,
]))
}
lifecycle {
create_before_destroy = true
}
}
You need to define the triggers that should trigger a new deployment, I used without the id
and it works great.
Solution 4
There are a couple of things which you need to be careful about.
- Mention the depends on properly to make sure the deployment block is executed after the integration and method block is executed(especially when you have any authorizers in place).
Add the timestamp function in variables to deploy it immediately once all the dependent blocks are executed.
resource "aws_api_gateway_deployment" "mydeployment" { depends_on =["aws_api_gateway_method.mymethod","aws_api_gateway_integration.myintegration"] rest_api_id = "${aws_api_gateway_rest_api.myapi.id}" stage_name = "dev" variables = { deployed_at = "${timestamp()}" } }
Solution 5
If you are using swagger template and terraform ver >= 0.12 then you can give swagger file for MD5 computation like below. This work perfectly.
resource "aws_api_gateway_deployment" "deploy_stage" {
rest_api_id = aws_api_gateway_rest_api.product_api.id
stage_name = var.stage_name
stage_description = md5(file("swagger_api.yml"))
}
Related videos on Youtube
sethu
SOreadytohelp I am a java developer and have worked a lot on Swing and core java.
Updated on July 09, 2022Comments
-
sethu almost 2 years
I have been trying to create an API Gateway endpoint using terraform. Everything seems to be working except the last part of deploying a stage.
After I run terraform apply I go into the console and I find that the deployment has not happened. I need to manually click on Deploy Api in order to get it working.
Here's the terraform file for the api gateway.
variable "region" {} variable "account_id" {} resource "aws_api_gateway_rest_api" "online_tax_test_client_report_endpoint_api" { name = "online_tax_test_client_report_endpoint_api" description = "The endpoint that test has to hit when new client reports are available." depends_on = ["aws_lambda_function.onlinetax_test_endpoint_lambda"] } resource "aws_api_gateway_resource" "test_client_report_resource" { rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}" parent_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.root_resource_id}" path_part = "test_client_report" } resource "aws_api_gateway_method" "test_client_report_method" { rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}" resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}" http_method = "POST" authorization = "NONE" } resource "aws_api_gateway_integration" "test_client_report_resource_integration" { rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}" resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}" http_method = "${aws_api_gateway_method.test_client_report_method.http_method}" type = "AWS" integration_http_method = "${aws_api_gateway_method.test_client_report_method.http_method}" uri = "arn:aws:apigateway:${var.region}:lambda:path/2015-03-31/functions/${aws_lambda_function.onlinetax_test_endpoint_lambda.arn}/invocations" request_templates = { "application/json" = "${file("${path.module}/generic_request_mapping_template.vm")}" } } resource "aws_api_gateway_method_response" "200" { rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}" resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}" http_method = "${aws_api_gateway_method.test_client_report_method.http_method}" status_code = "200" } resource "aws_api_gateway_integration_response" "test_client_report_resource_integration_default_response" { rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}" resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}" http_method = "${aws_api_gateway_method.test_client_report_method.http_method}" status_code = "${aws_api_gateway_method_response.200.status_code}" selection_pattern = "" depends_on = ["aws_api_gateway_integration.test_client_report_resource_integration"] } resource "aws_api_gateway_method_response" "500" { rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}" resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}" http_method = "${aws_api_gateway_method.test_client_report_method.http_method}" status_code = "500" } resource "aws_api_gateway_integration_response" "test_client_report_resource_integration_error_response" { rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}" resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}" http_method = "${aws_api_gateway_method.test_client_report_method.http_method}" status_code = "${aws_api_gateway_method_response.500.status_code}" selection_pattern = ".*?Error.*" depends_on = ["aws_api_gateway_integration.test_client_report_resource_integration"] } resource "aws_lambda_permission" "allow_api_gateway" { statement_id = "AllowExecutionFromAPIGateway" action = "lambda:InvokeFunction" function_name = "${aws_lambda_function.onlinetax_test_endpoint_lambda.arn}" principal = "apigateway.amazonaws.com" source_arn = "arn:aws:execute-api:${var.region}:${var.account_id}:${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}/*/${aws_api_gateway_integration.test_client_report_resource_integration.integration_http_method}${aws_api_gateway_resource.test_client_report_resource.path}" depends_on = ["aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api"] } #This is the part that doesn't seem to work. resource "aws_api_gateway_deployment" "qa5" { rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}" stage_name = "qa5" depends_on = ["aws_api_gateway_method.test_client_report_method"] }
Edit
Added the graph in :
digraph { compound = "true" newrank = "true" subgraph "root" { "[root] module.lambda.aws_api_gateway_deployment.qa5" [label = "aws_api_gateway_deployment.qa5", shape = "box"] "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" [label = "aws_api_gateway_integration.sbr_client_report_resource_integration", shape = "box"] "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" [label = "aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response", shape = "box"] "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" [label = "aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response", shape = "box"] "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" [label = "aws_api_gateway_method.sbr_client_report_method", shape = "box"] "[root] module.lambda.aws_api_gateway_method_response.200" [label = "aws_api_gateway_method_response.200", shape = "box"] "[root] module.lambda.aws_api_gateway_method_response.500" [label = "aws_api_gateway_method_response.500", shape = "box"] "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" [label = "aws_api_gateway_resource.sbr_client_report_resource", shape = "box"] "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" [label = "aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api", shape = "box"] "[root] module.lambda.aws_iam_role.onlinetax_sbr_endpoint_role" [label = "aws_iam_role.onlinetax_sbr_endpoint_role", shape = "box"] "[root] module.lambda.aws_iam_role_policy.publish_to_sns_policy" [label = "aws_iam_role_policy.publish_to_sns_policy", shape = "box"] "[root] module.lambda.aws_iam_role_policy.write_to_cloudwatch_policy" [label = "aws_iam_role_policy.write_to_cloudwatch_policy", shape = "box"] "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda" [label = "aws_lambda_function.onlinetax_sbr_endpoint_lambda", shape = "box"] "[root] module.lambda.aws_lambda_permission.allow_api_gateway" [label = "aws_lambda_permission.allow_api_gateway", shape = "box"] "[root] module.lambda.provider.aws" [label = "provider.aws", shape = "diamond"] "[root] module.sns.aws_sns_topic.online_tax_qa5_sbr_client_report" [label = "aws_sns_topic.online_tax_qa5_sbr_client_report", shape = "box"] "[root] module.sns.provider.aws" [label = "provider.aws", shape = "diamond"] "[root] provider.aws (disabled)" [label = "provider.aws (disabled)", shape = "diamond"] "[root] module.lambda.aws_api_gateway_deployment.qa5" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" "[root] module.lambda.aws_api_gateway_deployment.qa5" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" "[root] module.lambda.aws_api_gateway_deployment.qa5" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" -> "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda" "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.aws_api_gateway_method_response.200" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.aws_api_gateway_method_response.500" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_api_gateway_method_response.200" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" "[root] module.lambda.aws_api_gateway_method_response.200" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" "[root] module.lambda.aws_api_gateway_method_response.200" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" "[root] module.lambda.aws_api_gateway_method_response.200" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_api_gateway_method_response.500" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" "[root] module.lambda.aws_api_gateway_method_response.500" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" "[root] module.lambda.aws_api_gateway_method_response.500" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" "[root] module.lambda.aws_api_gateway_method_response.500" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" -> "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda" "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_iam_role.onlinetax_sbr_endpoint_role" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_iam_role_policy.publish_to_sns_policy" -> "[root] module.lambda.aws_iam_role.onlinetax_sbr_endpoint_role" "[root] module.lambda.aws_iam_role_policy.publish_to_sns_policy" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_iam_role_policy.publish_to_sns_policy" -> "[root] module.sns.aws_sns_topic.online_tax_qa5_sbr_client_report" "[root] module.lambda.aws_iam_role_policy.write_to_cloudwatch_policy" -> "[root] module.lambda.aws_iam_role.onlinetax_sbr_endpoint_role" "[root] module.lambda.aws_iam_role_policy.write_to_cloudwatch_policy" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda" -> "[root] module.lambda.aws_iam_role.onlinetax_sbr_endpoint_role" "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda" -> "[root] module.lambda.provider.aws" "[root] module.lambda.aws_lambda_permission.allow_api_gateway" -> "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" "[root] module.lambda.aws_lambda_permission.allow_api_gateway" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" "[root] module.lambda.aws_lambda_permission.allow_api_gateway" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" "[root] module.lambda.aws_lambda_permission.allow_api_gateway" -> "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda" "[root] module.lambda.aws_lambda_permission.allow_api_gateway" -> "[root] module.lambda.provider.aws" "[root] module.lambda.provider.aws" -> "[root] provider.aws (disabled)" "[root] module.sns.aws_sns_topic.online_tax_qa5_sbr_client_report" -> "[root] module.sns.provider.aws" "[root] module.sns.provider.aws" -> "[root] provider.aws (disabled)" } }
The Graph has other resources which I have not provided in the tf file above. Its only the API GW that has issues. By the way, I am able to test the API from the console and it works fine. I am not able to execute it from my localbox or postman.
Any idea on what I am doing wrong?
-
ydaetskcoR over 7 yearsIs this the case for the first deployment or just future deployments when things change? There's an open issue on GH for the latter: github.com/hashicorp/terraform/issues/6613
-
sethu over 7 yearsEven the first deployment didn't work I guess. I destroyed the entire stack and applied it again. Still don't see the deployment. When terraform plan lists all the changes that need to be applied, the deployment resource is listed at the very top. Does that mean that gets deployed first?
-
ydaetskcoR over 7 yearsIt absolutely won't be run first because it is dependent on at least 2 resources (
aws_api_gateway_rest_api
andaws_api_gateway_method
) which in turn may well be dependent on other things. I'd have to run your TF to see but that will have to wait until tonight unfortunately. It might be interesting to see the output ofterraform graph
if you could edit that into your question?
-
-
Antonio Terreno over 6 yearsActually, I just checked also this GitHub issue github.com/hashicorp/terraform/issues/6613 Doing it this way: resource "aws_api_gateway_deployment" "default" { ... stage_description = "${md5(file("api_gateway.tf"))}" ... } is more clever and will force you to deploy less
-
Christopher Thomas almost 5 yearsI wasted hours on this problem. Thank you for letting me know!
-
babis21 about 4 yearsAntonio's answer helped me, the solution on this post seems 'better' (workaround, but works). Should be an accepted answer?
-
user1297406 almost 4 yearsThank you, your solution worked for me too on TF 0.12.24
-
d8aninja about 2 yearsthere no longer appears to be a
variables
block available to the resource, and the EXPORT TF_VAR_foo doesn't work anymore, either... FYI