Reputation: 65
I am trying to integrate an API Gateway WebSocket Route with SQS.
I have configured the SQS Integration with below properties
AWS Region: ap-southeast-1 AWS Service: SQS HTTP Method : POST Path override: 111111110111/my-queue
Configured Request Template as
"Action=SendMessage&MessageBody=$util.urlEncode($input.body)##
When I try to send the data to SQS it is failing with below error
Error:
(VK1mEHZSyQ0FlZg=) Endpoint request body after transformations: Action=SendMessage&MessageBody=foobar (VK1mEHZSyQ0FlZg=) Sending request to https://sqs.ap-southeast-1.amazonaws.com/111111110111/my-queue (VK1mEHZSyQ0FlZg=) Received response. Integration latency: 16 ms (VK1mEHZSyQ0FlZg=) Endpoint response body before transformations: Unable to determine service/operation name to be authorized
Upvotes: 3
Views: 4840
Reputation: 23
To elevate @Aksel's answer answer: here's a Terraform solution; in case anyone is searching for it.
The example given from Terraform's documentation doesn't work for me.
The following tf files are based on @Aksel's answer
# main.tf
# AWS region
variable "aws_region" {
description = "AWS region"
type = string
default = "ap-southeast-1"
# default = "ap-northeast-1"
# default = "us-east-1"
}
# Caller identity
data "aws_caller_identity" "current" {}
# iam.tf
resource "aws_iam_role" "apigw_sqs_role" {
name = "api_sqs_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_role_policy" "allow_apigw_sqs_policy" {
name = "allow_apigw_sqs_policy"
role = aws_iam_role.apigw_sqs_role.id
policy = <<EOF
{
"Version":"2012-10-17",
"Statement":[{
"Effect":"Allow",
"Action":[
"sqs:SendMessage",
],
"Resource":"*"
}]
}
EOF
}
# sqs.tf
resource "aws_sqs_queue" "my_sqs_queue" {
name = "my-queue"
}
integration_type = "AWS"
and integration_method = "POST"
integration_uri
= arn:aws:apigateway:<aws_region>:sqs:path/<aws_account_id>/<sqs_name>
arn:aws:apigateway:ap-southeast-1:sqs:path/111111110111/my-queue
credentials_arn
is the role defined in iam.tf
# apigateway.tf
# API Gateway
resource "aws_apigatewayv2_api" "apigw_websocket" {
name = "websocket-api"
protocol_type = "WEBSOCKET"
route_selection_expression = "$request.body.action"
}
resource "aws_apigatewayv2_route" "apigw_websocket_default_route" {
api_id = aws_apigatewayv2_api.apigw_websocket.id
route_key = "$default"
route_response_selection_expression = "$default"
target = "integrations/${aws_apigatewayv2_integration.apigw_websocket_default_integration_sqs.id}"
}
resource "aws_apigatewayv2_integration" "apigw_websocket_default_integration_sqs" {
api_id = aws_apigatewayv2_api.apigw_websocket.id
integration_type = "AWS"
integration_method = "POST"
integration_uri = "arn:aws:apigateway:${var.aws_region}:sqs:path/${data.aws_caller_identity.current.account_id}/${aws_sqs_queue.my_sqs_queue.name}/"
credentials_arn = aws_iam_role.apigw_sqs_role.arn
passthrough_behavior = "NEVER"
request_parameters = {
"integration.request.header.Content-Type" = "'application/x-www-form-urlencoded'"
}
request_templates = {
"application/json" : "Action=SendMessage&MessageBody=$util.urlEncode($input.body)"
}
}
Upvotes: 1
Reputation: 83
Almost a year late, but I figured out a way to do this. You can't do it from the console itself, but you can get it to work via the CLI.
Most of the steps are covered in this guide, but make it a WS api instead of REST api.
You'll notice that it isn't possible to specify HTTP header, nor is it possible to specify the mapping template. For some reason, this isn't available on the console. You'll have to do this via the CLI instead. Save the following as a JSON file.
{
"PassthroughBehavior": "NEVER",
"RequestParameters": {
"integration.request.header.Content-Type": "'application/x-www-form-urlencoded'"
},
"RequestTemplates": {
"application/json": "Action=SendMessage&MessageBody=$util.urlEncode($input.body)"
}
}
And update the integration like so:
aws apigatewayv2 update-integration \
--api-id API_ID \
--integration-id INTEGRATION_ID \
--cli-input-json file://update.json
You'll see the API id on the console on the API overview, but the integration ID you'll have to find via the CLI, like so:
aws apigatewayv2 get-integrations --api-id API_ID
This results in the body itself being sent as plaintext to the SQS queue.
Note: You can forego all of this if you create the API with CloudFormation/SAM, as that enables you to set RequestParameters and RequestTemplates directly.
Upvotes: 8