AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > Full Game Set Globals: Function: Layers: - !Sub arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:5 - !Sub arn:aws:lambda:${AWS::Region}:580247275435:layer:LambdaInsightsExtension:14 Runtime: nodejs18.x Handler: app.handler MemorySize: 512 Timeout: 10 Tracing: Active Environment: Variables: AWS_EMF_NAMESPACE: !Sub "${EMFNamespace}" Parameters: LogRetentionDays: Type: Number Description: Days to retain CloudWatch Logs for the Lambda Functions Default: 30 ResourceGroupPrefix: Type: String Description: Name of the Resource Group prefix Default: 'GameService' EMFNamespace: Type: String Description: Name of the EMF Namespace Default: 'STS' Resources: ResourceGroup: Type: "AWS::ResourceGroups::Group" Properties: Name: !Join ["-", [!Sub "${ResourceGroupPrefix}", "Main"]] PlayerProgressPutFunction: Type: AWS::Serverless::Function Properties: AutoPublishAlias: Live CodeUri: functions/playerprogression_put/ MemorySize: 1024 Environment: Variables: PLAYER_PROGRESS_TABLE_NAME: !ImportValue STS-PlayerProgressTable PLAYER_PROGRESS_IDEMPOTENCY_TABLE_NAME: !Ref PlayerProgressIdempotencyTable REGION: !Sub "${AWS::Region}" Policies: - DynamoDBCrudPolicy: TableName: !ImportValue STS-PlayerProgressTable - DynamoDBCrudPolicy: TableName: !Ref PlayerProgressIdempotencyTable - CloudWatchLambdaInsightsExecutionRolePolicy Events: SNSSendMessageEvent: Type: SNS Properties: Topic: !Ref PlayerProgressTopic Tags: Dashboard: GeneralOps Metadata: # Manage esbuild properties BuildMethod: esbuild BuildProperties: Minify: true Target: "es2020" Sourcemap: true EntryPoints: - app.ts PlayerProgressPutFunctionLogGroup: Type: AWS::Logs::LogGroup Properties: RetentionInDays: !Sub "${LogRetentionDays}" LogGroupName: !Join ["", ["/aws/lambda/", !Ref PlayerProgressPutFunction]] PlayerProgressIdempotencyTable: Type: AWS::DynamoDB::Table Properties: AttributeDefinitions: - AttributeName: msgId AttributeType: S KeySchema: - AttributeName: msgId KeyType: HASH TimeToLiveSpecification: AttributeName: expiration Enabled: true BillingMode: PAY_PER_REQUEST ScorePutFunction: Type: AWS::Serverless::Function Properties: AutoPublishAlias: Live MemorySize: 1536 CodeUri: functions/score_put/ Environment: Variables: SCORES_TABLE_NAME: !ImportValue STS-HighScoreTable REGION: !Sub "${AWS::Region}" Policies: - DynamoDBCrudPolicy: TableName: !ImportValue STS-HighScoreTable - CloudWatchLambdaInsightsExecutionRolePolicy Events: SNSSendMessageEvent: Type: SNS Properties: Topic: !Ref LeaderboardTopic Tags: Dashboard: GeneralOps Metadata: # Manage esbuild properties BuildMethod: esbuild BuildProperties: Minify: true Target: "es2020" Sourcemap: true EntryPoints: - app.ts ScorePutFunctionLogGroup: Type: AWS::Logs::LogGroup Properties: RetentionInDays: !Sub "${LogRetentionDays}" LogGroupName: !Join ["", ["/aws/lambda/", !Ref ScorePutFunction]] MoneyAdjustFunction: Type: AWS::Serverless::Function Properties: AutoPublishAlias: Live CodeUri: functions/money_adjust/ MemorySize: 2048 Environment: Variables: PLAYER_WALLET_TABLE_NAME: !ImportValue STS-PlayerWalletTable PLAYER_WALLET_IDEMPOTENCY_TABLE_NAME: !Ref MoneyAdjustIdempotencyTable REGION: !Sub "${AWS::Region}" Policies: - DynamoDBCrudPolicy: TableName: !ImportValue STS-PlayerWalletTable - DynamoDBCrudPolicy: TableName: !Ref MoneyAdjustIdempotencyTable - CloudWatchLambdaInsightsExecutionRolePolicy Events: SNSSendMessageEvent: Type: SNS Properties: Topic: !Ref PlayerWalletTopic Tags: Dashboard: GeneralOps Metadata: # Manage esbuild properties BuildMethod: esbuild BuildProperties: Minify: true Target: "es2020" Sourcemap: true EntryPoints: - app.ts MoneyAdjustFunctionLogGroup: Type: AWS::Logs::LogGroup Properties: RetentionInDays: !Sub "${LogRetentionDays}" LogGroupName: !Join ["", ["/aws/lambda/", !Ref MoneyAdjustFunction]] MoneyAdjustIdempotencyTable: Type: AWS::DynamoDB::Table Properties: AttributeDefinitions: - AttributeName: msgId AttributeType: S KeySchema: - AttributeName: msgId KeyType: HASH TimeToLiveSpecification: AttributeName: expiration Enabled: true BillingMode: PAY_PER_REQUEST SendChatFunction: Type: AWS::Serverless::Function Properties: AutoPublishAlias: Live CodeUri: functions/chat_send/ MemorySize: 2048 Environment: Variables: REGION: !Sub "${AWS::Region}" Policies: - CloudWatchLambdaInsightsExecutionRolePolicy - !Ref SendChatPolicy Events: SNSSendChatEvent: Type: SNS Properties: Topic: !Ref SendChatTopic Tags: Dashboard: GeneralOps Metadata: # Manage esbuild properties BuildMethod: esbuild BuildProperties: Minify: true Target: "es2020" Sourcemap: true EntryPoints: - app.ts SendChatFunctionLogGroup: Type: AWS::Logs::LogGroup Properties: RetentionInDays: !Sub "${LogRetentionDays}" LogGroupName: !Join ["", ["/aws/lambda/", !Ref SendChatFunction]] SendChatPolicy: Type: 'AWS::IAM::ManagedPolicy' Properties: ManagedPolicyName: !Join [ "", [!Ref "AWS::StackName", "-IoTSendChatPolicy" ] ] PolicyDocument: Version: 2012-10-17 Statement: - Effect: "Allow" Action: "iot:Publish" Resource: !Join ["", ["arn:aws:iot:", !Ref AWS::Region, ":", !Ref AWS::AccountId, ":topic/chat/*"]] STSEventBus: Type: AWS::Events::EventBus Properties: Name: !Sub ${AWS::StackName} PlayerProgressTopic: Type: AWS::SNS::Topic Properties: DisplayName: PlayerProgressTopic LeaderboardTopic: Type: AWS::SNS::Topic Properties: DisplayName: LeaderboardTopic SendChatTopic: Type: AWS::SNS::Topic Properties: DisplayName: SendChatTopic PlayerWalletTopic: Type: AWS::SNS::Topic Properties: DisplayName: WalletTopic PreSignUpTrigger: Type: AWS::Serverless::Function Properties: AutoPublishAlias: Live Timeout: 5 CodeUri: functions/cognito_presignup/ Metadata: # Manage esbuild properties BuildMethod: esbuild BuildProperties: Minify: true Target: "es2020" Sourcemap: true EntryPoints: - app.ts UserPoolLambdaInvokePermission: Type: AWS::Lambda::Permission Properties: Action: lambda:invokeFunction Principal: cognito-idp.amazonaws.com FunctionName: !Ref PreSignUpTrigger SourceArn: !GetAtt UserPool.Arn UserPool: Type: "AWS::Cognito::UserPool" Properties: MfaConfiguration: "OFF" Schema: - Name: email AttributeDataType: String Mutable: false Required: true Policies: PasswordPolicy: MinimumLength: 8 RequireLowercase: true RequireNumbers: true RequireSymbols: true RequireUppercase: true LambdaConfig: PreSignUp: !GetAtt PreSignUpTrigger.Arn UserPoolClient: Type: "AWS::Cognito::UserPoolClient" Properties: GenerateSecret: false UserPoolId: !Ref UserPool IdentityPool: Type: "AWS::Cognito::IdentityPool" Properties: AllowUnauthenticatedIdentities: true CognitoIdentityProviders: - ClientId: !Ref UserPoolClient ProviderName: !GetAtt UserPool.ProviderName CognitoUnAuthorizedRole: Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Federated: "cognito-identity.amazonaws.com" Action: - "sts:AssumeRoleWithWebIdentity" Policies: - PolicyName: "CognitoUnauthorizedPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "cognito-sync:*" Resource: !Join [ "", [ "arn:aws:cognito-sync:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":identitypool/", !Ref IdentityPool] ] - Effect: Allow Action: - iot:Connect Resource: !Join [ "", [ "arn:aws:iot:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":client/simpletrivia-*" ] ] - Effect: Allow Action: - iot:Subscribe Resource: !Join [ "", [ "arn:aws:iot:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":topicfilter/*" ] ] - Effect: Allow Action: - iot:Receive Resource: !Join [ "", [ "arn:aws:iot:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":topic/*" ] ] - Effect: Allow Action: - iot:Publish Resource: !Join [ "", [ "arn:aws:iot:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":topic/*" ] ] CognitoAuthorizedRole: Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Federated: "cognito-identity.amazonaws.com" Action: - "sts:AssumeRoleWithWebIdentity" Policies: - PolicyName: "CognitoAuthorizedPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "cognito-sync:*" Resource: !Join [ "", [ "arn:aws:cognito-sync:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":identitypool/", !Ref IdentityPool] ] - Effect: Allow Action: - iot:Connect Resource: !Join [ "", [ "arn:aws:iot:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":client/simpletrivia-*" ] ] - Effect: Allow Action: - iot:Subscribe Resource: !Join [ "", [ "arn:aws:iot:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":topicfilter/*" ] ] - Effect: Allow Action: - iot:Receive Resource: !Join [ "", [ "arn:aws:iot:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":topic/*" ] ] - Effect: Allow Action: - iot:Publish Resource: !Join [ "", [ "arn:aws:iot:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":topic/*" ] ] IdentityPoolRoleMapping: Type: "AWS::Cognito::IdentityPoolRoleAttachment" Properties: IdentityPoolId: !Ref IdentityPool Roles: authenticated: !GetAtt CognitoAuthorizedRole.Arn unauthenticated: !GetAtt CognitoUnAuthorizedRole.Arn SSMCreateAndDeleteVapidParametersPolicy: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: !Join [ "", [!Ref "AWS::StackName", "-SSMCreateAndDeleteParametersPolicy" ] ] PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - ssm:PutParameter* - ssm:DeleteParameters Resource: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:*' Outputs: identitypoolid: Description: "ID of the Identity Pool for STS" Value: !Ref IdentityPool Export: Name: "STS-IdentityPoolId" userpoolid: Description: "ID of the UserPool for STS" Value: !Ref UserPool Export: Name: "STS-UserPoolId" userpoolarn: Description: "ID of the UserPool for STS" Value: !GetAtt UserPool.Arn Export: Name: "STS-UserPoolArn" appclientid: Description: "ID of the AppClient for STS" Value: !Ref UserPoolClient Export: Name: "STS-AppClientId" playerprogressarn: Description: "Topic Arn for Player Progress" Value: !Ref PlayerProgressTopic Export: Name: "STS-PlayerProgressTopicArn" playerprogressname: Description: "Topic Name for Player Progress" Value: !GetAtt PlayerProgressTopic.TopicName Export: Name: "STS-PlayerProgressTopicName" playerwalletarn: Description: "Topic Arn for Player Wallet" Value: !Ref PlayerWalletTopic Export: Name: "STS-PlayerWalletTopicArn" playerwalletsname: Description: "Topic Name for Player Wallet" Value: !GetAtt PlayerWalletTopic.TopicName Export: Name: "STS-PlayerWalletTopicName" leaderboardarn: Description: "Topic Arn for Leaderboard" Value: !Ref LeaderboardTopic Export: Name: "STS-LeaderboardTopicArn" leaderboardname: Description: "Topic Name for Leaderboard" Value: !GetAtt LeaderboardTopic.TopicName Export: Name: "STS-LeaderboardTopicName" chatarn: Description: "Topic Arn for Chat" Value: !Ref SendChatTopic Export: Name: "STS-ChatTopicArn" chatname: Description: "Topic Name for Chat" Value: !GetAtt SendChatTopic.TopicName Export: Name: "STS-ChatTopicName" eventbus: Description: "EventBridge Bus Name" Value: !Ref STSEventBus Export: Name: "STS-STSEventBusName"