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.82k stars 9.16k forks source link

[Bug]: creating API Gateway Stage (api): ConflictException: Stage already exists #30256

Closed kpanamal closed 1 year ago

kpanamal commented 1 year ago

Terraform Core Version

1.4.2

AWS Provider Version

4.59.0

Affected Resource(s)

I am trying to restrict the size of incoming requests to my AWS API Gateway (maintained through Terraform) to be less than 500KB. I am using the size_constraint_statement to achieve this. To this affect, I am trying to create a new aws_api_gateway_stage and create a aws_wafv2_web_acl_association to it. The association is for the _aws_wafv2_webacl I am creating to implement the _size_constraintstatement. This is demonstrated in the sample code below. I have removed the stage_name attribute from the deployment, added it to the stage I am creating and added the lifecycle attribute.

resource "aws_api_gateway_deployment" "appsync_api_gateway" {
  depends_on = [
    aws_api_gateway_integration.appsync_api_gateway_post,
    aws_api_gateway_integration.sign_request,
    aws_api_gateway_integration.verify_sig,
    aws_api_gateway_integration.oc_lookup,
    aws_api_gateway_integration.get_csa_config
  ]

  rest_api_id = aws_api_gateway_rest_api.appsync_api_gateway.id

  triggers = {
    redeployment = join(",", [
      md5(file("${path.module}/appsync-api-gw.tf")),
      md5(file("${path.module}/variables.tf")),
      md5(file("${path.module}/../cors/cors.tf")),
      md5(file("${path.module}/../cors/variables.tf")),
    ])
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_wafv2_web_acl" "limit_request_body_size" {
  name  = "web-acl-association-limit_request_body_size"
  scope = "REGIONAL"

  default_action {
    allow {}
  }

  rule {
    name     = "BodySizeConstraint"
    priority = 0
    action {
      block {}
    }
    statement {
      size_constraint_statement {
        field_to_match {
          body {
            oversize_handling = "MATCH"
          }
        }
        comparison_operator = "GT"
        size                = 51200
        text_transformation {
          priority = 1
          type     = "NONE"
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "BodySizeConstraint"
      sampled_requests_enabled   = false
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = local.wafv2_cloudwatch_metrics
    sampled_requests_enabled   = false
  }

  tags = {
    Name = local.waf_web_acl_name
  }
}

resource "aws_api_gateway_stage" "intermediary_stage" {
  depends_on = [aws_api_gateway_deployment.appsync_api_gateway, aws_api_gateway_rest_api.appsync_api_gateway]
  deployment_id = aws_api_gateway_deployment.appsync_api_gateway.id
  rest_api_id   = aws_api_gateway_rest_api.appsync_api_gateway.id
  stage_name    = var.appsync_api_gw_stage_name
}

resource "aws_wafv2_web_acl_association" "limit_request_body_size" {
  #depends_on   = [aws_wafv2_web_acl.limit_request_body_size]
  resource_arn = aws_api_gateway_stage.intermediary_stage.arn
  web_acl_arn  = aws_wafv2_web_acl.limit_request_body_size.arn
}

Expected Behavior

I expected this to create the gateway stage and AWS WAF2 ACL rule and create the association for this.

Actual Behavior

I am getting the error similar to a lot of other posted issues saying Error: creating API Gateway Stage (api): ConflictException: Stage already exists

https://github.com/hashicorp/terraform-provider-aws/issues/14424 https://github.com/hashicorp/terraform-provider-aws/issues/1153 https://github.com/hashicorp/terraform-provider-aws/issues/11344

Relevant Error/Panic Output Snippet

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

module.iroh-auth.okta_auth_server_policy.iroh_auth_policy: Modifying... [id=00p1kv2b70dbIXl0e0h8]
module.appsync_api_gw.aws_api_gateway_deployment.appsync_api_gateway: Creating...
module.iroh-auth.okta_auth_server_policy.iroh_auth_policy: Modifications complete after 1s [id=00p1kv2b70dbIXl0e0h8]
module.appsync_api_gw.aws_api_gateway_deployment.appsync_api_gateway: Creation complete after 0s [id=5nd8p3]
module.appsync_api_gw.aws_api_gateway_stage.intermediary_stage: Creating...
╷
│ Error: creating API Gateway Stage (api): ConflictException: Stage already exists
│ 
│   with module.appsync_api_gw.aws_api_gateway_stage.intermediary_stage,
│   on modules/appsync-api-gw/appsync-api-gw.tf line 759, in resource "aws_api_gateway_stage" "intermediary_stage":
│  759: resource "aws_api_gateway_stage" "intermediary_stage" {
│ 
╵
error Command failed with exit code 1.

Terraform Configuration Files

Terraform v1.4.2 on darwin_amd64

Steps to Reproduce

Do terraform apply with the above configuration

Debug Output

No response

Panic Output

No response

Important Factoids

I have already tried these suggestion from other Github issues:

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 1 year ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

trevorrea commented 1 year ago

Hi,

This isn't a bug. You can't just remove the stage name from the deployment. That won't actually delete it from AWS and more importantly you wouldn't want it to as that'll mean your API is unavailable.

I have done this exact same thing before (and for this reason) and the solution is to import the stage into the Terraform state before you ran the plan/apply.

If I've read your plan correctly it would be:-

terraform import module.appsync_api_gw.aws_api_gateway_stage.intermediary_stage apiid/stage name

eg.

terraform import module.appsync_api_gw.aws_api_gateway_stage.intermediary_stage m1cznnd69h/stagename

Once you've done that do a plan to see if all the settings match up and then an apply.

Hope that helps, Trevor

kpanamal commented 1 year ago

Hi @trevorrea thanks for the reply. I am mainly trying to create the aws deployment stage and associate the waf2 acl rule to by creating an _aws_wafv2_web_acl_association_ to it.

At the end of your example command, where do I get the apiid and stage name from? Is it "intermediary stage"? Can I just use one instead of both? i.e. either apiid or stage_name at the end of the command but not both.

trevorrea commented 1 year ago

Hi,

I get that you're trying to create the stage but what I'm saying is that it already exists and you need to import it.

The Hashicorp doc to import a stage is https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_stage#import

You need the REST-API-ID and STAGE-NAME. REST-API-ID will be obtained from the AWS console and STAGE-NAME based on reading your code will be whatever var.appsync_api_gw_stage_name is.

Or you can just get both from the AWS console.

Regards, Trevor

kpanamal commented 1 year ago

thanks for the clarification trevor ... I understand it better now.

justinretzolk commented 1 year ago

Hey @kpanamal and @trevorrea 👋 Thank you for taking the time to raise this, and for the great discussion around it! Based on the most recent updates, it seems that this issue may be able to be closed. Are you comfortable with us doing so, @kpanamal?

kpanamal commented 1 year ago

yes, for now ... I am still tweaking with the implementation because when I run the import I get a prompt asking for the different variables in my terraform config which I don't wanted to enter. Is there a way to get around that?

enter vars
trevorrea commented 1 year ago

You've cut off the top of the screenshot but it looks like you haven't passed any vars / var files arguments to your import command.

See https://developer.hashicorp.com/terraform/cli/commands/import#var-file-foo and https://developer.hashicorp.com/terraform/cli/commands/import#var-foo-bar

This is not a bug so I'd say you can close this ticket and if you have any further issues ask on one of the Terraform community forums at https://discuss.hashicorp.com/c/terraform-core/27

github-actions[bot] commented 1 year ago

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.