AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: > SAM-CallCenterWebApp Deploy State Machine, Lambda Functions, API Gateway and S3 bucket. Mappings: AccountMap: #Different settings based on the AWS Account to which is being deployed "xxxxxxxxxxxxx": "s3bucketname": "callcentertestbucket" "xxxxxxxxxxxxx": "s3bucketname": "callcenterprodbucket" Resources: CallCenterStateMachine: Type: AWS::Serverless::StateMachine Properties: DefinitionUri: statemachines/CallCenterStateMachine.asl.json DefinitionSubstitutions: OpenCaseFunctionArn: !GetAtt OpenCaseFunction.Arn AssignCaseFunctionArn: !GetAtt AssignCaseFunction.Arn WorkOnCaseFunctionArn: !GetAtt WorkOnCaseFunction.Arn CloseCaseFunctionArn: !GetAtt CloseCaseFunction.Arn EscalateCaseFunctionArn: !GetAtt EscalateCaseFunction.Arn Role: !GetAtt CallCenterBasicStepFunctionsRole.Arn Logging: Destinations: - CloudWatchLogsLogGroup: LogGroupArn: !GetAtt CallCenterStateMachineLogGroup.Arn IncludeExecutionData: true Level: ALL Events: APIEvent: Type: Api Properties: Path: /case Method: post RestApiId: !Ref CallCenterAPI CallCenterWebAppBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain Properties: BucketName: !FindInMap [AccountMap, !Ref "AWS::AccountId", s3bucketname] AccessControl: PublicRead WebsiteConfiguration: IndexDocument: index.html ErrorDocument: error.html CallCenterWebAppBucketPolicy: Type: AWS::S3::BucketPolicy Properties: PolicyDocument: Id: MyPolicy Version: 2012-10-17 Statement: - Sid: PublicReadForGetBucketObjects Effect: Allow Principal: '*' Action: 's3:GetObject' Resource: !Join - '' - - 'arn:aws:s3:::' - !Ref CallCenterWebAppBucket - /* Bucket: !Ref CallCenterWebAppBucket OpenCaseFunction: Type: AWS::Serverless::Function Properties: CodeUri: functions/open-case/ Handler: app.handler Runtime: nodejs12.x Role: !GetAtt CallCenterBasicLambdaRole.Arn AssignCaseFunction: Type: AWS::Serverless::Function Properties: CodeUri: functions/assign-case/ Handler: app.handler Runtime: nodejs12.x Role: !GetAtt CallCenterBasicLambdaRole.Arn WorkOnCaseFunction: Type: AWS::Serverless::Function Properties: CodeUri: functions/work-on-case/ Handler: app.handler Runtime: nodejs12.x Role: !GetAtt CallCenterBasicLambdaRole.Arn CloseCaseFunction: Type: AWS::Serverless::Function Properties: CodeUri: functions/close-case/ Handler: app.handler Runtime: nodejs12.x Role: !GetAtt CallCenterBasicLambdaRole.Arn EscalateCaseFunction: Type: AWS::Serverless::Function Properties: CodeUri: functions/escalate-case/ Handler: app.handler Runtime: nodejs12.x Role: !GetAtt CallCenterBasicLambdaRole.Arn # API CallCenterAPI: Type: AWS::Serverless::Api Properties: StageName: prod Cors: AllowMethods: "'POST, GET, OPTIONS, HEAD'" AllowHeaders: "'*'" AllowOrigin: "'*'" MethodSettings: - LoggingLevel: INFO # OFF, ERROR, INFO ResourcePath: '/*' # allows for logging on any resource HttpMethod: '*' # allows for logging on any method GatewayResponses: DEFAULT_4xx: ResponseParameters: Headers: Access-Control-Allow-Origin: "'*'" Access-Control-Allow-Methods: "'POST, OPTIONS'" Access-Control-Allow-Headers: "'*'" DEFAULT_5xx: ResponseParameters: Headers: Access-Control-Allow-Origin: "'*'" Access-Control-Allow-Methods: "'POST, OPTIONS'" Access-Control-Allow-Headers: "'*'" DefinitionBody: swagger: "2.0" info: title: "sam-callcenterwebapp" #This is the name of the API paths: /case: post: consumes: - "application/json" responses: "200": description: "200 response" headers: Access-Control-Allow-Origin: type: "string" "400": description: "400 response" x-amazon-apigateway-integration: credentials: !GetAtt CallCenterAPIGatewayRole.Arn uri: Fn::Sub: "arn:aws:apigateway:${AWS::Region}:states:action/StartExecution" responses: "200": statusCode: "200" responseParameters: method.response.header.Access-Control-Allow-Origin: "'*'" "400": statusCode: "400" requestTemplates: application/json: Fn::Sub: "{\"input\": \"$util.escapeJavaScript($input.json('$'))\"\ , \"stateMachineArn\": \"${CallCenterStateMachine.Arn}\"\ }" passthroughBehavior: "when_no_match" httpMethod: "POST" type: "aws" options: consumes: - "application/json" produces: - "application/json" responses: "200": description: "200 response" headers: Access-Control-Allow-Origin: type: "string" Access-Control-Allow-Methods: type: "string" Access-Control-Allow-Headers: type: "string" x-amazon-apigateway-integration: responses: default: statusCode: "200" responseParameters: method.response.header.Access-Control-Allow-Methods: "'OPTIONS,POST'" method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'" method.response.header.Access-Control-Allow-Origin: "'*'" responseTemplates: application/json: "{}\n" requestTemplates: application/json: "{\n \"statusCode\" : 200\n}\n" passthroughBehavior: "when_no_match" type: "mock" CallCenterAPIGatewayAccount: Type: AWS::ApiGateway::Account Properties: CloudWatchRoleArn: !GetAtt CallCenterAPIGatewayAccountRole.Arn #IAM CallCenterBasicLambdaRole: Type: AWS::IAM::Role Properties: Description: "Basic Lamda execution role, provides access to Cloudwatch for logging. " RoleName: !Join - '' - - !Ref AWS::StackName - '-' - !Ref AWS::Region - '-' - CallCenterBasicLambdaRole ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - 'lambda.amazonaws.com' Action: - 'sts:AssumeRole' CallCenterBasicStepFunctionsRole: Type: AWS::IAM::Role Properties: Description: "Basic Step Functions role. Allows to invoke Lambda Functions, and logging to Cloudwatch. " RoleName: !Join - '' - - !Ref AWS::StackName - '-' - !Ref AWS::Region - '-' - CallCenterBasicStepFunctionsRole ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AWSLambdaRole' - 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - 'states.amazonaws.com' Action: - 'sts:AssumeRole' CallCenterAPIGatewayRole: Type: AWS::IAM::Role Properties: Description: "API Gateway role. Allows to invoke Step Functions state machine. " RoleName: !Join - '' - - !Ref AWS::StackName - '-' - !Ref AWS::Region - '-' - CallCenterAPIGatewayRole AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - 'apigateway.amazonaws.com' Action: - 'sts:AssumeRole' Policies: - PolicyName: 'StateMachine-StartExecution' PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - 'states:StartExecution' Resource: !GetAtt CallCenterStateMachine.Arn CallCenterAPIGatewayAccountRole: Type: AWS::IAM::Role Properties: Description: "API Gateway role, provides access to Cloudwatch for logging. " RoleName: !Join - '' - - !Ref AWS::StackName - '-' - !Ref AWS::Region - '-' - CallCenterAPIGatewayAccountRole ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - 'apigateway.amazonaws.com' Action: - 'sts:AssumeRole' CallCenterStateMachineLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub /aws/stepfunctions/CallCenterStateMachine RetentionInDays: 30 #[1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653] Outputs: # In AWS Toolkit for VS Code the output is not displayed. Check the output in the AWS Cloudformation Console WebsiteURL: Description: URL for website hosted on S3 Value: !GetAtt - CallCenterWebAppBucket - WebsiteURL APIInvokeURL: Description: "API Prod stage endpoint" Value: !Sub "https://${CallCenterAPI}.execute-api.${AWS::Region}.amazonaws.com/prod/case"