AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: Serverlesspresso core stack. Parameters: Source: Type: String Description: Event bus source by application Default: 'awsserverlessda.serverlesspresso' Resources: ########################################## # Custom event bus # ########################################## ServerlesspressoEventBus: Type: AWS::Events::EventBus Properties: Name: "Serverlesspresso" LogsRule: Type: AWS::Events::Rule Properties: EventBusName: !Ref ServerlesspressoEventBus EventPattern: source: - 'awsserverlessda.serverlesspresso' Targets: - Arn: !GetAtt LogGroupForEvents.Arn Id: LogTarget LogGroupForEvents: Type: AWS::Logs::LogGroup Properties: LogGroupName: /aws/serverlesspresso-event-bus LogGroupForEventsPolicy: Type: AWS::Logs::ResourcePolicy Properties: PolicyName: EventBridgeToCWLogsPolicy PolicyDocument: !Sub > { "Version": "2012-10-17", "Statement": [ { "Sid": "EventBridgetoCWLogsCreateLogStreamPolicy", "Effect": "Allow", "Principal": { "Service": [ "events.amazonaws.com" ] }, "Action": [ "logs:CreateLogStream" ], "Resource": [ "${LogGroupForEvents.Arn}" ] }, { "Sid": "EventBridgetoCWLogsPutLogEventsPolicy", "Effect": "Allow", "Principal": { "Service": [ "events.amazonaws.com" ] }, "Action": [ "logs:PutLogEvents" ], "Resource": [ "${LogGroupForEvents.Arn}" ], "Condition": { "ArnEquals": {"AWS:SourceArn": "${LogsRule.Arn}"} } } ] } ############################################# # Resources for IoT Core realtime messaging # ############################################# ServerlesspressoRealtime: Type: "AWS::IoT::Thing" Properties: ThingName: "serverlesspresso-realtime-workshop" AttributePayload: Attributes: {} GetIoTEndpointFunction: Type: 'AWS::Serverless::Function' Properties: Handler: GetIoTEndpoint.handler Runtime: nodejs14.x CodeUri: ./ MemorySize: 128 Timeout: 3 Policies: - Version: '2012-10-17' Statement: - Effect: Allow Action: - iot:DescribeEndpoint Resource: - '*' GetIoTEndpointLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub "/aws/lambda/${GetIoTEndpointFunction}" IotEndpoint: Type: 'Custom::IotEndpoint' Properties: ServiceToken: !GetAtt GetIoTEndpointFunction.Arn ########################################## # Custom auth flow Lambda functions # ########################################## DefineAuthChallenge: Type: AWS::Serverless::Function Properties: CodeUri: ./cognito-triggers/ Handler: define-auth-challenge.handler Runtime: nodejs14.x CreateAuthChallenge: Type: AWS::Serverless::Function Properties: CodeUri: ./cognito-triggers/ Handler: create-auth-challenge.handler Runtime: nodejs14.x Policies: - Version: "2012-10-17" Statement: - Effect: Allow Action: - mobiletargeting:* - sns:* Resource: "*" VerifyAuthChallengeResponse: Type: AWS::Serverless::Function Properties: CodeUri: ./cognito-triggers/ Handler: verify-auth-challenge-response.handler Runtime: nodejs14.x PreSignUp: Type: AWS::Serverless::Function Properties: CodeUri: ./cognito-triggers/ Handler: pre-sign-up.handler Runtime: nodejs14.x ########################################## # Cognito Resources # ########################################## UserPool: Type: "AWS::Cognito::UserPool" Properties: UserPoolName: ServerlesspressoUserPool MfaConfiguration: "OFF" Schema: - Name: phone_number AttributeDataType: String Mutable: false Required: true Policies: PasswordPolicy: MinimumLength: 6 RequireLowercase: false RequireNumbers: false RequireSymbols: false RequireUppercase: false UsernameAttributes: - phone_number MfaConfiguration: "OFF" LambdaConfig: CreateAuthChallenge: !GetAtt CreateAuthChallenge.Arn DefineAuthChallenge: !GetAtt DefineAuthChallenge.Arn PreSignUp: !GetAtt PreSignUp.Arn VerifyAuthChallengeResponse: !GetAtt VerifyAuthChallengeResponse.Arn DefineAuthChallengeInvocationPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !GetAtt DefineAuthChallenge.Arn Principal: cognito-idp.amazonaws.com SourceArn: !GetAtt UserPool.Arn CreateAuthChallengeInvocationPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !GetAtt CreateAuthChallenge.Arn Principal: cognito-idp.amazonaws.com SourceArn: !GetAtt UserPool.Arn VerifyAuthChallengeResponseInvocationPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !GetAtt VerifyAuthChallengeResponse.Arn Principal: cognito-idp.amazonaws.com SourceArn: !GetAtt UserPool.Arn PreSignUpInvocationPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !GetAtt PreSignUp.Arn Principal: cognito-idp.amazonaws.com SourceArn: !GetAtt UserPool.Arn UserPoolClient: Type: AWS::Cognito::UserPoolClient Properties: GenerateSecret: false UserPoolId: !Ref UserPool # Creates a federated Identity pool IdentityPool: Type: "AWS::Cognito::IdentityPool" Properties: IdentityPoolName: ServerlesspressoIdentityPool AllowUnauthenticatedIdentities: true CognitoIdentityProviders: - ClientId: !Ref UserPoolClient ProviderName: !GetAtt UserPool.ProviderName # Create a role for unauthorized access to AWS resources. CognitoUnAuthorizedRole: Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Federated: "cognito-identity.amazonaws.com" Action: - "sts:AssumeRoleWithWebIdentity" Condition: StringEquals: "cognito-identity.amazonaws.com:aud": !Ref IdentityPool "ForAnyValue:StringLike": "cognito-identity.amazonaws.com:amr": unauthenticated 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/serverlesspresso-*" ] ] - Effect: Allow Action: - iot:Subscribe Resource: "*" - Effect: Allow Action: - iot:Receive Resource: !Join [ "", [ "arn:aws:iot:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":topic/*" ] ] # Create a role for authorized acces to AWS resources. CognitoAuthorizedRole: Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Federated: "cognito-identity.amazonaws.com" Action: - "sts:AssumeRoleWithWebIdentity" Condition: StringEquals: "cognito-identity.amazonaws.com:aud": !Ref IdentityPool "ForAnyValue:StringLike": "cognito-identity.amazonaws.com:amr": authenticated 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/serverlesspresso-*" ] ] - Effect: Allow Action: - iot:Subscribe Resource: "*" - Effect: Allow Action: - iot:Receive Resource: !Join [ "", [ "arn:aws:iot:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":topic/*" ] ] # Assigns the roles to the Identity Pool IdentityPoolRoleMapping: Type: "AWS::Cognito::IdentityPoolRoleAttachment" Properties: IdentityPoolId: !Ref IdentityPool Roles: authenticated: !GetAtt CognitoAuthorizedRole.Arn unauthenticated: !GetAtt CognitoUnAuthorizedRole.Arn ########################################## # Outputs # ########################################## Outputs: UserPoolID: Description: UserPool ID Value: !Ref UserPool UserPoolWebClientId: Description: UserPool Web Client ID Value: !Ref UserPoolClient CoreEventBusARN: Description: CoreEventBus ARN Value: !GetAtt ServerlesspressoEventBus.Arn IoTRealtimeName: Description: IoTRealtime Name Value: !Ref ServerlesspressoRealtime IotEndpointAddress: Description: IotEndpointAddress URL Value: !GetAtt IotEndpoint.IotEndpointAddress Export: Name: !Sub "${AWS::StackName}-IotEndpointAddress" UserPoolParameter: Value: !Ref UserPool ServerlesspressoEventBusARNParameter: Value: !GetAtt ServerlesspressoEventBus.Arn UserPoolClientParameter: Value: !Ref UserPoolClient UserPoolARNParameter: Value: !GetAtt UserPool.Arn IOTDataEndpoint: Value: !GetAtt IotEndpoint.IotEndpointAddress