-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Description
Description:
This is related to #651 where it was requested to have a way to apply an Event to certain CloudFormation Resources. The ask was to simplify the integration of API Gateway to other AWS services like SQS, SNS, DynamoDB, etc.
To do this today, one needs to pour through API Gateway documentation, posted online examples, and stitch together a full swagger definition for their API. The simplify of SAM is lost when the swagger definition is brought into play.
I'd like to propose the introduction of a new SAM type meant to represent an AWS service integration to an API Gateway and generate the required swagger elements/extensions for the developer.
Current Example
Here is a template from an example I posted in that issue (integrating an SQS queue with an API Gateway):
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: >-
Create an API Gateway integrated with an SQS queue that is processed by a
Lambda function as messages are populated.
Resources:
QueueApiGateway:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
DefinitionBody:
swagger: "2.0"
info:
title: !Ref AWS::StackName
paths:
"/":
post:
consumes:
- "application/json"
produces:
- "application/json"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/Empty"
x-amazon-apigateway-integration:
credentials: !GetAtt QueueApiGatewayRole.Arn
uri: !Sub "arn:aws:apigateway:${AWS::Region}:sqs:path//"
responses:
default:
statusCode: "200"
requestParameters:
integration.request.header.Content-Type: "'application/x-www-form-urlencoded'"
requestTemplates:
application/json: !Sub "Action=SendMessage##\n&QueueUrl=$util.urlEncode('${ApiQueue}')##\n\
&MessageBody=$util.urlEncode($input.body)##\n"
passthroughBehavior: "never"
httpMethod: "POST"
type: "aws"
definitions:
Empty:
type: "object"
title: "Empty Schema"
ApiQueue:
Type: AWS::SQS::Queue
QueueApiGatewayRole:
Type: AWS::IAM::Role
Properties:
Path: "/"
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- apigateway.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs
Policies:
- PolicyName: ApiQueuePolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- sqs:ReceiveMessage
- sqs:SendMessage
Resource: !GetAtt ApiQueue.ArnProposed Example
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Resources:
QueueApiGateway:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
ApiQueue:
Type: AWS::SQS::Queue
QueueApiIntegration:
Type: AWS::Serverless::ApiIntegration
Properties:
RestApiId: !Ref QueueApiGateway
Path: /
Method: post
Service:
Type: SQS
Properties:
QueueUrl: !Ref ApiQueue
Method: post
I won't pretend to know much about performing these service integrations. The idea with my proposed model is to strip away the swagger work and match how other SAM resources operated. All of the information required to infer the SQS integration in swagger are present in the Service payload (assuming the intent of this integration is to sent the HTTP payload as the MessageBody).
This resource would support multiple service types much like Events with functions. If a RestApiId is not provided it would use the implicit API created by SAM. The resource policy would be generated automatically using the !Refs between the API and the queue.
I think there's a huge opportunity for SAM to make these types of service integrations easier to adopt for AWS developers. While we hear and know that having a Lambda in-between an API and a service can be a waste, or unnecessary, it's usually the easier path.