Closed clocked0ne closed 3 years ago
Hi @clocked0ne ,
I tried a run like your who works like a charm.
provider "aws" {
region = "${var.region}"
version = "2.3.0"
}
variable "name" {
default = "api-name"
}
variable "stage_name" {
default = "v1"
}
variable "gateway_version" {
default = "test API"
}
resource "aws_api_gateway_rest_api" "app" {
name = "${var.name}"
description = "redacted"
}
resource "aws_api_gateway_api_key" "app" {
name = "${var.name}"
}
resource "aws_api_gateway_usage_plan" "app" {
name = "${var.name}"
description = "Unlimited usage plan"
api_stages {
api_id = "${aws_api_gateway_rest_api.app.id}"
stage = "${var.stage_name}"
}
depends_on = ["aws_api_gateway_stage.app"]
}
resource "aws_api_gateway_usage_plan_key" "app" {
key_id = "${aws_api_gateway_api_key.app.id}"
key_type = "API_KEY"
usage_plan_id = "${aws_api_gateway_usage_plan.app.id}"
}
resource "aws_api_gateway_deployment" "app" {
stage_description = "${var.gateway_version}"
description = "${var.gateway_version}"
rest_api_id = "${aws_api_gateway_rest_api.app.id}"
depends_on = ["aws_api_gateway_integration.app"]
}
resource "aws_api_gateway_stage" "app" {
stage_name = "${var.stage_name}"
rest_api_id = "${aws_api_gateway_rest_api.app.id}"
deployment_id = "${aws_api_gateway_deployment.app.id}"
}
resource "aws_api_gateway_resource" "app" {
rest_api_id = "${aws_api_gateway_rest_api.app.id}"
parent_id = "${aws_api_gateway_rest_api.app.root_resource_id}"
path_part = "mydemoresource"
}
resource "aws_api_gateway_method" "app" {
rest_api_id = "${aws_api_gateway_rest_api.app.id}"
resource_id = "${aws_api_gateway_resource.app.id}"
http_method = "POST"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "app" {
http_method = "${aws_api_gateway_method.app.http_method}"
resource_id = "${aws_api_gateway_resource.app.id}"
rest_api_id = "${aws_api_gateway_rest_api.app.id}"
type = "MOCK"
}
https://gist.github.com/sousmangoosta/4b5f2511e9357ee59d79cdab1d5c0f97
Strange, I can only think that it is either because there is a race condition or it was not a 'fresh' deployment when we ran it as some elements of the config had changed. It would be good for someone else to be able to verify this with their own example.
@clocked0ne I can confirm, issue is still in version 2.3.0, getting error: Resource 'aws_api_gateway_deployment.test' does not have attribute 'stage_name' for variable 'aws_api_gateway_deployment.test.stage_name' when 'stage_name' is missing in 'aws_api_gateway_deployment'
@clocked0ne @kgrodzicki : Can you provide a usable as-is example of non working terraform configuration, could you please give a real debug output with command like TF_LOG=DEBUG terraform apply
Cannot reproduce it with version 2.4.0. LGTM 👍
Does this mean this is resolved in 2.4.0 aws provider and this issue can therefore be closed?
@sousmangoosta I am unable to test with a fresh configuration at this point but assume based on the responses from @kgrodzicki that the problem is fixed, I have seen no further issues.
I'm still having this issue using 2.12.0 version. Planning runs fine in case of stage_name="", when apply I'm getting "Error creating API Gateway Stage: BadRequestException: Stage name must be non-empty"
upd: I can see that this option is still required - https://github.com/terraform-providers/terraform-provider-aws/blame/master/aws/resource_aws_api_gateway_stage.go#L99
I'm still having this issue using 2.12.0 version. Planning runs fine in case of stage_name="", when apply I'm getting "Error creating API Gateway Stage: BadRequestException: Stage name must be non-empty"
upd: I can see that this option is still required - https://github.com/terraform-providers/terraform-provider-aws/blame/master/aws/resource_aws_api_gateway_stage.go#L99
Yes for resource "aws_api_gateway_stage"
the stage_name
is required, it's not required for resource "aws_api_gateway_deployment"
@sousmangoosta sorry to come back to this after such a long time, but it's still an issue. The problem with your test script from 23rd March 2019 is that aws_api_gateway_deployment.app doesn't have the stage_name set, just stage_description. This will deploy just fine, but the API won't be accessible. The problem everyone is having is where you need to have aws_api_gateway_stage and aws_api_gateway_deployment with both having the same stage name set. In my case, deploying from scratch results in a 'stage already exists' error when creating the aws_api_gateway_stage. Manually deleting the stage and redeploying works, but it's too hand-held to be a solution.
A potential solution is presented in 'important factoids' at the top of this ticket.
My particular use case is: enable api gateway access logging. It's not possible to enable this without a aws_api_gateway_stage, and it's not possible to deploy a working api using a aws_api_gateway_stage as things stand.
I have been reading through the trail of tickets related to this (from March 2019!) with incorrect and misleading information, closed after inactivity, and incorrect solutions. This is a critical problem which makes Terraform not fit for purpose for any use of API Gateway that:
The suggested solution in important factoids only works if you are creating all the API Gateway Resources by hand rather than using body
and importing the Swagger.
In other words, it means anyone using API Gateway in a non-toy project essentially must avoid Terraform as a deployment mechanism or accept a manual deployment step.
@SemiConscious I upgraded my example here :
provider "aws" {
region = var.region
version = "2.65.0"
}
variable "name" {
default = "api-name"
}
variable "stage_name" {
default = "v1"
}
variable "gateway_version" {
default = "test API"
}
resource "aws_api_gateway_rest_api" "app" {
name = var.name
description = "redacted"
}
resource "aws_api_gateway_api_key" "app" {
name = var.name
}
resource "aws_api_gateway_usage_plan" "app" {
name = var.name
description = "Unlimited usage plan"
api_stages {
api_id = aws_api_gateway_rest_api.app.id
stage = var.stage_name
}
depends_on = [aws_api_gateway_stage.app]
}
resource "aws_api_gateway_usage_plan_key" "app" {
key_id = aws_api_gateway_api_key.app.id
key_type = "API_KEY"
usage_plan_id = aws_api_gateway_usage_plan.app.id
}
resource "aws_api_gateway_deployment" "app" {
stage_description = var.gateway_version
description = var.gateway_version
rest_api_id = aws_api_gateway_rest_api.app.id
depends_on = [aws_api_gateway_integration.app]
}
resource "aws_api_gateway_stage" "app" {
stage_name = var.stage_name
rest_api_id = aws_api_gateway_rest_api.app.id
deployment_id = aws_api_gateway_deployment.app.id
}
resource "aws_api_gateway_resource" "app" {
rest_api_id = aws_api_gateway_rest_api.app.id
parent_id = aws_api_gateway_rest_api.app.root_resource_id
path_part = "mydemoresource"
}
resource "aws_api_gateway_method" "app" {
rest_api_id = aws_api_gateway_rest_api.app.id
resource_id = aws_api_gateway_resource.app.id
http_method = "POST"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "app" {
http_method = aws_api_gateway_method.app.http_method
resource_id = aws_api_gateway_resource.app.id
rest_api_id = aws_api_gateway_rest_api.app.id
type = "MOCK"
}
resource "aws_api_gateway_method_response" "app" {
rest_api_id = aws_api_gateway_rest_api.app.id
resource_id = aws_api_gateway_resource.app.id
http_method = aws_api_gateway_method.app.http_method
status_code = "200"
}
resource "aws_api_gateway_integration_response" "MyDemoIntegrationResponse" {
rest_api_id = aws_api_gateway_rest_api.app.id
resource_id = aws_api_gateway_resource.app.id
http_method = aws_api_gateway_method.app.http_method
status_code = aws_api_gateway_method_response.app.status_code
}
output "api_url" {
value = [aws_api_gateway_stage.app.invoke_url,aws_api_gateway_resource.app.path_part]
}
$ terraform version
Terraform v0.12.26
$
https://gist.github.com/sousmangoosta/4b5f2511e9357ee59d79cdab1d5c0f97
https://gist.github.com/sousmangoosta/339aa5a0ea3731a1eda75576ce0a9020
@shederman Could you please provide an example ?
I don't see a WAF option for any of the resources?
@davidkarlsen You got an example of associate an Waf ACL to API Gateway here on the last block aws_wafv2_web_acl_association
Hi folks 👋
The stage_name
attribute of the aws_api_gateway_deployment
resource should be avoided where possible in configurations (both as an argument or an attribute reference) and it will likely be deprecated soon. It serves a confusing purpose of managing a stage during deployment creation that typically does not work well with Terraform's design. My initial comment from the previous issue suggesting that the aws_api_gateway_deployment
resource could theoretically lookup a stage name would only work if there was one stage associated with a deployment, however since multiple stages can be associated with a deployment attempting to fill it in would result inaccurate results for the value.
In this situation, it is better to use the aws_api_gateway_stage
resource stage_name
attribute instead of aws_api_gateway_deployment
resource stage_name
argument.
To summarize this in a quick configuration example:
resource "aws_api_gateway_deployment" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
triggers = {
redeployment = # ... references to upstream resources (see issue link below) ...
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_api_gateway_stage" "example" {
deployment_id = aws_api_gateway_deployment.example.id
rest_api_id = aws_api_gateway_rest_api.example.id
stage_name = "example"
}
# ... downstream references should be to aws_api_gateway_stage.example.stage_name ...
If you are having further trouble with this functionality after applying these recommendations, please submit new GitHub issues following the bug report and feature request issue templates for further triage.
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!
Community Note
Terraform Version
Affected Resource(s)
Terraform Configuration Files
Debug Output
https://gist.github.com/clocked0ne/f3932eea73bec35b289ac952035c6f12
Panic Output
Expected Behavior
Terraform Apply should have completed successfully as the
stage_name
inaws_api_gateway_deployment
is now optionalActual Behavior
The Terraform Apply failed with the error described.
Steps to Reproduce
terraform apply
Important Factoids
In the issue referenced below @bflad suggested:
References
2918