CloudFormation
1,385 lines of IaC template
{
"AWSTemplateFormatVersion": "2010-09-09",
"Transform": "AWS::Serverless-2016-10-31",
"Description": "Example: kitchen sink",
"Resources": {
"Role": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
},
"Policies": [
{
"PolicyName": "ArcGlobalPolicy",
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
},
{
"PolicyName": "ArcStaticBucketPolicy",
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
{
"Fn::Sub": [
"arn:aws:s3:::${bukkit}",
{
"bukkit": {
"Ref": "StaticBucket"
}
}
]
},
{
"Fn::Sub": [
"arn:aws:s3:::${bukkit}/*",
{
"bukkit": {
"Ref": "StaticBucket"
}
}
]
}
]
}
]
}
},
{
"PolicyName": "ArcDynamoPolicy",
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Action": "dynamodb:*",
"Resource": [
{
"Fn::Sub": [
"arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tablename}",
{
"tablename": {
"Ref": "LikesTable"
}
}
]
},
{
"Fn::Sub": [
"arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tablename}/*",
{
"tablename": {
"Ref": "LikesTable"
}
}
]
}
]
},
{
"Effect": "Deny",
"Action": "dynamodb:DeleteTable",
"Resource": {
"Fn::Sub": "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/*"
}
}
]
}
},
{
"PolicyName": "ArcSimpleNotificationServicePolicy",
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": {
"Fn::Sub": [
"arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${AWS::StackName}*",
{}
]
}
}
]
}
}
]
}
},
"LikesParam": {
"Type": "AWS::SSM::Parameter",
"Properties": {
"Type": "String",
"Name": {
"Fn::Sub": [
"/${AWS::StackName}/tables/${tablename}",
{
"tablename": "likes"
}
]
},
"Value": {
"Ref": "LikesTable"
}
}
},
"HitCounterEventTopicParam": {
"Type": "AWS::SSM::Parameter",
"Properties": {
"Type": "String",
"Name": {
"Fn::Sub": [
"/${AWS::StackName}/events/${event}",
{
"event": "hit-counter"
}
]
},
"Value": {
"Ref": "HitCounterEventTopic"
}
}
},
"StaticBucketParam": {
"Type": "AWS::SSM::Parameter",
"Properties": {
"Type": "String",
"Name": {
"Fn::Sub": [
"/${AWS::StackName}/static/${key}",
{
"key": "bucket"
}
]
},
"Value": {
"Ref": "StaticBucket"
}
}
},
"StaticFingerprintParam": {
"Type": "AWS::SSM::Parameter",
"Properties": {
"Type": "String",
"Name": {
"Fn::Sub": [
"/${AWS::StackName}/static/${key}",
{
"key": "fingerprint"
}
]
},
"Value": "true"
}
},
"ParameterStorePolicy": {
"Type": "AWS::IAM::Policy",
"DependsOn": "Role",
"Properties": {
"PolicyName": "ArcParameterStorePolicy",
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetParametersByPath",
"ssm:GetParameter"
],
"Resource": {
"Fn::Sub": [
"arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${AWS::StackName}",
{}
]
}
},
{
"Effect": "Allow",
"Action": [
"ssm:GetParametersByPath",
"ssm:GetParameter"
],
"Resource": {
"Fn::Sub": [
"arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${AWS::StackName}/*",
{}
]
}
},
{
"Effect": "Allow",
"Action": [
"ssm:GetParametersByPath",
"ssm:GetParameter"
],
"Resource": {
"Fn::Sub": [
"arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${AWS::StackName}/*/*",
{}
]
}
}
]
},
"Roles": [
{
"Ref": "Role"
}
]
}
},
"HTTP": {
"Type": "AWS::Serverless::HttpApi",
"Properties": {
"StageName": "$default",
"DefinitionBody": {
"openapi": "3.0.1",
"info": {
"title": {
"Ref": "AWS::StackName"
}
},
"paths": {
"/likes": {
"get": {
"x-amazon-apigateway-integration": {
"payloadFormatVersion": "2.0",
"type": "aws_proxy",
"httpMethod": "POST",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetLikesHTTPLambda.Arn}/invocations"
},
"connectionType": "INTERNET"
}
},
"post": {
"x-amazon-apigateway-integration": {
"payloadFormatVersion": "2.0",
"type": "aws_proxy",
"httpMethod": "POST",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PostLikesHTTPLambda.Arn}/invocations"
},
"connectionType": "INTERNET"
}
}
},
"/": {
"get": {
"x-amazon-apigateway-integration": {
"payloadFormatVersion": "2.0",
"type": "aws_proxy",
"httpMethod": "POST",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetIndexHTTPLambda.Arn}/invocations"
},
"connectionType": "INTERNET"
}
}
},
"/_static/{proxy+}": {
"get": {
"x-amazon-apigateway-integration": {
"payloadFormatVersion": "1.0",
"type": "http_proxy",
"httpMethod": "GET",
"uri": {
"Fn::Sub": [
"https://${bukkit}.s3.${AWS::Region}.amazonaws.com/{proxy}",
{
"bukkit": {
"Ref": "StaticBucket"
}
}
]
},
"connectionType": "INTERNET",
"timeoutInMillis": 30000
}
}
}
}
}
}
},
"GetLikesHTTPLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/var/task/src/http/get-likes",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "hello",
"ARC_ENV": "staging",
"ARC_ROLE": {
"Ref": "Role"
},
"ARC_SESSION_TABLE_NAME": "jwe",
"ARC_STACK_NAME": {
"Ref": "AWS::StackName"
},
"ARC_STATIC_BUCKET": {
"Ref": "StaticBucket"
},
"ARC_WSS_URL": {
"Fn::Sub": [
"wss://${WS}.execute-api.${AWS::Region}.amazonaws.com/staging",
{}
]
}
}
},
"Role": {
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:role/${roleName}",
{
"roleName": {
"Ref": "Role"
}
}
]
},
"Events": {
"GetLikesHTTPEvent": {
"Type": "HttpApi",
"Properties": {
"Path": "/likes",
"Method": "GET",
"ApiId": {
"Ref": "HTTP"
}
}
}
}
},
"ArcMetadata": {
"pragma": "http",
"name": "get /likes",
"method": "get",
"path": "/likes"
}
},
"GetIndexHTTPLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/var/task/src/http/get-index",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "hello",
"ARC_ENV": "staging",
"ARC_ROLE": {
"Ref": "Role"
},
"ARC_SESSION_TABLE_NAME": "jwe",
"ARC_STACK_NAME": {
"Ref": "AWS::StackName"
},
"ARC_STATIC_BUCKET": {
"Ref": "StaticBucket"
},
"ARC_WSS_URL": {
"Fn::Sub": [
"wss://${WS}.execute-api.${AWS::Region}.amazonaws.com/staging",
{}
]
},
"ARC_STATIC_SPA": false
}
},
"Role": {
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:role/${roleName}",
{
"roleName": {
"Ref": "Role"
}
}
]
},
"Events": {
"GetIndexHTTPEvent": {
"Type": "HttpApi",
"Properties": {
"Path": "/",
"Method": "GET",
"ApiId": {
"Ref": "HTTP"
}
}
}
}
},
"ArcMetadata": {
"pragma": "http",
"name": "get /",
"method": "get",
"path": "/"
}
},
"PostLikesHTTPLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/var/task/src/http/post-likes",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "hello",
"ARC_ENV": "staging",
"ARC_ROLE": {
"Ref": "Role"
},
"ARC_SESSION_TABLE_NAME": "jwe",
"ARC_STACK_NAME": {
"Ref": "AWS::StackName"
},
"ARC_STATIC_BUCKET": {
"Ref": "StaticBucket"
},
"ARC_WSS_URL": {
"Fn::Sub": [
"wss://${WS}.execute-api.${AWS::Region}.amazonaws.com/staging",
{}
]
}
}
},
"Role": {
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:role/${roleName}",
{
"roleName": {
"Ref": "Role"
}
}
]
},
"Events": {
"PostLikesHTTPEvent": {
"Type": "HttpApi",
"Properties": {
"Path": "/likes",
"Method": "POST",
"ApiId": {
"Ref": "HTTP"
}
}
}
}
},
"ArcMetadata": {
"pragma": "http",
"name": "post /likes",
"method": "post",
"path": "/likes"
}
},
"LikesTable": {
"Type": "AWS::DynamoDB::Table",
"Properties": {
"KeySchema": [
{
"AttributeName": "likeID",
"KeyType": "HASH"
}
],
"AttributeDefinitions": [
{
"AttributeName": "likeID",
"AttributeType": "S"
},
{
"AttributeName": "date",
"AttributeType": "S"
}
],
"BillingMode": "PAY_PER_REQUEST",
"GlobalSecondaryIndexes": [
{
"IndexName": "date-index",
"KeySchema": [
{
"AttributeName": "date",
"KeyType": "HASH"
}
],
"Projection": {
"ProjectionType": "ALL"
}
}
],
"StreamSpecification": {
"StreamViewType": "NEW_AND_OLD_IMAGES"
}
}
},
"HitCounterEventLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/var/task/src/events/hit-counter",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "hello",
"ARC_ENV": "staging",
"ARC_ROLE": {
"Ref": "Role"
},
"ARC_SESSION_TABLE_NAME": "jwe",
"ARC_STACK_NAME": {
"Ref": "AWS::StackName"
},
"ARC_STATIC_BUCKET": {
"Ref": "StaticBucket"
},
"ARC_WSS_URL": {
"Fn::Sub": [
"wss://${WS}.execute-api.${AWS::Region}.amazonaws.com/staging",
{}
]
}
}
},
"Role": {
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:role/${roleName}",
{
"roleName": {
"Ref": "Role"
}
}
]
},
"Events": {
"HitCounterEvent": {
"Type": "SNS",
"Properties": {
"Topic": {
"Ref": "HitCounterEventTopic"
}
}
}
}
},
"ArcMetadata": {
"pragma": "events",
"name": "hit-counter"
}
},
"HitCounterEventTopic": {
"Type": "AWS::SNS::Topic",
"Properties": {
"DisplayName": "HitCounter",
"Subscription": []
}
},
"DailyAffirmationScheduledLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/var/task/src/scheduled/daily-affirmation",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "hello",
"ARC_ENV": "staging",
"ARC_ROLE": {
"Ref": "Role"
},
"ARC_SESSION_TABLE_NAME": "jwe",
"ARC_STACK_NAME": {
"Ref": "AWS::StackName"
},
"ARC_STATIC_BUCKET": {
"Ref": "StaticBucket"
},
"ARC_WSS_URL": {
"Fn::Sub": [
"wss://${WS}.execute-api.${AWS::Region}.amazonaws.com/staging",
{}
]
}
}
},
"Role": {
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:role/${roleName}",
{
"roleName": {
"Ref": "Role"
}
}
]
},
"Events": {}
},
"ArcMetadata": {
"pragma": "scheduled",
"name": "daily-affirmation"
}
},
"DailyAffirmationScheduledEvent": {
"Type": "AWS::Events::Rule",
"Properties": {
"ScheduleExpression": "rate(1 day)",
"Targets": [
{
"Arn": {
"Fn::GetAtt": [
"DailyAffirmationScheduledLambda",
"Arn"
]
},
"Id": "DailyAffirmationScheduledLambda"
}
]
}
},
"DailyAffirmationScheduledPermission": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "DailyAffirmationScheduledLambda"
},
"Principal": "events.amazonaws.com",
"SourceArn": {
"Fn::GetAtt": [
"DailyAffirmationScheduledEvent",
"Arn"
]
}
}
},
"StaticBucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"OwnershipControls": {
"Rules": [
{
"ObjectOwnership": "BucketOwnerEnforced"
}
]
},
"WebsiteConfiguration": {
"IndexDocument": "index.html",
"ErrorDocument": "404.html"
},
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": false,
"BlockPublicPolicy": false,
"IgnorePublicAcls": false,
"RestrictPublicBuckets": false
}
}
},
"StaticBucketPolicy": {
"Type": "AWS::S3::BucketPolicy",
"Properties": {
"Bucket": {
"Ref": "StaticBucket"
},
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Principal": "*",
"Resource": [
{
"Fn::Sub": [
"arn:aws:s3:::${bukkit}/*",
{
"bukkit": {
"Ref": "StaticBucket"
}
}
]
}
],
"Sid": "PublicReadGetObject"
}
]
}
}
},
"LikesTableStreamLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/var/task/src/tables-streams/likes",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "hello",
"ARC_ENV": "staging",
"ARC_ROLE": {
"Ref": "Role"
},
"ARC_SESSION_TABLE_NAME": "jwe",
"ARC_STACK_NAME": {
"Ref": "AWS::StackName"
},
"ARC_STATIC_BUCKET": {
"Ref": "StaticBucket"
},
"ARC_WSS_URL": {
"Fn::Sub": [
"wss://${WS}.execute-api.${AWS::Region}.amazonaws.com/staging",
{}
]
}
}
},
"Role": {
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:role/${roleName}",
{
"roleName": {
"Ref": "Role"
}
}
]
},
"Events": {}
},
"ArcMetadata": {
"pragma": "tables-streams",
"name": "likes"
}
},
"LikesTableStreamEvent": {
"Type": "AWS::Lambda::EventSourceMapping",
"Properties": {
"BatchSize": 10,
"EventSourceArn": {
"Fn::GetAtt": [
"LikesTable",
"StreamArn"
]
},
"FunctionName": {
"Fn::GetAtt": [
"LikesTableStreamLambda",
"Arn"
]
},
"StartingPosition": "TRIM_HORIZON"
}
},
"WS": {
"Type": "AWS::ApiGatewayV2::Api",
"Properties": {
"Name": "HelloWebsocketStaging",
"ProtocolType": "WEBSOCKET",
"RouteSelectionExpression": "$request.body.action"
}
},
"WebsocketDeployment": {
"Type": "AWS::ApiGatewayV2::Deployment",
"DependsOn": [
"ConnectWSRoute",
"DefaultWSRoute",
"DisconnectWSRoute"
],
"Properties": {
"ApiId": {
"Ref": "WS"
}
}
},
"WebsocketStage": {
"Type": "AWS::ApiGatewayV2::Stage",
"Properties": {
"StageName": "staging",
"DeploymentId": {
"Ref": "WebsocketDeployment"
},
"ApiId": {
"Ref": "WS"
}
}
},
"WebSocketPolicy": {
"Type": "AWS::IAM::Policy",
"DependsOn": "Role",
"Properties": {
"PolicyName": "ArcWebSocketPolicy",
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke",
"execute-api:ManageConnections"
],
"Resource": [
{
"Fn::Sub": [
"arn:aws:execute-api:${AWS::Region}:*:${api}/*",
{
"api": {
"Ref": "WS"
}
}
]
}
]
}
]
},
"Roles": [
{
"Ref": "Role"
}
]
}
},
"ActionWSLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/var/task/src/ws/action",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "hello",
"ARC_ENV": "staging",
"ARC_ROLE": {
"Ref": "Role"
},
"ARC_SESSION_TABLE_NAME": "jwe",
"ARC_STACK_NAME": {
"Ref": "AWS::StackName"
},
"ARC_STATIC_BUCKET": {
"Ref": "StaticBucket"
},
"ARC_WSS_URL": {
"Fn::Sub": [
"wss://${WS}.execute-api.${AWS::Region}.amazonaws.com/staging",
{}
]
}
}
},
"Role": {
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:role/${roleName}",
{
"roleName": {
"Ref": "Role"
}
}
]
},
"Events": {}
},
"ArcMetadata": {
"pragma": "ws",
"name": "action"
}
},
"ActionWSRoute": {
"Type": "AWS::ApiGatewayV2::Route",
"Properties": {
"ApiId": {
"Ref": "WS"
},
"RouteKey": "action",
"OperationName": "ActionWSRoute",
"Target": {
"Fn::Join": [
"/",
[
"integrations",
{
"Ref": "ActionWSIntegration"
}
]
]
}
}
},
"ActionWSIntegration": {
"Type": "AWS::ApiGatewayV2::Integration",
"Properties": {
"ApiId": {
"Ref": "WS"
},
"IntegrationType": "AWS_PROXY",
"IntegrationUri": {
"Fn::Sub": [
"arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ActionWSLambda.Arn}/invocations",
{}
]
}
}
},
"ActionWSPermission": {
"Type": "AWS::Lambda::Permission",
"DependsOn": [
"WS",
"ActionWSLambda"
],
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "ActionWSLambda"
},
"Principal": "apigateway.amazonaws.com"
}
},
"ConnectWSLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/var/task/src/ws/connect",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "hello",
"ARC_ENV": "staging",
"ARC_ROLE": {
"Ref": "Role"
},
"ARC_SESSION_TABLE_NAME": "jwe",
"ARC_STACK_NAME": {
"Ref": "AWS::StackName"
},
"ARC_STATIC_BUCKET": {
"Ref": "StaticBucket"
},
"ARC_WSS_URL": {
"Fn::Sub": [
"wss://${WS}.execute-api.${AWS::Region}.amazonaws.com/staging",
{}
]
}
}
},
"Role": {
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:role/${roleName}",
{
"roleName": {
"Ref": "Role"
}
}
]
},
"Events": {}
},
"ArcMetadata": {
"pragma": "ws",
"name": "connect"
}
},
"ConnectWSRoute": {
"Type": "AWS::ApiGatewayV2::Route",
"Properties": {
"ApiId": {
"Ref": "WS"
},
"RouteKey": "$connect",
"OperationName": "ConnectWSRoute",
"Target": {
"Fn::Join": [
"/",
[
"integrations",
{
"Ref": "ConnectWSIntegration"
}
]
]
}
}
},
"ConnectWSIntegration": {
"Type": "AWS::ApiGatewayV2::Integration",
"Properties": {
"ApiId": {
"Ref": "WS"
},
"IntegrationType": "AWS_PROXY",
"IntegrationUri": {
"Fn::Sub": [
"arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ConnectWSLambda.Arn}/invocations",
{}
]
}
}
},
"ConnectWSPermission": {
"Type": "AWS::Lambda::Permission",
"DependsOn": [
"WS",
"ConnectWSLambda"
],
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "ConnectWSLambda"
},
"Principal": "apigateway.amazonaws.com"
}
},
"DefaultWSLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/var/task/src/ws/default",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "hello",
"ARC_ENV": "staging",
"ARC_ROLE": {
"Ref": "Role"
},
"ARC_SESSION_TABLE_NAME": "jwe",
"ARC_STACK_NAME": {
"Ref": "AWS::StackName"
},
"ARC_STATIC_BUCKET": {
"Ref": "StaticBucket"
},
"ARC_WSS_URL": {
"Fn::Sub": [
"wss://${WS}.execute-api.${AWS::Region}.amazonaws.com/staging",
{}
]
}
}
},
"Role": {
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:role/${roleName}",
{
"roleName": {
"Ref": "Role"
}
}
]
},
"Events": {}
},
"ArcMetadata": {
"pragma": "ws",
"name": "default"
}
},
"DefaultWSRoute": {
"Type": "AWS::ApiGatewayV2::Route",
"Properties": {
"ApiId": {
"Ref": "WS"
},
"RouteKey": "$default",
"OperationName": "DefaultWSRoute",
"Target": {
"Fn::Join": [
"/",
[
"integrations",
{
"Ref": "DefaultWSIntegration"
}
]
]
}
}
},
"DefaultWSIntegration": {
"Type": "AWS::ApiGatewayV2::Integration",
"Properties": {
"ApiId": {
"Ref": "WS"
},
"IntegrationType": "AWS_PROXY",
"IntegrationUri": {
"Fn::Sub": [
"arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DefaultWSLambda.Arn}/invocations",
{}
]
}
}
},
"DefaultWSPermission": {
"Type": "AWS::Lambda::Permission",
"DependsOn": [
"WS",
"DefaultWSLambda"
],
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "DefaultWSLambda"
},
"Principal": "apigateway.amazonaws.com"
}
},
"DisconnectWSLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/var/task/src/ws/disconnect",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "hello",
"ARC_ENV": "staging",
"ARC_ROLE": {
"Ref": "Role"
},
"ARC_SESSION_TABLE_NAME": "jwe",
"ARC_STACK_NAME": {
"Ref": "AWS::StackName"
},
"ARC_STATIC_BUCKET": {
"Ref": "StaticBucket"
},
"ARC_WSS_URL": {
"Fn::Sub": [
"wss://${WS}.execute-api.${AWS::Region}.amazonaws.com/staging",
{}
]
}
}
},
"Role": {
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:role/${roleName}",
{
"roleName": {
"Ref": "Role"
}
}
]
},
"Events": {}
},
"ArcMetadata": {
"pragma": "ws",
"name": "disconnect"
}
},
"DisconnectWSRoute": {
"Type": "AWS::ApiGatewayV2::Route",
"Properties": {
"ApiId": {
"Ref": "WS"
},
"RouteKey": "$disconnect",
"OperationName": "DisconnectWSRoute",
"Target": {
"Fn::Join": [
"/",
[
"integrations",
{
"Ref": "DisconnectWSIntegration"
}
]
]
}
}
},
"DisconnectWSIntegration": {
"Type": "AWS::ApiGatewayV2::Integration",
"Properties": {
"ApiId": {
"Ref": "WS"
},
"IntegrationType": "AWS_PROXY",
"IntegrationUri": {
"Fn::Sub": [
"arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DisconnectWSLambda.Arn}/invocations",
{}
]
}
}
},
"DisconnectWSPermission": {
"Type": "AWS::Lambda::Permission",
"DependsOn": [
"WS",
"DisconnectWSLambda"
],
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "DisconnectWSLambda"
},
"Principal": "apigateway.amazonaws.com"
}
}
},
"Outputs": {
"API": {
"Description": "API Gateway (HTTP)",
"Value": {
"Fn::Sub": [
"https://${ApiId}.execute-api.${AWS::Region}.amazonaws.com",
{
"ApiId": {
"Ref": "HTTP"
}
}
]
}
},
"ApiId": {
"Description": "API ID (ApiId)",
"Value": {
"Ref": "HTTP"
}
},
"HitCounterEventTopic": {
"Description": "An SNS Topic",
"Value": {
"Ref": "HitCounterEventTopic"
}
},
"BucketURL": {
"Description": "Bucket URL",
"Value": {
"Fn::Sub": [
"http://${bukkit}.s3-website-${AWS::Region}.amazonaws.com",
{
"bukkit": {
"Ref": "StaticBucket"
}
}
]
}
},
"WSS": {
"Description": "WebSocket Endpoint",
"Value": {
"Fn::Sub": [
"wss://${WS}.execute-api.${AWS::Region}.amazonaws.com/staging",
{}
]
}
}
}
}