{ "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", "Description": "An AWS Serverless Application.", "Parameters": { "ConnectionMappingTableName": { "Type": "String", "Default": "SimpleChatConnections", "Description": "The name of the new DynamoDB to store connection identifiers for each connected clients. Minimum 3 characters.", "MinLength": "3", "MaxLength": "50", "AllowedPattern": "^[A-Za-z_]+$" } }, "Resources": { "ConnectionMappingTable": { "Type": "AWS::DynamoDB::Table", "Properties": { "TableName": { "Ref": "ConnectionMappingTableName" }, "AttributeDefinitions": [ { "AttributeName": "connectionId", "AttributeType": "S" } ], "KeySchema": [ { "AttributeName": "connectionId", "KeyType": "HASH" } ], "BillingMode": "PAY_PER_REQUEST" } }, "OnConnectFunction": { "Type": "AWS::Serverless::Function", "Properties": { "Handler": "BlueprintBaseName.1::BlueprintBaseName._1.Functions::OnConnectHandler", "Runtime": "dotnet6", "CodeUri": "", "MemorySize": 256, "Timeout": 30, "Role": null, "Policies": [ { "DynamoDBCrudPolicy": { "TableName": { "Ref": "ConnectionMappingTableName" } } } ], "Environment": { "Variables": { "TABLE_NAME": { "Ref": "ConnectionMappingTableName" } } } } }, "OnDisconnectFunction": { "Type": "AWS::Serverless::Function", "Properties": { "Handler": "BlueprintBaseName.1::BlueprintBaseName._1.Functions::OnDisconnectHandler", "Runtime": "dotnet6", "CodeUri": "", "MemorySize": 256, "Timeout": 30, "Role": null, "Policies": [ { "DynamoDBCrudPolicy": { "TableName": { "Ref": "ConnectionMappingTableName" } } } ], "Environment": { "Variables": { "TABLE_NAME": { "Ref": "ConnectionMappingTableName" } } } } }, "SendMessageFunction": { "Type": "AWS::Serverless::Function", "Properties": { "Handler": "BlueprintBaseName.1::BlueprintBaseName._1.Functions::SendMessageHandler", "Runtime": "dotnet6", "CodeUri": "", "MemorySize": 256, "Timeout": 30, "Role": null, "Policies": [ { "DynamoDBCrudPolicy": { "TableName": { "Ref": "ConnectionMappingTableName" } } }, { "Statement": { "Effect": "Allow", "Action": "execute-api:ManageConnections", "Resource": "arn:aws:execute-api:*:*:*/@connections/*" } } ], "Environment": { "Variables": { "TABLE_NAME": { "Ref": "ConnectionMappingTableName" } } } } }, "SimpleChatWebSocketApi": { "Type": "AWS::ApiGatewayV2::Api", "Properties": { "Name": "SimpleChatWebSocket", "ProtocolType": "WEBSOCKET", "RouteSelectionExpression": "$request.body.message" } }, "ConnectRoute": { "Type": "AWS::ApiGatewayV2::Route", "Properties": { "ApiId": { "Ref": "SimpleChatWebSocketApi" }, "RouteKey": "$connect", "AuthorizationType": "NONE", "OperationName": "ConnectRoute", "Target": { "Fn::Join": [ "/", [ "integrations", { "Ref": "ConnectInteg" } ] ] } } }, "ConnectInteg": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { "Ref": "SimpleChatWebSocketApi" }, "IntegrationType": "AWS_PROXY", "IntegrationUri": { "Fn::Sub": [ "arn:aws:apigateway:${region}:lambda:path/2015-03-31/functions/${function}/invocations", { "region": { "Ref": "AWS::Region" }, "function": { "Fn::GetAtt": [ "OnConnectFunction", "Arn" ] } } ] } } }, "DisconnectRoute": { "Type": "AWS::ApiGatewayV2::Route", "Properties": { "ApiId": { "Ref": "SimpleChatWebSocketApi" }, "RouteKey": "$disconnect", "AuthorizationType": "NONE", "OperationName": "ConnectRoute", "Target": { "Fn::Join": [ "/", [ "integrations", { "Ref": "DisconnectInteg" } ] ] } } }, "DisconnectInteg": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { "Ref": "SimpleChatWebSocketApi" }, "IntegrationType": "AWS_PROXY", "IntegrationUri": { "Fn::Sub": [ "arn:aws:apigateway:${region}:lambda:path/2015-03-31/functions/${function}/invocations", { "region": { "Ref": "AWS::Region" }, "function": { "Fn::GetAtt": [ "OnDisconnectFunction", "Arn" ] } } ] } } }, "SendMessageRoute": { "Type": "AWS::ApiGatewayV2::Route", "Properties": { "ApiId": { "Ref": "SimpleChatWebSocketApi" }, "RouteKey": "sendmessage", "AuthorizationType": "NONE", "OperationName": "ConnectRoute", "Target": { "Fn::Join": [ "/", [ "integrations", { "Ref": "SendMessageInteg" } ] ] } } }, "SendMessageInteg": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { "Ref": "SimpleChatWebSocketApi" }, "IntegrationType": "AWS_PROXY", "IntegrationUri": { "Fn::Sub": [ "arn:aws:apigateway:${region}:lambda:path/2015-03-31/functions/${function}/invocations", { "region": { "Ref": "AWS::Region" }, "function": { "Fn::GetAtt": [ "SendMessageFunction", "Arn" ] } } ] } } }, "Deployment": { "Type": "AWS::ApiGatewayV2::Deployment", "DependsOn": [ "ConnectRoute", "SendMessageRoute", "DisconnectRoute" ], "Properties": { "ApiId": { "Ref": "SimpleChatWebSocketApi" } } }, "Stage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { "ApiId": { "Ref": "SimpleChatWebSocketApi" }, "DeploymentId": { "Ref": "Deployment" }, "StageName": "Prod" } }, "OnConnectPermission": { "Type": "AWS::Lambda::Permission", "DependsOn": [ "OnConnectFunction", "SimpleChatWebSocketApi" ], "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { "Ref": "OnConnectFunction" }, "Principal": "apigateway.amazonaws.com" } }, "OnDisconnectPermission": { "Type": "AWS::Lambda::Permission", "DependsOn": [ "OnDisconnectFunction", "SimpleChatWebSocketApi" ], "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { "Ref": "OnDisconnectFunction" }, "Principal": "apigateway.amazonaws.com" } }, "SendMessagePermission": { "Type": "AWS::Lambda::Permission", "DependsOn": [ "SendMessageFunction", "SimpleChatWebSocketApi" ], "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { "Ref": "SendMessageFunction" }, "Principal": "apigateway.amazonaws.com" } } }, "Outputs": { "WebSocketURI": { "Value": { "Fn::Join": [ "", [ "wss://", { "Ref": "SimpleChatWebSocketApi" }, ".execute-api.", { "Ref": "AWS::Region" }, ".amazonaws.com/", { "Ref": "Stage" } ] ] }, "Description": "The WSS Protocol URI to connect to" } } }