# You must have an AWS account to use the Amazon Connect CTI Adapter. # Downloading and/or using the Amazon Connect CTI Adapter is subject to the terms of the AWS Customer Agreement, # AWS Service Terms, and AWS Privacy Notice. # © 2017, Amazon Web Services, Inc. or its affiliates. All rights reserved. # NOTE: Other license terms may apply to certain, identified software components # contained within or distributed with the Amazon Connect CTI Adapter if such terms are # included in the LibPhoneNumber-js and Salesforce Open CTI. For such identified components, # such other license terms will then apply in lieu of the terms above. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: 'Amazon Connect SalesForce Lambda integration' Parameters: SalesforceProduction: Default: true Description: True for Production Environment, False for Sandbox Type: String AllowedPattern: ^([Tt]rue|[Ff]alse)$ SalesforceHost: Default: https://... Description: Your Salesforce Host. Please make sure the host url starts with "https". AllowedPattern: (^$|^https(.*)) Type: String SalesforceUsername: Default: apiuser@.com Description: The username of a valid Salesforce API account for your environment. Salesforce usernames are in the form of an email address. For example, user@domain.com Type: String AllowedPattern: ^.+@.+\..+$ SalesforceVersion: Default: v42.0 Description: To find the Salesforce Edition and API Version please visit https://help.salesforce.com/articleView?id=000199268&type=1. The pattern for this field is vXX.X Type: String AllowedPattern: ^v[0-9]+\.[0-9]+$ ConnectReportingS3BucketName: Default: '' Description: This is the S3 bucket where Amazon Connect stores scheduled reports. Please refer to http://docs.aws.amazon.com/connect/latest/adminguide/amazon-connect-instance.html#datastorage for details on how retrieve the S3 bucket associated with your Amazon Connect instance. Not required if HistoricalReportingImportEnabled set to false. Type: String ConnectRecordingS3BucketName: Default: '' Description: This is the S3 bucket where Amazon Connect stores call recordings. Please refer to http://docs.aws.amazon.com/connect/latest/adminguide/amazon-connect-instance.html#datastorage for details on how retrieve the S3 bucket associated with your Amazon Connect instance. Not required if both PostcallRecordingImportEnabled and PostcallTranscribeEnabled set to false. Type: String TranscribeOutputS3BucketName: Default: '' Description: This is the S3 bucket where Amazon Transcribe stores the output. If you don't specify an encryption key, the output of the transcription job is encrypted with the default Amazon S3 key (SSE-S3). Not required if both PostcallRecordingImportEnabled and PostcallTranscribeEnabled set to false. Type: String SalesforceCredentialsSecretsManagerARN: Default: '' Description: Enter the ARN for the Salesforce Credentials Secret in AWS Secrets Manager. This field is required. Type: String SalesforceCredentialsKMSKeyARN: Default: '' Description: Enter the ARN for the Salesforce Credentials KMS Key. This field is required. Type: String # TranscribeOutputEncryptionKMSKeyId: # Default: '' # Description: The Amazon Resource Name (ARN) of the AWS Key Management Service (KMS) key used to encrypt the output of the transcription job. Leave blank to use S3 SSE. # Type: String TranscriptionJobCheckWaitTime: Default: 20 Description: Time between transcription job checks Type: Number CTRKinesisARN: Type: String Default: '' Description: Enter Kinesis Stream ARN for CTR. Not required is PostcallCTRImportEnabled, PostcallRecordingImportEnabled and PostcallTranscribeEnabled all set to false CTREventSourceMappingMaximumRetryAttempts: Type: Number Default: 100 Description: Maximum retry attempts on failure for lambdas triggered by Kinesis Events SalesforceAdapterNamespace: Default: 'amazonconnect' Description: This is the namespace for CTI Adapter managed package. The default value is [amazonconnect]. If a non-managed package is used, leave this field blank. Type: String AmazonConnectInstanceId: Default: '' Description: Enter Amazon Connect Instance Id, the string after the last / in your Amazon Connect instance ARN (aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee). Not required if RealtimeReportingImportEnabled is set to false. Type: String AmazonConnectQueueMaxRecords: Default: 100 Description: Enter record set size for list queue query. Max is 100. Type: Number AmazonConnectQueueMetricsMaxRecords: Default: 100 Description: Enter record set size for queue metrics query. Max is 100. Type: Number LambdaLoggingLevel: Default: 'INFO' Description: 'Logging level for Lambda functions. Set one of the following DEBUG | INFO | WARNING | ERROR | CRITICAL' Type: String AllowedValues: - DEBUG - INFO - WARNING - ERROR - CRITICAL PostcallRecordingImportEnabled: Default: true Description: Set to false if importing call recordings into Salesforce should not be enabled on the package level. See installation guide for setup details. Type: String AllowedPattern: ^([Tt]rue|[Ff]alse)$ PostcallTranscribeEnabled: Default: true Description: Set to false if post-call transcription should not be enabled on the package level. See installation guide for setup details. Type: String AllowedPattern: ^([Tt]rue|[Ff]alse)$ PostcallCTRImportEnabled: Default: true Description: Set to false if importing CTRs into Salesforce should not be enabled on the package level. Type: String AllowedPattern: ^([Tt]rue|[Ff]alse)$ HistoricalReportingImportEnabled: Default: true Description: Set to false if importing Historical Reporting into Salesforce should not be enabled. Type: String AllowedPattern: ^([Tt]rue|[Ff]alse)$ RealtimeReportingImportEnabled: Default: true Description: Set to false if importing Realtime Reporting into Salesforce should not be enabled. Type: String AllowedPattern: ^([Tt]rue|[Ff]alse)$ ContactLensImportEnabled: Default: true Description: Set to false if importing Contact Lens into Salesforce should not be enabled. Type: String AllowedPattern: ^([Tt]rue|[Ff]alse)$ PrivateVpcEnabled: Default: false Description: Set to true if functions should be deployed to a private VPC, set VpcSecurityGroupList and VpcSubnetList if true Type: String AllowedPattern: ^([Tt]rue|[Ff]alse)$ VpcSecurityGroupList: Type: CommaDelimitedList Description: The list of SecurityGroupIds for the Virtual Private Cloud (VPC). Not required if PrivateVpcEnabled is set to false. Default: '' VpcSubnetList: Type: CommaDelimitedList Description: The list of Subnets for the Virtual Private Cloud (VPC). Not required if PrivateVpcEnabled is set to false. Default: '' Conditions: PostcallRecordingImportEnabledCondition: !Or [!Equals [!Ref PostcallRecordingImportEnabled, true ], !Equals [!Ref PostcallRecordingImportEnabled, 'True' ]] PostcallTranscribeEnabledCondition: !Or [!Equals [!Ref PostcallTranscribeEnabled, true], !Equals [!Ref PostcallTranscribeEnabled, 'True']] PostcallCTRImportEnabledCondition: !Or [!Equals [!Ref PostcallCTRImportEnabled, true], !Equals [!Ref PostcallCTRImportEnabled, 'True']] HistoricalReportingImportEnabledCondition: !Or [!Equals [!Ref HistoricalReportingImportEnabled, true], !Equals [!Ref HistoricalReportingImportEnabled, 'True']] RealtimeReportingImportEnabledCondition: !Or [!Equals [!Ref RealtimeReportingImportEnabled, true], !Equals [!Ref RealtimeReportingImportEnabled, 'True']] ContactLensImportEnabledCondition: !Or [!Equals [!Ref ContactLensImportEnabled, true], !Equals [!Ref ContactLensImportEnabled, 'True']] PrivateVpcEnabledCondition: !Or [!Equals [!Ref PrivateVpcEnabled, true], !Equals [!Ref PrivateVpcEnabled, 'True']] ConnectReportingS3BucketNameHasValue: !Not [!Equals [!Ref ConnectReportingS3BucketName, '']] ConnectRecordingS3BucketNameHasValue: !Not [!Equals [!Ref ConnectRecordingS3BucketName, '']] TranscribeOutputS3BucketNameHasValue: !Not [!Equals [!Ref TranscribeOutputS3BucketName, '']] SalesforceCredentialsSecretsManagerARNHasValue: !Not [!Equals [!Ref SalesforceCredentialsSecretsManagerARN, '']] SalesforceCredentialsKMSKeyARNHasValue: !Not [!Equals [!Ref SalesforceCredentialsKMSKeyARN, '']] CTRKinesisARNHasValue: !Not [!Equals [!Ref CTRKinesisARN, '']] AmazonConnectInstanceIdHasValue: !Not [!Equals [!Ref AmazonConnectInstanceId, '']] CTREventSourceMappingCondition: !And - Condition: CTRKinesisARNHasValue - !Or - Condition: PostcallRecordingImportEnabledCondition - Condition: PostcallTranscribeEnabledCondition - Condition: PostcallCTRImportEnabledCondition sfSubmitTranscribeJobConnectRecordingS3PolicyCondition: !And - Condition: PostcallTranscribeEnabledCondition - Condition: ConnectRecordingS3BucketNameHasValue sfSubmitTranscribeJobTranscribeOutputS3PolicyCondition: !And - Condition: PostcallTranscribeEnabledCondition - Condition: TranscribeOutputS3BucketNameHasValue sfExecuteTranscriptionStateMachineRecordingS3PolicyCondition: !And - Condition: PostcallRecordingImportEnabledCondition - Condition: ConnectRecordingS3BucketNameHasValue sfProcessContactLensRecordingS3PolicyCondition: !And - Condition: ContactLensImportEnabledCondition - Condition: ConnectRecordingS3BucketNameHasValue - Condition: AmazonConnectInstanceIdHasValue sfProcessContactLensDataS3PolicyCondition: !And - Condition: ContactLensImportEnabledCondition - Condition: ConnectRecordingS3BucketNameHasValue sfAudioRecordingStreamingCloudFrontDistributionCondition: !And - Condition: PostcallRecordingImportEnabledCondition - Condition: ConnectRecordingS3BucketNameHasValue sfExecuteTranscriptionStateMachineLockS3PolicyCondition: !And - !Or - Condition: PostcallRecordingImportEnabledCondition - Condition: PostcallTranscribeEnabledCondition - Condition: TranscribeOutputS3BucketNameHasValue sfProcessTranscriptionResultS3PolicyCondition: !And - Condition: PostcallTranscribeEnabledCondition - Condition: TranscribeOutputS3BucketNameHasValue sfProcessContactLensResultS3PolicyCondition: !And - Condition: ContactLensImportEnabledCondition - Condition: TranscribeOutputS3BucketNameHasValue sfRealTimeQueueMetricsConnectPolicyCondition: !And - Condition: RealtimeReportingImportEnabledCondition - Condition: AmazonConnectInstanceIdHasValue sfProcessContactLensConnectPolicyCondition: !And - Condition: ContactLensImportEnabledCondition - Condition: AmazonConnectInstanceIdHasValue Globals: Function: Timeout: 6 Runtime: python3.7 CodeUri: ./sam-app-deployment-artifact.zip Resources: sfLambdaLayer: Type: AWS::Serverless::LayerVersion Properties: Description: Salesforce Lambda function external dependencies ContentUri: ./lambda_layers.zip CompatibleRuntimes: - python3.7 invokeSfExecuteAWSServicePolicy: Type: AWS::IAM::ManagedPolicy Properties: Path: / PolicyDocument: Statement: - Action: - lambda:InvokeFunction Effect: Allow Resource: Fn::GetAtt: sfExecuteAWSService.Arn Version: '2012-10-17' SecretsManagerManagedPolicy: Condition: SalesforceCredentialsSecretsManagerARNHasValue Type: AWS::IAM::ManagedPolicy Properties: Path: / PolicyDocument: Statement: - Action: - secretsmanager:GetSecretValue - secretsmanager:PutSecretValue Effect: Allow Resource: !Ref SalesforceCredentialsSecretsManagerARN Version: '2012-10-17' KMSManagedPolicy: Condition: SalesforceCredentialsKMSKeyARNHasValue Type: AWS::IAM::ManagedPolicy Properties: Path: / PolicyDocument: Statement: - Action: - kms:Decrypt - kms:GenerateDataKey Effect: Allow Resource: !Ref SalesforceCredentialsKMSKeyARN Version: '2012-10-17' CloudWatchManagedPolicy: Type: AWS::IAM::ManagedPolicy Properties: Path: / PolicyDocument: Statement: - Action: - logs:CreateLogStream - logs:CreateLogGroup - logs:PutLogEvents Effect: Allow Resource: - arn:aws:logs:*:*:* Version: '2012-10-17' VpcManagedPolicy: Condition: PrivateVpcEnabledCondition Type: AWS::IAM::ManagedPolicy Properties: Path: / PolicyDocument: Statement: - Action: - "ec2:CreateNetworkInterface" - "ec2:DescribeNetworkInterfaces" - "ec2:DeleteNetworkInterface" Effect: Allow Resource: "*" Version: '2012-10-17' sfLambdaBasicExec: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - !If [SalesforceCredentialsSecretsManagerARNHasValue, !Ref SecretsManagerManagedPolicy, !Ref AWS::NoValue] - !If [SalesforceCredentialsKMSKeyARNHasValue, !Ref KMSManagedPolicy, !Ref AWS::NoValue] - !Ref CloudWatchManagedPolicy - !If [PrivateVpcEnabledCondition, !Ref VpcManagedPolicy, !Ref AWS::NoValue] sfExecuteAWSServiceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - !Ref CloudWatchManagedPolicy - !If [PrivateVpcEnabledCondition, !Ref VpcManagedPolicy, !Ref AWS::NoValue] Policies: - Fn::If: - AmazonConnectInstanceIdHasValue - PolicyDocument: Statement: - Action: - connect:ResumeContactRecording - connect:UpdateContactAttributes - connect:StartContactRecording - connect:SuspendContactRecording - connect:StopContactRecording Effect: Allow Resource: Fn::Sub: arn:aws:connect:${AWS::Region}:${AWS::AccountId}:instance/${AmazonConnectInstanceId}/* Version: '2012-10-17' PolicyName: sfExecuteAWSServiceConnectContactLensPolicy - !Ref AWS::NoValue - PolicyDocument: Statement: - Action: - connect:CreateInstance - connect:ListInstances - connect:AssociateApprovedOrigin - connect:AssociateInstanceStorageConfig - connect:ListInstanceStorageConfigs - connect:UpdateInstanceStorageConfig - ds:DescribeDirectories - ds:AuthorizeApplication - ds:CheckAlias - ds:CreateAlias - ds:CreateIdentityPoolDirectory - ds:DeleteDirectory - ds:UnauthorizeApplication Effect: Allow Resource: '*' Version: '2012-10-17' PolicyName: sfExecuteAWSServiceConnectGuidedSetupInstancePolicy - PolicyDocument: Statement: - Action: - kms:CreateGrant - kms:DescribeKey Effect: Allow Resource: Fn::Sub: arn:aws:kms:*:${AWS::AccountId}:key/* Version: '2012-10-17' PolicyName: sfExecuteAWSServiceConnectGuidedSetupInstancePolicyKMS - PolicyDocument: Statement: - Action: - s3:GetBucketLocation - s3:GetBucketAcl - s3:CreateBucket Effect: Allow Resource: '*' Version: '2012-10-17' PolicyName: sfExecuteAWSServiceConnectGuidedSetupInstancePolicyS3 - PolicyDocument: Statement: - Action: - kinesis:CreateStream - kinesis:DescribeStream Effect: Allow Resource: Fn::Sub: arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/* Version: '2012-10-17' PolicyName: sfExecuteAWSServiceConnectGuidedSetupInstancePolicyKinesis - PolicyDocument: Statement: - Action: - iam:PutRolePolicy - iam:CreateServiceLinkedRole Effect: Allow Resource: Fn::Sub: arn:aws:iam::${AWS::AccountId}:role/aws-service-role/connect.amazonaws.com* Version: '2012-10-17' PolicyName: sfExecuteAWSServiceServiceLinkedRolePolicy - Fn::If: - sfAudioRecordingStreamingCloudFrontDistributionCondition - PolicyDocument: Statement: - Action: - cloudfront:GetDistributionConfig - cloudfront:UpdateDistribution Effect: Allow Resource: Fn::Sub: arn:aws:cloudfront::${AWS::AccountId}:distribution/${sfAudioRecordingStreamingCloudFrontDistribution} Version: '2012-10-17' PolicyName: sfExecuteAWSServiceConnectAudioRecordingPolicyCloudfront - !Ref AWS::NoValue - Fn::If: - sfAudioRecordingStreamingCloudFrontDistributionCondition - PolicyDocument: Statement: - Action: - iam:PassRole Effect: Allow Resource: Fn::GetAtt: sfSig4RequestToS3Role.Arn Version: '2012-10-17' PolicyName: sfExecuteAWSServiceConnectAudioRecordingPolicyIAM - !Ref AWS::NoValue - Fn::If: - sfAudioRecordingStreamingCloudFrontDistributionCondition - PolicyDocument: Statement: - Action: - cloudfront:CreatePublicKey - cloudfront:CreateKeyGroup Effect: Allow Resource: '*' Version: '2012-10-17' PolicyName: sfExecuteAWSServiceConnectAudioRecordingPolicyCloudfrontKey - !Ref AWS::NoValue - Fn::If: - sfAudioRecordingStreamingCloudFrontDistributionCondition - PolicyDocument: Statement: - Action: - lambda:EnableReplication - lambda:PublishVersion - lambda:CreateFunction - lambda:GetFunction Effect: Allow Resource: Fn::Sub: arn:aws:lambda:us-east-1:${AWS::AccountId}:function:*-sfSig4RequestToS3* Version: '2012-10-17' PolicyName: sfExecuteAWSServiceConnectAudioRecordingPolicyLambdaReplication - !Ref AWS::NoValue - Fn::If: - sfAudioRecordingStreamingCloudFrontDistributionCondition - PolicyDocument: Statement: - Action: - lambda:InvokeFunction Effect: Allow Resource: Fn::GetAtt: sfGenerateAudioRecordingStreamingURL.Arn Version: '2012-10-17' PolicyName: sfExecuteAWSServiceConnectAudioRecordingPolicyLambdaInvoke - !Ref AWS::NoValue - Fn::If: - sfAudioRecordingStreamingCloudFrontDistributionCondition - PolicyDocument: Statement: - Action: - s3:GetBucketCors - s3:PutBucketCors Effect: Allow Resource: Fn::Sub: "arn:aws:s3:::${ConnectRecordingS3BucketName}" Version: '2012-10-17' PolicyName: sfExecuteAWSServiceConnectAudioRecordingPolicyS3 - !Ref AWS::NoValue sfLambdaBasicExecWithS3Read: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - !If [SalesforceCredentialsSecretsManagerARNHasValue, !Ref SecretsManagerManagedPolicy, !Ref AWS::NoValue] - !If [SalesforceCredentialsKMSKeyARNHasValue, !Ref KMSManagedPolicy, !Ref AWS::NoValue] - !Ref CloudWatchManagedPolicy - !If [PrivateVpcEnabledCondition, !Ref VpcManagedPolicy, !Ref AWS::NoValue] Policies: - Fn::If: - HistoricalReportingImportEnabledCondition - PolicyDocument: Statement: - Action: - s3:GetObject Effect: Allow Resource: - Fn::Sub: "arn:aws:s3:::${ConnectReportingS3BucketName}/*" Version: '2012-10-17' PolicyName: sfLambdaBasicExecWithS3ReadReportingS3Policy - Ref: AWS::NoValue sfRealTimeQueueMetricsRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - !If [SalesforceCredentialsSecretsManagerARNHasValue, !Ref SecretsManagerManagedPolicy, !Ref AWS::NoValue] - !If [SalesforceCredentialsKMSKeyARNHasValue, !Ref KMSManagedPolicy, !Ref AWS::NoValue] - !Ref CloudWatchManagedPolicy - !If [PrivateVpcEnabledCondition, !Ref VpcManagedPolicy, !Ref AWS::NoValue] Policies: - Fn::If: - sfRealTimeQueueMetricsConnectPolicyCondition - PolicyDocument: Statement: - Action: - connect:ListQueues - connect:GetCurrentMetricData Effect: Allow Resource: - Fn::Sub: arn:aws:connect:${AWS::Region}:${AWS::AccountId}:instance/${AmazonConnectInstanceId}/* Version: '2012-10-17' PolicyName: sfRealTimeQueueMetricsConnectPolicy - Ref: AWS::NoValue sfRealTimeQueueMetricsLoopJobRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - !Ref CloudWatchManagedPolicy - !If [PrivateVpcEnabledCondition, !Ref VpcManagedPolicy, !Ref AWS::NoValue] Policies: - PolicyDocument: Statement: - Action: - lambda:InvokeFunction Effect: Allow Resource: - Fn::GetAtt: sfRealTimeQueueMetrics.Arn Version: '2012-10-17' PolicyName: sfRealTimeQueueMetricsLoopJobInvokeLambdaPolicy sfGetTranscribeJobStatusRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com Version: '2012-10-17' Path: / ManagedPolicyArns: - !Ref CloudWatchManagedPolicy - !If [PrivateVpcEnabledCondition, !Ref VpcManagedPolicy, !Ref AWS::NoValue] Policies: - PolicyDocument: Statement: - Action: - transcribe:GetTranscriptionJob Effect: Allow Resource: '*' Version: '2012-10-17' PolicyName: sfGetTranscribeJobStatusTranscribePolicy sfSubmitTranscribeJobRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com Version: '2012-10-17' Path: / ManagedPolicyArns: - !Ref CloudWatchManagedPolicy - !If [PrivateVpcEnabledCondition, !Ref VpcManagedPolicy, !Ref AWS::NoValue] Policies: - PolicyDocument: Statement: - Action: - transcribe:StartTranscriptionJob Effect: Allow Resource: '*' Version: '2012-10-17' PolicyName: sfSubmitTranscribeJobTranscribePolicy - Fn::If: - sfSubmitTranscribeJobConnectRecordingS3PolicyCondition - PolicyDocument: Statement: - Action: - s3:GetObject - s3:GetObjectAcl Effect: Allow Resource: - Fn::Sub: arn:aws:s3:::${ConnectRecordingS3BucketName}/* Version: '2012-10-17' PolicyName: sfSubmitTranscribeJobConnectRecordingS3Policy - !Ref AWS::NoValue - Fn::If: - sfSubmitTranscribeJobTranscribeOutputS3PolicyCondition - PolicyDocument: Statement: - Action: - s3:GetObject - s3:PutObject Effect: Allow Resource: - Fn::Sub: arn:aws:s3:::${TranscribeOutputS3BucketName}/* Version: '2012-10-17' PolicyName: sfSubmitTranscribeJobTranscribeOutputS3Policy - !Ref AWS::NoValue sfExecuteTranscriptionStateMachineRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com Version: '2012-10-17' Path: / ManagedPolicyArns: - !Ref CloudWatchManagedPolicy - !If [PrivateVpcEnabledCondition, !Ref VpcManagedPolicy, !Ref AWS::NoValue] Policies: - PolicyDocument: Statement: - Action: - states:StartExecution - states:StopExecution Effect: Allow Resource: Ref: sfTranscribeStateMachine Version: '2012-10-17' PolicyName: sfExecuteTranscriptionStateMachineStepFunctionPolicy - Fn::If: - sfExecuteTranscriptionStateMachineLockS3PolicyCondition - PolicyDocument: Statement: - Action: - s3:GetObject - s3:PutObject - s3:ListBucket Effect: Allow Resource: - Fn::Sub: arn:aws:s3:::${TranscribeOutputS3BucketName} - Fn::Sub: arn:aws:s3:::${TranscribeOutputS3BucketName}/* Version: '2012-10-17' PolicyName: sfExecuteTranscriptionStateMachineLockS3Policy - !Ref AWS::NoValue - Fn::If: - sfExecuteTranscriptionStateMachineRecordingS3PolicyCondition - PolicyDocument: Statement: - Action: - s3:GetObject Effect: Allow Resource: - Fn::Sub: arn:aws:s3:::${ConnectRecordingS3BucketName}/* Version: '2012-10-17' PolicyName: sfExecuteTranscriptionStateMachineRecordingS3Policy - !Ref AWS::NoValue - PolicyDocument: Statement: - Action: - lambda:InvokeFunction Effect: Allow Resource: Fn::GetAtt: sfInvokeAPI.Arn Version: '2012-10-17' PolicyName: sfExecuteTranscriptionStateMachineSfInvokeAPIPolicy sfSig4RequestToS3Role: Condition: PostcallRecordingImportEnabledCondition Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com - edgelambda.amazonaws.com Version: '2012-10-17' Policies: - Fn::If: - ConnectRecordingS3BucketNameHasValue - PolicyDocument: Statement: - Action: - s3:GetObject Effect: Allow Resource: - Fn::Sub: arn:aws:s3:::${ConnectRecordingS3BucketName}/* Version: '2012-10-17' PolicyName: sfSig4RequestToS3RolePolicy - !Ref AWS::NoValue ManagedPolicyArns: - !Ref CloudWatchManagedPolicy sfCTRTriggerRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com Version: '2012-10-17' Path: / ManagedPolicyArns: - !Ref CloudWatchManagedPolicy - !If [PrivateVpcEnabledCondition, !Ref VpcManagedPolicy, !Ref AWS::NoValue] Policies: - Fn::If: - CTREventSourceMappingCondition - PolicyDocument: Statement: - Action: - kinesis:GetShardIterator - kinesis:GetRecords - kinesis:DescribeStream Effect: Allow Resource: - Ref: CTRKinesisARN Version: '2012-10-17' PolicyName: sfCTRTriggerKinesisPolicy - Ref: AWS::NoValue - PolicyDocument: Statement: - Action: - lambda:InvokeAsync - lambda:InvokeFunction Effect: Allow Resource: - Fn::GetAtt: sfExecuteTranscriptionStateMachine.Arn - Fn::GetAtt: sfContactTraceRecord.Arn Version: '2012-10-17' PolicyName: sfCTRTriggerLambdaPolicy sfProcessTranscriptionResultRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com Version: '2012-10-17' Path: / ManagedPolicyArns: - !Ref CloudWatchManagedPolicy - !If [PrivateVpcEnabledCondition, !Ref VpcManagedPolicy, !Ref AWS::NoValue] Policies: - Fn::If: - sfProcessTranscriptionResultS3PolicyCondition - PolicyDocument: Statement: - Action: - s3:GetObject - s3:PutObject Effect: Allow Resource: - Fn::Sub: arn:aws:s3:::${TranscribeOutputS3BucketName}/* Version: '2012-10-17' PolicyName: sfProcessTranscriptionResultS3Policy - Ref: AWS::NoValue - PolicyDocument: Statement: - Action: - comprehend:Detect* - comprehend:BatchDetect* Effect: Allow Resource: '*' Version: '2012-10-17' PolicyName: sfProcessTranscriptionResultComprehendPolicy - PolicyDocument: Statement: - Action: - lambda:InvokeFunction Effect: Allow Resource: Fn::GetAtt: sfInvokeAPI.Arn Version: '2012-10-17' PolicyName: sfProcessTranscriptionResultSfInvokeAPIPolicy sfProcessContactLensRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com Version: '2012-10-17' Path: / ManagedPolicyArns: - !Ref CloudWatchManagedPolicy - !If [PrivateVpcEnabledCondition, !Ref VpcManagedPolicy, !Ref AWS::NoValue] Policies: - Fn::If: - sfProcessContactLensResultS3PolicyCondition - PolicyDocument: Statement: - Action: - s3:GetObject - s3:PutObject Effect: Allow Resource: - Fn::Sub: arn:aws:s3:::${TranscribeOutputS3BucketName}/* Version: '2012-10-17' PolicyName: sfProcessContactLensResultS3Policy - !Ref AWS::NoValue - Fn::If: - sfProcessContactLensRecordingS3PolicyCondition - PolicyDocument: Statement: - Action: - s3:GetObject Effect: Allow Resource: - Fn::Sub: arn:aws:s3:::${ConnectRecordingS3BucketName}/connect/${AmazonConnectInstanceId}/CallRecordings/* Version: '2012-10-17' PolicyName: sfProcessContactLensRecordingS3Policy - !Ref AWS::NoValue - Fn::If: - sfProcessContactLensDataS3PolicyCondition - PolicyDocument: Statement: - Action: - s3:GetObject - s3:ListBucket Effect: Allow Resource: - Fn::Sub: arn:aws:s3:::${ConnectRecordingS3BucketName}/* - Fn::Sub: arn:aws:s3:::${ConnectRecordingS3BucketName} Version: '2012-10-17' PolicyName: sfProcessContactLensDataS3Policy - !Ref AWS::NoValue - Fn::If: - sfProcessContactLensConnectPolicyCondition - PolicyDocument: Statement: - Action: - connect:GetContactAttributes Effect: Allow Resource: - Fn::Sub: arn:aws:connect:${AWS::Region}:${AWS::AccountId}:instance/${AmazonConnectInstanceId}/contact/* Version: '2012-10-17' PolicyName: sfProcessContactLensConnectPolicy - !Ref AWS::NoValue - PolicyDocument: Statement: - Action: - lambda:InvokeFunction Effect: Allow Resource: Fn::GetAtt: sfInvokeAPI.Arn Version: '2012-10-17' PolicyName: sfProcessContactLensSfInvokeAPIPolicy sfTranscribeStateMachineRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - Fn::Sub: states.${AWS::Region}.amazonaws.com Version: '2012-10-17' Path: / Policies: - PolicyDocument: Statement: - Action: - lambda:InvokeFunction Effect: Allow Resource: - Fn::GetAtt: sfSubmitTranscribeJob.Arn - Fn::GetAtt: sfGetTranscribeJobStatus.Arn - Fn::GetAtt: sfProcessTranscriptionResult.Arn Version: '2012-10-17' PolicyName: sfTranscribeStateMachinePolicy sfRealTimeQueueMetricsLoopJobStateMachineRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - Fn::Sub: states.${AWS::Region}.amazonaws.com Version: '2012-10-17' Path: / Policies: - PolicyDocument: Statement: - Action: - lambda:InvokeFunction Effect: Allow Resource: - Fn::GetAtt: sfRealTimeQueueMetricsLoopJob.Arn Version: '2012-10-17' PolicyName: sfRealTimeQueueMetricsLoopJobStateMachinePolicy sfInvokeAPI: Type: AWS::Serverless::Function Properties: Handler: sfInvokeAPI.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - !Ref AWS::NoValue Role: Fn::GetAtt: sfLambdaBasicExec.Arn Layers: - Ref: sfLambdaLayer Environment: Variables: SF_HOST: Ref: SalesforceHost SF_PRODUCTION: Ref: SalesforceProduction SF_USERNAME: Ref: SalesforceUsername SF_VERSION: Ref: SalesforceVersion SF_ADAPTER_NAMESPACE: Ref: SalesforceAdapterNamespace SF_CREDENTIALS_SECRETS_MANAGER_ARN: Ref: SalesforceCredentialsSecretsManagerARN LOGGING_LEVEL: Ref: LambdaLoggingLevel sfExecuteAWSService: Type: AWS::Serverless::Function Properties: Handler: sfExecuteAWSService.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfExecuteAWSServiceRole.Arn Timeout: 10 Environment: Variables: GENERATE_AUDIO_RECORDING_LAMBDA: Fn::If: - sfAudioRecordingStreamingCloudFrontDistributionCondition - !Ref sfGenerateAudioRecordingStreamingURL - !Ref AWS::NoValue CLOUDFORMATION_STACK_ID: Ref: AWS::StackId CLOUDFORMATION_STACK_NAME: Ref: AWS::StackName LOGGING_LEVEL: Ref: LambdaLoggingLevel CLOUDFRONT_DISTRIBUTION_ID: Fn::If: - sfAudioRecordingStreamingCloudFrontDistributionCondition - !Ref sfAudioRecordingStreamingCloudFrontDistribution - !Ref AWS::NoValue RECORDING_BUCKET_NAME: Ref: ConnectRecordingS3BucketName NAMESPACE: Ref: SalesforceAdapterNamespace SALESFORCE_HOST: Ref: SalesforceHost SIG4_LAMBDA_ROLE_ARN: Fn::If: - PostcallRecordingImportEnabledCondition - Fn::GetAtt: sfSig4RequestToS3Role.Arn - !Ref AWS::NoValue sfContactTraceRecord: Type: AWS::Serverless::Function Properties: Handler: sfContactTraceRecord.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfLambdaBasicExec.Arn Layers: - Ref: sfLambdaLayer Timeout: 30 Environment: Variables: SF_HOST: Ref: SalesforceHost SF_PRODUCTION: Ref: SalesforceProduction SF_USERNAME: Ref: SalesforceUsername SF_VERSION: Ref: SalesforceVersion SF_ADAPTER_NAMESPACE: Ref: SalesforceAdapterNamespace SF_CREDENTIALS_SECRETS_MANAGER_ARN: Ref: SalesforceCredentialsSecretsManagerARN LOGGING_LEVEL: Ref: LambdaLoggingLevel sfIntervalAgent: Type: AWS::Serverless::Function Properties: Handler: sfIntervalAgent.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfLambdaBasicExecWithS3Read.Arn Layers: - Ref: sfLambdaLayer Timeout: 60 Environment: Variables: SF_HOST: Ref: SalesforceHost SF_PRODUCTION: Ref: SalesforceProduction SF_USERNAME: Ref: SalesforceUsername SF_VERSION: Ref: SalesforceVersion SF_ADAPTER_NAMESPACE: Ref: SalesforceAdapterNamespace SF_CREDENTIALS_SECRETS_MANAGER_ARN: Ref: SalesforceCredentialsSecretsManagerARN LOGGING_LEVEL: Ref: LambdaLoggingLevel sfIntervalQueue: Type: AWS::Serverless::Function Properties: Handler: sfIntervalQueue.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfLambdaBasicExecWithS3Read.Arn Layers: - Ref: sfLambdaLayer Timeout: 60 Environment: Variables: SF_HOST: Ref: SalesforceHost SF_PRODUCTION: Ref: SalesforceProduction SF_USERNAME: Ref: SalesforceUsername SF_VERSION: Ref: SalesforceVersion SF_ADAPTER_NAMESPACE: Ref: SalesforceAdapterNamespace SF_CREDENTIALS_SECRETS_MANAGER_ARN: Ref: SalesforceCredentialsSecretsManagerARN LOGGING_LEVEL: Ref: LambdaLoggingLevel sfRealTimeQueueMetrics: Type: AWS::Serverless::Function Properties: Handler: sfRealTimeQueueMetrics.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfRealTimeQueueMetricsRole.Arn Layers: - Ref: sfLambdaLayer Timeout: 900 Environment: Variables: SF_HOST: Ref: SalesforceHost SF_PRODUCTION: Ref: SalesforceProduction SF_USERNAME: Ref: SalesforceUsername SF_VERSION: Ref: SalesforceVersion SF_ADAPTER_NAMESPACE: Ref: SalesforceAdapterNamespace AMAZON_CONNECT_INSTANCE_ID: Ref: AmazonConnectInstanceId AMAZON_CONNECT_QUEUE_MAX_RESULT: Ref: AmazonConnectQueueMaxRecords AMAZON_CONNECT_QUEUEMETRICS_MAX_RESULT: Ref: AmazonConnectQueueMetricsMaxRecords SF_CREDENTIALS_SECRETS_MANAGER_ARN: Ref: SalesforceCredentialsSecretsManagerARN LOGGING_LEVEL: Ref: LambdaLoggingLevel sfRealTimeQueueMetricsLoopJob: Type: AWS::Serverless::Function Properties: Handler: sfRealTimeQueueMetricsLoopJob.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfRealTimeQueueMetricsLoopJobRole.Arn Layers: - Ref: sfLambdaLayer Timeout: 10 Environment: Variables: SFDC_REALTIME_QUEUE_METRICS_LAMBDA: Fn::GetAtt: sfRealTimeQueueMetrics.Arn LOGGING_LEVEL: Ref: LambdaLoggingLevel sfGenerateAudioRecordingStreamingURL: Condition: sfAudioRecordingStreamingCloudFrontDistributionCondition Type: AWS::Serverless::Function Properties: Handler: sfGenerateAudioRecordingStreamingURL.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfLambdaBasicExec.Arn Layers: - Ref: sfLambdaLayer Timeout: 10 Environment: Variables: SF_HOST: Ref: SalesforceHost SF_CREDENTIALS_SECRETS_MANAGER_ARN: Ref: SalesforceCredentialsSecretsManagerARN CLOUDFRONT_DISTRIBUTION_DOMAIN_NAME: Fn::GetAtt: sfAudioRecordingStreamingCloudFrontDistribution.DomainName LOGGING_LEVEL: Ref: LambdaLoggingLevel sfAudioRecordingStreamingCloudFrontDistribution: Condition: sfAudioRecordingStreamingCloudFrontDistributionCondition Type: AWS::CloudFront::Distribution Properties: DistributionConfig: DefaultCacheBehavior: AllowedMethods: [GET, HEAD, OPTIONS] Compress: true CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6 # Managed-CachingOptimized OriginRequestPolicyId: 88a5eaf4-2fd4-4709-b370-b4c650ea3fcf # Managed-CORS-S3Origin TargetOriginId: AudioRecordingStreamingCloudFrontOrigin TrustedSigners: [self] ViewerProtocolPolicy: redirect-to-https Enabled: true IPV6Enabled: true Origins: - DomainName: !Join ['.', [!Ref ConnectRecordingS3BucketName, 's3', !Ref 'AWS::Region', 'amazonaws.com']] Id: AudioRecordingStreamingCloudFrontOrigin CustomOriginConfig: OriginProtocolPolicy: https-only OriginSSLProtocols: - TLSv1.2 OriginCustomHeaders: - HeaderName: Access-Control-Allow-Origin HeaderValue: !Ref SalesforceHost sfGetTranscribeJobStatus: Type: AWS::Serverless::Function Properties: Handler: sfGetTranscribeJobStatus.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfGetTranscribeJobStatusRole.Arn Layers: - Ref: sfLambdaLayer Timeout: 10 Environment: Variables: LOGGING_LEVEL: Ref: LambdaLoggingLevel sfSubmitTranscribeJob: Type: AWS::Serverless::Function Properties: Handler: sfSubmitTranscribeJob.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfSubmitTranscribeJobRole.Arn Layers: - Ref: sfLambdaLayer Timeout: 10 Environment: Variables: LOGGING_LEVEL: Ref: LambdaLoggingLevel sfExecuteTranscriptionStateMachine: Type: AWS::Serverless::Function Properties: Handler: sfExecuteTranscriptionStateMachine.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfExecuteTranscriptionStateMachineRole.Arn Layers: - Ref: sfLambdaLayer Timeout: 120 Environment: Variables: MEDIA_FORMAT: wav TRANSCRIBE_STATE_MACHINE_ARN: Ref: sfTranscribeStateMachine WAIT_TIME: Ref: TranscriptionJobCheckWaitTime TRANSCRIPTS_DESTINATION: Ref: TranscribeOutputS3BucketName TRANSCRIPTS_DESTINATION_KMS: '' #Ref: TranscribeOutputEncryptionKMSKeyId SFDC_INVOKE_API_LAMBDA: Fn::GetAtt: sfInvokeAPI.Arn SF_ADAPTER_NAMESPACE: Ref: SalesforceAdapterNamespace LOGGING_LEVEL: Ref: LambdaLoggingLevel sfCTRTrigger: Type: AWS::Serverless::Function Properties: Handler: sfCTRTrigger.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfCTRTriggerRole.Arn Layers: - Ref: sfLambdaLayer Timeout: 20 Environment: Variables: EXECUTE_TRANSCRIPTION_STATE_MACHINE_LAMBDA: Ref: sfExecuteTranscriptionStateMachine EXECUTE_CTR_IMPORT_LAMBDA: Ref: sfContactTraceRecord POSTCALL_CTR_IMPORT_ENABLED: Ref: PostcallCTRImportEnabled POSTCALL_RECORDING_IMPORT_ENABLED: Ref: PostcallRecordingImportEnabled POSTCALL_TRANSCRIBE_ENABLED: Ref: PostcallTranscribeEnabled LOGGING_LEVEL: Ref: LambdaLoggingLevel CTREventSourceMapping: Type: "AWS::Lambda::EventSourceMapping" Condition: CTREventSourceMappingCondition Properties: EventSourceArn: Ref: CTRKinesisARN FunctionName: Fn::GetAtt: sfCTRTrigger.Arn StartingPosition: "LATEST" BatchSize: 100 MaximumRetryAttempts: !Ref CTREventSourceMappingMaximumRetryAttempts sfProcessTranscriptionResult: Type: AWS::Serverless::Function Properties: Handler: sfProcessTranscriptionResult.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfProcessTranscriptionResultRole.Arn Layers: - Ref: sfLambdaLayer Timeout: 60 Environment: Variables: SFDC_INVOKE_API_LAMBDA: Fn::GetAtt: sfInvokeAPI.Arn SF_ADAPTER_NAMESPACE: Ref: SalesforceAdapterNamespace LOGGING_LEVEL: Ref: LambdaLoggingLevel sfProcessContactLens: Type: AWS::Serverless::Function Properties: Handler: sfProcessContactLens.lambda_handler VpcConfig: !If - PrivateVpcEnabledCondition - SubnetIds: !Ref VpcSubnetList SecurityGroupIds: !Ref VpcSecurityGroupList - Ref: AWS::NoValue Role: Fn::GetAtt: sfProcessContactLensRole.Arn Timeout: 60 Layers: - Ref: sfLambdaLayer Environment: Variables: SFDC_INVOKE_API_LAMBDA: Fn::GetAtt: sfInvokeAPI.Arn SF_ADAPTER_NAMESPACE: Ref: SalesforceAdapterNamespace TRANSCRIPTS_DESTINATION: Ref: TranscribeOutputS3BucketName CONTACT_LENS_IMPORT_ENABLED: Ref: ContactLensImportEnabled AMAZON_CONNECT_INSTANCE_ID: Ref: AmazonConnectInstanceId LOGGING_LEVEL: Ref: LambdaLoggingLevel sfRealTimeQueueMetricsLoopJobStateMachine: Type: AWS::StepFunctions::StateMachine Properties: DefinitionString: !Sub - |- { "Comment": "Invoke Real time Queue Metrics Lambda function every 15 seconds", "StartAt": "ConfigureCount", "States": { "ConfigureCount": { "Type": "Pass", "Result": { "index": 0, "count": 4 }, "ResultPath": "$.iterator", "Next": "Iterator" }, "Iterator": { "Type": "Task", "Resource": "${sfRealTimeQueueMetricsLoopJob}", "ResultPath": "$.iterator", "Next": "IsCountReached" }, "IsCountReached": { "Type": "Choice", "Choices": [ { "Variable": "$.iterator.continue", "BooleanEquals": true, "Next": "Wait" } ], "Default": "Done" }, "Wait": { "Type": "Wait", "Seconds": 15, "Next": "Iterator" }, "Done": { "Type": "Pass", "End": true } } } - { sfRealTimeQueueMetricsLoopJob: !GetAtt [sfRealTimeQueueMetricsLoopJob, Arn] } RoleArn: Fn::GetAtt: sfRealTimeQueueMetricsLoopJobStateMachineRole.Arn sfTranscribeStateMachine: Type: AWS::StepFunctions::StateMachine Properties: DefinitionString: !Sub - |- { "Comment": "A state machine that submits a Job to transcribe audio", "StartAt": "Submit Transcription Job", "States": { "Submit Transcription Job": { "Type": "Task", "Resource": "${sfSubmitTranscribeJob}", "ResultPath": "$.TranscriptionJob", "Next": "Wait X Seconds", "Retry": [ { "ErrorEquals": [ "States.ALL" ], "IntervalSeconds": 20, "MaxAttempts": 3, "BackoffRate": 2 } ] }, "Wait X Seconds": { "Type": "Wait", "SecondsPath": "$.wait_time", "Next": "Get Transcription Job Status" }, "Get Transcription Job Status": { "Type": "Task", "Resource": "${sfGetTranscribeJobStatus}", "Next": "Job Complete?", "InputPath": "$.TranscriptionJob", "ResultPath": "$.TranscriptionJob", "Retry": [ { "ErrorEquals": [ "States.ALL" ], "IntervalSeconds": 20, "MaxAttempts": 3, "BackoffRate": 2 } ] }, "Job Complete?": { "Type": "Choice", "Choices": [ { "Variable": "$.TranscriptionJob.TranscriptionJobStatus", "StringEquals": "FAILED", "Next": "Job Failed" }, { "Variable": "$.TranscriptionJob.TranscriptionJobStatus", "StringEquals": "COMPLETED", "Next": "Process Transcription Result" } ], "Default": "Wait X Seconds" }, "Job Failed": { "Type": "Fail", "Cause": "Transcription job Failed", "Error": "Transcription job FAILED" }, "Process Transcription Result": { "Type": "Task", "Resource": "${sfProcessTranscriptionResult}", "InputPath": "$", "End": true, "Retry": [ { "ErrorEquals": [ "States.ALL" ], "IntervalSeconds": 20, "MaxAttempts": 3, "BackoffRate": 2 } ] } } } - { sfSubmitTranscribeJob: !GetAtt [sfSubmitTranscribeJob, Arn], sfGetTranscribeJobStatus: !GetAtt [sfGetTranscribeJobStatus,Arn], sfProcessTranscriptionResult: !GetAtt [sfProcessTranscriptionResult,Arn] } RoleArn: Fn::GetAtt: sfTranscribeStateMachineRole.Arn sfRealTimeQueueMetricsCron: Type: AWS::Events::Rule Properties: Description: Executes Step Functions every minute ScheduleExpression: rate(1 minute) State: !If [RealtimeReportingImportEnabledCondition, ENABLED, DISABLED] Targets: - Arn: !Ref sfRealTimeQueueMetricsLoopJobStateMachine Id: !Sub '${AWS::StackName}-sfRealTimeQueue' RoleArn: !GetAtt sfRealTimeQueueMetricsCronExecutionRole.Arn sfRealTimeQueueMetricsCronExecutionRole: 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: sfRealTimeQueueMetricsCronStartStepFunctions PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: states:StartExecution Resource: !Ref sfRealTimeQueueMetricsLoopJobStateMachine