From a840c4c5701c23db018fe3ba521cdb2a2e511178 Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Mon, 17 Feb 2025 16:29:48 -0600 Subject: [PATCH 01/22] Enhanced SSM Parameter Resolution and Resource Naming --- .DS_Store | Bin 0 -> 6148 bytes .idea/.gitignore | 8 + .../amazon-transcribe-post-call-analytics.iml | 9 + .idea/aws.xml | 17 + .idea/cfnlintPlugin.xml | 8 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/vcs.xml | 7 + pca-main-nokendra.template | 10 +- pca-main.template | 10 +- pca-server/cfn/lib/boto3.template | 15 +- pca-server/cfn/lib/bulk.template | 68 ++- pca-server/cfn/lib/ffmpeg.template | 13 +- pca-server/cfn/lib/glue-database.template | 45 +- pca-server/cfn/lib/pca.template | 263 +++++---- pca-server/cfn/lib/python-utilities.template | 15 +- pca-server/cfn/lib/trigger.template | 76 ++- pca-server/cfn/pca-server.template | 19 + pca-server/src/pca/pcaconfiguration.py | 90 +-- pca-ssm/.DS_Store | Bin 0 -> 6148 bytes pca-ssm/cfn/ssm.template | 533 +++++++++--------- pca-ui/cfn/pca-ui.template | 6 +- 22 files changed, 721 insertions(+), 505 deletions(-) create mode 100644 .DS_Store create mode 100644 .idea/.gitignore create mode 100644 .idea/amazon-transcribe-post-call-analytics.iml create mode 100644 .idea/aws.xml create mode 100644 .idea/cfnlintPlugin.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 pca-ssm/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ffba39b5f741f9bb3e49a19316c97625434fc2da GIT binary patch literal 6148 zcmeHK%}T>S5Z<-brW7Fu1-&hJtytSq6fYsx7cim+m718M!8BW%)*MP9cYPsW#OHBl zcOz7D@FZeqVDrt+&+g6#*&oIjcW2=tV>V;Vf`-UZDG@Z6y4FlEB3EOiEM=o0OUFT6 zGSFW%;o56#%z4s|-hy!)rPEgHov&4@>l-zzW;Lu^?@?yn)Su2$*PmQt z??TErD0Dx#jE333-a3`Z)Q^(kL?uMw5JGOQq9l}=D`!cVs$5Syth!Yn*t_$2r+d_H zie9g~Xo~r9yVVrkPH(ZOTibgFC+CBwc$CN&%_Rrgm24U;;1!fFWj%Y7B$mkoc#5nd znvfVE28aP-V5Jx^$AHyXsj8`1Vt^R<2?Mx42xy3o!Ca%-I^cuXXY^MQQ9#GH1fnqL z7|b<-2ZZZXK%L6X6NBq?unQCC7|b>5bjH=pFpinIc)V~mJJ^K^XWY?9Ut)k5SZ1K2 zyEdNxXYk9EKJu4Ss7DMC1OJQxUhR8*7m6}x>$mdotQFAiprK$~jtU6qOP2uX;6AdW eoZ2r?hd9Szt`SE;yGjS7i-018KE%K;Fz^A}_e^sD literal 0 HcmV?d00001 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..13566b81 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/amazon-transcribe-post-call-analytics.iml b/.idea/amazon-transcribe-post-call-analytics.iml new file mode 100644 index 00000000..d6ebd480 --- /dev/null +++ b/.idea/amazon-transcribe-post-call-analytics.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/aws.xml b/.idea/aws.xml new file mode 100644 index 00000000..e14a2062 --- /dev/null +++ b/.idea/aws.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/cfnlintPlugin.xml b/.idea/cfnlintPlugin.xml new file mode 100644 index 00000000..e700753a --- /dev/null +++ b/.idea/cfnlintPlugin.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..639900d1 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..1823aeee --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..bc514777 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/pca-main-nokendra.template b/pca-main-nokendra.template index e8e0bca7..02e9a1bb 100644 --- a/pca-main-nokendra.template +++ b/pca-main-nokendra.template @@ -354,8 +354,8 @@ Parameters: DatabaseName: Type: String - Default: 'pca' - Description: Glue catalog database name used to contain tables/views for SQL integration. + AllowedPattern: "[a-zA-Z0-9_-]+" + Description: (Required) Glue catalog database name used to contain tables/views for SQL integration. EnablePcaDashboards: Type: String @@ -848,6 +848,7 @@ Resources: Properties: TemplateURL: pca-ssm/cfn/ssm.template Parameters: + StackName: !Ref 'AWS::StackName' BulkUploadBucketName: !If - ShouldCreateBulkUploadBucket @@ -918,6 +919,8 @@ Resources: Type: AWS::CloudFormation::Stack Properties: TemplateURL: pca-server/cfn/lib/python-utilities.template + Parameters: + ParentStackName: !Ref 'AWS::StackName' BedrockBoto3Layer: Type: AWS::CloudFormation::Stack @@ -944,6 +947,8 @@ Resources: Properties: TemplateURL: pca-server/cfn/pca-server.template Parameters: + DatabaseName: !Ref DatabaseName + ParentStackName: !Ref 'AWS::StackName' ffmpegDownloadUrl: !Ref ffmpegDownloadUrl CallSummarization: !Ref CallSummarization SummarizationBedrockModelId: !Ref SummarizationBedrockModelId @@ -966,6 +971,7 @@ Resources: Properties: TemplateURL: pca-ui/cfn/pca-ui.template Parameters: + ParentStackName: !Ref 'AWS::StackName' AdminUsername: !Ref AdminUsername AdminEmail: !Ref AdminEmail AllowedSignUpEmailDomain: !Ref AllowedSignUpEmailDomain diff --git a/pca-main.template b/pca-main.template index c99c4a71..504a4a41 100644 --- a/pca-main.template +++ b/pca-main.template @@ -395,8 +395,8 @@ Parameters: DatabaseName: Type: String - Default: 'pca' - Description: Glue catalog database name used to contain tables/views for SQL integration. + AllowedPattern: "[a-zA-Z0-9_-]+" + Description: (Required) Glue catalog database name used to contain tables/views for SQL integration. EnablePcaDashboards: Type: String @@ -1031,6 +1031,7 @@ Resources: Properties: TemplateURL: pca-ssm/cfn/ssm.template Parameters: + StackName: !Ref 'AWS::StackName' BulkUploadBucketName: !If - ShouldCreateBulkUploadBucket @@ -1102,6 +1103,8 @@ Resources: Type: AWS::CloudFormation::Stack Properties: TemplateURL: pca-server/cfn/lib/python-utilities.template + Parameters: + ParentStackName: !Ref 'AWS::StackName' BedrockBoto3Layer: Type: AWS::CloudFormation::Stack @@ -1128,6 +1131,8 @@ Resources: Properties: TemplateURL: pca-server/cfn/pca-server.template Parameters: + DatabaseName: !Ref DatabaseName + ParentStackName: !Ref 'AWS::StackName' ffmpegDownloadUrl: !Ref ffmpegDownloadUrl CallSummarization: !Ref CallSummarization SummarizationBedrockModelId: !Ref SummarizationBedrockModelId @@ -1150,6 +1155,7 @@ Resources: Properties: TemplateURL: pca-ui/cfn/pca-ui.template Parameters: + ParentStackName: !Ref 'AWS::StackName' AdminUsername: !Ref AdminUsername AdminEmail: !Ref AdminEmail AllowedSignUpEmailDomain: !Ref AllowedSignUpEmailDomain diff --git a/pca-server/cfn/lib/boto3.template b/pca-server/cfn/lib/boto3.template index 575878c2..8238e131 100644 --- a/pca-server/cfn/lib/boto3.template +++ b/pca-server/cfn/lib/boto3.template @@ -5,10 +5,13 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - Boto3 Layer Zi Transform: AWS::Serverless-2016-10-31 Parameters: + ParentStackName: + Type: String + Description: Name of the parent stack - SupportFilesBucketName: - Type: AWS::SSM::Parameter::Value - Default: SupportFilesBucketName +# SupportFilesBucketName: +# Type: AWS::SSM::Parameter::Value +# Default: SupportFilesBucketName Boto3ZipName: Type: String @@ -36,7 +39,7 @@ Resources: Resource: !Sub - 'arn:aws:s3:::${bucket}*' - - bucket: !Ref SupportFilesBucketName + - bucket: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' Action: - 's3:PutObject' PolicyName: boto3ZipFunctionS3Policy @@ -51,7 +54,7 @@ Resources: MemorySize: 512 Environment: Variables: - SUPPORT_FILES_BUCKET: !Ref SupportFilesBucketName + SUPPORT_FILES_BUCKET: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' BOTO3_ZIP_NAME: !Ref Boto3ZipName Code: ZipFile: | @@ -124,7 +127,7 @@ Resources: DependsOn: boto3Zip Properties: Content: - S3Bucket: !Ref SupportFilesBucketName + S3Bucket: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' S3Key: !Ref Boto3ZipName Outputs: diff --git a/pca-server/cfn/lib/bulk.template b/pca-server/cfn/lib/bulk.template index 009bc214..09a91048 100644 --- a/pca-server/cfn/lib/bulk.template +++ b/pca-server/cfn/lib/bulk.template @@ -5,17 +5,21 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - BulkImport Sta Transform: AWS::Serverless-2016-10-31 Parameters: - BulkUploadStepFunctionName: - Type: AWS::SSM::Parameter::Value - Default: BulkUploadStepFunctionName + ParentStackName: + Type: String + Description: Name of the parent stack - BulkUploadBucketName: - Type: AWS::SSM::Parameter::Value - Default: BulkUploadBucket - - InputBucketName: - Type: AWS::SSM::Parameter::Value - Default: InputBucketName +# BulkUploadStepFunctionName: +# Type: AWS::SSM::Parameter::Value +# Default: BulkUploadStepFunctionName + +# BulkUploadBucketName: +# Type: AWS::SSM::Parameter::Value +# Default: BulkUploadBucket + +# InputBucketName: +# Type: AWS::SSM::Parameter::Value +# Default: InputBucketName Globals: Function: @@ -37,8 +41,17 @@ Resources: - s3:ListBucket - s3:GetObject Resource: - - !Sub arn:aws:s3:::${BulkUploadBucketName} - - !Sub arn:aws:s3:::${BulkUploadBucketName}/* + - !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-BulkUploadBucket}}' + - !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-BulkUploadBucket}}' + - '/*' + #- !Sub arn:aws:s3:::${BulkUploadBucketName} + #- !Sub arn:aws:s3:::${BulkUploadBucketName}/* - Statement: - Sid: SSMGetParameterPolicy Effect: Allow @@ -62,10 +75,24 @@ Resources: - s3:PutObject - s3:DeleteObject Resource: - - !Sub arn:aws:s3:::${BulkUploadBucketName} - - !Sub arn:aws:s3:::${BulkUploadBucketName}/* - - !Sub arn:aws:s3:::${InputBucketName} - - !Sub arn:aws:s3:::${InputBucketName}/* + - !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-BulkUploadBucket}}' + - !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-BulkUploadBucket}}' + - '/*' + - !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + - !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + - '/*' BulkQueueSpace: Type: "AWS::Serverless::Function" @@ -78,8 +105,11 @@ Resources: LogGroup: Type: AWS::Logs::LogGroup - Properties: - LogGroupName: !Sub '/aws/vendedlogs/${BulkUploadStepFunctionName}' + Properties: + LogGroupName: !Join + - '' + - - '/aws/vendedlogs/' + - !Sub "{{resolve:ssm:${ParentStackName}-BulkUploadStepFunctionName}}" RetentionInDays: 90 Role: @@ -119,7 +149,7 @@ Resources: StateMachine: Type: "AWS::StepFunctions::StateMachine" Properties: - StateMachineName: !Ref BulkUploadStepFunctionName + StateMachineName: !Sub "{{resolve:ssm:${ParentStackName}-BulkUploadStepFunctionName}}" DefinitionS3Location: ./bulk-definition.json DefinitionSubstitutions: BulkFilesCountArn: !GetAtt BulkFilesCount.Arn diff --git a/pca-server/cfn/lib/ffmpeg.template b/pca-server/cfn/lib/ffmpeg.template index aedb8778..bd48c02a 100644 --- a/pca-server/cfn/lib/ffmpeg.template +++ b/pca-server/cfn/lib/ffmpeg.template @@ -5,10 +5,13 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - FFMPEG Downloa Transform: AWS::Serverless-2016-10-31 Parameters: + ParentStackName: + Type: String + Description: Name of the parent stack - SupportFilesBucketName: - Type: AWS::SSM::Parameter::Value - Default: SupportFilesBucketName +# SupportFilesBucketName: +# Type: AWS::SSM::Parameter::Value +# Default: SupportFilesBucketName FFMPEGZipName: Type: String @@ -42,7 +45,7 @@ Resources: Resource: !Sub - 'arn:aws:s3:::${bucket}*' - - bucket: !Ref SupportFilesBucketName + - bucket: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' Action: - 's3:PutObject' PolicyName: ffmpegZipFunctionS3Policy @@ -58,7 +61,7 @@ Resources: Environment: Variables: FFMPEG_DOWNLOAD_URL: !Ref ffmpegDownloadUrl - SUPPORT_FILES_BUCKET: !Ref SupportFilesBucketName + SUPPORT_FILES_BUCKET: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' FFMPEG_ZIP_NAME: !Ref FFMPEGZipName Code: ZipFile: | diff --git a/pca-server/cfn/lib/glue-database.template b/pca-server/cfn/lib/glue-database.template index dd4c0d7f..e99d1c86 100644 --- a/pca-server/cfn/lib/glue-database.template +++ b/pca-server/cfn/lib/glue-database.template @@ -5,18 +5,25 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - Glue Catalog D Transform: AWS::Serverless-2016-10-31 Parameters: + ParentStackName: + Type: String + Description: Name of the parent stack - DatabaseName: - Type: AWS::SSM::Parameter::Value - Default: DatabaseName +# DatabaseName: +# Type: AWS::SSM::Parameter::Value + #Default: DatabaseName - OutputBucketName: - Type: AWS::SSM::Parameter::Value - Default: OutputBucketName - - OutputBucketParsedResults: - Type: AWS::SSM::Parameter::Value - Default: OutputBucketParsedResults +# DatabaseName: +# Type: String +# Description: Glue catalog database name used to contain tables/views for SQL integration. + +# OutputBucketName: +# Type: AWS::SSM::Parameter::Value +# Default: OutputBucketName +# +# OutputBucketParsedResults: +# Type: AWS::SSM::Parameter::Value +# Default: OutputBucketParsedResults Resources: @@ -26,8 +33,14 @@ Resources: CatalogId: !Ref AWS::AccountId DatabaseInput: Description: Post Call Analytics - LocationUri: !Sub 's3://${OutputBucketName}/${OutputBucketParsedResults}/' - Name: !Ref DatabaseName + LocationUri: !Join + - '' + - - 's3://' + - !Sub '{{resolve:ssm:${ParentStackName}-OutputBucketName}}' + - '/' + - !Sub '{{resolve:ssm:${ParentStackName}-OutputBucketParsedResults}}' + - '/' + Name: !Sub "{{resolve:ssm:${ParentStackName}-DatabaseName}}" ParsedResultsTable: Type: AWS::Glue::Table @@ -48,7 +61,13 @@ Resources: Compressed: false NumberOfBuckets: -1 InputFormat: org.apache.hadoop.mapred.TextInputFormat - Location: !Sub 's3://${OutputBucketName}/${OutputBucketParsedResults}/' + Location: !Join + - '' + - - 's3://' + - !Sub '{{resolve:ssm:${ParentStackName}-OutputBucketName}}' + - '/' + - !Sub '{{resolve:ssm:${ParentStackName}-OutputBucketParsedResults}}' + - '/' OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat SerdeInfo: Name: JSON diff --git a/pca-server/cfn/lib/pca.template b/pca-server/cfn/lib/pca.template index 182b17cc..bfce59ec 100644 --- a/pca-server/cfn/lib/pca.template +++ b/pca-server/cfn/lib/pca.template @@ -1,10 +1,14 @@ -AWSTemplateFormatVersion: "2010-09-09" +AWSTemplateFormatVersion: '2010-09-09' Description: Amazon Transcribe Post Call Analytics - PCA Server - PCA State Machine Transform: AWS::Serverless-2016-10-31 Parameters: + ParentStackName: + Type: String + Description: Name of the parent stack + TableName: Type: String @@ -18,33 +22,33 @@ Parameters: PyUtilsLayer: Type: String - SupportFilesBucketName: - Type: AWS::SSM::Parameter::Value - Default: SupportFilesBucketName +# SupportFilesBucketName: +# Type: AWS::SSM::Parameter::Value +# Default: SupportFilesBucketName - StepFunctionName: - Type: AWS::SSM::Parameter::Value - Default: StepFunctionName - - InputBucketName: - Type: AWS::SSM::Parameter::Value - Default: InputBucketName +# StepFunctionName: +# Type: AWS::SSM::Parameter::Value +# Default: StepFunctionName - CallSummarization: +# InputBucketName: +# Type: AWS::SSM::Parameter::Value +# Default: InputBucketName + + CallSummarization: Type: String - Default: 'DISABLED' - SummarizationSagemakerEndpointName: + Default: DISABLED + SummarizationSagemakerEndpointName: Type: String Default: '' - SummarizationSagemakerEndpointArn: + SummarizationSagemakerEndpointArn: Type: String Default: '' SummarizationLLMThirdPartyApiKey: Type: String - Description: > + Description: | Secrets manager secret Arn containing the third party LLM API key Default: '' - SummarizationLambdaFunctionArn: + SummarizationLambdaFunctionArn: Type: String Default: '' SummarizationBedrockModelId: @@ -61,20 +65,26 @@ Globals: Timeout: 60 Conditions: - ProvisionedSageMakerEndpoint: !Equals [!Ref CallSummarization, "SAGEMAKER"] - HasCustomSummarizerLambda: !Equals [!Ref CallSummarization, "LAMBDA"] - HasAnthropicSummary: !Equals [!Ref CallSummarization, "ANTHROPIC"] + ProvisionedSageMakerEndpoint: !Equals + - !Ref CallSummarization + - SAGEMAKER + HasCustomSummarizerLambda: !Equals + - !Ref CallSummarization + - LAMBDA + HasAnthropicSummary: !Equals + - !Ref CallSummarization + - ANTHROPIC Resources: FFMPEGLayer: - Type: "AWS::Lambda::LayerVersion" + Type: AWS::Lambda::LayerVersion Properties: Content: - S3Bucket: !Ref SupportFilesBucketName + S3Bucket: !Sub "{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}" S3Key: !Ref FFMPEGZipName TranscribeRole: - Type: "AWS::IAM::Role" + Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: @@ -91,7 +101,7 @@ Resources: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess TranscribeLambdaRole: - Type: "AWS::IAM::Role" + Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: @@ -122,8 +132,17 @@ Resources: - s3:PutObject - s3:DeleteObject Resource: - - !Sub arn:aws:s3:::${InputBucketName} - - !Sub arn:aws:s3:::${InputBucketName}/* + #- !Sub arn:aws:s3:::${InputBucketName} + #- !Sub arn:aws:s3:::${InputBucketName}/* + - !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + - !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + - '/*' - PolicyName: SSMGetParameterPolicy PolicyDocument: Statement: @@ -134,9 +153,9 @@ Resources: Resource: !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/* SFStartTranscribeJob: - Type: "AWS::Serverless::Function" + Type: AWS::Serverless::Function Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-start-transcribe-job.lambda_handler EphemeralStorage: Size: 4096 @@ -147,13 +166,14 @@ Resources: Environment: Variables: RoleArn: !GetAtt TranscribeRole.Arn - AWS_DATA_PATH: "/opt/models" + AWS_DATA_PATH: /opt/models + STACK_NAME: !Ref ParentStackName Role: !GetAtt TranscribeLambdaRole.Arn SFExtractJobHeader: - Type: "AWS::Serverless::Function" + Type: AWS::Serverless::Function Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-extract-job-header.lambda_handler MemorySize: 1024 Timeout: 900 @@ -161,16 +181,17 @@ Resources: - !Ref Boto3Layer Environment: Variables: - AWS_DATA_PATH: "/opt/models" + AWS_DATA_PATH: /opt/models + STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonTranscribeReadOnlyAccess - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess SFExtractTranscriptHeader: - Type: "AWS::Serverless::Function" + Type: AWS::Serverless::Function Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-extract-transcript-header.lambda_handler MemorySize: 1024 Timeout: 900 @@ -179,15 +200,16 @@ Resources: - !Ref FFMPEGLayer Environment: Variables: - AWS_DATA_PATH: "/opt/models" + AWS_DATA_PATH: /opt/models + STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess SFProcessTurn: - Type: "AWS::Serverless::Function" + Type: AWS::Serverless::Function Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-process-turn-by-turn.lambda_handler MemorySize: 1024 Timeout: 900 @@ -196,7 +218,8 @@ Resources: - !Ref Boto3Layer Environment: Variables: - AWS_DATA_PATH: "/opt/models" + AWS_DATA_PATH: /opt/models + STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonTranscribeReadOnlyAccess - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess @@ -205,63 +228,69 @@ Resources: - arn:aws:iam::aws:policy/AmazonKendraFullAccess SFFinalProcessing: - Type: "AWS::Serverless::Function" + Type: AWS::Serverless::Function Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-post-processing.lambda_handler Layers: - !Ref Boto3Layer Environment: Variables: - AWS_DATA_PATH: "/opt/models" + AWS_DATA_PATH: /opt/models + STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess SFCTRGenesys: - Type: "AWS::Serverless::Function" + Type: AWS::Serverless::Function Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-ctr-genesys.lambda_handler Layers: - !Ref Boto3Layer Environment: Variables: - AWS_DATA_PATH: "/opt/models" + AWS_DATA_PATH: /opt/models + STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess SFPostCTRProcessing: - Type: "AWS::Serverless::Function" + Type: AWS::Serverless::Function Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-post-ctr-processing.lambda_handler Layers: - !Ref Boto3Layer Environment: Variables: - AWS_DATA_PATH: "/opt/models" + AWS_DATA_PATH: /opt/models + STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess - + SFFetchTranscript: - Type: "AWS::Serverless::Function" + Type: AWS::Serverless::Function Properties: Runtime: python3.11 - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-fetch-transcript.lambda_handler + Environment: + Variables: + STACK_NAME: !Ref ParentStackName Timeout: 900 Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess SFSummarize: - Type: "AWS::Serverless::Function" + Type: AWS::Serverless::Function Properties: Runtime: python3.11 - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-summarize.lambda_handler Timeout: 900 Layers: @@ -269,7 +298,8 @@ Resources: - !Ref Boto3Layer Environment: Variables: - AWS_DATA_PATH: "/opt/models" + STACK_NAME: !Ref ParentStackName + AWS_DATA_PATH: /opt/models FETCH_TRANSCRIPT_LAMBDA_ARN: !GetAtt SFFetchTranscript.Arn BEDROCK_MODEL_ID: !Ref SummarizationBedrockModelId LLM_TABLE_NAME: !Ref LLMTableName @@ -277,9 +307,9 @@ Resources: SUMMARY_SAGEMAKER_ENDPOINT: !Ref SummarizationSagemakerEndpointName ANTHROPIC_API_KEY: !Ref SummarizationLLMThirdPartyApiKey SUMMARY_LAMBDA_ARN: !Ref SummarizationLambdaFunctionArn - ANTHROPIC_MODEL_IDENTIFIER: "claude-v1.3-100k" - ANTHROPIC_ENDPOINT_URL: "https://api.anthropic.com/v1/complete" - TOKEN_COUNT: !If + ANTHROPIC_MODEL_IDENTIFIER: claude-v1.3-100k + ANTHROPIC_ENDPOINT_URL: https://api.anthropic.com/v1/complete + TOKEN_COUNT: !If - ProvisionedSageMakerEndpoint - 1024 - 0 @@ -287,82 +317,87 @@ Resources: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess - Statement: - - Sid: InvokeGetTranscript - Effect: Allow - Action: - - lambda:InvokeFunction - Resource: !GetAtt SFFetchTranscript.Arn - - Sid: DynamoDBAccess - Effect: Allow - Resource: !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${LLMTableName} - Action: - - 'dynamodb:GetItem' - - Sid: InvokeBedrock - Effect: Allow - Action: - - bedrock:InvokeModel - Resource: - - !Sub "arn:${AWS::Partition}:bedrock:*::foundation-model/*" - - !Sub "arn:${AWS::Partition}:bedrock:*:${AWS::AccountId}:custom-model/*" - - !If - - HasAnthropicSummary - - Sid: SecretsManagerPolicy + - Sid: InvokeGetTranscript Effect: Allow Action: - - 'secretsmanager:GetResourcePolicy' - - 'secretsmanager:GetSecretValue' - - 'secretsmanager:DescribeSecret' - - 'secretsmanager:ListSecretVersionIds' - Resource: !Ref SummarizationLLMThirdPartyApiKey - - !Ref "AWS::NoValue" - - !If - - ProvisionedSageMakerEndpoint - - Sid: InvokeSummarizer + - lambda:InvokeFunction + Resource: !GetAtt SFFetchTranscript.Arn + - Sid: DynamoDBAccess Effect: Allow + Resource: !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${LLMTableName} Action: - - sagemaker:InvokeEndpoint - Resource: !Ref SummarizationSagemakerEndpointArn - - !Ref "AWS::NoValue" - - !If - - HasCustomSummarizerLambda - - Sid: SummarizationLambda + - dynamodb:GetItem + - Sid: InvokeBedrock Effect: Allow Action: - - lambda:InvokeFunction - Resource: !Ref SummarizationLambdaFunctionArn - - !Ref "AWS::NoValue" + - bedrock:InvokeModel + Resource: + - !Sub arn:${AWS::Partition}:bedrock:*::foundation-model/* + - !Sub arn:${AWS::Partition}:bedrock:*:${AWS::AccountId}:custom-model/* + - !If + - HasAnthropicSummary + - Sid: SecretsManagerPolicy + Effect: Allow + Action: + - secretsmanager:GetResourcePolicy + - secretsmanager:GetSecretValue + - secretsmanager:DescribeSecret + - secretsmanager:ListSecretVersionIds + Resource: !Ref SummarizationLLMThirdPartyApiKey + - !Ref AWS::NoValue + - !If + - ProvisionedSageMakerEndpoint + - Sid: InvokeSummarizer + Effect: Allow + Action: + - sagemaker:InvokeEndpoint + Resource: !Ref SummarizationSagemakerEndpointArn + - !Ref AWS::NoValue + - !If + - HasCustomSummarizerLambda + - Sid: SummarizationLambda + Effect: Allow + Action: + - lambda:InvokeFunction + Resource: !Ref SummarizationLambdaFunctionArn + - !Ref AWS::NoValue SFAwaitNotification: - Type: "AWS::Serverless::Function" + Type: AWS::Serverless::Function Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-wait-for-transcribe-notification.lambda_handler Environment: Variables: TableName: !Ref TableName + STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess SFTranscribeFailed: - Type: "AWS::Serverless::Function" + Type: AWS::Serverless::Function Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-transcribe-failed.lambda_handler Environment: Variables: RoleArn: !GetAtt TranscribeRole.Arn + STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess LogGroup: Type: AWS::Logs::LogGroup - Properties: - LogGroupName: !Sub '/aws/vendedlogs/${StepFunctionName}' + Properties: + LogGroupName: !Join + - '' + - - '/aws/vendedlogs/' + - !Sub "{{resolve:ssm:${ParentStackName}-StepFunctionName}}" RetentionInDays: 90 Role: - Type: "AWS::IAM::Role" + Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: @@ -390,22 +425,22 @@ Resources: - PolicyName: CloudWatchLogs PolicyDocument: Statement: - - Effect: Allow - Action: - - logs:CreateLogDelivery - - logs:GetLogDelivery - - logs:UpdateLogDelivery - - logs:DeleteLogDelivery - - logs:ListLogDeliveries - - logs:PutResourcePolicy - - logs:DescribeResourcePolicies - - logs:DescribeLogGroups - Resource: "*" + - Effect: Allow + Action: + - logs:CreateLogDelivery + - logs:GetLogDelivery + - logs:UpdateLogDelivery + - logs:DeleteLogDelivery + - logs:ListLogDeliveries + - logs:PutResourcePolicy + - logs:DescribeResourcePolicies + - logs:DescribeLogGroups + Resource: '*' StateMachine: - Type: "AWS::StepFunctions::StateMachine" + Type: AWS::StepFunctions::StateMachine Properties: - StateMachineName: !Ref StepFunctionName + StateMachineName: !Sub "{{resolve:ssm:${ParentStackName}-StepFunctionName}}" DefinitionS3Location: ./pca-definition.json DefinitionSubstitutions: SFExtractJobHeaderArn: !GetAtt SFExtractJobHeader.Arn diff --git a/pca-server/cfn/lib/python-utilities.template b/pca-server/cfn/lib/python-utilities.template index cd8ba09c..a8acd0e5 100644 --- a/pca-server/cfn/lib/python-utilities.template +++ b/pca-server/cfn/lib/python-utilities.template @@ -5,10 +5,13 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - Install python Transform: AWS::Serverless-2016-10-31 Parameters: + ParentStackName: + Type: String + Description: Name of the parent stack - SupportFilesBucketName: - Type: AWS::SSM::Parameter::Value - Default: SupportFilesBucketName +# SupportFilesBucketName: +# Type: AWS::SSM::Parameter::Value +# Default: SupportFilesBucketName PyZipName: Type: String @@ -36,7 +39,7 @@ Resources: Resource: !Sub - 'arn:aws:s3:::${bucket}*' - - bucket: !Ref SupportFilesBucketName + - bucket: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' Action: - 's3:PutObject' PolicyName: PyUtilsZipFunctionS3Policy @@ -51,7 +54,7 @@ Resources: MemorySize: 1024 Environment: Variables: - SUPPORT_FILES_BUCKET: !Ref SupportFilesBucketName + SUPPORT_FILES_BUCKET: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' PY_ZIP_NAME: !Ref PyZipName Code: ZipFile: | @@ -118,7 +121,7 @@ Resources: CompatibleRuntimes: - python3.11 Content: - S3Bucket: !Ref SupportFilesBucketName + S3Bucket: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' S3Key: !Ref PyZipName Outputs: diff --git a/pca-server/cfn/lib/trigger.template b/pca-server/cfn/lib/trigger.template index 53347c70..839db848 100644 --- a/pca-server/cfn/lib/trigger.template +++ b/pca-server/cfn/lib/trigger.template @@ -5,6 +5,10 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - S3 Trigger Transform: AWS::Serverless-2016-10-31 Parameters: + ParentStackName: + Type: String + Description: Name of the parent stack + TableName: Type: String @@ -14,21 +18,21 @@ Parameters: PyUtilsLayer: Type: String - InputBucketName: - Type: AWS::SSM::Parameter::Value - Default: InputBucketName - - InputBucketRawAudio: - Type: AWS::SSM::Parameter::Value - Default: InputBucketRawAudio - - InputBucketOrigTranscripts: - Type: AWS::SSM::Parameter::Value - Default: InputBucketOrigTranscripts - - StepFunctionName: - Type: AWS::SSM::Parameter::Value - Default: StepFunctionName +# InputBucketName: +# Type: AWS::SSM::Parameter::Value +# Default: InputBucketName +# +# InputBucketRawAudio: +# Type: AWS::SSM::Parameter::Value +# Default: InputBucketRawAudio +# +# InputBucketOrigTranscripts: +# Type: AWS::SSM::Parameter::Value +# Default: InputBucketOrigTranscripts +# +# StepFunctionName: +# Type: AWS::SSM::Parameter::Value +# Default: StepFunctionName Summarize: Type: String @@ -46,6 +50,7 @@ Resources: Environment: Variables: SUMMARIZE: !Ref Summarize + STACK_NAME: !Ref ParentStackName CodeUri: ../../src/pca Handler: pca-aws-file-drop-trigger.lambda_handler Layers: @@ -60,8 +65,15 @@ Resources: - s3:ListBucket - s3:GetObject Resource: - - !Sub arn:aws:s3:::${InputBucketName} - - !Sub arn:aws:s3:::${InputBucketName}/* + - !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + - !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + - '/*' - Statement: - Sid: SSMGetParameterPolicy Effect: Allow @@ -77,7 +89,16 @@ Resources: - Sid: StartExecutionPolicy Effect: Allow Action: states:StartExecution - Resource: !Sub arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:${StepFunctionName} + Resource: #!Sub arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:${StepFunctionName} + - !Join + - '' + - - 'arn:aws:states:' + - !Ref 'AWS::Region' + - ':' + - !Ref 'AWS::AccountId' + - ':stateMachine:' + - !Sub '{{resolve:ssm:${ParentStackName}-StepFunctionName}}' + FileDropTriggerPermission: @@ -87,7 +108,10 @@ Resources: Action: lambda:InvokeFunction Principal: s3.amazonaws.com SourceAccount: !Ref AWS::AccountId - SourceArn: !Sub arn:aws:s3:::${InputBucketName} + SourceArn: !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' ConfigureBucketRole: Type: "AWS::IAM::Role" @@ -109,7 +133,10 @@ Resources: Action: - s3:GetBucketNotification - s3:PutBucketNotification - Resource: !Sub arn:aws:s3:::${InputBucketName} + Resource: !Join + - '' + - - 'arn:aws:s3:::' + - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' ConfigureBucketFunction: Type: "AWS::Lambda::Function" @@ -128,8 +155,8 @@ Resources: - FileDropTriggerPermission Properties: ServiceToken: !GetAtt ConfigureBucketFunction.Arn - BucketName: !Ref InputBucketName - Prefix: !Ref InputBucketRawAudio + BucketName: !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + Prefix: !Sub '{{resolve:ssm:${ParentStackName}-InputBucketRawAudio}}' LambdaArn: !GetAtt FileDropTrigger.Arn FileUpload: "true" @@ -140,8 +167,8 @@ Resources: - ConfigureBucket Properties: ServiceToken: !GetAtt ConfigureBucketFunction.Arn - BucketName: !Ref InputBucketName - Prefix: !Ref InputBucketOrigTranscripts + BucketName: !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + Prefix: !Sub '{{resolve:ssm:${ParentStackName}-InputBucketOrigTranscripts}}' LambdaArn: !GetAtt FileDropTrigger.Arn TranscribeEventbridge: @@ -180,6 +207,7 @@ Resources: Variables: TableName: !Ref TableName AWS_DATA_PATH: "/opt/models" + STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonTranscribeReadOnlyAccess - Statement: diff --git a/pca-server/cfn/pca-server.template b/pca-server/cfn/pca-server.template index ecc6dac7..292a99cf 100644 --- a/pca-server/cfn/pca-server.template +++ b/pca-server/cfn/pca-server.template @@ -3,6 +3,14 @@ AWSTemplateFormatVersion: "2010-09-09" Description: Amazon Transcribe Post Call Analytics - PCA Server Parameters: + ParentStackName: + Type: String + Description: Name of the parent stack + + DatabaseName: + Type: String + Description: Glue catalog database name used to contain tables/views for SQL integration. + ffmpegDownloadUrl: Type: String Default: http://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz @@ -96,6 +104,7 @@ Resources: Properties: TemplateURL: lib/ffmpeg.template Parameters: + ParentStackName: !Ref ParentStackName ffmpegDownloadUrl: !Ref ffmpegDownloadUrl BOTO3: @@ -103,6 +112,8 @@ Resources: Type: AWS::CloudFormation::Stack Properties: TemplateURL: lib/boto3.template + Parameters: + ParentStackName: !Ref ParentStackName DDB: Type: AWS::CloudFormation::Stack @@ -114,6 +125,7 @@ Resources: Properties: TemplateURL: lib/pca.template Parameters: + ParentStackName: !Ref ParentStackName TableName: !GetAtt DDB.Outputs.TableName FFMPEGZipName: !GetAtt FFMPEG.Outputs.FFMPEGZipName Boto3Layer: !If @@ -140,6 +152,7 @@ Resources: Properties: TemplateURL: lib/trigger.template Parameters: + ParentStackName: !Ref ParentStackName TableName: !GetAtt DDB.Outputs.TableName Boto3Layer: !If - ShouldCreateBoto3Layer @@ -152,11 +165,17 @@ Resources: Type: AWS::CloudFormation::Stack Properties: TemplateURL: lib/bulk.template + Parameters: + ParentStackName: !Ref ParentStackName GlueDatabase: Type: AWS::CloudFormation::Stack Properties: TemplateURL: lib/glue-database.template + Parameters: + ParentStackName: !Ref ParentStackName + #DatabaseName: !Ref DatabaseName + ########################################################################## # Transcript Summary diff --git a/pca-server/src/pca/pcaconfiguration.py b/pca-server/src/pca/pcaconfiguration.py index 47134b2d..7b7b5cf8 100644 --- a/pca-server/src/pca/pcaconfiguration.py +++ b/pca-server/src/pca/pcaconfiguration.py @@ -7,54 +7,58 @@ SPDX-License-Identifier: Apache-2.0 """ import boto3 +import os from botocore.config import Config +# Get the stack name from environment variable +STACK_NAME = os.environ.get('STACK_NAME') + # Parameter Store Field Names used by main workflow -CONF_COMP_LANGS = "ComprehendLanguages" -CONF_REDACTION_LANGS = "ContentRedactionLanguages" -CONF_CONVO_LOCATION = "ConversationLocation" -CONF_ENTITYENDPOINT = "EntityRecognizerEndpoint" -CONF_ENTITY_FILE = "EntityStringMap" -CONF_ENTITYCONF = "EntityThreshold" -CONF_ENTITY_TYPES = "EntityTypes" -CONF_PREFIX_AUDIO_PLAYBACK = "InputBucketAudioPlayback" -CONF_S3BUCKET_INPUT = "InputBucketName" -CONF_PREFIX_RAW_AUDIO = "InputBucketRawAudio" -CONF_PREFIX_FAILED_AUDIO = "InputBucketFailedTranscriptions" -CONF_PREFIX_INPUT_TRANSCRIPTS = "InputBucketOrigTranscripts" -CONF_MAX_SPEAKERS = "MaxSpeakers" -CONF_MINNEGATIVE = "MinSentimentNegative" -CONF_MINPOSITIVE = "MinSentimentPositive" -CONF_S3BUCKET_OUTPUT = "OutputBucketName" -CONF_PREFIX_TRANSCRIBE_RESULTS = "OutputBucketTranscribeResults" -CONF_PREFIX_PARSED_RESULTS = "OutputBucketParsedResults" -CONF_SPEAKER_NAMES = "SpeakerNames" -CONF_SPEAKER_MODE = "SpeakerSeparationType" -COMP_SFN_NAME = "StepFunctionName" -CONF_SUPPORT_BUCKET = "SupportFilesBucketName" -CONF_TRANSCRIBE_LANG = "TranscribeLanguages" -CONF_TELEPHONY_CTR = "TelephonyCTRType" -CONF_TELEPHONY_CTR_SUFFIX = "TelephonyCTRFileSuffix" -CONF_VOCABNAME = "VocabularyName" -CONF_CLMNAME = "CustomLangModelName" -CONF_FILENAME_DATETIME_REGEX = "FilenameDatetimeRegex" -CONF_FILENAME_DATETIME_FIELDMAP = "FilenameDatetimeFieldMap" -CONF_FILENAME_GUID_REGEX = "FilenameGUIDRegex" -CONF_FILENAME_AGENT_REGEX = "FilenameAgentRegex" -CONF_FILENAME_CUST_REGEX = "FilenameCustRegex" -CONF_FILTER_MODE = "VocabFilterMode" -CONF_FILTER_NAME = "VocabFilterName" -CONF_KENDRA_INDEX_ID = "KendraIndexId" -CONF_WEB_URI = "WebUiUri" -CONF_TRANSCRIBE_API = "TranscribeApiMode" -CONF_REDACTION_TRANSCRIPT = "CallRedactionTranscript" -CONF_REDACTION_AUDIO = "CallRedactionAudio" -CONF_CALL_SUMMARIZATION = "CallSummarization" +CONF_COMP_LANGS = f"{STACK_NAME}-ComprehendLanguages" +CONF_REDACTION_LANGS = f"{STACK_NAME}-ContentRedactionLanguages" +CONF_CONVO_LOCATION = f"{STACK_NAME}-ConversationLocation" +CONF_ENTITYENDPOINT = f"{STACK_NAME}-EntityRecognizerEndpoint" +CONF_ENTITY_FILE = f"{STACK_NAME}-EntityStringMap" +CONF_ENTITYCONF = f"{STACK_NAME}-EntityThreshold" +CONF_ENTITY_TYPES = f"{STACK_NAME}-EntityTypes" +CONF_PREFIX_AUDIO_PLAYBACK = f"{STACK_NAME}-InputBucketAudioPlayback" +CONF_S3BUCKET_INPUT = f"{STACK_NAME}-InputBucketName" +CONF_PREFIX_RAW_AUDIO = f"{STACK_NAME}-InputBucketRawAudio" +CONF_PREFIX_FAILED_AUDIO = f"{STACK_NAME}-InputBucketFailedTranscriptions" +CONF_PREFIX_INPUT_TRANSCRIPTS = f"{STACK_NAME}-InputBucketOrigTranscripts" +CONF_MAX_SPEAKERS = f"{STACK_NAME}-MaxSpeakers" +CONF_MINNEGATIVE = f"{STACK_NAME}-MinSentimentNegative" +CONF_MINPOSITIVE = f"{STACK_NAME}-MinSentimentPositive" +CONF_S3BUCKET_OUTPUT = f"{STACK_NAME}-OutputBucketName" +CONF_PREFIX_TRANSCRIBE_RESULTS = f"{STACK_NAME}-OutputBucketTranscribeResults" +CONF_PREFIX_PARSED_RESULTS = f"{STACK_NAME}-OutputBucketParsedResults" +CONF_SPEAKER_NAMES = f"{STACK_NAME}-SpeakerNames" +CONF_SPEAKER_MODE = f"{STACK_NAME}-SpeakerSeparationType" +COMP_SFN_NAME = f"{STACK_NAME}-StepFunctionName" +CONF_SUPPORT_BUCKET = f"{STACK_NAME}-SupportFilesBucketName" +CONF_TRANSCRIBE_LANG = f"{STACK_NAME}-TranscribeLanguages" +CONF_TELEPHONY_CTR = f"{STACK_NAME}-TelephonyCTRType" +CONF_TELEPHONY_CTR_SUFFIX = f"{STACK_NAME}-TelephonyCTRFileSuffix" +CONF_VOCABNAME = f"{STACK_NAME}-VocabularyName" +CONF_CLMNAME = f"{STACK_NAME}-CustomLangModelName" +CONF_FILENAME_DATETIME_REGEX = f"{STACK_NAME}-FilenameDatetimeRegex" +CONF_FILENAME_DATETIME_FIELDMAP = f"{STACK_NAME}-FilenameDatetimeFieldMap" +CONF_FILENAME_GUID_REGEX = f"{STACK_NAME}-FilenameGUIDRegex" +CONF_FILENAME_AGENT_REGEX = f"{STACK_NAME}-FilenameAgentRegex" +CONF_FILENAME_CUST_REGEX = f"{STACK_NAME}-FilenameCustRegex" +CONF_FILTER_MODE = f"{STACK_NAME}-VocabFilterMode" +CONF_FILTER_NAME = f"{STACK_NAME}-VocabFilterName" +CONF_KENDRA_INDEX_ID = f"{STACK_NAME}-KendraIndexId" +CONF_WEB_URI = f"{STACK_NAME}-WebUiUri" +CONF_TRANSCRIBE_API = f"{STACK_NAME}-TranscribeApiMode" +CONF_REDACTION_TRANSCRIPT = f"{STACK_NAME}-CallRedactionTranscript" +CONF_REDACTION_AUDIO = f"{STACK_NAME}-CallRedactionAudio" +CONF_CALL_SUMMARIZATION = f"{STACK_NAME}-CallSummarization" # Parameter store fieldnames used by bulk import -BULK_S3_BUCKET = "BulkUploadBucket" -BULK_JOB_LIMIT = "BulkUploadMaxTranscribeJobs" -BULK_MAX_DRIP_RATE = "BulkUploadMaxDripRate" +BULK_S3_BUCKET = f"{STACK_NAME}-BulkUploadBucket" +BULK_JOB_LIMIT = f"{STACK_NAME}-BulkUploadMaxTranscribeJobs" +BULK_MAX_DRIP_RATE = f"{STACK_NAME}-BulkUploadMaxDripRate" # Transcribe API Modes API_STANDARD = "standard" diff --git a/pca-ssm/.DS_Store b/pca-ssm/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..489fa726e5ff71ad4622ebe8cdb33bf7e8f3a6ca GIT binary patch literal 6148 zcmeHK%}T>S5Z-O8O({YS3VK`cTCldIC|*LWFJMFuDm5`xgE3p0)Er77cYPsW#OHBl zcLNr47O^w1`_1oe_JiyXV~o4=@Q^W^F=jzSxkiSuQ5`*}*SVI^&K;>WKkjV3mQoHf=or&)}D-eB`f| zkVOm-1OJQx-WYi!7ZzpC)*s8mvsOU6gNA~61u7t*uUrDaz- - (Optional) Existing bucket where files can be dropped, and a secondary Step Function can be - manually enabled to drip feed them into the system. - Leave blank to automatically create new bucket. + Description: (Optional) Existing bucket where files can be dropped, and a + secondary Step Function can be manually enabled to drip feed them into + the system. Leave blank to automatically create new bucket. BulkUploadMaxDripRate: Type: String - Default: "25" - Description: Maximum number of files that the bulk uploader will move to the PCA source bucket in one pass + Default: '25' + Description: Maximum number of files that the bulk uploader will move to the PCA + source bucket in one pass BulkUploadMaxTranscribeJobs: Type: String - Default: "50" - Description: Number of concurrent Transcribe jobs (executing or queuing) where bulk upload will pause + Default: '50' + Description: Number of concurrent Transcribe jobs (executing or queuing) where + bulk upload will pause CallSummarization: - Default: 'BEDROCK' + Default: BEDROCK Type: String AllowedValues: - - 'DISABLED' - - 'BEDROCK+TCA' - - 'BEDROCK' - - 'TCA-ONLY' - - 'SAGEMAKER' - - 'ANTHROPIC' - - 'LAMBDA' - Description: > - Set to enable call summarization by a Large Language Model. - The BEDROCK+TCA will use Transcribe Call Analytics for summarization and Bedrock for other analytics. - The BEDROCK option requires you to choose one of the supported model IDs from the provided list (SummarizationBedrockModelId). - You must also accept access to that model in the Amazon Bedrock > Model Access console. - The TCA-ONLY option will not use Bedrock, but will only use Transcribe Call Analytics summarization. - The SAGEMAKER option uses a SageMaker endpoint with the pretrained bart-large-cnn-samsum model with a ml.m5.xlarge instance type. - The LAMBDA option requires you to provide a function ARN below. - The ANTHROPIC option is a third party service, and you must enter your Anthropic API key in the Third Party LLM API Key section. + - DISABLED + - BEDROCK+TCA + - BEDROCK + - TCA-ONLY + - SAGEMAKER + - ANTHROPIC + - LAMBDA + Description: | + Set to enable call summarization by a Large Language Model. The BEDROCK+TCA will use Transcribe Call Analytics for summarization and Bedrock for other analytics. The BEDROCK option requires you to choose one of the supported model IDs from the provided list (SummarizationBedrockModelId). You must also accept access to that model in the Amazon Bedrock > Model Access console. The TCA-ONLY option will not use Bedrock, but will only use Transcribe Call Analytics summarization. The SAGEMAKER option uses a SageMaker endpoint with the pretrained bart-large-cnn-samsum model with a ml.m5.xlarge instance type. The LAMBDA option requires you to provide a function ARN below. The ANTHROPIC option is a third party service, and you must enter your Anthropic API key in the Third Party LLM API Key section. ComprehendLanguages: Type: String @@ -50,37 +47,47 @@ Parameters: ContentRedactionLanguages: Type: String Default: en-US - Description: Languages supported by Transcribe's Content Redaction feature, separated by " | " + Description: Languages supported by Transcribe's Content Redaction feature, + separated by " | " ConversationLocation: Type: String Default: America/New_York - Description: Name of the timezone location for the call source - this is the TZ database name from https://en.wikipedia.org/wiki/List_of_tz_database_time_zones + Description: Name of the timezone location for the call source - this is the TZ + database name from + https://en.wikipedia.org/wiki/List_of_tz_database_time_zones EntityRecognizerEndpoint: Type: String Default: undefined - Description: Name of the custom entity recognizer for Amazon Comprehend (not including language suffix, e.g. -en). If one cannot be found then simple entity string matching is attempted instead + Description: Name of the custom entity recognizer for Amazon Comprehend (not + including language suffix, e.g. -en). If one cannot be found then simple + entity string matching is attempted instead EntityStringMap: Type: String Default: sample-entities.csv - Description: Basename of a CSV file containing item/Entity maps for when we don't have data for Comprehend Custom Entities (not including language suffix, e.g. -en) + Description: Basename of a CSV file containing item/Entity maps for when we + don't have data for Comprehend Custom Entities (not including language + suffix, e.g. -en) EntityThreshold: Type: String - Default: "0.5" + Default: '0.5' Description: Confidence threshold where we accept the custom entity detection result EntityTypes: Type: String - Default: PERSON | LOCATION | ORGANIZATION | COMMERCIAL_ITEM | EVENT | DATE | QUANTITY | TITLE - Description: Entity types supported by Comprehend's standard entity detection, separated by " | " + Default: PERSON | LOCATION | ORGANIZATION | COMMERCIAL_ITEM | EVENT | DATE | + QUANTITY | TITLE + Description: Entity types supported by Comprehend's standard entity detection, + separated by " | " InputBucketAudioPlayback: Type: String Default: playbackAudio - Description: Folder that holds the audio files to playback in the browser when original audio cannot be used + Description: Folder that holds the audio files to playback in the browser when + original audio cannot be used InputBucketFailedTranscriptions: Type: String @@ -89,9 +96,8 @@ Parameters: InputBucketName: Type: String - Description: >- - (Optional) Existing bucket holding all audio files for the system. - Leave blank to automatically create new bucket. + Description: (Optional) Existing bucket holding all audio files for the + system. Leave blank to automatically create new bucket. InputBucketRawAudio: Type: String @@ -101,36 +107,37 @@ Parameters: InputBucketOrigTranscripts: Type: String Default: originalTranscripts - Description: >- - Folder that holds Transcripts from other applications (e.g. Live Call Analytics) that are to be - processed as if PCA had processed that audio + Description: Folder that holds Transcripts from other applications (e.g. Live + Call Analytics) that are to be processed as if PCA had processed that + audio MaxSpeakers: Type: String - Default: "2" + Default: '2' Description: Maximum number of speakers that are expected on a call MinSentimentNegative: Type: String - Default: "2.0" - Description: Minimum sentiment level required to declare a phrase as having negative sentiment, in the range 0.0-5.0 + Default: '2.0' + Description: Minimum sentiment level required to declare a phrase as having + negative sentiment, in the range 0.0-5.0 MinSentimentPositive: Type: String - Default: "2.0" - Description: Minimum sentiment level required to declare a phrase as having positive sentiment, in the range 0.0-5.0 + Default: '2.0' + Description: Minimum sentiment level required to declare a phrase as having + positive sentiment, in the range 0.0-5.0 OutputBucketName: Type: String - Description: >- - (Optional) Existing bucket where Transcribe output files are delivered. - Leave blank to automatically create new bucket. + Description: (Optional) Existing bucket where Transcribe output files are + delivered. Leave blank to automatically create new bucket. OutputBucketTranscribeResults: Type: String Default: transcribeResults Description: Folder within the output S3 bucket where Transcribe results are written - + OutputBucketParsedResults: Type: String Default: parsedFiles @@ -139,49 +146,49 @@ Parameters: SpeakerNames: Type: String Default: Caller | Agent - Description: >- - Tags used for speaker names in transcripts, in channel/speaker order, separated by " | ". - For Call Analytics the name Agent must exist in either the first or second posision + Description: Tags used for speaker names in transcripts, in channel/speaker + order, separated by " | ". For Call Analytics the name Agent must exist in + either the first or second posision SpeakerSeparationType: Type: String Default: channel - Description: Separation mode for speakers - must be speaker (mono) channel (stereo/auto-select) + Description: Separation mode for speakers - must be speaker (mono) channel + (stereo/auto-select) StepFunctionName: Type: String - Default: PostCallAnalyticsWorkflow + #Default: PostCallAnalyticsWorkflow Description: Name of Step Functions workflow that orchestrates this process BulkUploadStepFunctionName: Type: String - Default: BulkUploadWorkflow + #Default: BulkUploadWorkflow Description: Name of Step Functions workflow that orchestrates the bulk import process SupportFilesBucketName: Type: String - Description: >- - (Optional) Existing bucket that hold supporting files, such as the - file-based entity recognition mapping files. - Leave blank to automatically create new bucket. + Description: (Optional) Existing bucket that hold supporting files, such as + the file-based entity recognition mapping files. Leave blank to + automatically create new bucket. TranscribeApiMode: Type: String Default: analytics - Description: Specifies which Transcribe API to use for new jobs - must be standard or analytics + Description: Specifies which Transcribe API to use for new jobs - must be + standard or analytics TelephonyCTRType: Type: String Default: none - Description: Type of telephony system that will deliver Contact Trace Record files along with the audio recordings + Description: Type of telephony system that will deliver Contact Trace Record + files along with the audio recordings TelephonyCTRFileSuffix: Type: String Default: none - Description: > - File number suffixes for the CTR file(s) associated with the chosen telephony type, separated by " | ". - For Genesys, this needs two entries: one for the conversation CTR file, and one for the call-specific file. - Other telephony systems may need fewer or additional entries, please consult the documentation. + Description: | + File number suffixes for the CTR file(s) associated with the chosen telephony type, separated by " | ". For Genesys, this needs two entries: one for the conversation CTR file, and one for the call-specific file. Other telephony systems may need fewer or additional entries, please consult the documentation. CallRedactionTranscript: Type: String @@ -191,486 +198,472 @@ Parameters: CallRedactionAudio: Type: String Default: true - Description: When transcript redaction is enabled in Call Analytics, only allow playback of the redacted audio + Description: When transcript redaction is enabled in Call Analytics, only allow + playback of the redacted audio TranscribeLanguages: Type: String Default: en-US - Description: Language to be used for Transcription - multiple entries separated by " | " will trigger Language Detection + Description: Language to be used for Transcription - multiple entries separated + by " | " will trigger Language Detection VocabFilterMode: Type: String Default: mask - Description: The mode to use for vocabulary filtering - must be one of mask or remove (tag is not supported) + Description: The mode to use for vocabulary filtering - must be one of mask or + remove (tag is not supported) VocabFilterName: Type: String Default: undefined - Description: Name of the vocabulary filter to use for Transcribe (not including language suffix, e.g. -en) + Description: Name of the vocabulary filter to use for Transcribe (not including + language suffix, e.g. -en) VocabularyName: Type: String Default: undefined - Description: Name of the custom vocabulary to use for Transcribe (not including language suffix, e.g. -en-US) + Description: Name of the custom vocabulary to use for Transcribe (not including + language suffix, e.g. -en-US) CustomLangModelName: Type: String Default: undefined - Description: Name of the custom language model to use for Transcribe (omit the language suffix, e.g. -en-US) + Description: Name of the custom language model to use for Transcribe (omit the + language suffix, e.g. -en-US) FilenameDatetimeRegex: Type: String - Default: '(\d{4})-(\d{2})-(\d{2})T(\d{2})-(\d{2})-(\d{2})' - Description: > - Regular Expression (regex) used to parse call Date/Time from audio filenames. - Each datetime field (year, month, etc.) must be matched using a separate parenthesized group in the regex. - Example: the regex '(\d{4})-(\d{2})-(\d{2})T(\d{2})-(\d{2})-(\d{2})' parses - the filename: CallAudioFile-2021-12-01T07-55-51.wav into a value list: [2021, 12, 01, 07, 55, 51] - The next parameter, FilenameDatetimeFieldMap, maps the values to datetime field codes. - If the filename doesn't match the regex pattern, the current time is used as the call timestamp. + Default: (\d{4})-(\d{2})-(\d{2})T(\d{2})-(\d{2})-(\d{2}) + Description: | + Regular Expression (regex) used to parse call Date/Time from audio filenames. Each datetime field (year, month, etc.) must be matched using a separate parenthesized group in the regex. Example: the regex '(\d{4})-(\d{2})-(\d{2})T(\d{2})-(\d{2})-(\d{2})' parses the filename: CallAudioFile-2021-12-01T07-55-51.wav into a value list: [2021, 12, 01, 07, 55, 51] The next parameter, FilenameDatetimeFieldMap, maps the values to datetime field codes. If the filename doesn't match the regex pattern, the current time is used as the call timestamp. FilenameDatetimeFieldMap: Type: String Default: '%Y %m %d %H %M %S' - Description: > - Space separated ordered sequence of time field codes as used by Python's datetime.strptime() function. - Each field code refers to a corresponding value parsed by the regex parameter filenameTimestampRegex. - Example: the mapping '%Y %m %d %H %M %S' assembles the regex output values [2021, 12, 01, 07, 55, 51] - into the full datetime: '2021-12-01 07:55:51'. - If the field map doesn't match the value list parsed by the regex, then the current time is used as the call timestamp. + Description: | + Space separated ordered sequence of time field codes as used by Python's datetime.strptime() function. Each field code refers to a corresponding value parsed by the regex parameter filenameTimestampRegex. Example: the mapping '%Y %m %d %H %M %S' assembles the regex output values [2021, 12, 01, 07, 55, 51] into the full datetime: '2021-12-01 07:55:51'. If the field map doesn't match the value list parsed by the regex, then the current time is used as the call timestamp. FilenameGUIDRegex: Type: String - Default: '_GUID_(.*?)_' - Description: > - Regular Expression (regex) used to parse call GUID from audio filenames. - The GUID value must be matched using a parenthesized group in the regex. - Example: the regex '_GUID_(.*?)_' parses - the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav - to extract the GUID value '2a602c1a-4ca3-4d37-a933-444d575c0222'. + Default: _GUID_(.*?)_ + Description: | + Regular Expression (regex) used to parse call GUID from audio filenames. The GUID value must be matched using a parenthesized group in the regex. Example: the regex '_GUID_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the GUID value '2a602c1a-4ca3-4d37-a933-444d575c0222'. FilenameAgentRegex: Type: String - Default: '_AGENT_(.*?)_' - Description: > - Regular Expression (regex) used to parse call AGENT from audio filenames. - The AGENT value must be matched using a parenthesized group in the regex. - Example: the regex '_AGENT_(.*?)_' parses - the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav - to extract the AGENT value 'BobS'. - + Default: _AGENT_(.*?)_ + Description: | + Regular Expression (regex) used to parse call AGENT from audio filenames. The AGENT value must be matched using a parenthesized group in the regex. Example: the regex '_AGENT_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the AGENT value 'BobS'. + FilenameCustRegex: Type: String - Default: '_CUST_(.*?)_' - Description: > - Regular Expression (regex) used to parse Customer from audio filenames. - The customer id value must be matched using one or more parenthesized groups in the regex. - Example: the regex '_CUST_(.*?)_' parses - the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav - to extract the Customer value '12345'. + Default: _CUST_(.*?)_ + Description: | + Regular Expression (regex) used to parse Customer from audio filenames. The customer id value must be matched using one or more parenthesized groups in the regex. Example: the regex '_CUST_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the Customer value '12345'. KendraIndexId: Type: String - Description: Kendra Index ID, or empty string if call transcription indexing is not enabled - + Description: Kendra Index ID, or empty string if call transcription indexing is + not enabled + #WebUri: # Type: String # Description: PCA Web Application URI - + DatabaseName: Type: String - Default: 'pca' - Description: Glue catalog database name used to contain tables/views for SQL integration. - + Description: Glue catalog database name used to contain tables/views for SQL + integration. + Resources: BulkUploadBucketParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: BulkUploadBucket + Name: !Sub ${StackName}-BulkUploadBucket Type: String - Description: Bucket where files can be dropped, and a secondary Step Function can be manually enabled to drip feed them into the system + Description: Bucket where files can be dropped, and a secondary Step Function + can be manually enabled to drip feed them into the system Value: !Ref BulkUploadBucketName BulkUploadMaxDripRateParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: BulkUploadMaxDripRate + Name: !Sub ${StackName}-BulkUploadMaxDripRate Type: String - Description: Maximum number of files that the bulk uploader will move to the PCA source bucket in one pass + Description: Maximum number of files that the bulk uploader will move to the PCA + source bucket in one pass Value: !Ref BulkUploadMaxDripRate BulkUploadMaxTranscribeJobsParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: BulkUploadMaxTranscribeJobs + Name: !Sub ${StackName}-BulkUploadMaxTranscribeJobs Type: String - Description: Number of concurrent Transcribe jobs (executing or queuing) where bulk upload will pause + Description: Number of concurrent Transcribe jobs (executing or queuing) where + bulk upload will pause Value: !Ref BulkUploadMaxTranscribeJobs CallSummarizationParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: CallSummarization + Name: !Sub ${StackName}-CallSummarization Type: String - Description: >- - What type of call summarization to use. + Description: 'What type of call summarization to use. ' Value: !Ref CallSummarization ComprehendLanguagesParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: ComprehendLanguages + Name: !Sub ${StackName}-ComprehendLanguages Type: String Description: Languages supported by Comprehend's standard calls, separated by " | " Value: !Ref ComprehendLanguages ContentRedactionLanguagesParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: ContentRedactionLanguages + Name: !Sub ${StackName}-ContentRedactionLanguages Type: String - Description: Languages supported by Transcribe's Content Redaction feature, separated by " | " + Description: Languages supported by Transcribe's Content Redaction feature, + separated by " | " Value: !Ref ContentRedactionLanguages ConversationLocationParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: ConversationLocation + Name: !Sub ${StackName}-ConversationLocation Type: String - Description: Name of the timezone location for the call source - this is the TZ database name from https://en.wikipedia.org/wiki/List_of_tz_database_time_zones + Description: Name of the timezone location for the call source - this is the TZ + database name from + https://en.wikipedia.org/wiki/List_of_tz_database_time_zones Value: !Ref ConversationLocation EntityRecognizerEndpointParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: EntityRecognizerEndpoint + Name: !Sub ${StackName}-EntityRecognizerEndpoint Type: String - Description: Name of the custom entity recognizer for Amazon Comprehend (not including language suffix, e.g. -en). If one cannot be found then simple entity string matching is attempted instead + Description: Name of the custom entity recognizer for Amazon Comprehend (not + including language suffix, e.g. -en). If one cannot be found then simple + entity string matching is attempted instead Value: !Ref EntityRecognizerEndpoint EntityStringMapParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: EntityStringMap + Name: !Sub ${StackName}-EntityStringMap Type: String - Description: Basename of a CSV file containing item/Entity maps for when we don't have data for Comprehend Custom Entities (not including language suffix, e.g. -en) + Description: Basename of a CSV file containing item/Entity maps for when we + don't have data for Comprehend Custom Entities (not including language + suffix, e.g. -en) Value: !Ref EntityStringMap EntityThresholdParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: EntityThreshold + Name: !Sub ${StackName}-EntityThreshold Type: String Description: Confidence threshold where we accept the custom entity detection result Value: !Ref EntityThreshold EntityTypesParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: EntityTypes + Name: !Sub ${StackName}-EntityTypes Type: String - Description: Entity types supported by Comprehend's standard entity detection, separated by " | " + Description: Entity types supported by Comprehend's standard entity detection, + separated by " | " Value: !Ref EntityTypes InputBucketAudioPlaybackParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: InputBucketAudioPlayback + Name: !Sub ${StackName}-InputBucketAudioPlayback Type: String - Description: Folder that holds the audio to playback in the browser when original audio cannot be used + Description: Folder that holds the audio to playback in the browser when + original audio cannot be used Value: !Ref InputBucketAudioPlayback InputBucketFailedTranscriptionsParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: InputBucketFailedTranscriptions + Name: !Sub ${StackName}-InputBucketFailedTranscriptions Type: String Description: Folder that holds audio files that for some reason failed transcription Value: !Ref InputBucketFailedTranscriptions InputBucketNameParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: InputBucketName + Name: !Sub ${StackName}-InputBucketName Type: String Description: Bucket where where audio files are delivered Value: !Ref InputBucketName InputBucketRawAudioParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: InputBucketRawAudio + Name: !Sub ${StackName}-InputBucketRawAudio Type: String Description: Folder that holds the original call audio to be ingested Value: !Ref InputBucketRawAudio InputBucketOrigTranscriptsParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: InputBucketOrigTranscripts + Name: !Sub ${StackName}-InputBucketOrigTranscripts Type: String - Description: > - Folder that holds Transcripts from other applications (e.g. Live Call Analytics) that are to be - processed as if PCA had processed that audio + Description: | + Folder that holds Transcripts from other applications (e.g. Live Call Analytics) that are to be processed as if PCA had processed that audio Value: !Ref InputBucketOrigTranscripts MaxSpeakersParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: MaxSpeakers + Name: !Sub ${StackName}-MaxSpeakers Type: String Description: Maximum number of speakers that are expected on a call Value: !Ref MaxSpeakers MinSentimentNegativeParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: MinSentimentNegative + Name: !Sub ${StackName}-MinSentimentNegative Type: String - Description: Minimum sentiment level required to declare a phrase as having negative sentiment + Description: Minimum sentiment level required to declare a phrase as having + negative sentiment Value: !Ref MinSentimentNegative MinSentimentPositiveParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: MinSentimentPositive + Name: !Sub ${StackName}-MinSentimentPositive Type: String - Description: Minimum sentiment level required to declare a phrase as having positive sentiment + Description: Minimum sentiment level required to declare a phrase as having + positive sentiment Value: !Ref MinSentimentPositive OutputBucketNameParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: OutputBucketName + Name: !Sub ${StackName}-OutputBucketName Type: String Description: Bucket where Transcribe output files are delivered Value: !Ref OutputBucketName OutputBucketTranscribeResultsParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: OutputBucketTranscribeResults + Name: !Sub ${StackName}-OutputBucketTranscribeResults Type: String Description: Folder within the output S3 bucket where Transcribe results are written - Value: !Ref OutputBucketTranscribeResults + Value: !Ref OutputBucketTranscribeResults OutputBucketParsedResultsParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: OutputBucketParsedResults + Name: !Sub ${StackName}-OutputBucketParsedResults Type: String Description: Folder within the output S3 bucket where parsed results are written Value: !Ref OutputBucketParsedResults SpeakerNamesParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: SpeakerNames + Name: !Sub ${StackName}-SpeakerNames Type: String Description: Default tags used for speaker names, separated by " | " Value: !Ref SpeakerNames SpeakerSeparationTypeParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: SpeakerSeparationType + Name: !Sub ${StackName}-SpeakerSeparationType Type: String - Description: Separation mode for speakers, either explicitly Speaker or Channel, or Auto where audio stereo=>Channel and mono=>Speaker + Description: Separation mode for speakers, either explicitly Speaker or Channel, + or Auto where audio stereo=>Channel and mono=>Speaker Value: !Ref SpeakerSeparationType StepFunctionNameParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: StepFunctionName + Name: !Sub ${StackName}-StepFunctionName Type: String Description: Name of Step Functions workflow that orchestrates this process - Value: !Ref StepFunctionName + Value: !Sub ${StackName}-${StepFunctionName} BulkUploadStepFunctionNameParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: BulkUploadStepFunctionName + Name: !Sub ${StackName}-BulkUploadStepFunctionName Type: String Description: Name of Step Functions workflow that orchestrates the bulk import process - Value: !Ref BulkUploadStepFunctionName - + Value: !Sub ${StackName}-${BulkUploadStepFunctionName} + SupportFilesBucketNameParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: SupportFilesBucketName + Name: !Sub ${StackName}-SupportFilesBucketName Type: String - Description: Bucket that hold supporting files, such as the file-based entity recognition mapping files + Description: Bucket that hold supporting files, such as the file-based entity + recognition mapping files Value: !Ref SupportFilesBucketName TranscribeApiModeParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: TranscribeApiMode + Name: !Sub ${StackName}-TranscribeApiMode Type: String - Description: Specifies which Transcribe API to use for new jobs - must be standard or analytics + Description: Specifies which Transcribe API to use for new jobs - must be + standard or analytics Value: !Ref TranscribeApiMode TelephonyCTRTypeParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: TelephonyCTRType + Name: !Sub ${StackName}-TelephonyCTRType Type: String - Description: Type of telephony system that will deliver Contact Trace Record files along with the audio recordings + Description: Type of telephony system that will deliver Contact Trace Record + files along with the audio recordings Value: !Ref TelephonyCTRType TelephonyCTRFileSuffixParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: TelephonyCTRFileSuffix + Name: !Sub ${StackName}-TelephonyCTRFileSuffix Type: String - Description: > - File name suffixes for the CTR file(s) associated with the chosen telephony type, separated by " | ". - For Genesys, this needs two entries: one for the conversation CTR file, and one for the call-specific file. - Other telephony systems may need fewer or additional entries, please consult the documentation.rdings + Description: | + File name suffixes for the CTR file(s) associated with the chosen telephony type, separated by " | ". For Genesys, this needs two entries: one for the conversation CTR file, and one for the call-specific file. Other telephony systems may need fewer or additional entries, please consult the documentation.rdings Value: !Ref TelephonyCTRFileSuffix CallRedactionTranscriptParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: CallRedactionTranscript + Name: !Sub ${StackName}-CallRedactionTranscript Type: String Description: Enable or disable Transcribe's redaction feature Value: !Ref CallRedactionTranscript CallRedactionAudioParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: CallRedactionAudio + Name: !Sub ${StackName}-CallRedactionAudio Type: String - Description: When transcript redaction is enabled in Call Analytics, only allow playback of the redacted audio + Description: When transcript redaction is enabled in Call Analytics, only allow + playback of the redacted audio Value: !Ref CallRedactionAudio TranscribeLanguagesParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: TranscribeLanguages + Name: !Sub ${StackName}-TranscribeLanguages Type: String - Description: Language to be used for Transcription - multiple entries separated by " | " will trigger Language Detection + Description: Language to be used for Transcription - multiple entries separated + by " | " will trigger Language Detection Value: !Ref TranscribeLanguages VocabFilterModeParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: VocabFilterMode + Name: !Sub ${StackName}-VocabFilterMode Type: String - Description: The mode to use for vocabulary filtering - must be one of mask or remove (tag is not supported) + Description: The mode to use for vocabulary filtering - must be one of mask or + remove (tag is not supported) Value: !Ref VocabFilterMode VocabFilterNameParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: VocabFilterName + Name: !Sub ${StackName}-VocabFilterName Type: String - Description: Name of the vocabulary filter to use for Transcribe (not including language suffix, e.g. -en-US) + Description: Name of the vocabulary filter to use for Transcribe (not including + language suffix, e.g. -en-US) Value: !Ref VocabFilterName VocabularyNameParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: VocabularyName + Name: !Sub ${StackName}-VocabularyName Type: String - Description: Name of the custom vocabulary to use for Transcribe (not including language suffix, e.g. -en-US) + Description: Name of the custom vocabulary to use for Transcribe (not including + language suffix, e.g. -en-US) Value: !Ref VocabularyName CustomLangModelNameParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: CustomLangModelName + Name: !Sub ${StackName}-CustomLangModelName Type: String - Description: Name of the custom language model to use for Transcribe (omit the language suffix, e.g. -en-US) + Description: Name of the custom language model to use for Transcribe (omit the + language suffix, e.g. -en-US) Value: !Ref CustomLangModelName FilenameDatetimeRegexParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: FilenameDatetimeRegex + Name: !Sub ${StackName}-FilenameDatetimeRegex Type: String Value: !Ref FilenameDatetimeRegex - Description: > - Regular Expression (regex) used to parse call Date/Time from audio filenames. - Each datetime field (year, month, etc.) must be matched using a separate parenthesized group in the regex. - Example: the regex '(\d{2}).(\d{2}).(\d{2}).(\d{3})-(\d{2})-(\d{2})-(\d{4})' parses - the filename: CallAudioFile-09.25.51.067-09-26-2019.wav into a value list: [09, 25, 51, 067, 09, 26, 2019] - The next parameter, FilenameDatetimeFieldMap, maps the values to datetime field codes. - If the filename doesn't match the regex pattern, the current time is used as the call timestamp. + Description: | + Regular Expression (regex) used to parse call Date/Time from audio filenames. Each datetime field (year, month, etc.) must be matched using a separate parenthesized group in the regex. Example: the regex '(\d{2}).(\d{2}).(\d{2}).(\d{3})-(\d{2})-(\d{2})-(\d{4})' parses the filename: CallAudioFile-09.25.51.067-09-26-2019.wav into a value list: [09, 25, 51, 067, 09, 26, 2019] The next parameter, FilenameDatetimeFieldMap, maps the values to datetime field codes. If the filename doesn't match the regex pattern, the current time is used as the call timestamp. FilenameDatetimeFieldMapParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: FilenameDatetimeFieldMap + Name: !Sub ${StackName}-FilenameDatetimeFieldMap Type: String Value: !Ref FilenameDatetimeFieldMap - Description: > - Space separated ordered sequence of time field codes as used by Python's datetime.strptime() function. - Each field code refers to a corresponding value parsed by the regex parameter filenameTimestampRegex. - Example: the mapping '%H %M %S %f %m %d %Y' assembles the regex output values [09, 25, 51, 067, 09, 26, 2019] - into the full datetime: '2019-09-26 09:25:51.067000'. - If the field map doesn't match the value list parsed by the regex, then the current time is used as the call timestamp. + Description: | + Space separated ordered sequence of time field codes as used by Python's datetime.strptime() function. Each field code refers to a corresponding value parsed by the regex parameter filenameTimestampRegex. Example: the mapping '%H %M %S %f %m %d %Y' assembles the regex output values [09, 25, 51, 067, 09, 26, 2019] into the full datetime: '2019-09-26 09:25:51.067000'. If the field map doesn't match the value list parsed by the regex, then the current time is used as the call timestamp. FilenameGUIDRegexParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: FilenameGUIDRegex + Name: !Sub ${StackName}-FilenameGUIDRegex Type: String Value: !Ref FilenameGUIDRegex - Description: > - Regular Expression (regex) used to parse call GUID from audio filenames. - The GUID value must be matched using one or more parenthesized groups in the regex. - Example: the regex '_GUID_(.*?)_' parses - the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav - to extract the GUID value '2a602c1a-4ca3-4d37-a933-444d575c0222'. + Description: | + Regular Expression (regex) used to parse call GUID from audio filenames. The GUID value must be matched using one or more parenthesized groups in the regex. Example: the regex '_GUID_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the GUID value '2a602c1a-4ca3-4d37-a933-444d575c0222'. FilenameAgentRegexParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: FilenameAgentRegex + Name: !Sub ${StackName}-FilenameAgentRegex Type: String Value: !Ref FilenameAgentRegex - Description: > - Regular Expression (regex) used to parse call AGENT from audio filenames. - The AGENT value must be matched using one or more parenthesized groups in the regex. - Example: the regex '_AGENT_(.*?)_' parses - the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav - to extract the AGENT value 'BobS'. + Description: | + Regular Expression (regex) used to parse call AGENT from audio filenames. The AGENT value must be matched using one or more parenthesized groups in the regex. Example: the regex '_AGENT_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the AGENT value 'BobS'. FilenameCustRegexParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: FilenameCustRegex + Name: !Sub ${StackName}-FilenameCustRegex Type: String Value: !Ref FilenameCustRegex - Description: > - Regular Expression (regex) used to parse Customer from audio filenames. - The customer id value must be matched using one or more parenthesized groups in the regex. - Example: the regex '_CUST_(.*?)_' parses - the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav - to extract the Customer value '12345'. + Description: | + Regular Expression (regex) used to parse Customer from audio filenames. The customer id value must be matched using one or more parenthesized groups in the regex. Example: the regex '_CUST_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the Customer value '12345'. KendraIndexIdParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: KendraIndexId + Name: !Sub ${StackName}-KendraIndexId Type: String Value: !Ref KendraIndexId - Description: Kendra Index ID, or empty string if call transcription indexing is not enabled - + Description: Kendra Index ID, or empty string if call transcription indexing is + not enabled + #WebUriParameter: # Type: "AWS::SSM::Parameter" # Properties: - # Name: WebUri + # Name: !Sub '${StackName}-WebUri' # Type: String # Value: !Ref WebUri # Description: PCA Web Application URI DatabaseNameParameter: - Type: "AWS::SSM::Parameter" + Type: AWS::SSM::Parameter Properties: - Name: DatabaseName + Name: !Sub ${StackName}-DatabaseName Type: String Value: !Ref DatabaseName - Description: PCA Glue catalog database name + Description: PCA Glue catalog database name \ No newline at end of file diff --git a/pca-ui/cfn/pca-ui.template b/pca-ui/cfn/pca-ui.template index 094bb9cb..00cfeb9b 100644 --- a/pca-ui/cfn/pca-ui.template +++ b/pca-ui/cfn/pca-ui.template @@ -3,6 +3,10 @@ AWSTemplateFormatVersion: "2010-09-09" Description: Amazon Transcribe Post Call Analytics - PCA UI Parameters: + ParentStackName: + Type: String + Description: Name of the parent stack + AdminUsername: Type: String Default: "admin" @@ -201,7 +205,7 @@ Resources: WebUriParameter: Type: "AWS::SSM::Parameter" Properties: - Name: WebUiUri + Name: !Sub ${ParentStackName}-WebUiUri Type: String Value: !GetAtt Web.Outputs.Uri Description: PCA Web Application URI From a289c222bfa0ec7d652c43289634cc49a3484312 Mon Sep 17 00:00:00 2001 From: Bob Strahan Date: Tue, 18 Feb 2025 17:42:18 +0000 Subject: [PATCH 02/22] removed unintended hidden file artifacts --- .DS_Store | Bin 6148 -> 0 bytes .idea/.gitignore | 8 -------- .../amazon-transcribe-post-call-analytics.iml | 9 --------- .idea/aws.xml | 17 ----------------- .idea/cfnlintPlugin.xml | 8 -------- .idea/misc.xml | 6 ------ .idea/modules.xml | 8 -------- .idea/vcs.xml | 7 ------- pca-ssm/.DS_Store | Bin 6148 -> 0 bytes 9 files changed, 63 deletions(-) delete mode 100644 .DS_Store delete mode 100644 .idea/.gitignore delete mode 100644 .idea/amazon-transcribe-post-call-analytics.iml delete mode 100644 .idea/aws.xml delete mode 100644 .idea/cfnlintPlugin.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 pca-ssm/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index ffba39b5f741f9bb3e49a19316c97625434fc2da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5Z<-brW7Fu1-&hJtytSq6fYsx7cim+m718M!8BW%)*MP9cYPsW#OHBl zcOz7D@FZeqVDrt+&+g6#*&oIjcW2=tV>V;Vf`-UZDG@Z6y4FlEB3EOiEM=o0OUFT6 zGSFW%;o56#%z4s|-hy!)rPEgHov&4@>l-zzW;Lu^?@?yn)Su2$*PmQt z??TErD0Dx#jE333-a3`Z)Q^(kL?uMw5JGOQq9l}=D`!cVs$5Syth!Yn*t_$2r+d_H zie9g~Xo~r9yVVrkPH(ZOTibgFC+CBwc$CN&%_Rrgm24U;;1!fFWj%Y7B$mkoc#5nd znvfVE28aP-V5Jx^$AHyXsj8`1Vt^R<2?Mx42xy3o!Ca%-I^cuXXY^MQQ9#GH1fnqL z7|b<-2ZZZXK%L6X6NBq?unQCC7|b>5bjH=pFpinIc)V~mJJ^K^XWY?9Ut)k5SZ1K2 zyEdNxXYk9EKJu4Ss7DMC1OJQxUhR8*7m6}x>$mdotQFAiprK$~jtU6qOP2uX;6AdW eoZ2r?hd9Szt`SE;yGjS7i-018KE%K;Fz^A}_e^sD diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b81..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/amazon-transcribe-post-call-analytics.iml b/.idea/amazon-transcribe-post-call-analytics.iml deleted file mode 100644 index d6ebd480..00000000 --- a/.idea/amazon-transcribe-post-call-analytics.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/aws.xml b/.idea/aws.xml deleted file mode 100644 index e14a2062..00000000 --- a/.idea/aws.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/cfnlintPlugin.xml b/.idea/cfnlintPlugin.xml deleted file mode 100644 index e700753a..00000000 --- a/.idea/cfnlintPlugin.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 639900d1..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 1823aeee..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index bc514777..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/pca-ssm/.DS_Store b/pca-ssm/.DS_Store deleted file mode 100644 index 489fa726e5ff71ad4622ebe8cdb33bf7e8f3a6ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5Z-O8O({YS3VK`cTCldIC|*LWFJMFuDm5`xgE3p0)Er77cYPsW#OHBl zcLNr47O^w1`_1oe_JiyXV~o4=@Q^W^F=jzSxkiSuQ5`*}*SVI^&K;>WKkjV3mQoHf=or&)}D-eB`f| zkVOm-1OJQx-WYi!7ZzpC)*s8mvsOU6gNA~61u7t*uUrDaz Date: Tue, 18 Feb 2025 14:10:56 -0600 Subject: [PATCH 03/22] Remove .DS_Store files, comments and add to .gitignore --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 3 +++ .idea/.gitignore | 8 -------- .../amazon-transcribe-post-call-analytics.iml | 9 --------- .idea/aws.xml | 17 ----------------- .idea/cfnlintPlugin.xml | 8 -------- .idea/misc.xml | 6 ------ .idea/modules.xml | 8 -------- .idea/vcs.xml | 7 ------- pca-server/cfn/lib/boto3.template | 4 ---- pca-server/cfn/lib/ffmpeg.template | 4 ---- pca-server/cfn/lib/glue-database.template | 16 ---------------- pca-server/cfn/lib/pca.template | 12 ------------ pca-server/cfn/lib/python-utilities.template | 4 ---- pca-server/cfn/lib/trigger.template | 16 ---------------- pca-ssm/.DS_Store | Bin 6148 -> 0 bytes 16 files changed, 3 insertions(+), 119 deletions(-) delete mode 100644 .DS_Store delete mode 100644 .idea/.gitignore delete mode 100644 .idea/amazon-transcribe-post-call-analytics.iml delete mode 100644 .idea/aws.xml delete mode 100644 .idea/cfnlintPlugin.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 pca-ssm/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index ffba39b5f741f9bb3e49a19316c97625434fc2da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5Z<-brW7Fu1-&hJtytSq6fYsx7cim+m718M!8BW%)*MP9cYPsW#OHBl zcOz7D@FZeqVDrt+&+g6#*&oIjcW2=tV>V;Vf`-UZDG@Z6y4FlEB3EOiEM=o0OUFT6 zGSFW%;o56#%z4s|-hy!)rPEgHov&4@>l-zzW;Lu^?@?yn)Su2$*PmQt z??TErD0Dx#jE333-a3`Z)Q^(kL?uMw5JGOQq9l}=D`!cVs$5Syth!Yn*t_$2r+d_H zie9g~Xo~r9yVVrkPH(ZOTibgFC+CBwc$CN&%_Rrgm24U;;1!fFWj%Y7B$mkoc#5nd znvfVE28aP-V5Jx^$AHyXsj8`1Vt^R<2?Mx42xy3o!Ca%-I^cuXXY^MQQ9#GH1fnqL z7|b<-2ZZZXK%L6X6NBq?unQCC7|b>5bjH=pFpinIc)V~mJJ^K^XWY?9Ut)k5SZ1K2 zyEdNxXYk9EKJu4Ss7DMC1OJQxUhR8*7m6}x>$mdotQFAiprK$~jtU6qOP2uX;6AdW eoZ2r?hd9Szt`SE;yGjS7i-018KE%K;Fz^A}_e^sD diff --git a/.gitignore b/.gitignore index a50f9291..ff377447 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ build /sample-data .vscode /pca-ui/src/witch/witch.zip +.DS_Store +.idea/ +pca-ssm/.DS_Store diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b81..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/amazon-transcribe-post-call-analytics.iml b/.idea/amazon-transcribe-post-call-analytics.iml deleted file mode 100644 index d6ebd480..00000000 --- a/.idea/amazon-transcribe-post-call-analytics.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/aws.xml b/.idea/aws.xml deleted file mode 100644 index e14a2062..00000000 --- a/.idea/aws.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/cfnlintPlugin.xml b/.idea/cfnlintPlugin.xml deleted file mode 100644 index e700753a..00000000 --- a/.idea/cfnlintPlugin.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 639900d1..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 1823aeee..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index bc514777..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/pca-server/cfn/lib/boto3.template b/pca-server/cfn/lib/boto3.template index 8238e131..9ec632df 100644 --- a/pca-server/cfn/lib/boto3.template +++ b/pca-server/cfn/lib/boto3.template @@ -9,10 +9,6 @@ Parameters: Type: String Description: Name of the parent stack -# SupportFilesBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: SupportFilesBucketName - Boto3ZipName: Type: String Default: transcribeCallAnalyticsModels.zip diff --git a/pca-server/cfn/lib/ffmpeg.template b/pca-server/cfn/lib/ffmpeg.template index bd48c02a..9a084314 100644 --- a/pca-server/cfn/lib/ffmpeg.template +++ b/pca-server/cfn/lib/ffmpeg.template @@ -8,10 +8,6 @@ Parameters: ParentStackName: Type: String Description: Name of the parent stack - -# SupportFilesBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: SupportFilesBucketName FFMPEGZipName: Type: String diff --git a/pca-server/cfn/lib/glue-database.template b/pca-server/cfn/lib/glue-database.template index e99d1c86..d2752746 100644 --- a/pca-server/cfn/lib/glue-database.template +++ b/pca-server/cfn/lib/glue-database.template @@ -9,22 +9,6 @@ Parameters: Type: String Description: Name of the parent stack -# DatabaseName: -# Type: AWS::SSM::Parameter::Value - #Default: DatabaseName - -# DatabaseName: -# Type: String -# Description: Glue catalog database name used to contain tables/views for SQL integration. - -# OutputBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: OutputBucketName -# -# OutputBucketParsedResults: -# Type: AWS::SSM::Parameter::Value -# Default: OutputBucketParsedResults - Resources: Database: diff --git a/pca-server/cfn/lib/pca.template b/pca-server/cfn/lib/pca.template index bfce59ec..37a21559 100644 --- a/pca-server/cfn/lib/pca.template +++ b/pca-server/cfn/lib/pca.template @@ -22,18 +22,6 @@ Parameters: PyUtilsLayer: Type: String -# SupportFilesBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: SupportFilesBucketName - -# StepFunctionName: -# Type: AWS::SSM::Parameter::Value -# Default: StepFunctionName - -# InputBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: InputBucketName - CallSummarization: Type: String Default: DISABLED diff --git a/pca-server/cfn/lib/python-utilities.template b/pca-server/cfn/lib/python-utilities.template index a8acd0e5..cf6bcb8a 100644 --- a/pca-server/cfn/lib/python-utilities.template +++ b/pca-server/cfn/lib/python-utilities.template @@ -9,10 +9,6 @@ Parameters: Type: String Description: Name of the parent stack -# SupportFilesBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: SupportFilesBucketName - PyZipName: Type: String Default: python-utils-layer-v2.zip diff --git a/pca-server/cfn/lib/trigger.template b/pca-server/cfn/lib/trigger.template index 839db848..ac2eda97 100644 --- a/pca-server/cfn/lib/trigger.template +++ b/pca-server/cfn/lib/trigger.template @@ -18,22 +18,6 @@ Parameters: PyUtilsLayer: Type: String -# InputBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: InputBucketName -# -# InputBucketRawAudio: -# Type: AWS::SSM::Parameter::Value -# Default: InputBucketRawAudio -# -# InputBucketOrigTranscripts: -# Type: AWS::SSM::Parameter::Value -# Default: InputBucketOrigTranscripts -# -# StepFunctionName: -# Type: AWS::SSM::Parameter::Value -# Default: StepFunctionName - Summarize: Type: String diff --git a/pca-ssm/.DS_Store b/pca-ssm/.DS_Store deleted file mode 100644 index 489fa726e5ff71ad4622ebe8cdb33bf7e8f3a6ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5Z-O8O({YS3VK`cTCldIC|*LWFJMFuDm5`xgE3p0)Er77cYPsW#OHBl zcLNr47O^w1`_1oe_JiyXV~o4=@Q^W^F=jzSxkiSuQ5`*}*SVI^&K;>WKkjV3mQoHf=or&)}D-eB`f| zkVOm-1OJQx-WYi!7ZzpC)*s8mvsOU6gNA~61u7t*uUrDaz Date: Tue, 18 Feb 2025 14:23:43 -0600 Subject: [PATCH 04/22] Remove comments --- pca-ssm/cfn/ssm.template | 2 -- 1 file changed, 2 deletions(-) diff --git a/pca-ssm/cfn/ssm.template b/pca-ssm/cfn/ssm.template index d6ee9551..93e43bc2 100644 --- a/pca-ssm/cfn/ssm.template +++ b/pca-ssm/cfn/ssm.template @@ -158,12 +158,10 @@ Parameters: StepFunctionName: Type: String - #Default: PostCallAnalyticsWorkflow Description: Name of Step Functions workflow that orchestrates this process BulkUploadStepFunctionName: Type: String - #Default: BulkUploadWorkflow Description: Name of Step Functions workflow that orchestrates the bulk import process SupportFilesBucketName: From ebf05f658130fd5e902dfe8acd2994398744ec8b Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Tue, 18 Feb 2025 14:26:57 -0600 Subject: [PATCH 05/22] Remove comments --- pca-server/cfn/lib/trigger.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pca-server/cfn/lib/trigger.template b/pca-server/cfn/lib/trigger.template index ac2eda97..f435bd52 100644 --- a/pca-server/cfn/lib/trigger.template +++ b/pca-server/cfn/lib/trigger.template @@ -73,7 +73,7 @@ Resources: - Sid: StartExecutionPolicy Effect: Allow Action: states:StartExecution - Resource: #!Sub arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:${StepFunctionName} + Resource: - !Join - '' - - 'arn:aws:states:' From ea5acea917092cb1554cea1ef2c8b1a14e562f23 Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Tue, 18 Feb 2025 14:36:34 -0600 Subject: [PATCH 06/22] Remove comments --- pca-server/cfn/pca-server.template | 1 - 1 file changed, 1 deletion(-) diff --git a/pca-server/cfn/pca-server.template b/pca-server/cfn/pca-server.template index 292a99cf..5f64bb70 100644 --- a/pca-server/cfn/pca-server.template +++ b/pca-server/cfn/pca-server.template @@ -174,7 +174,6 @@ Resources: TemplateURL: lib/glue-database.template Parameters: ParentStackName: !Ref ParentStackName - #DatabaseName: !Ref DatabaseName ########################################################################## From e06d36ca0295efe04a68e40483e519bfacd3a2fd Mon Sep 17 00:00:00 2001 From: Bob Strahan Date: Tue, 18 Feb 2025 16:43:31 -0500 Subject: [PATCH 07/22] Revert "Enhanced SSM Parameter Resolution and Resource Naming" --- pca-main-nokendra.template | 10 +- pca-main.template | 10 +- pca-server/cfn/lib/boto3.template | 15 +- pca-server/cfn/lib/bulk.template | 68 +-- pca-server/cfn/lib/ffmpeg.template | 13 +- pca-server/cfn/lib/glue-database.template | 45 +- pca-server/cfn/lib/pca.template | 263 ++++----- pca-server/cfn/lib/python-utilities.template | 15 +- pca-server/cfn/lib/trigger.template | 76 +-- pca-server/cfn/pca-server.template | 19 - pca-server/src/pca/pcaconfiguration.py | 90 ++-- pca-ssm/cfn/ssm.template | 533 ++++++++++--------- pca-ui/cfn/pca-ui.template | 6 +- 13 files changed, 505 insertions(+), 658 deletions(-) diff --git a/pca-main-nokendra.template b/pca-main-nokendra.template index 02e9a1bb..e8e0bca7 100644 --- a/pca-main-nokendra.template +++ b/pca-main-nokendra.template @@ -354,8 +354,8 @@ Parameters: DatabaseName: Type: String - AllowedPattern: "[a-zA-Z0-9_-]+" - Description: (Required) Glue catalog database name used to contain tables/views for SQL integration. + Default: 'pca' + Description: Glue catalog database name used to contain tables/views for SQL integration. EnablePcaDashboards: Type: String @@ -848,7 +848,6 @@ Resources: Properties: TemplateURL: pca-ssm/cfn/ssm.template Parameters: - StackName: !Ref 'AWS::StackName' BulkUploadBucketName: !If - ShouldCreateBulkUploadBucket @@ -919,8 +918,6 @@ Resources: Type: AWS::CloudFormation::Stack Properties: TemplateURL: pca-server/cfn/lib/python-utilities.template - Parameters: - ParentStackName: !Ref 'AWS::StackName' BedrockBoto3Layer: Type: AWS::CloudFormation::Stack @@ -947,8 +944,6 @@ Resources: Properties: TemplateURL: pca-server/cfn/pca-server.template Parameters: - DatabaseName: !Ref DatabaseName - ParentStackName: !Ref 'AWS::StackName' ffmpegDownloadUrl: !Ref ffmpegDownloadUrl CallSummarization: !Ref CallSummarization SummarizationBedrockModelId: !Ref SummarizationBedrockModelId @@ -971,7 +966,6 @@ Resources: Properties: TemplateURL: pca-ui/cfn/pca-ui.template Parameters: - ParentStackName: !Ref 'AWS::StackName' AdminUsername: !Ref AdminUsername AdminEmail: !Ref AdminEmail AllowedSignUpEmailDomain: !Ref AllowedSignUpEmailDomain diff --git a/pca-main.template b/pca-main.template index 504a4a41..c99c4a71 100644 --- a/pca-main.template +++ b/pca-main.template @@ -395,8 +395,8 @@ Parameters: DatabaseName: Type: String - AllowedPattern: "[a-zA-Z0-9_-]+" - Description: (Required) Glue catalog database name used to contain tables/views for SQL integration. + Default: 'pca' + Description: Glue catalog database name used to contain tables/views for SQL integration. EnablePcaDashboards: Type: String @@ -1031,7 +1031,6 @@ Resources: Properties: TemplateURL: pca-ssm/cfn/ssm.template Parameters: - StackName: !Ref 'AWS::StackName' BulkUploadBucketName: !If - ShouldCreateBulkUploadBucket @@ -1103,8 +1102,6 @@ Resources: Type: AWS::CloudFormation::Stack Properties: TemplateURL: pca-server/cfn/lib/python-utilities.template - Parameters: - ParentStackName: !Ref 'AWS::StackName' BedrockBoto3Layer: Type: AWS::CloudFormation::Stack @@ -1131,8 +1128,6 @@ Resources: Properties: TemplateURL: pca-server/cfn/pca-server.template Parameters: - DatabaseName: !Ref DatabaseName - ParentStackName: !Ref 'AWS::StackName' ffmpegDownloadUrl: !Ref ffmpegDownloadUrl CallSummarization: !Ref CallSummarization SummarizationBedrockModelId: !Ref SummarizationBedrockModelId @@ -1155,7 +1150,6 @@ Resources: Properties: TemplateURL: pca-ui/cfn/pca-ui.template Parameters: - ParentStackName: !Ref 'AWS::StackName' AdminUsername: !Ref AdminUsername AdminEmail: !Ref AdminEmail AllowedSignUpEmailDomain: !Ref AllowedSignUpEmailDomain diff --git a/pca-server/cfn/lib/boto3.template b/pca-server/cfn/lib/boto3.template index 8238e131..575878c2 100644 --- a/pca-server/cfn/lib/boto3.template +++ b/pca-server/cfn/lib/boto3.template @@ -5,13 +5,10 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - Boto3 Layer Zi Transform: AWS::Serverless-2016-10-31 Parameters: - ParentStackName: - Type: String - Description: Name of the parent stack -# SupportFilesBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: SupportFilesBucketName + SupportFilesBucketName: + Type: AWS::SSM::Parameter::Value + Default: SupportFilesBucketName Boto3ZipName: Type: String @@ -39,7 +36,7 @@ Resources: Resource: !Sub - 'arn:aws:s3:::${bucket}*' - - bucket: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' + - bucket: !Ref SupportFilesBucketName Action: - 's3:PutObject' PolicyName: boto3ZipFunctionS3Policy @@ -54,7 +51,7 @@ Resources: MemorySize: 512 Environment: Variables: - SUPPORT_FILES_BUCKET: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' + SUPPORT_FILES_BUCKET: !Ref SupportFilesBucketName BOTO3_ZIP_NAME: !Ref Boto3ZipName Code: ZipFile: | @@ -127,7 +124,7 @@ Resources: DependsOn: boto3Zip Properties: Content: - S3Bucket: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' + S3Bucket: !Ref SupportFilesBucketName S3Key: !Ref Boto3ZipName Outputs: diff --git a/pca-server/cfn/lib/bulk.template b/pca-server/cfn/lib/bulk.template index 09a91048..009bc214 100644 --- a/pca-server/cfn/lib/bulk.template +++ b/pca-server/cfn/lib/bulk.template @@ -5,21 +5,17 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - BulkImport Sta Transform: AWS::Serverless-2016-10-31 Parameters: - ParentStackName: - Type: String - Description: Name of the parent stack + BulkUploadStepFunctionName: + Type: AWS::SSM::Parameter::Value + Default: BulkUploadStepFunctionName -# BulkUploadStepFunctionName: -# Type: AWS::SSM::Parameter::Value -# Default: BulkUploadStepFunctionName - -# BulkUploadBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: BulkUploadBucket - -# InputBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: InputBucketName + BulkUploadBucketName: + Type: AWS::SSM::Parameter::Value + Default: BulkUploadBucket + + InputBucketName: + Type: AWS::SSM::Parameter::Value + Default: InputBucketName Globals: Function: @@ -41,17 +37,8 @@ Resources: - s3:ListBucket - s3:GetObject Resource: - - !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-BulkUploadBucket}}' - - !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-BulkUploadBucket}}' - - '/*' - #- !Sub arn:aws:s3:::${BulkUploadBucketName} - #- !Sub arn:aws:s3:::${BulkUploadBucketName}/* + - !Sub arn:aws:s3:::${BulkUploadBucketName} + - !Sub arn:aws:s3:::${BulkUploadBucketName}/* - Statement: - Sid: SSMGetParameterPolicy Effect: Allow @@ -75,24 +62,10 @@ Resources: - s3:PutObject - s3:DeleteObject Resource: - - !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-BulkUploadBucket}}' - - !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-BulkUploadBucket}}' - - '/*' - - !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' - - !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' - - '/*' + - !Sub arn:aws:s3:::${BulkUploadBucketName} + - !Sub arn:aws:s3:::${BulkUploadBucketName}/* + - !Sub arn:aws:s3:::${InputBucketName} + - !Sub arn:aws:s3:::${InputBucketName}/* BulkQueueSpace: Type: "AWS::Serverless::Function" @@ -105,11 +78,8 @@ Resources: LogGroup: Type: AWS::Logs::LogGroup - Properties: - LogGroupName: !Join - - '' - - - '/aws/vendedlogs/' - - !Sub "{{resolve:ssm:${ParentStackName}-BulkUploadStepFunctionName}}" + Properties: + LogGroupName: !Sub '/aws/vendedlogs/${BulkUploadStepFunctionName}' RetentionInDays: 90 Role: @@ -149,7 +119,7 @@ Resources: StateMachine: Type: "AWS::StepFunctions::StateMachine" Properties: - StateMachineName: !Sub "{{resolve:ssm:${ParentStackName}-BulkUploadStepFunctionName}}" + StateMachineName: !Ref BulkUploadStepFunctionName DefinitionS3Location: ./bulk-definition.json DefinitionSubstitutions: BulkFilesCountArn: !GetAtt BulkFilesCount.Arn diff --git a/pca-server/cfn/lib/ffmpeg.template b/pca-server/cfn/lib/ffmpeg.template index bd48c02a..aedb8778 100644 --- a/pca-server/cfn/lib/ffmpeg.template +++ b/pca-server/cfn/lib/ffmpeg.template @@ -5,13 +5,10 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - FFMPEG Downloa Transform: AWS::Serverless-2016-10-31 Parameters: - ParentStackName: - Type: String - Description: Name of the parent stack -# SupportFilesBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: SupportFilesBucketName + SupportFilesBucketName: + Type: AWS::SSM::Parameter::Value + Default: SupportFilesBucketName FFMPEGZipName: Type: String @@ -45,7 +42,7 @@ Resources: Resource: !Sub - 'arn:aws:s3:::${bucket}*' - - bucket: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' + - bucket: !Ref SupportFilesBucketName Action: - 's3:PutObject' PolicyName: ffmpegZipFunctionS3Policy @@ -61,7 +58,7 @@ Resources: Environment: Variables: FFMPEG_DOWNLOAD_URL: !Ref ffmpegDownloadUrl - SUPPORT_FILES_BUCKET: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' + SUPPORT_FILES_BUCKET: !Ref SupportFilesBucketName FFMPEG_ZIP_NAME: !Ref FFMPEGZipName Code: ZipFile: | diff --git a/pca-server/cfn/lib/glue-database.template b/pca-server/cfn/lib/glue-database.template index e99d1c86..dd4c0d7f 100644 --- a/pca-server/cfn/lib/glue-database.template +++ b/pca-server/cfn/lib/glue-database.template @@ -5,25 +5,18 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - Glue Catalog D Transform: AWS::Serverless-2016-10-31 Parameters: - ParentStackName: - Type: String - Description: Name of the parent stack -# DatabaseName: -# Type: AWS::SSM::Parameter::Value - #Default: DatabaseName + DatabaseName: + Type: AWS::SSM::Parameter::Value + Default: DatabaseName -# DatabaseName: -# Type: String -# Description: Glue catalog database name used to contain tables/views for SQL integration. - -# OutputBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: OutputBucketName -# -# OutputBucketParsedResults: -# Type: AWS::SSM::Parameter::Value -# Default: OutputBucketParsedResults + OutputBucketName: + Type: AWS::SSM::Parameter::Value + Default: OutputBucketName + + OutputBucketParsedResults: + Type: AWS::SSM::Parameter::Value + Default: OutputBucketParsedResults Resources: @@ -33,14 +26,8 @@ Resources: CatalogId: !Ref AWS::AccountId DatabaseInput: Description: Post Call Analytics - LocationUri: !Join - - '' - - - 's3://' - - !Sub '{{resolve:ssm:${ParentStackName}-OutputBucketName}}' - - '/' - - !Sub '{{resolve:ssm:${ParentStackName}-OutputBucketParsedResults}}' - - '/' - Name: !Sub "{{resolve:ssm:${ParentStackName}-DatabaseName}}" + LocationUri: !Sub 's3://${OutputBucketName}/${OutputBucketParsedResults}/' + Name: !Ref DatabaseName ParsedResultsTable: Type: AWS::Glue::Table @@ -61,13 +48,7 @@ Resources: Compressed: false NumberOfBuckets: -1 InputFormat: org.apache.hadoop.mapred.TextInputFormat - Location: !Join - - '' - - - 's3://' - - !Sub '{{resolve:ssm:${ParentStackName}-OutputBucketName}}' - - '/' - - !Sub '{{resolve:ssm:${ParentStackName}-OutputBucketParsedResults}}' - - '/' + Location: !Sub 's3://${OutputBucketName}/${OutputBucketParsedResults}/' OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat SerdeInfo: Name: JSON diff --git a/pca-server/cfn/lib/pca.template b/pca-server/cfn/lib/pca.template index bfce59ec..182b17cc 100644 --- a/pca-server/cfn/lib/pca.template +++ b/pca-server/cfn/lib/pca.template @@ -1,14 +1,10 @@ -AWSTemplateFormatVersion: '2010-09-09' +AWSTemplateFormatVersion: "2010-09-09" Description: Amazon Transcribe Post Call Analytics - PCA Server - PCA State Machine Transform: AWS::Serverless-2016-10-31 Parameters: - ParentStackName: - Type: String - Description: Name of the parent stack - TableName: Type: String @@ -22,33 +18,33 @@ Parameters: PyUtilsLayer: Type: String -# SupportFilesBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: SupportFilesBucketName + SupportFilesBucketName: + Type: AWS::SSM::Parameter::Value + Default: SupportFilesBucketName -# StepFunctionName: -# Type: AWS::SSM::Parameter::Value -# Default: StepFunctionName + StepFunctionName: + Type: AWS::SSM::Parameter::Value + Default: StepFunctionName + + InputBucketName: + Type: AWS::SSM::Parameter::Value + Default: InputBucketName -# InputBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: InputBucketName - - CallSummarization: + CallSummarization: Type: String - Default: DISABLED - SummarizationSagemakerEndpointName: + Default: 'DISABLED' + SummarizationSagemakerEndpointName: Type: String Default: '' - SummarizationSagemakerEndpointArn: + SummarizationSagemakerEndpointArn: Type: String Default: '' SummarizationLLMThirdPartyApiKey: Type: String - Description: | + Description: > Secrets manager secret Arn containing the third party LLM API key Default: '' - SummarizationLambdaFunctionArn: + SummarizationLambdaFunctionArn: Type: String Default: '' SummarizationBedrockModelId: @@ -65,26 +61,20 @@ Globals: Timeout: 60 Conditions: - ProvisionedSageMakerEndpoint: !Equals - - !Ref CallSummarization - - SAGEMAKER - HasCustomSummarizerLambda: !Equals - - !Ref CallSummarization - - LAMBDA - HasAnthropicSummary: !Equals - - !Ref CallSummarization - - ANTHROPIC + ProvisionedSageMakerEndpoint: !Equals [!Ref CallSummarization, "SAGEMAKER"] + HasCustomSummarizerLambda: !Equals [!Ref CallSummarization, "LAMBDA"] + HasAnthropicSummary: !Equals [!Ref CallSummarization, "ANTHROPIC"] Resources: FFMPEGLayer: - Type: AWS::Lambda::LayerVersion + Type: "AWS::Lambda::LayerVersion" Properties: Content: - S3Bucket: !Sub "{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}" + S3Bucket: !Ref SupportFilesBucketName S3Key: !Ref FFMPEGZipName TranscribeRole: - Type: AWS::IAM::Role + Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Statement: @@ -101,7 +91,7 @@ Resources: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess TranscribeLambdaRole: - Type: AWS::IAM::Role + Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Statement: @@ -132,17 +122,8 @@ Resources: - s3:PutObject - s3:DeleteObject Resource: - #- !Sub arn:aws:s3:::${InputBucketName} - #- !Sub arn:aws:s3:::${InputBucketName}/* - - !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' - - !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' - - '/*' + - !Sub arn:aws:s3:::${InputBucketName} + - !Sub arn:aws:s3:::${InputBucketName}/* - PolicyName: SSMGetParameterPolicy PolicyDocument: Statement: @@ -153,9 +134,9 @@ Resources: Resource: !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/* SFStartTranscribeJob: - Type: AWS::Serverless::Function + Type: "AWS::Serverless::Function" Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-start-transcribe-job.lambda_handler EphemeralStorage: Size: 4096 @@ -166,14 +147,13 @@ Resources: Environment: Variables: RoleArn: !GetAtt TranscribeRole.Arn - AWS_DATA_PATH: /opt/models - STACK_NAME: !Ref ParentStackName + AWS_DATA_PATH: "/opt/models" Role: !GetAtt TranscribeLambdaRole.Arn SFExtractJobHeader: - Type: AWS::Serverless::Function + Type: "AWS::Serverless::Function" Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-extract-job-header.lambda_handler MemorySize: 1024 Timeout: 900 @@ -181,17 +161,16 @@ Resources: - !Ref Boto3Layer Environment: Variables: - AWS_DATA_PATH: /opt/models - STACK_NAME: !Ref ParentStackName + AWS_DATA_PATH: "/opt/models" Policies: - arn:aws:iam::aws:policy/AmazonTranscribeReadOnlyAccess - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess SFExtractTranscriptHeader: - Type: AWS::Serverless::Function + Type: "AWS::Serverless::Function" Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-extract-transcript-header.lambda_handler MemorySize: 1024 Timeout: 900 @@ -200,16 +179,15 @@ Resources: - !Ref FFMPEGLayer Environment: Variables: - AWS_DATA_PATH: /opt/models - STACK_NAME: !Ref ParentStackName + AWS_DATA_PATH: "/opt/models" Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess SFProcessTurn: - Type: AWS::Serverless::Function + Type: "AWS::Serverless::Function" Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-process-turn-by-turn.lambda_handler MemorySize: 1024 Timeout: 900 @@ -218,8 +196,7 @@ Resources: - !Ref Boto3Layer Environment: Variables: - AWS_DATA_PATH: /opt/models - STACK_NAME: !Ref ParentStackName + AWS_DATA_PATH: "/opt/models" Policies: - arn:aws:iam::aws:policy/AmazonTranscribeReadOnlyAccess - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess @@ -228,69 +205,63 @@ Resources: - arn:aws:iam::aws:policy/AmazonKendraFullAccess SFFinalProcessing: - Type: AWS::Serverless::Function + Type: "AWS::Serverless::Function" Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-post-processing.lambda_handler Layers: - !Ref Boto3Layer Environment: Variables: - AWS_DATA_PATH: /opt/models - STACK_NAME: !Ref ParentStackName + AWS_DATA_PATH: "/opt/models" Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess SFCTRGenesys: - Type: AWS::Serverless::Function + Type: "AWS::Serverless::Function" Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-ctr-genesys.lambda_handler Layers: - !Ref Boto3Layer Environment: Variables: - AWS_DATA_PATH: /opt/models - STACK_NAME: !Ref ParentStackName + AWS_DATA_PATH: "/opt/models" Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess SFPostCTRProcessing: - Type: AWS::Serverless::Function + Type: "AWS::Serverless::Function" Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-post-ctr-processing.lambda_handler Layers: - !Ref Boto3Layer Environment: Variables: - AWS_DATA_PATH: /opt/models - STACK_NAME: !Ref ParentStackName + AWS_DATA_PATH: "/opt/models" Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess - + SFFetchTranscript: - Type: AWS::Serverless::Function + Type: "AWS::Serverless::Function" Properties: Runtime: python3.11 - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-fetch-transcript.lambda_handler - Environment: - Variables: - STACK_NAME: !Ref ParentStackName Timeout: 900 Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess SFSummarize: - Type: AWS::Serverless::Function + Type: "AWS::Serverless::Function" Properties: Runtime: python3.11 - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-summarize.lambda_handler Timeout: 900 Layers: @@ -298,8 +269,7 @@ Resources: - !Ref Boto3Layer Environment: Variables: - STACK_NAME: !Ref ParentStackName - AWS_DATA_PATH: /opt/models + AWS_DATA_PATH: "/opt/models" FETCH_TRANSCRIPT_LAMBDA_ARN: !GetAtt SFFetchTranscript.Arn BEDROCK_MODEL_ID: !Ref SummarizationBedrockModelId LLM_TABLE_NAME: !Ref LLMTableName @@ -307,9 +277,9 @@ Resources: SUMMARY_SAGEMAKER_ENDPOINT: !Ref SummarizationSagemakerEndpointName ANTHROPIC_API_KEY: !Ref SummarizationLLMThirdPartyApiKey SUMMARY_LAMBDA_ARN: !Ref SummarizationLambdaFunctionArn - ANTHROPIC_MODEL_IDENTIFIER: claude-v1.3-100k - ANTHROPIC_ENDPOINT_URL: https://api.anthropic.com/v1/complete - TOKEN_COUNT: !If + ANTHROPIC_MODEL_IDENTIFIER: "claude-v1.3-100k" + ANTHROPIC_ENDPOINT_URL: "https://api.anthropic.com/v1/complete" + TOKEN_COUNT: !If - ProvisionedSageMakerEndpoint - 1024 - 0 @@ -317,87 +287,82 @@ Resources: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess - Statement: - - Sid: InvokeGetTranscript + - Sid: InvokeGetTranscript + Effect: Allow + Action: + - lambda:InvokeFunction + Resource: !GetAtt SFFetchTranscript.Arn + - Sid: DynamoDBAccess + Effect: Allow + Resource: !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${LLMTableName} + Action: + - 'dynamodb:GetItem' + - Sid: InvokeBedrock + Effect: Allow + Action: + - bedrock:InvokeModel + Resource: + - !Sub "arn:${AWS::Partition}:bedrock:*::foundation-model/*" + - !Sub "arn:${AWS::Partition}:bedrock:*:${AWS::AccountId}:custom-model/*" + - !If + - HasAnthropicSummary + - Sid: SecretsManagerPolicy Effect: Allow Action: - - lambda:InvokeFunction - Resource: !GetAtt SFFetchTranscript.Arn - - Sid: DynamoDBAccess + - 'secretsmanager:GetResourcePolicy' + - 'secretsmanager:GetSecretValue' + - 'secretsmanager:DescribeSecret' + - 'secretsmanager:ListSecretVersionIds' + Resource: !Ref SummarizationLLMThirdPartyApiKey + - !Ref "AWS::NoValue" + - !If + - ProvisionedSageMakerEndpoint + - Sid: InvokeSummarizer Effect: Allow - Resource: !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${LLMTableName} Action: - - dynamodb:GetItem - - Sid: InvokeBedrock + - sagemaker:InvokeEndpoint + Resource: !Ref SummarizationSagemakerEndpointArn + - !Ref "AWS::NoValue" + - !If + - HasCustomSummarizerLambda + - Sid: SummarizationLambda Effect: Allow Action: - - bedrock:InvokeModel - Resource: - - !Sub arn:${AWS::Partition}:bedrock:*::foundation-model/* - - !Sub arn:${AWS::Partition}:bedrock:*:${AWS::AccountId}:custom-model/* - - !If - - HasAnthropicSummary - - Sid: SecretsManagerPolicy - Effect: Allow - Action: - - secretsmanager:GetResourcePolicy - - secretsmanager:GetSecretValue - - secretsmanager:DescribeSecret - - secretsmanager:ListSecretVersionIds - Resource: !Ref SummarizationLLMThirdPartyApiKey - - !Ref AWS::NoValue - - !If - - ProvisionedSageMakerEndpoint - - Sid: InvokeSummarizer - Effect: Allow - Action: - - sagemaker:InvokeEndpoint - Resource: !Ref SummarizationSagemakerEndpointArn - - !Ref AWS::NoValue - - !If - - HasCustomSummarizerLambda - - Sid: SummarizationLambda - Effect: Allow - Action: - - lambda:InvokeFunction - Resource: !Ref SummarizationLambdaFunctionArn - - !Ref AWS::NoValue + - lambda:InvokeFunction + Resource: !Ref SummarizationLambdaFunctionArn + - !Ref "AWS::NoValue" SFAwaitNotification: - Type: AWS::Serverless::Function + Type: "AWS::Serverless::Function" Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-wait-for-transcribe-notification.lambda_handler Environment: Variables: TableName: !Ref TableName - STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess SFTranscribeFailed: - Type: AWS::Serverless::Function + Type: "AWS::Serverless::Function" Properties: - CodeUri: ../../src/pca + CodeUri: ../../src/pca Handler: pca-aws-sf-transcribe-failed.lambda_handler Environment: Variables: RoleArn: !GetAtt TranscribeRole.Arn - STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess LogGroup: Type: AWS::Logs::LogGroup - Properties: - LogGroupName: !Join - - '' - - - '/aws/vendedlogs/' - - !Sub "{{resolve:ssm:${ParentStackName}-StepFunctionName}}" + Properties: + LogGroupName: !Sub '/aws/vendedlogs/${StepFunctionName}' RetentionInDays: 90 Role: - Type: AWS::IAM::Role + Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Statement: @@ -425,22 +390,22 @@ Resources: - PolicyName: CloudWatchLogs PolicyDocument: Statement: - - Effect: Allow - Action: - - logs:CreateLogDelivery - - logs:GetLogDelivery - - logs:UpdateLogDelivery - - logs:DeleteLogDelivery - - logs:ListLogDeliveries - - logs:PutResourcePolicy - - logs:DescribeResourcePolicies - - logs:DescribeLogGroups - Resource: '*' + - Effect: Allow + Action: + - logs:CreateLogDelivery + - logs:GetLogDelivery + - logs:UpdateLogDelivery + - logs:DeleteLogDelivery + - logs:ListLogDeliveries + - logs:PutResourcePolicy + - logs:DescribeResourcePolicies + - logs:DescribeLogGroups + Resource: "*" StateMachine: - Type: AWS::StepFunctions::StateMachine + Type: "AWS::StepFunctions::StateMachine" Properties: - StateMachineName: !Sub "{{resolve:ssm:${ParentStackName}-StepFunctionName}}" + StateMachineName: !Ref StepFunctionName DefinitionS3Location: ./pca-definition.json DefinitionSubstitutions: SFExtractJobHeaderArn: !GetAtt SFExtractJobHeader.Arn diff --git a/pca-server/cfn/lib/python-utilities.template b/pca-server/cfn/lib/python-utilities.template index a8acd0e5..cd8ba09c 100644 --- a/pca-server/cfn/lib/python-utilities.template +++ b/pca-server/cfn/lib/python-utilities.template @@ -5,13 +5,10 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - Install python Transform: AWS::Serverless-2016-10-31 Parameters: - ParentStackName: - Type: String - Description: Name of the parent stack -# SupportFilesBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: SupportFilesBucketName + SupportFilesBucketName: + Type: AWS::SSM::Parameter::Value + Default: SupportFilesBucketName PyZipName: Type: String @@ -39,7 +36,7 @@ Resources: Resource: !Sub - 'arn:aws:s3:::${bucket}*' - - bucket: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' + - bucket: !Ref SupportFilesBucketName Action: - 's3:PutObject' PolicyName: PyUtilsZipFunctionS3Policy @@ -54,7 +51,7 @@ Resources: MemorySize: 1024 Environment: Variables: - SUPPORT_FILES_BUCKET: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' + SUPPORT_FILES_BUCKET: !Ref SupportFilesBucketName PY_ZIP_NAME: !Ref PyZipName Code: ZipFile: | @@ -121,7 +118,7 @@ Resources: CompatibleRuntimes: - python3.11 Content: - S3Bucket: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' + S3Bucket: !Ref SupportFilesBucketName S3Key: !Ref PyZipName Outputs: diff --git a/pca-server/cfn/lib/trigger.template b/pca-server/cfn/lib/trigger.template index 839db848..53347c70 100644 --- a/pca-server/cfn/lib/trigger.template +++ b/pca-server/cfn/lib/trigger.template @@ -5,10 +5,6 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - S3 Trigger Transform: AWS::Serverless-2016-10-31 Parameters: - ParentStackName: - Type: String - Description: Name of the parent stack - TableName: Type: String @@ -18,21 +14,21 @@ Parameters: PyUtilsLayer: Type: String -# InputBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: InputBucketName -# -# InputBucketRawAudio: -# Type: AWS::SSM::Parameter::Value -# Default: InputBucketRawAudio -# -# InputBucketOrigTranscripts: -# Type: AWS::SSM::Parameter::Value -# Default: InputBucketOrigTranscripts -# -# StepFunctionName: -# Type: AWS::SSM::Parameter::Value -# Default: StepFunctionName + InputBucketName: + Type: AWS::SSM::Parameter::Value + Default: InputBucketName + + InputBucketRawAudio: + Type: AWS::SSM::Parameter::Value + Default: InputBucketRawAudio + + InputBucketOrigTranscripts: + Type: AWS::SSM::Parameter::Value + Default: InputBucketOrigTranscripts + + StepFunctionName: + Type: AWS::SSM::Parameter::Value + Default: StepFunctionName Summarize: Type: String @@ -50,7 +46,6 @@ Resources: Environment: Variables: SUMMARIZE: !Ref Summarize - STACK_NAME: !Ref ParentStackName CodeUri: ../../src/pca Handler: pca-aws-file-drop-trigger.lambda_handler Layers: @@ -65,15 +60,8 @@ Resources: - s3:ListBucket - s3:GetObject Resource: - - !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' - - !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' - - '/*' + - !Sub arn:aws:s3:::${InputBucketName} + - !Sub arn:aws:s3:::${InputBucketName}/* - Statement: - Sid: SSMGetParameterPolicy Effect: Allow @@ -89,16 +77,7 @@ Resources: - Sid: StartExecutionPolicy Effect: Allow Action: states:StartExecution - Resource: #!Sub arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:${StepFunctionName} - - !Join - - '' - - - 'arn:aws:states:' - - !Ref 'AWS::Region' - - ':' - - !Ref 'AWS::AccountId' - - ':stateMachine:' - - !Sub '{{resolve:ssm:${ParentStackName}-StepFunctionName}}' - + Resource: !Sub arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:${StepFunctionName} FileDropTriggerPermission: @@ -108,10 +87,7 @@ Resources: Action: lambda:InvokeFunction Principal: s3.amazonaws.com SourceAccount: !Ref AWS::AccountId - SourceArn: !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + SourceArn: !Sub arn:aws:s3:::${InputBucketName} ConfigureBucketRole: Type: "AWS::IAM::Role" @@ -133,10 +109,7 @@ Resources: Action: - s3:GetBucketNotification - s3:PutBucketNotification - Resource: !Join - - '' - - - 'arn:aws:s3:::' - - !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + Resource: !Sub arn:aws:s3:::${InputBucketName} ConfigureBucketFunction: Type: "AWS::Lambda::Function" @@ -155,8 +128,8 @@ Resources: - FileDropTriggerPermission Properties: ServiceToken: !GetAtt ConfigureBucketFunction.Arn - BucketName: !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' - Prefix: !Sub '{{resolve:ssm:${ParentStackName}-InputBucketRawAudio}}' + BucketName: !Ref InputBucketName + Prefix: !Ref InputBucketRawAudio LambdaArn: !GetAtt FileDropTrigger.Arn FileUpload: "true" @@ -167,8 +140,8 @@ Resources: - ConfigureBucket Properties: ServiceToken: !GetAtt ConfigureBucketFunction.Arn - BucketName: !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' - Prefix: !Sub '{{resolve:ssm:${ParentStackName}-InputBucketOrigTranscripts}}' + BucketName: !Ref InputBucketName + Prefix: !Ref InputBucketOrigTranscripts LambdaArn: !GetAtt FileDropTrigger.Arn TranscribeEventbridge: @@ -207,7 +180,6 @@ Resources: Variables: TableName: !Ref TableName AWS_DATA_PATH: "/opt/models" - STACK_NAME: !Ref ParentStackName Policies: - arn:aws:iam::aws:policy/AmazonTranscribeReadOnlyAccess - Statement: diff --git a/pca-server/cfn/pca-server.template b/pca-server/cfn/pca-server.template index 292a99cf..ecc6dac7 100644 --- a/pca-server/cfn/pca-server.template +++ b/pca-server/cfn/pca-server.template @@ -3,14 +3,6 @@ AWSTemplateFormatVersion: "2010-09-09" Description: Amazon Transcribe Post Call Analytics - PCA Server Parameters: - ParentStackName: - Type: String - Description: Name of the parent stack - - DatabaseName: - Type: String - Description: Glue catalog database name used to contain tables/views for SQL integration. - ffmpegDownloadUrl: Type: String Default: http://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz @@ -104,7 +96,6 @@ Resources: Properties: TemplateURL: lib/ffmpeg.template Parameters: - ParentStackName: !Ref ParentStackName ffmpegDownloadUrl: !Ref ffmpegDownloadUrl BOTO3: @@ -112,8 +103,6 @@ Resources: Type: AWS::CloudFormation::Stack Properties: TemplateURL: lib/boto3.template - Parameters: - ParentStackName: !Ref ParentStackName DDB: Type: AWS::CloudFormation::Stack @@ -125,7 +114,6 @@ Resources: Properties: TemplateURL: lib/pca.template Parameters: - ParentStackName: !Ref ParentStackName TableName: !GetAtt DDB.Outputs.TableName FFMPEGZipName: !GetAtt FFMPEG.Outputs.FFMPEGZipName Boto3Layer: !If @@ -152,7 +140,6 @@ Resources: Properties: TemplateURL: lib/trigger.template Parameters: - ParentStackName: !Ref ParentStackName TableName: !GetAtt DDB.Outputs.TableName Boto3Layer: !If - ShouldCreateBoto3Layer @@ -165,17 +152,11 @@ Resources: Type: AWS::CloudFormation::Stack Properties: TemplateURL: lib/bulk.template - Parameters: - ParentStackName: !Ref ParentStackName GlueDatabase: Type: AWS::CloudFormation::Stack Properties: TemplateURL: lib/glue-database.template - Parameters: - ParentStackName: !Ref ParentStackName - #DatabaseName: !Ref DatabaseName - ########################################################################## # Transcript Summary diff --git a/pca-server/src/pca/pcaconfiguration.py b/pca-server/src/pca/pcaconfiguration.py index 7b7b5cf8..47134b2d 100644 --- a/pca-server/src/pca/pcaconfiguration.py +++ b/pca-server/src/pca/pcaconfiguration.py @@ -7,58 +7,54 @@ SPDX-License-Identifier: Apache-2.0 """ import boto3 -import os from botocore.config import Config -# Get the stack name from environment variable -STACK_NAME = os.environ.get('STACK_NAME') - # Parameter Store Field Names used by main workflow -CONF_COMP_LANGS = f"{STACK_NAME}-ComprehendLanguages" -CONF_REDACTION_LANGS = f"{STACK_NAME}-ContentRedactionLanguages" -CONF_CONVO_LOCATION = f"{STACK_NAME}-ConversationLocation" -CONF_ENTITYENDPOINT = f"{STACK_NAME}-EntityRecognizerEndpoint" -CONF_ENTITY_FILE = f"{STACK_NAME}-EntityStringMap" -CONF_ENTITYCONF = f"{STACK_NAME}-EntityThreshold" -CONF_ENTITY_TYPES = f"{STACK_NAME}-EntityTypes" -CONF_PREFIX_AUDIO_PLAYBACK = f"{STACK_NAME}-InputBucketAudioPlayback" -CONF_S3BUCKET_INPUT = f"{STACK_NAME}-InputBucketName" -CONF_PREFIX_RAW_AUDIO = f"{STACK_NAME}-InputBucketRawAudio" -CONF_PREFIX_FAILED_AUDIO = f"{STACK_NAME}-InputBucketFailedTranscriptions" -CONF_PREFIX_INPUT_TRANSCRIPTS = f"{STACK_NAME}-InputBucketOrigTranscripts" -CONF_MAX_SPEAKERS = f"{STACK_NAME}-MaxSpeakers" -CONF_MINNEGATIVE = f"{STACK_NAME}-MinSentimentNegative" -CONF_MINPOSITIVE = f"{STACK_NAME}-MinSentimentPositive" -CONF_S3BUCKET_OUTPUT = f"{STACK_NAME}-OutputBucketName" -CONF_PREFIX_TRANSCRIBE_RESULTS = f"{STACK_NAME}-OutputBucketTranscribeResults" -CONF_PREFIX_PARSED_RESULTS = f"{STACK_NAME}-OutputBucketParsedResults" -CONF_SPEAKER_NAMES = f"{STACK_NAME}-SpeakerNames" -CONF_SPEAKER_MODE = f"{STACK_NAME}-SpeakerSeparationType" -COMP_SFN_NAME = f"{STACK_NAME}-StepFunctionName" -CONF_SUPPORT_BUCKET = f"{STACK_NAME}-SupportFilesBucketName" -CONF_TRANSCRIBE_LANG = f"{STACK_NAME}-TranscribeLanguages" -CONF_TELEPHONY_CTR = f"{STACK_NAME}-TelephonyCTRType" -CONF_TELEPHONY_CTR_SUFFIX = f"{STACK_NAME}-TelephonyCTRFileSuffix" -CONF_VOCABNAME = f"{STACK_NAME}-VocabularyName" -CONF_CLMNAME = f"{STACK_NAME}-CustomLangModelName" -CONF_FILENAME_DATETIME_REGEX = f"{STACK_NAME}-FilenameDatetimeRegex" -CONF_FILENAME_DATETIME_FIELDMAP = f"{STACK_NAME}-FilenameDatetimeFieldMap" -CONF_FILENAME_GUID_REGEX = f"{STACK_NAME}-FilenameGUIDRegex" -CONF_FILENAME_AGENT_REGEX = f"{STACK_NAME}-FilenameAgentRegex" -CONF_FILENAME_CUST_REGEX = f"{STACK_NAME}-FilenameCustRegex" -CONF_FILTER_MODE = f"{STACK_NAME}-VocabFilterMode" -CONF_FILTER_NAME = f"{STACK_NAME}-VocabFilterName" -CONF_KENDRA_INDEX_ID = f"{STACK_NAME}-KendraIndexId" -CONF_WEB_URI = f"{STACK_NAME}-WebUiUri" -CONF_TRANSCRIBE_API = f"{STACK_NAME}-TranscribeApiMode" -CONF_REDACTION_TRANSCRIPT = f"{STACK_NAME}-CallRedactionTranscript" -CONF_REDACTION_AUDIO = f"{STACK_NAME}-CallRedactionAudio" -CONF_CALL_SUMMARIZATION = f"{STACK_NAME}-CallSummarization" +CONF_COMP_LANGS = "ComprehendLanguages" +CONF_REDACTION_LANGS = "ContentRedactionLanguages" +CONF_CONVO_LOCATION = "ConversationLocation" +CONF_ENTITYENDPOINT = "EntityRecognizerEndpoint" +CONF_ENTITY_FILE = "EntityStringMap" +CONF_ENTITYCONF = "EntityThreshold" +CONF_ENTITY_TYPES = "EntityTypes" +CONF_PREFIX_AUDIO_PLAYBACK = "InputBucketAudioPlayback" +CONF_S3BUCKET_INPUT = "InputBucketName" +CONF_PREFIX_RAW_AUDIO = "InputBucketRawAudio" +CONF_PREFIX_FAILED_AUDIO = "InputBucketFailedTranscriptions" +CONF_PREFIX_INPUT_TRANSCRIPTS = "InputBucketOrigTranscripts" +CONF_MAX_SPEAKERS = "MaxSpeakers" +CONF_MINNEGATIVE = "MinSentimentNegative" +CONF_MINPOSITIVE = "MinSentimentPositive" +CONF_S3BUCKET_OUTPUT = "OutputBucketName" +CONF_PREFIX_TRANSCRIBE_RESULTS = "OutputBucketTranscribeResults" +CONF_PREFIX_PARSED_RESULTS = "OutputBucketParsedResults" +CONF_SPEAKER_NAMES = "SpeakerNames" +CONF_SPEAKER_MODE = "SpeakerSeparationType" +COMP_SFN_NAME = "StepFunctionName" +CONF_SUPPORT_BUCKET = "SupportFilesBucketName" +CONF_TRANSCRIBE_LANG = "TranscribeLanguages" +CONF_TELEPHONY_CTR = "TelephonyCTRType" +CONF_TELEPHONY_CTR_SUFFIX = "TelephonyCTRFileSuffix" +CONF_VOCABNAME = "VocabularyName" +CONF_CLMNAME = "CustomLangModelName" +CONF_FILENAME_DATETIME_REGEX = "FilenameDatetimeRegex" +CONF_FILENAME_DATETIME_FIELDMAP = "FilenameDatetimeFieldMap" +CONF_FILENAME_GUID_REGEX = "FilenameGUIDRegex" +CONF_FILENAME_AGENT_REGEX = "FilenameAgentRegex" +CONF_FILENAME_CUST_REGEX = "FilenameCustRegex" +CONF_FILTER_MODE = "VocabFilterMode" +CONF_FILTER_NAME = "VocabFilterName" +CONF_KENDRA_INDEX_ID = "KendraIndexId" +CONF_WEB_URI = "WebUiUri" +CONF_TRANSCRIBE_API = "TranscribeApiMode" +CONF_REDACTION_TRANSCRIPT = "CallRedactionTranscript" +CONF_REDACTION_AUDIO = "CallRedactionAudio" +CONF_CALL_SUMMARIZATION = "CallSummarization" # Parameter store fieldnames used by bulk import -BULK_S3_BUCKET = f"{STACK_NAME}-BulkUploadBucket" -BULK_JOB_LIMIT = f"{STACK_NAME}-BulkUploadMaxTranscribeJobs" -BULK_MAX_DRIP_RATE = f"{STACK_NAME}-BulkUploadMaxDripRate" +BULK_S3_BUCKET = "BulkUploadBucket" +BULK_JOB_LIMIT = "BulkUploadMaxTranscribeJobs" +BULK_MAX_DRIP_RATE = "BulkUploadMaxDripRate" # Transcribe API Modes API_STANDARD = "standard" diff --git a/pca-ssm/cfn/ssm.template b/pca-ssm/cfn/ssm.template index d6ee9551..d33f74ea 100644 --- a/pca-ssm/cfn/ssm.template +++ b/pca-ssm/cfn/ssm.template @@ -1,43 +1,46 @@ -AWSTemplateFormatVersion: '2010-09-09' +AWSTemplateFormatVersion: "2010-09-09" Description: Amazon Transcribe Post Call Analytics - PCA SSM Parameters Parameters: - StackName: - Type: String - Description: Name of the parent stack BulkUploadBucketName: Type: String - Description: (Optional) Existing bucket where files can be dropped, and a - secondary Step Function can be manually enabled to drip feed them into - the system. Leave blank to automatically create new bucket. + Description: >- + (Optional) Existing bucket where files can be dropped, and a secondary Step Function can be + manually enabled to drip feed them into the system. + Leave blank to automatically create new bucket. BulkUploadMaxDripRate: Type: String - Default: '25' - Description: Maximum number of files that the bulk uploader will move to the PCA - source bucket in one pass + Default: "25" + Description: Maximum number of files that the bulk uploader will move to the PCA source bucket in one pass BulkUploadMaxTranscribeJobs: Type: String - Default: '50' - Description: Number of concurrent Transcribe jobs (executing or queuing) where - bulk upload will pause + Default: "50" + Description: Number of concurrent Transcribe jobs (executing or queuing) where bulk upload will pause CallSummarization: - Default: BEDROCK + Default: 'BEDROCK' Type: String AllowedValues: - - DISABLED - - BEDROCK+TCA - - BEDROCK - - TCA-ONLY - - SAGEMAKER - - ANTHROPIC - - LAMBDA - Description: | - Set to enable call summarization by a Large Language Model. The BEDROCK+TCA will use Transcribe Call Analytics for summarization and Bedrock for other analytics. The BEDROCK option requires you to choose one of the supported model IDs from the provided list (SummarizationBedrockModelId). You must also accept access to that model in the Amazon Bedrock > Model Access console. The TCA-ONLY option will not use Bedrock, but will only use Transcribe Call Analytics summarization. The SAGEMAKER option uses a SageMaker endpoint with the pretrained bart-large-cnn-samsum model with a ml.m5.xlarge instance type. The LAMBDA option requires you to provide a function ARN below. The ANTHROPIC option is a third party service, and you must enter your Anthropic API key in the Third Party LLM API Key section. + - 'DISABLED' + - 'BEDROCK+TCA' + - 'BEDROCK' + - 'TCA-ONLY' + - 'SAGEMAKER' + - 'ANTHROPIC' + - 'LAMBDA' + Description: > + Set to enable call summarization by a Large Language Model. + The BEDROCK+TCA will use Transcribe Call Analytics for summarization and Bedrock for other analytics. + The BEDROCK option requires you to choose one of the supported model IDs from the provided list (SummarizationBedrockModelId). + You must also accept access to that model in the Amazon Bedrock > Model Access console. + The TCA-ONLY option will not use Bedrock, but will only use Transcribe Call Analytics summarization. + The SAGEMAKER option uses a SageMaker endpoint with the pretrained bart-large-cnn-samsum model with a ml.m5.xlarge instance type. + The LAMBDA option requires you to provide a function ARN below. + The ANTHROPIC option is a third party service, and you must enter your Anthropic API key in the Third Party LLM API Key section. ComprehendLanguages: Type: String @@ -47,47 +50,37 @@ Parameters: ContentRedactionLanguages: Type: String Default: en-US - Description: Languages supported by Transcribe's Content Redaction feature, - separated by " | " + Description: Languages supported by Transcribe's Content Redaction feature, separated by " | " ConversationLocation: Type: String Default: America/New_York - Description: Name of the timezone location for the call source - this is the TZ - database name from - https://en.wikipedia.org/wiki/List_of_tz_database_time_zones + Description: Name of the timezone location for the call source - this is the TZ database name from https://en.wikipedia.org/wiki/List_of_tz_database_time_zones EntityRecognizerEndpoint: Type: String Default: undefined - Description: Name of the custom entity recognizer for Amazon Comprehend (not - including language suffix, e.g. -en). If one cannot be found then simple - entity string matching is attempted instead + Description: Name of the custom entity recognizer for Amazon Comprehend (not including language suffix, e.g. -en). If one cannot be found then simple entity string matching is attempted instead EntityStringMap: Type: String Default: sample-entities.csv - Description: Basename of a CSV file containing item/Entity maps for when we - don't have data for Comprehend Custom Entities (not including language - suffix, e.g. -en) + Description: Basename of a CSV file containing item/Entity maps for when we don't have data for Comprehend Custom Entities (not including language suffix, e.g. -en) EntityThreshold: Type: String - Default: '0.5' + Default: "0.5" Description: Confidence threshold where we accept the custom entity detection result EntityTypes: Type: String - Default: PERSON | LOCATION | ORGANIZATION | COMMERCIAL_ITEM | EVENT | DATE | - QUANTITY | TITLE - Description: Entity types supported by Comprehend's standard entity detection, - separated by " | " + Default: PERSON | LOCATION | ORGANIZATION | COMMERCIAL_ITEM | EVENT | DATE | QUANTITY | TITLE + Description: Entity types supported by Comprehend's standard entity detection, separated by " | " InputBucketAudioPlayback: Type: String Default: playbackAudio - Description: Folder that holds the audio files to playback in the browser when - original audio cannot be used + Description: Folder that holds the audio files to playback in the browser when original audio cannot be used InputBucketFailedTranscriptions: Type: String @@ -96,8 +89,9 @@ Parameters: InputBucketName: Type: String - Description: (Optional) Existing bucket holding all audio files for the - system. Leave blank to automatically create new bucket. + Description: >- + (Optional) Existing bucket holding all audio files for the system. + Leave blank to automatically create new bucket. InputBucketRawAudio: Type: String @@ -107,37 +101,36 @@ Parameters: InputBucketOrigTranscripts: Type: String Default: originalTranscripts - Description: Folder that holds Transcripts from other applications (e.g. Live - Call Analytics) that are to be processed as if PCA had processed that - audio + Description: >- + Folder that holds Transcripts from other applications (e.g. Live Call Analytics) that are to be + processed as if PCA had processed that audio MaxSpeakers: Type: String - Default: '2' + Default: "2" Description: Maximum number of speakers that are expected on a call MinSentimentNegative: Type: String - Default: '2.0' - Description: Minimum sentiment level required to declare a phrase as having - negative sentiment, in the range 0.0-5.0 + Default: "2.0" + Description: Minimum sentiment level required to declare a phrase as having negative sentiment, in the range 0.0-5.0 MinSentimentPositive: Type: String - Default: '2.0' - Description: Minimum sentiment level required to declare a phrase as having - positive sentiment, in the range 0.0-5.0 + Default: "2.0" + Description: Minimum sentiment level required to declare a phrase as having positive sentiment, in the range 0.0-5.0 OutputBucketName: Type: String - Description: (Optional) Existing bucket where Transcribe output files are - delivered. Leave blank to automatically create new bucket. + Description: >- + (Optional) Existing bucket where Transcribe output files are delivered. + Leave blank to automatically create new bucket. OutputBucketTranscribeResults: Type: String Default: transcribeResults Description: Folder within the output S3 bucket where Transcribe results are written - + OutputBucketParsedResults: Type: String Default: parsedFiles @@ -146,49 +139,49 @@ Parameters: SpeakerNames: Type: String Default: Caller | Agent - Description: Tags used for speaker names in transcripts, in channel/speaker - order, separated by " | ". For Call Analytics the name Agent must exist in - either the first or second posision + Description: >- + Tags used for speaker names in transcripts, in channel/speaker order, separated by " | ". + For Call Analytics the name Agent must exist in either the first or second posision SpeakerSeparationType: Type: String Default: channel - Description: Separation mode for speakers - must be speaker (mono) channel - (stereo/auto-select) + Description: Separation mode for speakers - must be speaker (mono) channel (stereo/auto-select) StepFunctionName: Type: String - #Default: PostCallAnalyticsWorkflow + Default: PostCallAnalyticsWorkflow Description: Name of Step Functions workflow that orchestrates this process BulkUploadStepFunctionName: Type: String - #Default: BulkUploadWorkflow + Default: BulkUploadWorkflow Description: Name of Step Functions workflow that orchestrates the bulk import process SupportFilesBucketName: Type: String - Description: (Optional) Existing bucket that hold supporting files, such as - the file-based entity recognition mapping files. Leave blank to - automatically create new bucket. + Description: >- + (Optional) Existing bucket that hold supporting files, such as the + file-based entity recognition mapping files. + Leave blank to automatically create new bucket. TranscribeApiMode: Type: String Default: analytics - Description: Specifies which Transcribe API to use for new jobs - must be - standard or analytics + Description: Specifies which Transcribe API to use for new jobs - must be standard or analytics TelephonyCTRType: Type: String Default: none - Description: Type of telephony system that will deliver Contact Trace Record - files along with the audio recordings + Description: Type of telephony system that will deliver Contact Trace Record files along with the audio recordings TelephonyCTRFileSuffix: Type: String Default: none - Description: | - File number suffixes for the CTR file(s) associated with the chosen telephony type, separated by " | ". For Genesys, this needs two entries: one for the conversation CTR file, and one for the call-specific file. Other telephony systems may need fewer or additional entries, please consult the documentation. + Description: > + File number suffixes for the CTR file(s) associated with the chosen telephony type, separated by " | ". + For Genesys, this needs two entries: one for the conversation CTR file, and one for the call-specific file. + Other telephony systems may need fewer or additional entries, please consult the documentation. CallRedactionTranscript: Type: String @@ -198,472 +191,486 @@ Parameters: CallRedactionAudio: Type: String Default: true - Description: When transcript redaction is enabled in Call Analytics, only allow - playback of the redacted audio + Description: When transcript redaction is enabled in Call Analytics, only allow playback of the redacted audio TranscribeLanguages: Type: String Default: en-US - Description: Language to be used for Transcription - multiple entries separated - by " | " will trigger Language Detection + Description: Language to be used for Transcription - multiple entries separated by " | " will trigger Language Detection VocabFilterMode: Type: String Default: mask - Description: The mode to use for vocabulary filtering - must be one of mask or - remove (tag is not supported) + Description: The mode to use for vocabulary filtering - must be one of mask or remove (tag is not supported) VocabFilterName: Type: String Default: undefined - Description: Name of the vocabulary filter to use for Transcribe (not including - language suffix, e.g. -en) + Description: Name of the vocabulary filter to use for Transcribe (not including language suffix, e.g. -en) VocabularyName: Type: String Default: undefined - Description: Name of the custom vocabulary to use for Transcribe (not including - language suffix, e.g. -en-US) + Description: Name of the custom vocabulary to use for Transcribe (not including language suffix, e.g. -en-US) CustomLangModelName: Type: String Default: undefined - Description: Name of the custom language model to use for Transcribe (omit the - language suffix, e.g. -en-US) + Description: Name of the custom language model to use for Transcribe (omit the language suffix, e.g. -en-US) FilenameDatetimeRegex: Type: String - Default: (\d{4})-(\d{2})-(\d{2})T(\d{2})-(\d{2})-(\d{2}) - Description: | - Regular Expression (regex) used to parse call Date/Time from audio filenames. Each datetime field (year, month, etc.) must be matched using a separate parenthesized group in the regex. Example: the regex '(\d{4})-(\d{2})-(\d{2})T(\d{2})-(\d{2})-(\d{2})' parses the filename: CallAudioFile-2021-12-01T07-55-51.wav into a value list: [2021, 12, 01, 07, 55, 51] The next parameter, FilenameDatetimeFieldMap, maps the values to datetime field codes. If the filename doesn't match the regex pattern, the current time is used as the call timestamp. + Default: '(\d{4})-(\d{2})-(\d{2})T(\d{2})-(\d{2})-(\d{2})' + Description: > + Regular Expression (regex) used to parse call Date/Time from audio filenames. + Each datetime field (year, month, etc.) must be matched using a separate parenthesized group in the regex. + Example: the regex '(\d{4})-(\d{2})-(\d{2})T(\d{2})-(\d{2})-(\d{2})' parses + the filename: CallAudioFile-2021-12-01T07-55-51.wav into a value list: [2021, 12, 01, 07, 55, 51] + The next parameter, FilenameDatetimeFieldMap, maps the values to datetime field codes. + If the filename doesn't match the regex pattern, the current time is used as the call timestamp. FilenameDatetimeFieldMap: Type: String Default: '%Y %m %d %H %M %S' - Description: | - Space separated ordered sequence of time field codes as used by Python's datetime.strptime() function. Each field code refers to a corresponding value parsed by the regex parameter filenameTimestampRegex. Example: the mapping '%Y %m %d %H %M %S' assembles the regex output values [2021, 12, 01, 07, 55, 51] into the full datetime: '2021-12-01 07:55:51'. If the field map doesn't match the value list parsed by the regex, then the current time is used as the call timestamp. + Description: > + Space separated ordered sequence of time field codes as used by Python's datetime.strptime() function. + Each field code refers to a corresponding value parsed by the regex parameter filenameTimestampRegex. + Example: the mapping '%Y %m %d %H %M %S' assembles the regex output values [2021, 12, 01, 07, 55, 51] + into the full datetime: '2021-12-01 07:55:51'. + If the field map doesn't match the value list parsed by the regex, then the current time is used as the call timestamp. FilenameGUIDRegex: Type: String - Default: _GUID_(.*?)_ - Description: | - Regular Expression (regex) used to parse call GUID from audio filenames. The GUID value must be matched using a parenthesized group in the regex. Example: the regex '_GUID_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the GUID value '2a602c1a-4ca3-4d37-a933-444d575c0222'. + Default: '_GUID_(.*?)_' + Description: > + Regular Expression (regex) used to parse call GUID from audio filenames. + The GUID value must be matched using a parenthesized group in the regex. + Example: the regex '_GUID_(.*?)_' parses + the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav + to extract the GUID value '2a602c1a-4ca3-4d37-a933-444d575c0222'. FilenameAgentRegex: Type: String - Default: _AGENT_(.*?)_ - Description: | - Regular Expression (regex) used to parse call AGENT from audio filenames. The AGENT value must be matched using a parenthesized group in the regex. Example: the regex '_AGENT_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the AGENT value 'BobS'. - + Default: '_AGENT_(.*?)_' + Description: > + Regular Expression (regex) used to parse call AGENT from audio filenames. + The AGENT value must be matched using a parenthesized group in the regex. + Example: the regex '_AGENT_(.*?)_' parses + the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav + to extract the AGENT value 'BobS'. + FilenameCustRegex: Type: String - Default: _CUST_(.*?)_ - Description: | - Regular Expression (regex) used to parse Customer from audio filenames. The customer id value must be matched using one or more parenthesized groups in the regex. Example: the regex '_CUST_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the Customer value '12345'. + Default: '_CUST_(.*?)_' + Description: > + Regular Expression (regex) used to parse Customer from audio filenames. + The customer id value must be matched using one or more parenthesized groups in the regex. + Example: the regex '_CUST_(.*?)_' parses + the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav + to extract the Customer value '12345'. KendraIndexId: Type: String - Description: Kendra Index ID, or empty string if call transcription indexing is - not enabled - + Description: Kendra Index ID, or empty string if call transcription indexing is not enabled + #WebUri: # Type: String # Description: PCA Web Application URI - + DatabaseName: Type: String - Description: Glue catalog database name used to contain tables/views for SQL - integration. - + Default: 'pca' + Description: Glue catalog database name used to contain tables/views for SQL integration. + Resources: BulkUploadBucketParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-BulkUploadBucket + Name: BulkUploadBucket Type: String - Description: Bucket where files can be dropped, and a secondary Step Function - can be manually enabled to drip feed them into the system + Description: Bucket where files can be dropped, and a secondary Step Function can be manually enabled to drip feed them into the system Value: !Ref BulkUploadBucketName BulkUploadMaxDripRateParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-BulkUploadMaxDripRate + Name: BulkUploadMaxDripRate Type: String - Description: Maximum number of files that the bulk uploader will move to the PCA - source bucket in one pass + Description: Maximum number of files that the bulk uploader will move to the PCA source bucket in one pass Value: !Ref BulkUploadMaxDripRate BulkUploadMaxTranscribeJobsParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-BulkUploadMaxTranscribeJobs + Name: BulkUploadMaxTranscribeJobs Type: String - Description: Number of concurrent Transcribe jobs (executing or queuing) where - bulk upload will pause + Description: Number of concurrent Transcribe jobs (executing or queuing) where bulk upload will pause Value: !Ref BulkUploadMaxTranscribeJobs CallSummarizationParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-CallSummarization + Name: CallSummarization Type: String - Description: 'What type of call summarization to use. ' + Description: >- + What type of call summarization to use. Value: !Ref CallSummarization ComprehendLanguagesParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-ComprehendLanguages + Name: ComprehendLanguages Type: String Description: Languages supported by Comprehend's standard calls, separated by " | " Value: !Ref ComprehendLanguages ContentRedactionLanguagesParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-ContentRedactionLanguages + Name: ContentRedactionLanguages Type: String - Description: Languages supported by Transcribe's Content Redaction feature, - separated by " | " + Description: Languages supported by Transcribe's Content Redaction feature, separated by " | " Value: !Ref ContentRedactionLanguages ConversationLocationParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-ConversationLocation + Name: ConversationLocation Type: String - Description: Name of the timezone location for the call source - this is the TZ - database name from - https://en.wikipedia.org/wiki/List_of_tz_database_time_zones + Description: Name of the timezone location for the call source - this is the TZ database name from https://en.wikipedia.org/wiki/List_of_tz_database_time_zones Value: !Ref ConversationLocation EntityRecognizerEndpointParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-EntityRecognizerEndpoint + Name: EntityRecognizerEndpoint Type: String - Description: Name of the custom entity recognizer for Amazon Comprehend (not - including language suffix, e.g. -en). If one cannot be found then simple - entity string matching is attempted instead + Description: Name of the custom entity recognizer for Amazon Comprehend (not including language suffix, e.g. -en). If one cannot be found then simple entity string matching is attempted instead Value: !Ref EntityRecognizerEndpoint EntityStringMapParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-EntityStringMap + Name: EntityStringMap Type: String - Description: Basename of a CSV file containing item/Entity maps for when we - don't have data for Comprehend Custom Entities (not including language - suffix, e.g. -en) + Description: Basename of a CSV file containing item/Entity maps for when we don't have data for Comprehend Custom Entities (not including language suffix, e.g. -en) Value: !Ref EntityStringMap EntityThresholdParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-EntityThreshold + Name: EntityThreshold Type: String Description: Confidence threshold where we accept the custom entity detection result Value: !Ref EntityThreshold EntityTypesParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-EntityTypes + Name: EntityTypes Type: String - Description: Entity types supported by Comprehend's standard entity detection, - separated by " | " + Description: Entity types supported by Comprehend's standard entity detection, separated by " | " Value: !Ref EntityTypes InputBucketAudioPlaybackParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-InputBucketAudioPlayback + Name: InputBucketAudioPlayback Type: String - Description: Folder that holds the audio to playback in the browser when - original audio cannot be used + Description: Folder that holds the audio to playback in the browser when original audio cannot be used Value: !Ref InputBucketAudioPlayback InputBucketFailedTranscriptionsParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-InputBucketFailedTranscriptions + Name: InputBucketFailedTranscriptions Type: String Description: Folder that holds audio files that for some reason failed transcription Value: !Ref InputBucketFailedTranscriptions InputBucketNameParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-InputBucketName + Name: InputBucketName Type: String Description: Bucket where where audio files are delivered Value: !Ref InputBucketName InputBucketRawAudioParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-InputBucketRawAudio + Name: InputBucketRawAudio Type: String Description: Folder that holds the original call audio to be ingested Value: !Ref InputBucketRawAudio InputBucketOrigTranscriptsParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-InputBucketOrigTranscripts + Name: InputBucketOrigTranscripts Type: String - Description: | - Folder that holds Transcripts from other applications (e.g. Live Call Analytics) that are to be processed as if PCA had processed that audio + Description: > + Folder that holds Transcripts from other applications (e.g. Live Call Analytics) that are to be + processed as if PCA had processed that audio Value: !Ref InputBucketOrigTranscripts MaxSpeakersParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-MaxSpeakers + Name: MaxSpeakers Type: String Description: Maximum number of speakers that are expected on a call Value: !Ref MaxSpeakers MinSentimentNegativeParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-MinSentimentNegative + Name: MinSentimentNegative Type: String - Description: Minimum sentiment level required to declare a phrase as having - negative sentiment + Description: Minimum sentiment level required to declare a phrase as having negative sentiment Value: !Ref MinSentimentNegative MinSentimentPositiveParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-MinSentimentPositive + Name: MinSentimentPositive Type: String - Description: Minimum sentiment level required to declare a phrase as having - positive sentiment + Description: Minimum sentiment level required to declare a phrase as having positive sentiment Value: !Ref MinSentimentPositive OutputBucketNameParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-OutputBucketName + Name: OutputBucketName Type: String Description: Bucket where Transcribe output files are delivered Value: !Ref OutputBucketName OutputBucketTranscribeResultsParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-OutputBucketTranscribeResults + Name: OutputBucketTranscribeResults Type: String Description: Folder within the output S3 bucket where Transcribe results are written - Value: !Ref OutputBucketTranscribeResults + Value: !Ref OutputBucketTranscribeResults OutputBucketParsedResultsParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-OutputBucketParsedResults + Name: OutputBucketParsedResults Type: String Description: Folder within the output S3 bucket where parsed results are written Value: !Ref OutputBucketParsedResults SpeakerNamesParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-SpeakerNames + Name: SpeakerNames Type: String Description: Default tags used for speaker names, separated by " | " Value: !Ref SpeakerNames SpeakerSeparationTypeParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-SpeakerSeparationType + Name: SpeakerSeparationType Type: String - Description: Separation mode for speakers, either explicitly Speaker or Channel, - or Auto where audio stereo=>Channel and mono=>Speaker + Description: Separation mode for speakers, either explicitly Speaker or Channel, or Auto where audio stereo=>Channel and mono=>Speaker Value: !Ref SpeakerSeparationType StepFunctionNameParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-StepFunctionName + Name: StepFunctionName Type: String Description: Name of Step Functions workflow that orchestrates this process - Value: !Sub ${StackName}-${StepFunctionName} + Value: !Ref StepFunctionName BulkUploadStepFunctionNameParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-BulkUploadStepFunctionName + Name: BulkUploadStepFunctionName Type: String Description: Name of Step Functions workflow that orchestrates the bulk import process - Value: !Sub ${StackName}-${BulkUploadStepFunctionName} - + Value: !Ref BulkUploadStepFunctionName + SupportFilesBucketNameParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-SupportFilesBucketName + Name: SupportFilesBucketName Type: String - Description: Bucket that hold supporting files, such as the file-based entity - recognition mapping files + Description: Bucket that hold supporting files, such as the file-based entity recognition mapping files Value: !Ref SupportFilesBucketName TranscribeApiModeParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-TranscribeApiMode + Name: TranscribeApiMode Type: String - Description: Specifies which Transcribe API to use for new jobs - must be - standard or analytics + Description: Specifies which Transcribe API to use for new jobs - must be standard or analytics Value: !Ref TranscribeApiMode TelephonyCTRTypeParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-TelephonyCTRType + Name: TelephonyCTRType Type: String - Description: Type of telephony system that will deliver Contact Trace Record - files along with the audio recordings + Description: Type of telephony system that will deliver Contact Trace Record files along with the audio recordings Value: !Ref TelephonyCTRType TelephonyCTRFileSuffixParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-TelephonyCTRFileSuffix + Name: TelephonyCTRFileSuffix Type: String - Description: | - File name suffixes for the CTR file(s) associated with the chosen telephony type, separated by " | ". For Genesys, this needs two entries: one for the conversation CTR file, and one for the call-specific file. Other telephony systems may need fewer or additional entries, please consult the documentation.rdings + Description: > + File name suffixes for the CTR file(s) associated with the chosen telephony type, separated by " | ". + For Genesys, this needs two entries: one for the conversation CTR file, and one for the call-specific file. + Other telephony systems may need fewer or additional entries, please consult the documentation.rdings Value: !Ref TelephonyCTRFileSuffix CallRedactionTranscriptParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-CallRedactionTranscript + Name: CallRedactionTranscript Type: String Description: Enable or disable Transcribe's redaction feature Value: !Ref CallRedactionTranscript CallRedactionAudioParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-CallRedactionAudio + Name: CallRedactionAudio Type: String - Description: When transcript redaction is enabled in Call Analytics, only allow - playback of the redacted audio + Description: When transcript redaction is enabled in Call Analytics, only allow playback of the redacted audio Value: !Ref CallRedactionAudio TranscribeLanguagesParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-TranscribeLanguages + Name: TranscribeLanguages Type: String - Description: Language to be used for Transcription - multiple entries separated - by " | " will trigger Language Detection + Description: Language to be used for Transcription - multiple entries separated by " | " will trigger Language Detection Value: !Ref TranscribeLanguages VocabFilterModeParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-VocabFilterMode + Name: VocabFilterMode Type: String - Description: The mode to use for vocabulary filtering - must be one of mask or - remove (tag is not supported) + Description: The mode to use for vocabulary filtering - must be one of mask or remove (tag is not supported) Value: !Ref VocabFilterMode VocabFilterNameParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-VocabFilterName + Name: VocabFilterName Type: String - Description: Name of the vocabulary filter to use for Transcribe (not including - language suffix, e.g. -en-US) + Description: Name of the vocabulary filter to use for Transcribe (not including language suffix, e.g. -en-US) Value: !Ref VocabFilterName VocabularyNameParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-VocabularyName + Name: VocabularyName Type: String - Description: Name of the custom vocabulary to use for Transcribe (not including - language suffix, e.g. -en-US) + Description: Name of the custom vocabulary to use for Transcribe (not including language suffix, e.g. -en-US) Value: !Ref VocabularyName CustomLangModelNameParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-CustomLangModelName + Name: CustomLangModelName Type: String - Description: Name of the custom language model to use for Transcribe (omit the - language suffix, e.g. -en-US) + Description: Name of the custom language model to use for Transcribe (omit the language suffix, e.g. -en-US) Value: !Ref CustomLangModelName FilenameDatetimeRegexParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-FilenameDatetimeRegex + Name: FilenameDatetimeRegex Type: String Value: !Ref FilenameDatetimeRegex - Description: | - Regular Expression (regex) used to parse call Date/Time from audio filenames. Each datetime field (year, month, etc.) must be matched using a separate parenthesized group in the regex. Example: the regex '(\d{2}).(\d{2}).(\d{2}).(\d{3})-(\d{2})-(\d{2})-(\d{4})' parses the filename: CallAudioFile-09.25.51.067-09-26-2019.wav into a value list: [09, 25, 51, 067, 09, 26, 2019] The next parameter, FilenameDatetimeFieldMap, maps the values to datetime field codes. If the filename doesn't match the regex pattern, the current time is used as the call timestamp. + Description: > + Regular Expression (regex) used to parse call Date/Time from audio filenames. + Each datetime field (year, month, etc.) must be matched using a separate parenthesized group in the regex. + Example: the regex '(\d{2}).(\d{2}).(\d{2}).(\d{3})-(\d{2})-(\d{2})-(\d{4})' parses + the filename: CallAudioFile-09.25.51.067-09-26-2019.wav into a value list: [09, 25, 51, 067, 09, 26, 2019] + The next parameter, FilenameDatetimeFieldMap, maps the values to datetime field codes. + If the filename doesn't match the regex pattern, the current time is used as the call timestamp. FilenameDatetimeFieldMapParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-FilenameDatetimeFieldMap + Name: FilenameDatetimeFieldMap Type: String Value: !Ref FilenameDatetimeFieldMap - Description: | - Space separated ordered sequence of time field codes as used by Python's datetime.strptime() function. Each field code refers to a corresponding value parsed by the regex parameter filenameTimestampRegex. Example: the mapping '%H %M %S %f %m %d %Y' assembles the regex output values [09, 25, 51, 067, 09, 26, 2019] into the full datetime: '2019-09-26 09:25:51.067000'. If the field map doesn't match the value list parsed by the regex, then the current time is used as the call timestamp. + Description: > + Space separated ordered sequence of time field codes as used by Python's datetime.strptime() function. + Each field code refers to a corresponding value parsed by the regex parameter filenameTimestampRegex. + Example: the mapping '%H %M %S %f %m %d %Y' assembles the regex output values [09, 25, 51, 067, 09, 26, 2019] + into the full datetime: '2019-09-26 09:25:51.067000'. + If the field map doesn't match the value list parsed by the regex, then the current time is used as the call timestamp. FilenameGUIDRegexParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-FilenameGUIDRegex + Name: FilenameGUIDRegex Type: String Value: !Ref FilenameGUIDRegex - Description: | - Regular Expression (regex) used to parse call GUID from audio filenames. The GUID value must be matched using one or more parenthesized groups in the regex. Example: the regex '_GUID_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the GUID value '2a602c1a-4ca3-4d37-a933-444d575c0222'. + Description: > + Regular Expression (regex) used to parse call GUID from audio filenames. + The GUID value must be matched using one or more parenthesized groups in the regex. + Example: the regex '_GUID_(.*?)_' parses + the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav + to extract the GUID value '2a602c1a-4ca3-4d37-a933-444d575c0222'. FilenameAgentRegexParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-FilenameAgentRegex + Name: FilenameAgentRegex Type: String Value: !Ref FilenameAgentRegex - Description: | - Regular Expression (regex) used to parse call AGENT from audio filenames. The AGENT value must be matched using one or more parenthesized groups in the regex. Example: the regex '_AGENT_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the AGENT value 'BobS'. + Description: > + Regular Expression (regex) used to parse call AGENT from audio filenames. + The AGENT value must be matched using one or more parenthesized groups in the regex. + Example: the regex '_AGENT_(.*?)_' parses + the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav + to extract the AGENT value 'BobS'. FilenameCustRegexParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-FilenameCustRegex + Name: FilenameCustRegex Type: String Value: !Ref FilenameCustRegex - Description: | - Regular Expression (regex) used to parse Customer from audio filenames. The customer id value must be matched using one or more parenthesized groups in the regex. Example: the regex '_CUST_(.*?)_' parses the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav to extract the Customer value '12345'. + Description: > + Regular Expression (regex) used to parse Customer from audio filenames. + The customer id value must be matched using one or more parenthesized groups in the regex. + Example: the regex '_CUST_(.*?)_' parses + the filename: AutoRepairs1_CUST_12345_GUID_2a602c1a-4ca3-4d37-a933-444d575c0222_AGENT_BobS_DATETIME_07.55.51.067-09-16-2021.wav + to extract the Customer value '12345'. KendraIndexIdParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-KendraIndexId + Name: KendraIndexId Type: String Value: !Ref KendraIndexId - Description: Kendra Index ID, or empty string if call transcription indexing is - not enabled - + Description: Kendra Index ID, or empty string if call transcription indexing is not enabled + #WebUriParameter: # Type: "AWS::SSM::Parameter" # Properties: - # Name: !Sub '${StackName}-WebUri' + # Name: WebUri # Type: String # Value: !Ref WebUri # Description: PCA Web Application URI DatabaseNameParameter: - Type: AWS::SSM::Parameter + Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${StackName}-DatabaseName + Name: DatabaseName Type: String Value: !Ref DatabaseName - Description: PCA Glue catalog database name \ No newline at end of file + Description: PCA Glue catalog database name diff --git a/pca-ui/cfn/pca-ui.template b/pca-ui/cfn/pca-ui.template index 00cfeb9b..094bb9cb 100644 --- a/pca-ui/cfn/pca-ui.template +++ b/pca-ui/cfn/pca-ui.template @@ -3,10 +3,6 @@ AWSTemplateFormatVersion: "2010-09-09" Description: Amazon Transcribe Post Call Analytics - PCA UI Parameters: - ParentStackName: - Type: String - Description: Name of the parent stack - AdminUsername: Type: String Default: "admin" @@ -205,7 +201,7 @@ Resources: WebUriParameter: Type: "AWS::SSM::Parameter" Properties: - Name: !Sub ${ParentStackName}-WebUiUri + Name: WebUiUri Type: String Value: !GetAtt Web.Outputs.Uri Description: PCA Web Application URI From ca446391b06f831eccdb4637ff6a536702b68bee Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Tue, 18 Feb 2025 17:45:13 -0600 Subject: [PATCH 08/22] Glue Database Paramater allow an empty default and named dynamically, fixed copy samples SSM issue --- pca-main-nokendra.template | 24 +++++++++++++++---- pca-main.template | 22 +++++++++++++---- pca-samples/copy-samples.template | 29 ++++++++++------------- pca-server/cfn/lib/glue-database.template | 20 ++++------------ pca-server/cfn/pca-server.template | 4 +++- 5 files changed, 58 insertions(+), 41 deletions(-) diff --git a/pca-main-nokendra.template b/pca-main-nokendra.template index 02e9a1bb..d3181823 100644 --- a/pca-main-nokendra.template +++ b/pca-main-nokendra.template @@ -352,10 +352,10 @@ Parameters: - PROD Default: PROD - DatabaseName: + GlueDatabaseName: Type: String - AllowedPattern: "[a-zA-Z0-9_-]+" - Description: (Required) Glue catalog database name used to contain tables/views for SQL integration. + AllowedPattern: "^$|[a-z0-9_-]+" + Description: (Optional) Glue catalog database name in lowercase characters used to contain tables/views for SQL integration. EnablePcaDashboards: Type: String @@ -495,7 +495,7 @@ Metadata: default: Advanced analytics and reporting Parameters: - EnablePcaDashboards - - DatabaseName + - GlueDatabaseName - Label: default: S3 Bucket Names and Retention Policy Parameters: @@ -574,6 +574,7 @@ Conditions: ShouldCreateInputBucket: !Equals [!Ref InputBucketName, ''] ShouldCreateOutputBucket: !Equals [!Ref OutputBucketName, ''] ShouldCreateSupportFilesBucket: !Equals [!Ref SupportFilesBucketName, ''] + ShouldCreateDatabase: !Equals [!Ref GlueDatabaseName, ''] ShouldEnableGui: !Not [!Equals [!Ref EnableGui, false]] ShouldEnableKendraSearch: !Not [!Equals [!Ref EnableTranscriptKendraSearch, 'No']] ShouldCreateKendraIndexDeveloperEdition: !Equals [!Ref EnableTranscriptKendraSearch, 'Yes, create new Kendra Index (Developer Edition)'] @@ -673,6 +674,19 @@ Resources: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 + ######################################################## + # Glue Database + ######################################################## + + DatabaseName: + Condition: ShouldCreateDatabase + Type: AWS::Glue::Database + Properties: + CatalogId: !Ref AWS::AccountId + DatabaseInput: + Description: Post Call Analytics + LocationUri: !Sub 's3://${OutputBucket}/${OutputBucketParsedResults}/' + ######################################################## # If Bedrock Models are selected, verify that Bedrock # is available in the region, and that models are enabled @@ -845,6 +859,7 @@ Resources: SSM: Type: AWS::CloudFormation::Stack DependsOn: LLMPromptConfigure + Condition: ShouldCreateDatabase Properties: TemplateURL: pca-ssm/cfn/ssm.template Parameters: @@ -1029,6 +1044,7 @@ Resources: Properties: TemplateURL: pca-samples/copy-samples.template Parameters: + ParentStackName: !Ref 'AWS::StackName' DependsOnPCAServer: !Ref PCAServer DependsOnPCAUI: !If [ShouldEnableGui, !Ref PCAUI, !Ref AWS::NoValue] DependsOnPCADashboards: !If diff --git a/pca-main.template b/pca-main.template index 504a4a41..32850e8d 100644 --- a/pca-main.template +++ b/pca-main.template @@ -393,10 +393,10 @@ Parameters: - PROD Default: PROD - DatabaseName: + GlueDatabaseName: Type: String - AllowedPattern: "[a-zA-Z0-9_-]+" - Description: (Required) Glue catalog database name used to contain tables/views for SQL integration. + AllowedPattern: "^$|[a-z0-9_-]+" + Description: (Optional) Glue catalog database name in lowercase characters used to contain tables/views for SQL integration. EnablePcaDashboards: Type: String @@ -536,7 +536,7 @@ Metadata: default: Advanced analytics and reporting Parameters: - EnablePcaDashboards - - DatabaseName + - GlueDatabaseName - Label: default: S3 Bucket Names and Retention Policy Parameters: @@ -615,6 +615,7 @@ Conditions: ShouldCreateInputBucket: !Equals [!Ref InputBucketName, ''] ShouldCreateOutputBucket: !Equals [!Ref OutputBucketName, ''] ShouldCreateSupportFilesBucket: !Equals [!Ref SupportFilesBucketName, ''] + ShouldCreateDatabase: !Equals [!Ref GlueDatabaseName, ''] ShouldEnableGui: !Not [!Equals [!Ref EnableGui, "false"]] ShouldEnableKendraSearch: !Not [!Equals [!Ref EnableTranscriptKendraSearch, 'No']] ShouldCreateKendraIndexDeveloperEdition: !Equals [!Ref EnableTranscriptKendraSearch, 'Yes, create new Kendra Index (Developer Edition)'] @@ -721,6 +722,19 @@ Resources: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 + ######################################################## + # Glue Database + ######################################################## + + DatabaseName: + Condition: ShouldCreateDatabase + Type: AWS::Glue::Database + Properties: + CatalogId: !Ref AWS::AccountId + DatabaseInput: + Description: Post Call Analytics + LocationUri: !Sub 's3://${OutputBucket}/${OutputBucketParsedResults}/' + ######################################################## # Kendra Index ######################################################## diff --git a/pca-samples/copy-samples.template b/pca-samples/copy-samples.template index b8aec154..427f19a2 100644 --- a/pca-samples/copy-samples.template +++ b/pca-samples/copy-samples.template @@ -5,18 +5,9 @@ Description: Amazon Transcribe Post Call Analytics - PCA Server - Load sample au Transform: AWS::Serverless-2016-10-31 Parameters: - - SupportFilesBucketName: - Type: AWS::SSM::Parameter::Value - Default: SupportFilesBucketName - - InputBucketName: - Type: AWS::SSM::Parameter::Value - Default: InputBucketName - - InputBucketRawAudio: - Type: AWS::SSM::Parameter::Value - Default: InputBucketRawAudio + ParentStackName: + Type: String + Description: Name of the parent stack # DependsOn parameters used only to force conditional dependency from main stack DependsOnPCAServer: @@ -57,8 +48,12 @@ Resources: Action: - s3:PutObject Resource: - - !Sub arn:aws:s3:::${InputBucketName}/* - - !Sub arn:aws:s3:::${SupportFilesBucketName}/* + - !Sub + - 'arn:aws:s3:::${bucket}/*' + - bucket: !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + - !Sub + - 'arn:aws:s3:::${bucket}/*' + - bucket: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' CopySamplesFunction: @@ -71,9 +66,9 @@ Resources: Role: !GetAtt CopySamplesRole.Arn Environment: Variables: - SUPPORTFILES_BUCKET_NAME: !Ref SupportFilesBucketName - INPUT_BUCKET_NAME: !Ref InputBucketName - INPUT_BUCKET_RAW_AUDIO: !Ref InputBucketRawAudio + SUPPORTFILES_BUCKET_NAME: !Sub '{{resolve:ssm:${ParentStackName}-SupportFilesBucketName}}' + INPUT_BUCKET_NAME: !Sub '{{resolve:ssm:${ParentStackName}-InputBucketName}}' + INPUT_BUCKET_RAW_AUDIO: !Sub '{{resolve:ssm:${ParentStackName}-InputBucketRawAudio}}' CopySamples: Type: "AWS::CloudFormation::CustomResource" diff --git a/pca-server/cfn/lib/glue-database.template b/pca-server/cfn/lib/glue-database.template index d2752746..e934c712 100644 --- a/pca-server/cfn/lib/glue-database.template +++ b/pca-server/cfn/lib/glue-database.template @@ -9,22 +9,12 @@ Parameters: Type: String Description: Name of the parent stack -Resources: - Database: - Type: AWS::Glue::Database - Properties: - CatalogId: !Ref AWS::AccountId - DatabaseInput: - Description: Post Call Analytics - LocationUri: !Join - - '' - - - 's3://' - - !Sub '{{resolve:ssm:${ParentStackName}-OutputBucketName}}' - - '/' - - !Sub '{{resolve:ssm:${ParentStackName}-OutputBucketParsedResults}}' - - '/' - Name: !Sub "{{resolve:ssm:${ParentStackName}-DatabaseName}}" + Type: String + Description: Glue catalog database name used to contain tables/views for SQL + integration. + +Resources: ParsedResultsTable: Type: AWS::Glue::Table diff --git a/pca-server/cfn/pca-server.template b/pca-server/cfn/pca-server.template index 5f64bb70..d73a0869 100644 --- a/pca-server/cfn/pca-server.template +++ b/pca-server/cfn/pca-server.template @@ -9,7 +9,8 @@ Parameters: DatabaseName: Type: String - Description: Glue catalog database name used to contain tables/views for SQL integration. + Description: Glue catalog database name used to contain tables/views for SQL + integration. ffmpegDownloadUrl: Type: String @@ -174,6 +175,7 @@ Resources: TemplateURL: lib/glue-database.template Parameters: ParentStackName: !Ref ParentStackName + Database: !Ref DatabaseName ########################################################################## From 33068ea84b1cfbda924da0426d8aa5d5bea08918 Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Tue, 18 Feb 2025 17:50:05 -0600 Subject: [PATCH 09/22] Glue Database Paramater allow an empty default and named dynamically, fixed copy samples SSM issue --- pca-main-nokendra.template | 1 - 1 file changed, 1 deletion(-) diff --git a/pca-main-nokendra.template b/pca-main-nokendra.template index d3181823..4aa1e9eb 100644 --- a/pca-main-nokendra.template +++ b/pca-main-nokendra.template @@ -859,7 +859,6 @@ Resources: SSM: Type: AWS::CloudFormation::Stack DependsOn: LLMPromptConfigure - Condition: ShouldCreateDatabase Properties: TemplateURL: pca-ssm/cfn/ssm.template Parameters: From 4b86beeda5ded45f191615557b755c29723fb69f Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Tue, 18 Feb 2025 18:37:11 -0600 Subject: [PATCH 10/22] Glue Database Paramater allow an empty default and named dynamically, fixed copy samples SSM issue --- pca-main-nokendra.template | 13 +++++++------ pca-main.template | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/pca-main-nokendra.template b/pca-main-nokendra.template index 4aa1e9eb..40622b70 100644 --- a/pca-main-nokendra.template +++ b/pca-main-nokendra.template @@ -574,7 +574,7 @@ Conditions: ShouldCreateInputBucket: !Equals [!Ref InputBucketName, ''] ShouldCreateOutputBucket: !Equals [!Ref OutputBucketName, ''] ShouldCreateSupportFilesBucket: !Equals [!Ref SupportFilesBucketName, ''] - ShouldCreateDatabase: !Equals [!Ref GlueDatabaseName, ''] + #ShouldCreateDatabase: !Equals [!Ref GlueDatabaseName, ''] ShouldEnableGui: !Not [!Equals [!Ref EnableGui, false]] ShouldEnableKendraSearch: !Not [!Equals [!Ref EnableTranscriptKendraSearch, 'No']] ShouldCreateKendraIndexDeveloperEdition: !Equals [!Ref EnableTranscriptKendraSearch, 'Yes, create new Kendra Index (Developer Edition)'] @@ -678,12 +678,13 @@ Resources: # Glue Database ######################################################## - DatabaseName: - Condition: ShouldCreateDatabase + GlueDatabase: + #Condition: ShouldCreateDatabase Type: AWS::Glue::Database Properties: CatalogId: !Ref AWS::AccountId DatabaseInput: + Name: !Ref GlueDatabaseName Description: Post Call Analytics LocationUri: !Sub 's3://${OutputBucket}/${OutputBucketParsedResults}/' @@ -926,7 +927,7 @@ Resources: - 'None' - 'None' # WebUri: !GetAtt PCAUI.Outputs.WebUri - DatabaseName: !Ref DatabaseName + DatabaseName: !Ref GlueDatabase PythonUtilsLayer: DependsOn: SSM @@ -961,7 +962,7 @@ Resources: Properties: TemplateURL: pca-server/cfn/pca-server.template Parameters: - DatabaseName: !Ref DatabaseName + DatabaseName: !Ref GlueDatabase ParentStackName: !Ref 'AWS::StackName' ffmpegDownloadUrl: !Ref ffmpegDownloadUrl CallSummarization: !Ref CallSummarization @@ -1025,7 +1026,7 @@ Resources: Properties: TemplateURL: build/pca-dashboards.yaml Parameters: - PcaGlueCatalogDatabaseName: !Ref DatabaseName + PcaGlueCatalogDatabaseName: !Ref GlueDatabase PcaOutputBucket: !If - ShouldCreateOutputBucket diff --git a/pca-main.template b/pca-main.template index 32850e8d..45ca4e59 100644 --- a/pca-main.template +++ b/pca-main.template @@ -726,7 +726,7 @@ Resources: # Glue Database ######################################################## - DatabaseName: + GlueDatabase: Condition: ShouldCreateDatabase Type: AWS::Glue::Database Properties: @@ -1110,7 +1110,7 @@ Resources: - !Ref KendraIndex - 'None' # WebUri: !GetAtt PCAUI.Outputs.WebUri - DatabaseName: !Ref DatabaseName + DatabaseName: !Ref GlueDatabase PythonUtilsLayer: DependsOn: SSM @@ -1145,7 +1145,7 @@ Resources: Properties: TemplateURL: pca-server/cfn/pca-server.template Parameters: - DatabaseName: !Ref DatabaseName + DatabaseName: !Ref GlueDatabase ParentStackName: !Ref 'AWS::StackName' ffmpegDownloadUrl: !Ref ffmpegDownloadUrl CallSummarization: !Ref CallSummarization @@ -1224,7 +1224,7 @@ Resources: Properties: TemplateURL: build/pca-dashboards.yaml Parameters: - PcaGlueCatalogDatabaseName: !Ref DatabaseName + PcaGlueCatalogDatabaseName: !Ref GlueDatabase PcaOutputBucket: !If - ShouldCreateOutputBucket From bb0d33e9b41eea4336ff9a5d6653caa363dcbc5c Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Tue, 18 Feb 2025 18:47:57 -0600 Subject: [PATCH 11/22] Glue Database Paramater allow an empty default and named dynamically, fixed copy samples SSM issue --- pca-main-nokendra.template | 1 - 1 file changed, 1 deletion(-) diff --git a/pca-main-nokendra.template b/pca-main-nokendra.template index 40622b70..d3601fae 100644 --- a/pca-main-nokendra.template +++ b/pca-main-nokendra.template @@ -574,7 +574,6 @@ Conditions: ShouldCreateInputBucket: !Equals [!Ref InputBucketName, ''] ShouldCreateOutputBucket: !Equals [!Ref OutputBucketName, ''] ShouldCreateSupportFilesBucket: !Equals [!Ref SupportFilesBucketName, ''] - #ShouldCreateDatabase: !Equals [!Ref GlueDatabaseName, ''] ShouldEnableGui: !Not [!Equals [!Ref EnableGui, false]] ShouldEnableKendraSearch: !Not [!Equals [!Ref EnableTranscriptKendraSearch, 'No']] ShouldCreateKendraIndexDeveloperEdition: !Equals [!Ref EnableTranscriptKendraSearch, 'Yes, create new Kendra Index (Developer Edition)'] From 0a23361adeaadd30367950fc1f3efc6af9aaad3a Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Tue, 18 Feb 2025 18:52:52 -0600 Subject: [PATCH 12/22] Glue Database Paramater allow an empty default and named dynamically, fixed copy samples SSM issue --- pca-main-nokendra.template | 8 ++++---- pca-main.template | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pca-main-nokendra.template b/pca-main-nokendra.template index d3601fae..fac4dfdd 100644 --- a/pca-main-nokendra.template +++ b/pca-main-nokendra.template @@ -677,7 +677,7 @@ Resources: # Glue Database ######################################################## - GlueDatabase: + PCADatabase: #Condition: ShouldCreateDatabase Type: AWS::Glue::Database Properties: @@ -926,7 +926,7 @@ Resources: - 'None' - 'None' # WebUri: !GetAtt PCAUI.Outputs.WebUri - DatabaseName: !Ref GlueDatabase + DatabaseName: !Ref PCADatabase PythonUtilsLayer: DependsOn: SSM @@ -961,7 +961,7 @@ Resources: Properties: TemplateURL: pca-server/cfn/pca-server.template Parameters: - DatabaseName: !Ref GlueDatabase + DatabaseName: !Ref PCADatabase ParentStackName: !Ref 'AWS::StackName' ffmpegDownloadUrl: !Ref ffmpegDownloadUrl CallSummarization: !Ref CallSummarization @@ -1025,7 +1025,7 @@ Resources: Properties: TemplateURL: build/pca-dashboards.yaml Parameters: - PcaGlueCatalogDatabaseName: !Ref GlueDatabase + PcaGlueCatalogDatabaseName: !Ref PCADatabase PcaOutputBucket: !If - ShouldCreateOutputBucket diff --git a/pca-main.template b/pca-main.template index 45ca4e59..a9d9351e 100644 --- a/pca-main.template +++ b/pca-main.template @@ -726,7 +726,7 @@ Resources: # Glue Database ######################################################## - GlueDatabase: + PCADatabase: Condition: ShouldCreateDatabase Type: AWS::Glue::Database Properties: @@ -1110,7 +1110,7 @@ Resources: - !Ref KendraIndex - 'None' # WebUri: !GetAtt PCAUI.Outputs.WebUri - DatabaseName: !Ref GlueDatabase + DatabaseName: !Ref PCADatabase PythonUtilsLayer: DependsOn: SSM @@ -1145,7 +1145,7 @@ Resources: Properties: TemplateURL: pca-server/cfn/pca-server.template Parameters: - DatabaseName: !Ref GlueDatabase + DatabaseName: !Ref PCADatabase ParentStackName: !Ref 'AWS::StackName' ffmpegDownloadUrl: !Ref ffmpegDownloadUrl CallSummarization: !Ref CallSummarization @@ -1224,7 +1224,7 @@ Resources: Properties: TemplateURL: build/pca-dashboards.yaml Parameters: - PcaGlueCatalogDatabaseName: !Ref GlueDatabase + PcaGlueCatalogDatabaseName: !Ref PCADatabase PcaOutputBucket: !If - ShouldCreateOutputBucket From e60f6508a7708cef6d11ad333216b8c8ef020095 Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Tue, 18 Feb 2025 22:28:03 -0600 Subject: [PATCH 13/22] PCADatabase bug fix --- pca-main-nokendra.template | 1 - pca-main.template | 2 -- 2 files changed, 3 deletions(-) diff --git a/pca-main-nokendra.template b/pca-main-nokendra.template index fac4dfdd..9a6e808d 100644 --- a/pca-main-nokendra.template +++ b/pca-main-nokendra.template @@ -678,7 +678,6 @@ Resources: ######################################################## PCADatabase: - #Condition: ShouldCreateDatabase Type: AWS::Glue::Database Properties: CatalogId: !Ref AWS::AccountId diff --git a/pca-main.template b/pca-main.template index a9d9351e..b167ee18 100644 --- a/pca-main.template +++ b/pca-main.template @@ -615,7 +615,6 @@ Conditions: ShouldCreateInputBucket: !Equals [!Ref InputBucketName, ''] ShouldCreateOutputBucket: !Equals [!Ref OutputBucketName, ''] ShouldCreateSupportFilesBucket: !Equals [!Ref SupportFilesBucketName, ''] - ShouldCreateDatabase: !Equals [!Ref GlueDatabaseName, ''] ShouldEnableGui: !Not [!Equals [!Ref EnableGui, "false"]] ShouldEnableKendraSearch: !Not [!Equals [!Ref EnableTranscriptKendraSearch, 'No']] ShouldCreateKendraIndexDeveloperEdition: !Equals [!Ref EnableTranscriptKendraSearch, 'Yes, create new Kendra Index (Developer Edition)'] @@ -727,7 +726,6 @@ Resources: ######################################################## PCADatabase: - Condition: ShouldCreateDatabase Type: AWS::Glue::Database Properties: CatalogId: !Ref AWS::AccountId From c5e7650601c984d764fe4830bd2c1241186d382a Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Tue, 18 Feb 2025 22:30:50 -0600 Subject: [PATCH 14/22] PCADatabase bug fix --- pca-main.template | 1 + 1 file changed, 1 insertion(+) diff --git a/pca-main.template b/pca-main.template index b167ee18..ec5280c4 100644 --- a/pca-main.template +++ b/pca-main.template @@ -730,6 +730,7 @@ Resources: Properties: CatalogId: !Ref AWS::AccountId DatabaseInput: + Name: !Ref GlueDatabaseName Description: Post Call Analytics LocationUri: !Sub 's3://${OutputBucket}/${OutputBucketParsedResults}/' From ad793779489a6b8a5a7459b7e1ba6f8053843300 Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Tue, 18 Feb 2025 22:50:57 -0600 Subject: [PATCH 15/22] Remove unwanted comments --- pca-server/cfn/lib/bulk.template | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/pca-server/cfn/lib/bulk.template b/pca-server/cfn/lib/bulk.template index 09a91048..0451d76c 100644 --- a/pca-server/cfn/lib/bulk.template +++ b/pca-server/cfn/lib/bulk.template @@ -9,18 +9,6 @@ Parameters: Type: String Description: Name of the parent stack -# BulkUploadStepFunctionName: -# Type: AWS::SSM::Parameter::Value -# Default: BulkUploadStepFunctionName - -# BulkUploadBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: BulkUploadBucket - -# InputBucketName: -# Type: AWS::SSM::Parameter::Value -# Default: InputBucketName - Globals: Function: Runtime: python3.11 @@ -50,8 +38,6 @@ Resources: - - 'arn:aws:s3:::' - !Sub '{{resolve:ssm:${ParentStackName}-BulkUploadBucket}}' - '/*' - #- !Sub arn:aws:s3:::${BulkUploadBucketName} - #- !Sub arn:aws:s3:::${BulkUploadBucketName}/* - Statement: - Sid: SSMGetParameterPolicy Effect: Allow From 9ddea82b1a5c21fb83dc95c8aaae27dcc487a9fc Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Tue, 18 Feb 2025 23:00:04 -0600 Subject: [PATCH 16/22] Copy samples fix --- pca-main.template | 1 + 1 file changed, 1 insertion(+) diff --git a/pca-main.template b/pca-main.template index ec5280c4..428e65af 100644 --- a/pca-main.template +++ b/pca-main.template @@ -1241,6 +1241,7 @@ Resources: Properties: TemplateURL: pca-samples/copy-samples.template Parameters: + ParentStackName: !Ref 'AWS::StackName' DependsOnPCAServer: !Ref PCAServer DependsOnPCAUI: !If [ShouldEnableGui, !Ref PCAUI, !Ref AWS::NoValue] DependsOnPCADashboards: !If From 62025d35abd11691b9b3f1cd5984c7c82e8df5d5 Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Wed, 19 Feb 2025 12:04:09 -0600 Subject: [PATCH 17/22] Removed .gitignore from repository --- .gitignore | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index ff377447..00000000 --- a/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# Local development -node_modules -build -/pca-ui/src/www/public/config.js -/sample-data -.vscode -/pca-ui/src/witch/witch.zip -.DS_Store -.idea/ -pca-ssm/.DS_Store From a9cbe370e36dc04cba4f9fc1ca244d099d390344 Mon Sep 17 00:00:00 2001 From: Ola Ola Date: Wed, 19 Feb 2025 12:10:04 -0600 Subject: [PATCH 18/22] Restore .gitignore file --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ff377447 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Local development +node_modules +build +/pca-ui/src/www/public/config.js +/sample-data +.vscode +/pca-ui/src/witch/witch.zip +.DS_Store +.idea/ +pca-ssm/.DS_Store From 08d8649db67c741ef276cd83f1827e38cb69accc Mon Sep 17 00:00:00 2001 From: David Moser Date: Thu, 20 Feb 2025 10:23:13 -0800 Subject: [PATCH 19/22] fixes for SSM Parameter commit --- pca-server/src/pca/pcaconfiguration.py | 90 ++++++++++++++------------ pca-ui/cfn/pca-ui.template | 30 +++++---- 2 files changed, 64 insertions(+), 56 deletions(-) diff --git a/pca-server/src/pca/pcaconfiguration.py b/pca-server/src/pca/pcaconfiguration.py index 47134b2d..7b7b5cf8 100644 --- a/pca-server/src/pca/pcaconfiguration.py +++ b/pca-server/src/pca/pcaconfiguration.py @@ -7,54 +7,58 @@ SPDX-License-Identifier: Apache-2.0 """ import boto3 +import os from botocore.config import Config +# Get the stack name from environment variable +STACK_NAME = os.environ.get('STACK_NAME') + # Parameter Store Field Names used by main workflow -CONF_COMP_LANGS = "ComprehendLanguages" -CONF_REDACTION_LANGS = "ContentRedactionLanguages" -CONF_CONVO_LOCATION = "ConversationLocation" -CONF_ENTITYENDPOINT = "EntityRecognizerEndpoint" -CONF_ENTITY_FILE = "EntityStringMap" -CONF_ENTITYCONF = "EntityThreshold" -CONF_ENTITY_TYPES = "EntityTypes" -CONF_PREFIX_AUDIO_PLAYBACK = "InputBucketAudioPlayback" -CONF_S3BUCKET_INPUT = "InputBucketName" -CONF_PREFIX_RAW_AUDIO = "InputBucketRawAudio" -CONF_PREFIX_FAILED_AUDIO = "InputBucketFailedTranscriptions" -CONF_PREFIX_INPUT_TRANSCRIPTS = "InputBucketOrigTranscripts" -CONF_MAX_SPEAKERS = "MaxSpeakers" -CONF_MINNEGATIVE = "MinSentimentNegative" -CONF_MINPOSITIVE = "MinSentimentPositive" -CONF_S3BUCKET_OUTPUT = "OutputBucketName" -CONF_PREFIX_TRANSCRIBE_RESULTS = "OutputBucketTranscribeResults" -CONF_PREFIX_PARSED_RESULTS = "OutputBucketParsedResults" -CONF_SPEAKER_NAMES = "SpeakerNames" -CONF_SPEAKER_MODE = "SpeakerSeparationType" -COMP_SFN_NAME = "StepFunctionName" -CONF_SUPPORT_BUCKET = "SupportFilesBucketName" -CONF_TRANSCRIBE_LANG = "TranscribeLanguages" -CONF_TELEPHONY_CTR = "TelephonyCTRType" -CONF_TELEPHONY_CTR_SUFFIX = "TelephonyCTRFileSuffix" -CONF_VOCABNAME = "VocabularyName" -CONF_CLMNAME = "CustomLangModelName" -CONF_FILENAME_DATETIME_REGEX = "FilenameDatetimeRegex" -CONF_FILENAME_DATETIME_FIELDMAP = "FilenameDatetimeFieldMap" -CONF_FILENAME_GUID_REGEX = "FilenameGUIDRegex" -CONF_FILENAME_AGENT_REGEX = "FilenameAgentRegex" -CONF_FILENAME_CUST_REGEX = "FilenameCustRegex" -CONF_FILTER_MODE = "VocabFilterMode" -CONF_FILTER_NAME = "VocabFilterName" -CONF_KENDRA_INDEX_ID = "KendraIndexId" -CONF_WEB_URI = "WebUiUri" -CONF_TRANSCRIBE_API = "TranscribeApiMode" -CONF_REDACTION_TRANSCRIPT = "CallRedactionTranscript" -CONF_REDACTION_AUDIO = "CallRedactionAudio" -CONF_CALL_SUMMARIZATION = "CallSummarization" +CONF_COMP_LANGS = f"{STACK_NAME}-ComprehendLanguages" +CONF_REDACTION_LANGS = f"{STACK_NAME}-ContentRedactionLanguages" +CONF_CONVO_LOCATION = f"{STACK_NAME}-ConversationLocation" +CONF_ENTITYENDPOINT = f"{STACK_NAME}-EntityRecognizerEndpoint" +CONF_ENTITY_FILE = f"{STACK_NAME}-EntityStringMap" +CONF_ENTITYCONF = f"{STACK_NAME}-EntityThreshold" +CONF_ENTITY_TYPES = f"{STACK_NAME}-EntityTypes" +CONF_PREFIX_AUDIO_PLAYBACK = f"{STACK_NAME}-InputBucketAudioPlayback" +CONF_S3BUCKET_INPUT = f"{STACK_NAME}-InputBucketName" +CONF_PREFIX_RAW_AUDIO = f"{STACK_NAME}-InputBucketRawAudio" +CONF_PREFIX_FAILED_AUDIO = f"{STACK_NAME}-InputBucketFailedTranscriptions" +CONF_PREFIX_INPUT_TRANSCRIPTS = f"{STACK_NAME}-InputBucketOrigTranscripts" +CONF_MAX_SPEAKERS = f"{STACK_NAME}-MaxSpeakers" +CONF_MINNEGATIVE = f"{STACK_NAME}-MinSentimentNegative" +CONF_MINPOSITIVE = f"{STACK_NAME}-MinSentimentPositive" +CONF_S3BUCKET_OUTPUT = f"{STACK_NAME}-OutputBucketName" +CONF_PREFIX_TRANSCRIBE_RESULTS = f"{STACK_NAME}-OutputBucketTranscribeResults" +CONF_PREFIX_PARSED_RESULTS = f"{STACK_NAME}-OutputBucketParsedResults" +CONF_SPEAKER_NAMES = f"{STACK_NAME}-SpeakerNames" +CONF_SPEAKER_MODE = f"{STACK_NAME}-SpeakerSeparationType" +COMP_SFN_NAME = f"{STACK_NAME}-StepFunctionName" +CONF_SUPPORT_BUCKET = f"{STACK_NAME}-SupportFilesBucketName" +CONF_TRANSCRIBE_LANG = f"{STACK_NAME}-TranscribeLanguages" +CONF_TELEPHONY_CTR = f"{STACK_NAME}-TelephonyCTRType" +CONF_TELEPHONY_CTR_SUFFIX = f"{STACK_NAME}-TelephonyCTRFileSuffix" +CONF_VOCABNAME = f"{STACK_NAME}-VocabularyName" +CONF_CLMNAME = f"{STACK_NAME}-CustomLangModelName" +CONF_FILENAME_DATETIME_REGEX = f"{STACK_NAME}-FilenameDatetimeRegex" +CONF_FILENAME_DATETIME_FIELDMAP = f"{STACK_NAME}-FilenameDatetimeFieldMap" +CONF_FILENAME_GUID_REGEX = f"{STACK_NAME}-FilenameGUIDRegex" +CONF_FILENAME_AGENT_REGEX = f"{STACK_NAME}-FilenameAgentRegex" +CONF_FILENAME_CUST_REGEX = f"{STACK_NAME}-FilenameCustRegex" +CONF_FILTER_MODE = f"{STACK_NAME}-VocabFilterMode" +CONF_FILTER_NAME = f"{STACK_NAME}-VocabFilterName" +CONF_KENDRA_INDEX_ID = f"{STACK_NAME}-KendraIndexId" +CONF_WEB_URI = f"{STACK_NAME}-WebUiUri" +CONF_TRANSCRIBE_API = f"{STACK_NAME}-TranscribeApiMode" +CONF_REDACTION_TRANSCRIPT = f"{STACK_NAME}-CallRedactionTranscript" +CONF_REDACTION_AUDIO = f"{STACK_NAME}-CallRedactionAudio" +CONF_CALL_SUMMARIZATION = f"{STACK_NAME}-CallSummarization" # Parameter store fieldnames used by bulk import -BULK_S3_BUCKET = "BulkUploadBucket" -BULK_JOB_LIMIT = "BulkUploadMaxTranscribeJobs" -BULK_MAX_DRIP_RATE = "BulkUploadMaxDripRate" +BULK_S3_BUCKET = f"{STACK_NAME}-BulkUploadBucket" +BULK_JOB_LIMIT = f"{STACK_NAME}-BulkUploadMaxTranscribeJobs" +BULK_MAX_DRIP_RATE = f"{STACK_NAME}-BulkUploadMaxDripRate" # Transcribe API Modes API_STANDARD = "standard" diff --git a/pca-ui/cfn/pca-ui.template b/pca-ui/cfn/pca-ui.template index 094bb9cb..14ff32b2 100644 --- a/pca-ui/cfn/pca-ui.template +++ b/pca-ui/cfn/pca-ui.template @@ -3,18 +3,22 @@ AWSTemplateFormatVersion: "2010-09-09" Description: Amazon Transcribe Post Call Analytics - PCA UI Parameters: + ParentStackName: + Type: String + Description: Name of the parent stack + AdminUsername: Type: String Default: "admin" Description: (Required) Username for admin user - + AdminEmail: - Type: String - Description: >- - (Required) Email address for the admin user. Will be used for logging in and for setting the admin password. - This email will receive the temporary password for the admin user. - AllowedPattern: ".+\\@.+\\..+" - ConstraintDescription: Must be valid email address eg. johndoe@example.com + Type: String + Description: >- + (Required) Email address for the admin user. Will be used for logging in and for setting the admin password. + This email will receive the temporary password for the admin user. + AllowedPattern: ".+\\@.+\\..+" + ConstraintDescription: Must be valid email address eg. johndoe@example.com AllowedSignUpEmailDomain: Type: String @@ -26,7 +30,7 @@ Parameters: If left empty, signup via the web UI is disabled and users will have to be created using Cognito. - AllowedPattern: '^(\*||([\w-]+\.)+[\w-]{2,6}(, *([\w-]+\.)+[\w-]{2,6})*)$' + AllowedPattern: '^(\*||([\w-]+\.)+[\w-]{2,6}(, *([\w-]+\.)+[\w-]{2,6})*)$' AudioBucket: Type: String @@ -64,7 +68,7 @@ Parameters: - 'LAMBDA' - 'ANTHROPIC' Description: This is what model to use for GenAIQuery. - + GenAIQueryBedrockModelId: Type: String Default: anthropic.claude-3-haiku-20240307-v1:0 @@ -97,7 +101,7 @@ Parameters: Default: '' Type: String Description: External Boto3 Layer Arn to use. If none is provided, one will be created automatically via boto3.template - + PyUtilsLayerArn: Default: '' Type: String @@ -143,7 +147,7 @@ Resources: AllowedSignUpEmailDomain: !Ref AllowedSignUpEmailDomain WebUri: !GetAtt Web.Outputs.Uri Environment: !Ref Environment - Name: + Name: !If - isMainStackNameEmpty - !Ref AWS::StackName @@ -193,7 +197,7 @@ Resources: DeployCountName: !Ref DeployCount DeployCountValue: !Ref DeployCount # DistributionId: !GetAtt Web.Outputs.DistributionId - EnableGenAIQuery: !If + EnableGenAIQuery: !If - ShouldEnableGenAIQuery - 'true' - 'false' @@ -201,7 +205,7 @@ Resources: WebUriParameter: Type: "AWS::SSM::Parameter" Properties: - Name: WebUiUri + Name: !Sub ${ParentStackName}-WebUiUri Type: String Value: !GetAtt Web.Outputs.Uri Description: PCA Web Application URI From 4db892c09d12bfcd73c6846b41f5f34ef02c4b29 Mon Sep 17 00:00:00 2001 From: David Moser Date: Thu, 20 Feb 2025 21:43:54 -0800 Subject: [PATCH 20/22] add support for Nova / converse api / remove old models --- CHANGELOG.md | 7 ++ pca-main-nokendra.template | 128 ++++++++------------ pca-main.template | 129 ++++++++------------- pca-server/cfn/lib/pca.template | 7 ++ pca-server/cfn/pca-server.template | 13 ++- pca-server/src/pca/pca-aws-sf-summarize.py | 103 +++++----------- pca-ui/cfn/lib/api.template | 26 +++-- pca-ui/cfn/pca-ui.template | 13 ++- pca-ui/src/genai/index.py | 97 +++++----------- 9 files changed, 208 insertions(+), 315 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cfc9ca9..7e7003a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Added support for Amazon Nova models (amazon.nova-micro-v1:0, amazon.nova-lite-v1:0, amazon.nova-pro-v1:0) +- Updated Anthropic Claude models to the latest 3.5 versions (anthropic.claude-3-5-haiku-20241022-v1:0, anthropic.claude-3-5-sonnet-20241022-v2:0) +- Removed older versions of Amazon Titan and Anthropic Claude models (amazon.titan-text-express-v1, anthropic.claude-v1, anthropic.claude-instant-v1, anthropic.claude-v2) +- Refactored Bedrock calls to use the Converse API eliminating the need for custom model specific payloads +- Refactored all model invocation to use Inference Profiles. This is required for Nova models. It is also applied to Anthropic models for consistency and improved scalability. +- Added adaptive retry configuration to Bedrock api calls to add some tolerance for quota throttling exceptions (at the expense of latency) + ## [0.7.11] - 2024-10-09 ### Added diff --git a/pca-main-nokendra.template b/pca-main-nokendra.template index 9a6e808d..93c52758 100644 --- a/pca-main-nokendra.template +++ b/pca-main-nokendra.template @@ -384,14 +384,17 @@ Parameters: GenAIQueryBedrockModelId: Type: String - Default: anthropic.claude-3-haiku-20240307-v1:0 + Default: us.amazon.nova-lite-v1:0 AllowedValues: - anthropic.claude-3-haiku-20240307-v1:0 - anthropic.claude-3-sonnet-20240229-v1:0 - - amazon.titan-text-express-v1 - - anthropic.claude-v1 - - anthropic.claude-instant-v1 - - anthropic.claude-v2 + - us.amazon.nova-micro-v1:0 + - us.amazon.nova-lite-v1:0 + - us.amazon.nova-pro-v1:0 + - us.anthropic.claude-3-5-haiku-20241022-v1:0 + - us.anthropic.claude-3-5-sonnet-20241022-v2:0 + - eu.anthropic.claude-3-5-sonnet-20240620-v1:0 + - apac.anthropic.claude-3-5-sonnet-20240620-v1:0 Description: (Optional) If 'GenAIQuery' is BEDROCK, which Bedrock model to use. CallSummarization: @@ -417,14 +420,17 @@ Parameters: SummarizationBedrockModelId: Type: String - Default: anthropic.claude-3-haiku-20240307-v1:0 + Default: us.amazon.nova-lite-v1:0 AllowedValues: - anthropic.claude-3-haiku-20240307-v1:0 - anthropic.claude-3-sonnet-20240229-v1:0 - - amazon.titan-text-express-v1 - - anthropic.claude-v1 - - anthropic.claude-instant-v1 - - anthropic.claude-v2 + - us.amazon.nova-micro-v1:0 + - us.amazon.nova-lite-v1:0 + - us.amazon.nova-pro-v1:0 + - us.anthropic.claude-3-5-haiku-20241022-v1:0 + - us.anthropic.claude-3-5-sonnet-20241022-v2:0 + - eu.anthropic.claude-3-5-sonnet-20240620-v1:0 + - apac.anthropic.claude-3-5-sonnet-20240620-v1:0 Description: (Optional) If 'CallSummarization' is BEDROCK, which Bedrock model to use. TestBedrockModelId: @@ -714,6 +720,12 @@ Resources: Resource: - !Sub "arn:${AWS::Partition}:bedrock:*::foundation-model/*" - !Sub "arn:${AWS::Partition}:bedrock:*:${AWS::AccountId}:custom-model/*" + - !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:inference-profile/*" + - Effect: Allow + Action: + - "bedrock:GetInferenceProfile" + Resource: + - !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:inference-profile/*" PolicyName: BedrockPolicy TestBedrockModelFunction: @@ -736,76 +748,38 @@ Resources: subprocess.check_call([sys.executable, '-m', 'pip', 'install', '--target', '/tmp', 'boto3']) sys.path.insert(0,'/tmp') import boto3 - + from botocore.config import Config + # Defaults AWS_REGION = os.environ["AWS_REGION_OVERRIDE"] if "AWS_REGION_OVERRIDE" in os.environ else os.environ["AWS_REGION"] ENDPOINT_URL = os.environ.get("ENDPOINT_URL", f'https://bedrock-runtime.{AWS_REGION}.amazonaws.com') DEFAULT_MAX_TOKENS = 128 - def get_request_body(modelId, parameters, prompt): - provider = modelId.split(".")[0] - request_body = None - if provider == "anthropic": - if 'claude-3' in modelId: - request_body = { - "max_tokens": DEFAULT_MAX_TOKENS, - "messages": [{"role": "user", "content": prompt}], - "anthropic_version": "bedrock-2023-05-31" - } - else: - request_body = { - "prompt": prompt, - "max_tokens_to_sample": DEFAULT_MAX_TOKENS - } - - request_body.update(parameters) - elif provider == "ai21": - request_body = { - "prompt": prompt, - "maxTokens": DEFAULT_MAX_TOKENS + def get_generate_text(response): + return response["output"]["message"]["content"][0]["text"] + + def call_llm(prompt, modelId): + client = boto3.client( + service_name='bedrock-runtime', + region_name=AWS_REGION, + endpoint_url=ENDPOINT_URL, + config=Config(retries={'max_attempts': 50, 'mode': 'adaptive'}) + ) + + message = { + 'role': 'user', + 'content': [{'text': prompt}] + } + + response = client.converse( + modelId=modelId, + messages=[message], + inferenceConfig={ + 'maxTokens': DEFAULT_MAX_TOKENS, + 'temperature': 0 } - request_body.update(parameters) - elif provider == "amazon": - textGenerationConfig = { - "maxTokenCount": DEFAULT_MAX_TOKENS - } - textGenerationConfig.update(parameters) - request_body = { - "inputText": prompt, - "textGenerationConfig": textGenerationConfig - } - else: - raise Exception("Unsupported provider: ", provider) - return request_body - - def get_generate_text(modelId, response): - provider = modelId.split(".")[0] - generated_text = None - if provider == "anthropic": - if 'claude-3' in modelId: - response_raw = json.loads(response.get("body").read().decode()) - generated_text = response_raw.get('content')[0].get('text') - - else: - response_body = json.loads(response.get("body").read().decode()) - generated_text = response_body.get("completion") - elif provider == "ai21": - response_body = json.loads(response.get("body").read()) - generated_text = response_body.get("completions")[0].get("data").get("text") - elif provider == "amazon": - response_body = json.loads(response.get("body").read()) - generated_text = response_body.get("results")[0].get("outputText") - else: - raise Exception("Unsupported provider: ", provider) - return generated_text - - def call_llm(parameters, prompt): - modelId = parameters.pop("modelId") - body = get_request_body(modelId, parameters, prompt) - print("ModelId", modelId, "- Body: ", body) - client = boto3.client(service_name='bedrock-runtime', region_name=AWS_REGION, endpoint_url=ENDPOINT_URL) - response = client.invoke_model(body=json.dumps(body), modelId=modelId, accept='application/json', contentType='application/json') - generated_text = get_generate_text(modelId, response) + ) + generated_text = get_generate_text(response) return generated_text def lambda_handler(event, context): @@ -821,12 +795,8 @@ Resources: # Test LLMModel llmModelId = event['ResourceProperties'].get('LLMModelId', '') modelId = llmModelId - parameters = { - "modelId": modelId, - "temperature": 0 - } print(f"Testing {modelId}") - call_llm(parameters, prompt) + call_llm(prompt, modelId) except Exception as e: status = cfnresponse.FAILED reason = f"Exception thrown testing ModelId='{modelId}'. Check that Amazon Bedrock is available in your region, and that model is activated in your Amazon Bedrock account - {e}" diff --git a/pca-main.template b/pca-main.template index 428e65af..05b2bb4b 100644 --- a/pca-main.template +++ b/pca-main.template @@ -425,14 +425,17 @@ Parameters: GenAIQueryBedrockModelId: Type: String - Default: anthropic.claude-3-haiku-20240307-v1:0 + Default: us.amazon.nova-lite-v1:0 AllowedValues: - anthropic.claude-3-haiku-20240307-v1:0 - anthropic.claude-3-sonnet-20240229-v1:0 - - amazon.titan-text-express-v1 - - anthropic.claude-v1 - - anthropic.claude-instant-v1 - - anthropic.claude-v2 + - us.amazon.nova-micro-v1:0 + - us.amazon.nova-lite-v1:0 + - us.amazon.nova-pro-v1:0 + - us.anthropic.claude-3-5-haiku-20241022-v1:0 + - us.anthropic.claude-3-5-sonnet-20241022-v2:0 + - eu.anthropic.claude-3-5-sonnet-20240620-v1:0 + - apac.anthropic.claude-3-5-sonnet-20240620-v1:0 Description: (Optional) If 'GenAIQuery' is BEDROCK, which Bedrock model to use. CallSummarization: @@ -458,14 +461,17 @@ Parameters: SummarizationBedrockModelId: Type: String - Default: anthropic.claude-3-haiku-20240307-v1:0 + Default: us.amazon.nova-lite-v1:0 AllowedValues: - anthropic.claude-3-haiku-20240307-v1:0 - anthropic.claude-3-sonnet-20240229-v1:0 - - amazon.titan-text-express-v1 - - anthropic.claude-v1 - - anthropic.claude-instant-v1 - - anthropic.claude-v2 + - us.amazon.nova-micro-v1:0 + - us.amazon.nova-lite-v1:0 + - us.amazon.nova-pro-v1:0 + - us.anthropic.claude-3-5-haiku-20241022-v1:0 + - us.anthropic.claude-3-5-sonnet-20241022-v2:0 + - eu.anthropic.claude-3-5-sonnet-20240620-v1:0 + - apac.anthropic.claude-3-5-sonnet-20240620-v1:0 Description: (Optional) If 'CallSummarization' is BEDROCK, which Bedrock model to use. TestBedrockModelId: @@ -897,6 +903,12 @@ Resources: Resource: - !Sub "arn:${AWS::Partition}:bedrock:*::foundation-model/*" - !Sub "arn:${AWS::Partition}:bedrock:*:${AWS::AccountId}:custom-model/*" + - !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:inference-profile/*" + - Effect: Allow + Action: + - "bedrock:GetInferenceProfile" + Resource: + - !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:inference-profile/*" PolicyName: BedrockPolicy TestBedrockModelFunction: @@ -919,76 +931,38 @@ Resources: subprocess.check_call([sys.executable, '-m', 'pip', 'install', '--target', '/tmp', 'boto3']) sys.path.insert(0,'/tmp') import boto3 - + from botocore.config import Config + # Defaults AWS_REGION = os.environ["AWS_REGION_OVERRIDE"] if "AWS_REGION_OVERRIDE" in os.environ else os.environ["AWS_REGION"] ENDPOINT_URL = os.environ.get("ENDPOINT_URL", f'https://bedrock-runtime.{AWS_REGION}.amazonaws.com') DEFAULT_MAX_TOKENS = 128 - def get_request_body(modelId, parameters, prompt): - provider = modelId.split(".")[0] - request_body = None - if provider == "anthropic": - if 'claude-3' in modelId: - request_body = { - "max_tokens": DEFAULT_MAX_TOKENS, - "messages": [{"role": "user", "content": prompt}], - "anthropic_version": "bedrock-2023-05-31" - } - else: - request_body = { - "prompt": prompt, - "max_tokens_to_sample": DEFAULT_MAX_TOKENS - } - - request_body.update(parameters) - elif provider == "ai21": - request_body = { - "prompt": prompt, - "maxTokens": DEFAULT_MAX_TOKENS - } - request_body.update(parameters) - elif provider == "amazon": - textGenerationConfig = { - "maxTokenCount": DEFAULT_MAX_TOKENS + def get_generate_text(response): + return response["output"]["message"]["content"][0]["text"] + + def call_llm(prompt, modelId): + client = boto3.client( + service_name='bedrock-runtime', + region_name=AWS_REGION, + endpoint_url=ENDPOINT_URL, + config=Config(retries={'max_attempts': 50, 'mode': 'adaptive'}) + ) + + message = { + 'role': 'user', + 'content': [{'text': prompt}] + } + + response = client.converse( + modelId=modelId, + messages=[message], + inferenceConfig={ + 'maxTokens': DEFAULT_MAX_TOKENS, + 'temperature': 0 } - textGenerationConfig.update(parameters) - request_body = { - "inputText": prompt, - "textGenerationConfig": textGenerationConfig - } - else: - raise Exception("Unsupported provider: ", provider) - return request_body - - def get_generate_text(modelId, response): - provider = modelId.split(".")[0] - generated_text = None - if provider == "anthropic": - if 'claude-3' in modelId: - response_raw = json.loads(response.get("body").read().decode()) - generated_text = response_raw.get('content')[0].get('text') - - else: - response_body = json.loads(response.get("body").read().decode()) - generated_text = response_body.get("completion") - elif provider == "ai21": - response_body = json.loads(response.get("body").read()) - generated_text = response_body.get("completions")[0].get("data").get("text") - elif provider == "amazon": - response_body = json.loads(response.get("body").read()) - generated_text = response_body.get("results")[0].get("outputText") - else: - raise Exception("Unsupported provider: ", provider) - return generated_text - - def call_llm(parameters, prompt): - modelId = parameters.pop("modelId") - body = get_request_body(modelId, parameters, prompt) - print("ModelId", modelId, "- Body: ", body) - client = boto3.client(service_name='bedrock-runtime', region_name=AWS_REGION, endpoint_url=ENDPOINT_URL) - response = client.invoke_model(body=json.dumps(body), modelId=modelId, accept='application/json', contentType='application/json') - generated_text = get_generate_text(modelId, response) + ) + generated_text = get_generate_text(response) return generated_text def lambda_handler(event, context): @@ -1004,12 +978,9 @@ Resources: # Test LLMModel llmModelId = event['ResourceProperties'].get('LLMModelId', '') modelId = llmModelId - parameters = { - "modelId": modelId, - "temperature": 0 - } + print(f"Testing {modelId}") - call_llm(parameters, prompt) + call_llm(prompt, modelId) except Exception as e: status = cfnresponse.FAILED reason = f"Exception thrown testing ModelId='{modelId}'. Check that Amazon Bedrock is available in your region, and that model is activated in your Amazon Bedrock account - {e}" diff --git a/pca-server/cfn/lib/pca.template b/pca-server/cfn/lib/pca.template index 37a21559..9e4075fa 100644 --- a/pca-server/cfn/lib/pca.template +++ b/pca-server/cfn/lib/pca.template @@ -322,6 +322,13 @@ Resources: Resource: - !Sub arn:${AWS::Partition}:bedrock:*::foundation-model/* - !Sub arn:${AWS::Partition}:bedrock:*:${AWS::AccountId}:custom-model/* + - !Sub arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:inference-profile/* + - Sid: BedrockGetInferenceProfile + Effect: Allow + Action: + - bedrock:GetInferenceProfile + Resource: + - !Sub arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:inference-profile/* - !If - HasAnthropicSummary - Sid: SecretsManagerPolicy diff --git a/pca-server/cfn/pca-server.template b/pca-server/cfn/pca-server.template index d73a0869..2bf16292 100644 --- a/pca-server/cfn/pca-server.template +++ b/pca-server/cfn/pca-server.template @@ -40,14 +40,17 @@ Parameters: SummarizationBedrockModelId: Type: String - Default: anthropic.claude-3-haiku-20240307-v1:0 + Default: us.amazon.nova-lite-v1:0 AllowedValues: - anthropic.claude-3-haiku-20240307-v1:0 - anthropic.claude-3-sonnet-20240229-v1:0 - - amazon.titan-text-express-v1 - - anthropic.claude-v1 - - anthropic.claude-instant-v1 - - anthropic.claude-v2 + - us.amazon.nova-micro-v1:0 + - us.amazon.nova-lite-v1:0 + - us.amazon.nova-pro-v1:0 + - us.anthropic.claude-3-5-haiku-20241022-v1:0 + - us.anthropic.claude-3-5-sonnet-20241022-v2:0 + - eu.anthropic.claude-3-5-sonnet-20240620-v1:0 + - apac.anthropic.claude-3-5-sonnet-20240620-v1:0 Description: (Optional) If 'CallSummarization' is BEDROCK, which Bedrock model to use. SummarizationSageMakerInitialInstanceCount: diff --git a/pca-server/src/pca/pca-aws-sf-summarize.py b/pca-server/src/pca/pca-aws-sf-summarize.py index a66d6c8c..92081df2 100644 --- a/pca-server/src/pca/pca-aws-sf-summarize.py +++ b/pca-server/src/pca/pca-aws-sf-summarize.py @@ -35,13 +35,6 @@ s3Client = boto3.client('s3') dynamodb_client = boto3.client('dynamodb') -config = Config( - retries = { - 'max_attempts': 100, - 'mode': 'adaptive' - } -) - def get_third_party_llm_secret(): print("Getting API key from Secrets Manager") secrets_client = boto3.client('secretsmanager') @@ -56,76 +49,43 @@ def get_third_party_llm_secret(): def get_bedrock_client(): print("Connecting to Bedrock Service: ", BEDROCK_ENDPOINT_URL) - client = boto3.client(service_name='bedrock-runtime', region_name=AWS_REGION, endpoint_url=BEDROCK_ENDPOINT_URL, config=config) + client = boto3.client( + service_name='bedrock-runtime', + region_name=AWS_REGION, + endpoint_url=BEDROCK_ENDPOINT_URL, + config=Config(retries={'max_attempts': 50, 'mode': 'adaptive'}) + ) return client - -def get_bedrock_request_body(modelId, parameters, prompt): - provider = modelId.split(".")[0] - request_body = None - if provider == "anthropic": - if 'claude-3' in modelId: - request_body = { - "max_tokens": MAX_TOKENS, - "messages": [{"role": "user", "content": prompt}], - "anthropic_version": "bedrock-2023-05-31" - } - else: - request_body = { - "prompt": prompt, - "max_tokens_to_sample": MAX_TOKENS - } - request_body.update(parameters) - elif provider == "ai21": - request_body = { - "prompt": prompt, - "maxTokens": MAX_TOKENS - } - request_body.update(parameters) - elif provider == "amazon": - textGenerationConfig = { - "maxTokenCount": MAX_TOKENS - } - textGenerationConfig.update(parameters) - request_body = { - "inputText": prompt, - "textGenerationConfig": textGenerationConfig - } - else: - raise Exception("Unsupported provider: ", provider) - return request_body - -def get_bedrock_generate_text(modelId, response): - print("generating response with ", modelId) - provider = modelId.split(".")[0] - generated_text = None - if provider == "anthropic": - if 'claude-3' in modelId: - response_raw = json.loads(response.get("body").read().decode()) - generated_text = response_raw.get('content')[0].get('text') - - else: - response_body = json.loads(response.get("body").read().decode()) - generated_text = response_body.get("completion") - elif provider == "ai21": - response_body = json.loads(response.get("body").read()) - generated_text = response_body.get("completions")[0].get("data").get("text") - elif provider == "amazon": - response_body = json.loads(response.get("body").read()) - generated_text = response_body.get("results")[0].get("outputText") - else: - raise Exception("Unsupported provider: ", provider) + +def get_bedrock_generate_text(response): + generated_text = response["output"]["message"]["content"][0]["text"] generated_text = generated_text.replace('```','') return generated_text -def call_bedrock(parameters, prompt): +def call_bedrock(prompt, temperature, max_tokens): global bedrock_client modelId = BEDROCK_MODEL_ID - body = get_bedrock_request_body(modelId, parameters, prompt) - print("ModelId", modelId, "- Body: ", body) + + print(f"Bedrock request - ModelId: {modelId} Temperature: {temperature} Max Tokens: {max_tokens}") + if (bedrock_client is None): bedrock_client = get_bedrock_client() - response = bedrock_client.invoke_model(body=json.dumps(body), modelId=modelId, accept='application/json', contentType='application/json') - generated_text = get_bedrock_generate_text(modelId, response) + + message = { + "role": "user", + "content": [{"text": prompt}] + } + + response = bedrock_client.converse( + modelId=modelId, + messages=[message], + inferenceConfig={ + "maxTokens": max_tokens, + "temperature": temperature + } + ) + + generated_text = get_bedrock_generate_text(response) return generated_text def generate_sagemaker_summary(transcript): @@ -224,10 +184,7 @@ def generate_bedrock_summary(transcript, api_mode): continue else: prompt = prompt.replace("{transcript}", transcript) - parameters = { - "temperature": 0 - } - generated_text = call_bedrock(parameters, prompt) + generated_text = call_bedrock(prompt, 0, MAX_TOKENS) result[key] = generated_text if len(result.keys()) == 1: # This is a single node JSON with value that can be either: diff --git a/pca-ui/cfn/lib/api.template b/pca-ui/cfn/lib/api.template index d30f42a1..2e357068 100644 --- a/pca-ui/cfn/lib/api.template +++ b/pca-ui/cfn/lib/api.template @@ -33,14 +33,17 @@ Parameters: GenAIQueryBedrockModelId: Type: String - Default: anthropic.claude-3-haiku-20240307-v1:0 + Default: us.amazon.nova-lite-v1:0 AllowedValues: - anthropic.claude-3-haiku-20240307-v1:0 - anthropic.claude-3-sonnet-20240229-v1:0 - - amazon.titan-text-express-v1 - - anthropic.claude-v1 - - anthropic.claude-instant-v1 - - anthropic.claude-v2 + - us.amazon.nova-micro-v1:0 + - us.amazon.nova-lite-v1:0 + - us.amazon.nova-pro-v1:0 + - us.anthropic.claude-3-5-haiku-20241022-v1:0 + - us.anthropic.claude-3-5-sonnet-20241022-v2:0 + - eu.anthropic.claude-3-5-sonnet-20240620-v1:0 + - apac.anthropic.claude-3-5-sonnet-20240620-v1:0 Description: (Optional) If 'GenAIQuery' is BEDROCK, which Bedrock model to use. (Bedrock preview access only) FetchTranscriptArn: @@ -301,11 +304,18 @@ Resources: - 'dynamodb:GetItem' - Sid: InvokeBedrock Effect: Allow - Action: + Action: - bedrock:InvokeModel Resource: - - !Sub "arn:${AWS::Partition}:bedrock:*::foundation-model/*" - - !Sub "arn:${AWS::Partition}:bedrock:*:${AWS::AccountId}:custom-model/*" + - !Sub arn:${AWS::Partition}:bedrock:*::foundation-model/* + - !Sub arn:${AWS::Partition}:bedrock:*:${AWS::AccountId}:custom-model/* + - !Sub arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:inference-profile/* + - Sid: BedrockGetInferenceProfile + Effect: Allow + Action: + - bedrock:GetInferenceProfile + Resource: + - !Sub arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:inference-profile/* - !If - HasAnthropicSummary - Sid: SecretsManagerPolicy diff --git a/pca-ui/cfn/pca-ui.template b/pca-ui/cfn/pca-ui.template index 14ff32b2..cca29860 100644 --- a/pca-ui/cfn/pca-ui.template +++ b/pca-ui/cfn/pca-ui.template @@ -71,14 +71,17 @@ Parameters: GenAIQueryBedrockModelId: Type: String - Default: anthropic.claude-3-haiku-20240307-v1:0 + Default: us.amazon.nova-lite-v1:0 AllowedValues: - anthropic.claude-3-haiku-20240307-v1:0 - anthropic.claude-3-sonnet-20240229-v1:0 - - amazon.titan-text-express-v1 - - anthropic.claude-v1 - - anthropic.claude-instant-v1 - - anthropic.claude-v2 + - us.amazon.nova-micro-v1:0 + - us.amazon.nova-lite-v1:0 + - us.amazon.nova-pro-v1:0 + - us.anthropic.claude-3-5-haiku-20241022-v1:0 + - us.anthropic.claude-3-5-sonnet-20241022-v2:0 + - eu.anthropic.claude-3-5-sonnet-20240620-v1:0 + - apac.anthropic.claude-3-5-sonnet-20240620-v1:0 Description: (Optional) If 'GenAIQuery' is BEDROCK, which Bedrock model to use. LLMThirdPartyApiKey: diff --git a/pca-ui/src/genai/index.py b/pca-ui/src/genai/index.py index a04893ba..35e9a063 100644 --- a/pca-ui/src/genai/index.py +++ b/pca-ui/src/genai/index.py @@ -12,6 +12,7 @@ import requests import urllib.parse from botocore.exceptions import ClientError +from botocore.config import Config AWS_REGION = os.environ["AWS_REGION_OVERRIDE"] if "AWS_REGION_OVERRIDE" in os.environ else os.environ["AWS_REGION"] QUERY_TYPE = os.getenv('QUERY_TYPE', 'DISABLED') @@ -44,77 +45,43 @@ def get_third_party_llm_secret(): def get_bedrock_client(): print("Connecting to Bedrock Service: ", BEDROCK_ENDPOINT_URL) - client = boto3.client(service_name='bedrock-runtime', region_name=AWS_REGION, endpoint_url=BEDROCK_ENDPOINT_URL) + client = boto3.client( + service_name='bedrock-runtime', + region_name=AWS_REGION, + endpoint_url=BEDROCK_ENDPOINT_URL, + config=Config(retries={'max_attempts': 50, 'mode': 'adaptive'}) + ) return client - -def get_bedrock_request_body(modelId, parameters, prompt): - provider = modelId.split(".")[0] - request_body = None - if provider == "anthropic": - print(modelId) - if 'claude-3' in modelId: - request_body = { - "max_tokens": MAX_TOKENS, - "messages": [{"role": "user", "content": prompt}], - "anthropic_version": "bedrock-2023-05-31" - } - else: - request_body = { - "prompt": prompt, - "max_tokens_to_sample": MAX_TOKENS - } - request_body.update(parameters) - elif provider == "ai21": - request_body = { - "prompt": prompt, - "maxTokens": MAX_TOKENS - } - request_body.update(parameters) - elif provider == "amazon": - textGenerationConfig = { - "maxTokenCount": MAX_TOKENS - } - textGenerationConfig.update(parameters) - request_body = { - "inputText": prompt, - "textGenerationConfig": textGenerationConfig - } - else: - raise Exception("Unsupported provider: ", provider) - return request_body - -def get_bedrock_generate_text(modelId, response): - print("generating response with ", modelId) - provider = modelId.split(".")[0] - generated_text = None - if provider == "anthropic": - if 'claude-3' in modelId: - response_raw = json.loads(response.get("body").read().decode()) - generated_text = response_raw.get('content')[0].get('text') - else: - response_body = json.loads(response.get("body").read().decode()) - generated_text = response_body.get("completion") - elif provider == "ai21": - response_body = json.loads(response.get("body").read()) - generated_text = response_body.get("completions")[0].get("data").get("text") - elif provider == "amazon": - response_body = json.loads(response.get("body").read()) - generated_text = response_body.get("results")[0].get("outputText") - else: - raise Exception("Unsupported provider: ", provider) +def get_bedrock_generate_text(response): + generated_text = response["output"]["message"]["content"][0]["text"] generated_text = generated_text.replace('```','') return generated_text -def call_bedrock(parameters, prompt): +def call_bedrock(prompt, temperature, max_tokens): global bedrock_client modelId = BEDROCK_MODEL_ID - body = get_bedrock_request_body(modelId, parameters, prompt) - print("ModelId", modelId, "- Body: ", body) + + print(f"Bedrock request - ModelId: {modelId} Temperature: {temperature} Max Tokens: {max_tokens}") + if (bedrock_client is None): bedrock_client = get_bedrock_client() - response = bedrock_client.invoke_model(body=json.dumps(body), modelId=modelId, accept='application/json', contentType='application/json') - generated_text = get_bedrock_generate_text(modelId, response) + + message = { + "role": "user", + "content": [{"text": prompt}] + } + + response = bedrock_client.converse( + modelId=modelId, + messages=[message], + inferenceConfig={ + "maxTokens": max_tokens, + "temperature": temperature + } + ) + + generated_text = get_bedrock_generate_text(response) return generated_text def get_template_from_dynamodb(): @@ -164,10 +131,8 @@ def generate_bedrock_query(transcript, question): prompt = prompt.replace("{transcript}", transcript) prompt = prompt.replace("{question}", question) - parameters = { - "temperature": 0 - } - generated_text = call_bedrock(parameters, prompt) + + generated_text = call_bedrock(prompt, 0, MAX_TOKENS) return generated_text From 85dcb7a3a097305a50c6ae6dae120637b2fc23fa Mon Sep 17 00:00:00 2001 From: Bob Strahan Date: Fri, 21 Feb 2025 14:26:46 +0000 Subject: [PATCH 21/22] v0.7.12 --- CHANGELOG.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e7003a8..f4f22a6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Added support for Amazon Nova models (amazon.nova-micro-v1:0, amazon.nova-lite-v1:0, amazon.nova-pro-v1:0) -- Updated Anthropic Claude models to the latest 3.5 versions (anthropic.claude-3-5-haiku-20241022-v1:0, anthropic.claude-3-5-sonnet-20241022-v2:0) -- Removed older versions of Amazon Titan and Anthropic Claude models (amazon.titan-text-express-v1, anthropic.claude-v1, anthropic.claude-instant-v1, anthropic.claude-v2) -- Refactored Bedrock calls to use the Converse API eliminating the need for custom model specific payloads -- Refactored all model invocation to use Inference Profiles. This is required for Nova models. It is also applied to Anthropic models for consistency and improved scalability. -- Added adaptive retry configuration to Bedrock api calls to add some tolerance for quota throttling exceptions (at the expense of latency) +## [0.7.12] - 2025-02-21 + +### Added +- Added support for Amazon Nova models (amazon.nova-micro-v1:0, amazon.nova-lite-v1:0, amazon.nova-pro-v1:0) - PR #295 +- Updated Anthropic Claude models to the latest 3.5 versions (anthropic.claude-3-5-haiku-20241022-v1:0, anthropic.claude-3-5-sonnet-20241022-v2:0) - PR #295 +- Removed older versions of Amazon Titan and Anthropic Claude models (amazon.titan-text-express-v1, anthropic.claude-v1, anthropic.claude-instant-v1, anthropic.claude-v2) - PR #295 +- Refactored Bedrock calls to use the Converse API eliminating the need for custom model specific payloads - PR #295 +- Refactored all model invocation to use Inference Profiles. This is required for Nova models. It is also applied to Anthropic models for consistency and improved scalability. - PR #295 +- Added adaptive retry configuration to Bedrock api calls to add some tolerance for quota throttling exceptions (at the expense of latency) - PR #295 + +### Fixed +- Fixed: Only one PCA stack may be sucessfully deployed in a given account/region due to fixed SSM parameter names - PR #291, #293 +- Fixed: Current publish.sh does not work with ARM chipsets such as the Apple M series. Set x86_64 arch for local build - PR #288 + ## [0.7.11] - 2024-10-09 From a75d4e6dec66c8d91ad789191a0435e11041b909 Mon Sep 17 00:00:00 2001 From: Bob Strahan Date: Fri, 21 Feb 2025 14:31:46 +0000 Subject: [PATCH 22/22] v0.7.12 --- CHANGELOG.md | 1 + VERSION | 2 +- pca-main-nokendra.template | 2 +- pca-main.template | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4f22a6e..8055feb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -290,6 +290,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release [Unreleased]: https://github.com/aws-samples/amazon-transcribe-post-call-analytics/compare/main...develop +[0.7.12]: https://github.com/aws-samples/amazon-transcribe-post-call-analytics/releases/tag/v0.7.12 [0.7.11]: https://github.com/aws-samples/amazon-transcribe-post-call-analytics/releases/tag/v0.7.11 [0.7.10]: https://github.com/aws-samples/amazon-transcribe-post-call-analytics/releases/tag/v0.7.10 [0.7.9]: https://github.com/aws-samples/amazon-transcribe-post-call-analytics/releases/tag/v0.7.9 diff --git a/VERSION b/VERSION index b4d6d121..88a7b228 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.11 +0.7.12 diff --git a/pca-main-nokendra.template b/pca-main-nokendra.template index 93c52758..b3f020a2 100644 --- a/pca-main-nokendra.template +++ b/pca-main-nokendra.template @@ -1,6 +1,6 @@ AWSTemplateFormatVersion: "2010-09-09" -Description: Amazon Transcribe Post Call Analytics - PCA (v0.7.11) (uksb-1sn29lk73, SO9071) +Description: Amazon Transcribe Post Call Analytics - PCA (v0.7.12) (uksb-1sn29lk73, SO9071) Parameters: diff --git a/pca-main.template b/pca-main.template index 05b2bb4b..dd31f74c 100644 --- a/pca-main.template +++ b/pca-main.template @@ -1,6 +1,6 @@ AWSTemplateFormatVersion: "2010-09-09" -Description: Amazon Transcribe Post Call Analytics - PCA (v0.7.11) (uksb-1sn29lk73, SO9071) +Description: Amazon Transcribe Post Call Analytics - PCA (v0.7.12) (uksb-1sn29lk73, SO9071) Parameters: