AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-app Sample SAM Template for sam-app # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 60 Parameters: unauthRole: Type: String Description: Unauth Role associated with this project graphqlApi: Type: String Description: AppSync API ID associated with this project graphqlEndpoint: Type: String Description: AppSync Endpoint associated with this project tmdbApiKey: Type: String Description: API Key to access TMDb Resources: pubSubDataSource: Type: AWS::AppSync::DataSource Properties: Type: NONE Description: "Local Resolver" ApiId: !Ref graphqlApi Name: PubSub pubSubResolver: Type: "AWS::AppSync::Resolver" Properties: ApiId: !Ref graphqlApi TypeName: "Mutation" FieldName: "createMessage" DataSourceName: !GetAtt pubSubDataSource.Name RequestMappingTemplate: | { "version": "2017-02-28", "payload": { "message": "${context.arguments.message}", "sentAt": "$util.time.nowISO8601()" } } ResponseMappingTemplate: | $util.toJson($context.result) GetMovieFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: get-movie/ Handler: app.lambdaHandler Runtime: nodejs14.x Role: !GetAtt [ LambdaExecutionRole, Arn ] Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object Variables: ENDPOINT: !Ref graphqlEndpoint TMDBKEY: !Ref tmdbApiKey IteratorFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: InlineCode: | import boto3 import os client = boto3.client('lambda') function = os.environ['FUNCTION'] def lambda_handler(event, context): index = event['iterator']['index'] + 1 response = client.invoke( FunctionName=function, InvocationType='Event' ) return { 'index': index, 'continue': index < event['iterator']['count'], 'count': event['iterator']['count'] } Handler: index.lambda_handler Runtime: python2.7 Role: !GetAtt [ LambdaExecutionRole, Arn ] Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object Variables: FUNCTION: !GetAtt [ GetMovieFunction, Arn ] LambdaExecutionRole: Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: "sts:AssumeRole" Path: "/" Policies: - PolicyName: LambdaInvokePolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "lambda:*" - "appsync:GraphQL" - "logs:CreateLogGroup" - "logs:CreateLogStream" - "logs:PutLogEvents" Resource: "*" StatesExecutionRole: Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - !Sub states.${AWS::Region}.amazonaws.com Action: "sts:AssumeRole" Path: "/" Policies: - PolicyName: StatesExecutionPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "lambda:InvokeFunction" Resource: "*" UnauthRolePolicy: Type: AWS::IAM::Policy Properties: PolicyName: "AppSyncInvoke" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: "appsync:GraphQL" Resource: - !Join [ "/", [!Join [ ":", ["arn:aws:appsync",!Ref 'AWS::Region',!Ref 'AWS::AccountId',"apis"]],!Ref graphqlApi,"*"]] Roles: - !Ref unauthRole LambdaTimerStateMachine: Type: "AWS::StepFunctions::StateMachine" Properties: DefinitionString: !Sub - |- { "Comment": "Invoke Lambda every 10 seconds", "StartAt": "ConfigureCount", "States": { "ConfigureCount": { "Type": "Pass", "Result": { "index": 0, "count": 6 }, "ResultPath": "$.iterator", "Next": "Iterator" }, "Iterator": { "Type": "Task", "Resource": "${lambdaArn}", "ResultPath": "$.iterator", "Next": "IsCountReached" }, "IsCountReached": { "Type": "Choice", "Choices": [ { "Variable": "$.iterator.continue", "BooleanEquals": true, "Next": "Wait" } ], "Default": "Done" }, "Wait": { "Type": "Wait", "Seconds": 10, "Next": "Iterator" }, "Done": { "Type": "Pass", "End": true } } } - {lambdaArn: !GetAtt [ IteratorFunction, Arn ]} RoleArn: !GetAtt [ StatesExecutionRole, Arn ] Cron: Type: AWS::Events::Rule Properties: Description: Executes Step Functions every minute ScheduleExpression: rate(1 minute) State: ENABLED Targets: - Arn: !Ref LambdaTimerStateMachine Id: "LambdaTimerStateMachine" RoleArn: !GetAtt CronExecutionRole.Arn CronExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: events.amazonaws.com Action: sts:AssumeRole Path: /service-role/ Policies: - PolicyName: CloudWatchEventsStartStepFunctions PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: states:StartExecution Resource: !Ref LambdaTimerStateMachine