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.87k stars 9.21k forks source link

API Gateway V2 Integration- SQS - Request Parameters Not Re-Sent on Update #22647

Open dleavitt opened 2 years ago

dleavitt commented 2 years ago

Community Note

Terraform CLI and Terraform AWS Provider Version

Terraform v1.1.3
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v3.72.0

Affected Resource(s)

Relevant snippet attached here, full Terraform config for reproduction attached below.

resource "aws_apigatewayv2_integration" "main" {
  api_id              = aws_apigatewayv2_api.main.id
  credentials_arn     = aws_iam_role.main.arn
  integration_type    = "AWS_PROXY"
  integration_subtype = "SQS-SendMessage"
  description         = "SQS Repro Test"

  # These don't appear to be passed when updating if unchanged
  # But AWS requires that they be passed
  request_parameters = {
    QueueUrl    = aws_sqs_queue.main.id
    MessageBody = "$request.body"
  }
}

Debug Output

Here's the relevant part of the debug output after successfully applying, updating aws_apigatewayv2_integration.main.description and attempting to apply again:

https://gist.github.com/dleavitt/8d5abb1e3fb9bcbb429447b667ce8f5f

Expected Behavior

terraform apply should succeed.

Specifically, terraform should pass the two values in request_parameters: QueueUrl and MessageBody, even though they haven't changed.

Actual Behavior

Terraform does not pass these two values, so updating the resource fails with the following error:

│ Error: error updating API Gateway v2 integration: BadRequestException: Operation: SQS-SendMessage requires enabling passthrough, or defining all of the following parameters in the parameter mapping: [QueueUrl, MessageBody] │ │ with aws_apigatewayv2_integration.main, │ on sqs_repro.tf line 25, in resource "aws_apigatewayv2_integration" "main": │ 25: resource "aws_apigatewayv2_integration" "main" { │

Steps to Reproduce

  1. Apply the attached configuration via terraform apply. It should succeed.
  2. Update any field in aws_apigatewayv2_integration.main other than request_parameters. I changed the description from "SQS Repro Test" to "SQS Repro Test!".
  3. Apply the terraform configuration again via terraform apply.

Changing either of QueueUrl or MessageBody will force TF to resend all request parameters and will cause step 3 to succeed per #15894

References

Partially fixed by #15894

The above fixes the issue only when other request parameters change. However, if other attributes of the integration change but the request parameters don't, the request parameters won't be passed.

Specifically, this conditional seems incorrect; all request parameters need to be passed any time the resource is updated:

https://github.com/hashicorp/terraform-provider-aws/blob/3c1fd63d8e058f05beecbac4c70b52877d8a5eb6/internal/service/apigatewayv2/integration.go#L328

Full Terraform Config File

variable "name" {
  default = "repro-sqs-queue"
}

#
# Problem resource:
# Works when initially provisioned
# Fails when updating (e.g. by changing the description) with:
#
# error updating API Gateway v2 integration: BadRequestException: Operation: 
#   SQS-SendMessage requires enabling passthrough, or defining all of the 
#   following parameters in the parameter mapping: [QueueUrl, MessageBody]
#
resource "aws_apigatewayv2_integration" "main" {
  api_id              = aws_apigatewayv2_api.main.id
  credentials_arn     = aws_iam_role.main.arn
  integration_type    = "AWS_PROXY"
  integration_subtype = "SQS-SendMessage"
  description         = "SQS Repro Test"

  # These don't appear to be passed when updating if unchanged
  # But AWS requires that they be passed
  request_parameters = {
    QueueUrl    = aws_sqs_queue.main.id
    MessageBody = "$request.body"
  }
}

resource "aws_apigatewayv2_route" "main" {
  api_id         = aws_apigatewayv2_api.main.id
  route_key      = "POST /"
  operation_name = var.name

  target = "integrations/${aws_apigatewayv2_integration.main.id}"
}

#
# Other supporting setup
#
resource "aws_apigatewayv2_api" "main" {
  name          = "Repro Example"
  protocol_type = "HTTP"
}

resource "aws_sqs_queue" "main" {
  name = var.name
}

resource "aws_iam_role" "main" {
  name = "sqs-send-message-for-${var.name}"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "apigateway.amazonaws.com"
        }
      },
    ]
  })

  inline_policy {
    name = "sqs-send-message-for-${var.name}"
    policy = jsonencode({
      "Version" : "2012-10-17",
      "Statement" : [
        {
          "Action" : [
            "sqs:SendMessage"
          ],
          "Effect" : "Allow",
          "Resource" : "${aws_sqs_queue.main.arn}"
        }
      ]
      }
    )
  }
}
andreas-trvlk commented 2 years ago

Hi folks. Any plan to release the fix? This bug is blocking our deployment. Do you have any workaround to fix the issue?

ankur913 commented 2 years ago

hello Folks, I am also stuck with this issue, do we have any workarounds?? Thanks!!

JustellVonk commented 2 years ago

Have same problem here

skasyn commented 1 year ago

This problem still exists. We recreate integrations when encountering this issue instead of simply updating them.

duncanhall commented 1 year ago

@justinretzolk Apologies for the @ but wondering if there's any planned resolution for this or suggested workaround? As it stands, it seems to make the aws_apigatewayv2_integration resource completely unusable with SQS or other services needing request_parameters.

I can try to put together a fix with a bit of direction. As @dleavitt originally noted, the issue seems to be around the use of HasChange("request_parameters"). Is it a satisfactory fix to change this conditional to always submit request_parameters if they are present? Is there any precedent / example code of a resource doing similar elsewhere?

The relevant code block now seems to be https://github.com/hashicorp/terraform-provider-aws/blob/main/internal/service/apigatewayv2/integration.go#L335-L354

nickhealy commented 1 year ago

Also having the same problem, but with Kinesis integration

ivan-kiselev commented 1 year ago

Still present for SQS

marco-mald commented 9 months ago

Same issue here, now with Step function