Skip to content

Instantly share code, notes, and snippets.

@brianleroux
Created March 13, 2024 16:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianleroux/8629c5190826b3d64807afc152179c44 to your computer and use it in GitHub Desktop.
Save brianleroux/8629c5190826b3d64807afc152179c44 to your computer and use it in GitHub Desktop.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Transform": "AWS::Serverless-2016-10-31",
"Description": "Exported by architect/package@9.0.0-RC.1 on 2024-03-13T16:59:13.480Z",
"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": "ArcSimpleNotificationServicePolicy",
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": {
"Fn::Sub": [
"arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${AWS::StackName}*",
{}
]
}
}
]
}
},
{
"PolicyName": "ArcSimpleQueueServicePolicy",
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Action": [
"sqs:SendMessageBatch",
"sqs:SendMessage",
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes"
],
"Resource": "*"
}
]
}
}
]
}
},
"EEventTopicParam": {
"Type": "AWS::SSM::Parameter",
"Properties": {
"Type": "String",
"Name": {
"Fn::Sub": [
"/${AWS::StackName}/events/${event}",
{
"event": "e"
}
]
},
"Value": {
"Ref": "EEventTopic"
}
}
},
"QQueueParam": {
"Type": "AWS::SSM::Parameter",
"Properties": {
"Type": "String",
"Name": {
"Fn::Sub": [
"/${AWS::StackName}/queues/${queue}",
{
"queue": "q"
}
]
},
"Value": {
"Ref": "QQueue"
}
}
},
"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": "false"
}
},
"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": {
"/": {
"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
}
}
}
}
}
}
},
"GetIndexHTTPLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/Users/brian/Desktop/foobar/src/http/get-index",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "foobar",
"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": "/"
}
},
"EEventLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/Users/brian/Desktop/foobar/src/events/e",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "foobar",
"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": {
"EEvent": {
"Type": "SNS",
"Properties": {
"Topic": {
"Ref": "EEventTopic"
}
}
}
}
},
"ArcMetadata": {
"pragma": "events",
"name": "e"
}
},
"EEventTopic": {
"Type": "AWS::SNS::Topic",
"Properties": {
"DisplayName": "E",
"Subscription": []
}
},
"QQueueLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/Users/brian/Desktop/foobar/src/queues/q",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "foobar",
"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": {
"QQueueEvent": {
"Type": "SQS",
"Properties": {
"Queue": {
"Fn::GetAtt": [
"QQueue",
"Arn"
]
}
}
}
}
},
"ArcMetadata": {
"pragma": "queues",
"name": "q"
}
},
"QQueue": {
"Type": "AWS::SQS::Queue",
"Properties": {
"VisibilityTimeout": 5,
"FifoQueue": true,
"ContentBasedDeduplication": true
}
},
"OnceScheduledLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/Users/brian/Desktop/foobar/src/scheduled/once",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "foobar",
"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": "once"
}
},
"OnceScheduledEvent": {
"Type": "AWS::Events::Rule",
"Properties": {
"ScheduleExpression": "rate(1 day)",
"Targets": [
{
"Arn": {
"Fn::GetAtt": [
"OnceScheduledLambda",
"Arn"
]
},
"Id": "OnceScheduledLambda"
}
]
}
},
"OnceScheduledPermission": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "OnceScheduledLambda"
},
"Principal": "events.amazonaws.com",
"SourceArn": {
"Fn::GetAtt": [
"OnceScheduledEvent",
"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"
}
]
}
}
},
"WS": {
"Type": "AWS::ApiGatewayV2::Api",
"Properties": {
"Name": "FoobarWebsocketStaging",
"ProtocolType": "WEBSOCKET",
"RouteSelectionExpression": "$request.body.message"
}
},
"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"
}
]
}
},
"ConnectWSLambda": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "index.handler",
"CodeUri": "/Users/brian/Desktop/foobar/src/ws/connect",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "foobar",
"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": "/Users/brian/Desktop/foobar/src/ws/default",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "foobar",
"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": "/Users/brian/Desktop/foobar/src/ws/disconnect",
"Runtime": "nodejs20.x",
"Architectures": [
"arm64"
],
"MemorySize": 1152,
"EphemeralStorage": {
"Size": 512
},
"Timeout": 5,
"Environment": {
"Variables": {
"ARC_APP_NAME": "foobar",
"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"
}
},
"EEventTopic": {
"Description": "An SNS Topic",
"Value": {
"Ref": "EEventTopic"
}
},
"QSqsQueue": {
"Description": "An SQS Queue",
"Value": {
"Ref": "QQueue"
}
},
"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",
{}
]
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment