Transform:
  - AWS::LanguageExtensions
Parameters:
  ctrKinesisStreamARN:
    Type: String
    Description: The full ARN of the Kinesis Streams used by Amazon Connect for CTR records.
  connectInstanceFriendlyName:
    Type: String
    Description: The friendly name of your Amazon Connect instance for ease of reference (i.e. Dev, Prod, UAT). Alphanumeric, no spaces.
  operataGroupId:
    Type: String
    Description: Operata Group ID provided by Operata
  operataAPIKey:
    Type: String
    Description: API key generated in the Operata console
    NoEcho: true
  apiEndpointUrl:
    Type: String
    Default: https://api.operata.io
    Description: Operata API endpoint URL
  agentDataS3BucketName:
    Type: List<String>
    Description: "Optional `Agent Data` S3 Bucket Name (JSON Line/JSON array files). format: <bucket-name>,<prefix>"
  agentLookupKey:
    Type: String
    Description: Optional, The name of the agent field to use for agent data lookup (i.e. USERNAME, userId, etc)
Resources:
  operataAPIKeySM:
    Type: AWS::SecretsManager::Secret
    Properties:
      Description: Operata API token
      Name:
        Fn::Join:
          - ""
          - - cloud-collector-v3/ctr/
            - Ref: operataGroupId
            - /apiToken
      SecretString:
        Ref: operataAPIKey
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/operataAPIKeySM
  operataEventBridgePipeRole3EA09E25:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: pipes.amazonaws.com
            Condition:
              StringEquals:
                aws:SourceArn:
                  Fn::Join:
                    - ""
                    - - "arn:aws:pipes:"
                      - Ref: AWS::Region
                      - ":"
                      - Ref: AWS::AccountId
                      - :pipe/operataEventsPipe-
                      - Ref: connectInstanceFriendlyName
                      - -amazonConnect
                aws:SourceAccount:
                  Ref: AWS::AccountId
        Version: "2012-10-17"
      Description: Operata Event Bridge Pipes Role
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/operataEventBridgePipeRole/Resource
  operataEventBridgePipeRoleDefaultPolicyDD50B370:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - logs:CreateLogStream
              - logs:PutLogEvents
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - eventBridgePipeLogGroupF7A55BD8
                - Arn
        Version: "2012-10-17"
      PolicyName: operataEventBridgePipeRoleDefaultPolicyDD50B370
      Roles:
        - Ref: operataEventBridgePipeRole3EA09E25
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/operataEventBridgePipeRole/DefaultPolicy/Resource
  operataConnection322BC7D8:
    Type: AWS::Events::Connection
    Properties:
      AuthParameters:
        ApiKeyAuthParameters:
          ApiKeyName: Operata-API-Key
          ApiKeyValue:
            Ref: operataAPIKey
        InvocationHttpParameters:
          HeaderParameters:
            - IsValueSecret: false
              Key: Operata-Group-Id
              Value:
                Ref: operataGroupId
      AuthorizationType: API_KEY
      Description:
        Fn::Join:
          - ""
          - - "EventBridge connection for transmitting CTR events to Operata for the "
            - Ref: connectInstanceFriendlyName
            - " Amazon Connect instance"
      Name:
        Fn::Join:
          - ""
          - - operataAPIgroup-
            - Ref: operataGroupId
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/operataConnection/Connection
  operataApiDestinationFE63AEAB:
    Type: AWS::Events::ApiDestination
    Properties:
      ConnectionArn:
        Fn::GetAtt:
          - operataConnection322BC7D8
          - Arn
      Description:
        Fn::Join:
          - ""
          - - API destination for sending CTR data to Operata for the
            - Ref: connectInstanceFriendlyName
            - Amazon Connect instance
      HttpMethod: POST
      InvocationEndpoint:
        Fn::Join:
          - ""
          - - Ref: apiEndpointUrl
            - /v2/aws/events/contact-record
      Name:
        Fn::Join:
          - ""
          - - operataEndpointGroup-
            - Ref: operataGroupId
    DependsOn:
      - operataConnection322BC7D8
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/operataApiDestination/ApiDestination
  operataEventBridgePipeAPIDestinationPolicy6F5D8899:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action: events:InvokeApiDestination
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - operataApiDestinationFE63AEAB
                - Arn
        Version: "2012-10-17"
      PolicyName:
        Fn::Join:
          - ""
          - - APIDestinationPolicy-Operata-GroupId-
            - Ref: operataGroupId
      Roles:
        - Ref: operataEventBridgePipeRole3EA09E25
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/operataEventBridgePipeAPIDestinationPolicy/Resource
  operataEventBridgeKinesisPipeSourcePolicy754E6190:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - kinesis:DescribeStream
              - kinesis:DescribeStreamSummary
              - kinesis:GetRecords
              - kinesis:GetShardIterator
              - kinesis:ListShards
              - kinesis:ListStreams
            Effect: Allow
            Resource:
              Ref: ctrKinesisStreamARN
        Version: "2012-10-17"
      PolicyName:
        Fn::Join:
          - ""
          - - KinesisPipeSourcePolicy-Operata-GroupId-
            - Ref: operataGroupId
      Roles:
        - Ref: operataEventBridgePipeRole3EA09E25
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/operataEventBridgeKinesisPipeSourcePolicy/Resource
  cloudcollectorv3redactorServiceRole9543ADB8:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
        Version: "2012-10-17"
      ManagedPolicyArns:
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/cloud-collector-v3-redactor/ServiceRole/Resource
  cloudcollectorv3redactorServiceRoleDefaultPolicy3AE409B5:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action: secretsmanager:GetSecretValue
            Effect: Allow
            Resource:
              Ref: operataAPIKeySM
          - Action:
              - ec2:AttachNetworkInterface
              - ec2:CreateNetworkInterface
              - ec2:DeleteNetworkInterface
              - ec2:DescribeInstances
              - ec2:DescribeNetworkInterfaces
            Effect: Allow
            Resource: "*"
        Version: "2012-10-17"
      PolicyName: cloudcollectorv3redactorServiceRoleDefaultPolicy3AE409B5
      Roles:
        - Ref: cloudcollectorv3redactorServiceRole9543ADB8
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/cloud-collector-v3-redactor/ServiceRole/DefaultPolicy/Resource
  cloudcollectorv3redactorBACFAA12:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket:
          Fn::Join:
            - ""
            - - Ref: AWS::Region
              - -operata-shared-assets-prod
        S3Key: ccv3-lambdas/v1.2.6/cloud-collector-v3-contact-trace-records.zip
      Environment:
        Variables:
          OPERATA_API_KEY:
            Ref: operataAPIKeySM
          OPERATA_API_URL:
            Ref: apiEndpointUrl
          OPERATA_GROUP_ID:
            Ref: operataGroupId
          LOG_LEVEL: "0"
          BUILD_VERSION: v1.2.6
          AGENT_DATA_S3_BUCKET:
            Fn::If:
              - HasBucketName
              - Fn::Select:
                  - 0
                  - Ref: agentDataS3BucketName
              - ""
          AGENT_DATA_S3_BUCKET_PREFIX:
            Fn::If:
              - HasPrefix
              - Fn::Select:
                  - 1
                  - Ref: agentDataS3BucketName
              - ""
          AGENT_LOOKUP_KEY:
            Ref: agentLookupKey
      Handler: bootstrap
      Role:
        Fn::GetAtt:
          - cloudcollectorv3redactorServiceRole9543ADB8
          - Arn
      Runtime: provided.al2023
      Timeout: 60
    DependsOn:
      - cloudcollectorv3redactorServiceRoleDefaultPolicy3AE409B5
      - cloudcollectorv3redactorServiceRole9543ADB8
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/cloud-collector-v3-redactor/Resource
  LambdaS3Policy907BA583:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action: s3:GetObject
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - "arn:aws:s3:::"
                  - Fn::If:
                      - HasBucketName
                      - Fn::Select:
                          - 0
                          - Ref: agentDataS3BucketName
                      - ""
                  - /*
          - Action: s3:ListBucket
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - "arn:aws:s3:::"
                  - Fn::If:
                      - HasBucketName
                      - Fn::Select:
                          - 0
                          - Ref: agentDataS3BucketName
                      - ""
        Version: "2012-10-17"
      PolicyName: AgentDataS3Access
      Roles:
        - Ref: cloudcollectorv3redactorServiceRole9543ADB8
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/LambdaS3Policy/Resource
    Condition: HasBucketName
  operataEventBridgePipeLambdaPolicy21093044:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - lambda:InvokeFunction
              - lambda:InvokeFunctionUrl
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - cloudcollectorv3redactorBACFAA12
                - Arn
        Version: "2012-10-17"
      PolicyName:
        Fn::Join:
          - ""
          - - LambdaPolicy-Operata-GroupId-
            - Ref: operataGroupId
      Roles:
        - Ref: operataEventBridgePipeRole3EA09E25
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/operataEventBridgePipeLambdaPolicy/Resource
  eventBridgePipeLogGroupF7A55BD8:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName:
        Fn::Join:
          - ""
          - - /aws/pipes/operataEventsPipe-
            - Ref: connectInstanceFriendlyName
            - -amazonConnect
      RetentionInDays: 7
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/eventBridgePipeLogGroup/Resource
  operataPipe:
    Type: AWS::Pipes::Pipe
    Properties:
      Description:
        Fn::Join:
          - ""
          - - "Pipe for sending CTR records to Operata (group ID: "
            - Ref: operataGroupId
            - ") from the "
            - Ref: connectInstanceFriendlyName
            - " Amazon Connect instance in "
            - Ref: AWS::Region
      DesiredState: RUNNING
      Enrichment:
        Fn::GetAtt:
          - cloudcollectorv3redactorBACFAA12
          - Arn
      LogConfiguration:
        CloudwatchLogsLogDestination:
          LogGroupArn:
            Fn::GetAtt:
              - eventBridgePipeLogGroupF7A55BD8
              - Arn
        IncludeExecutionData:
          - ALL
        Level: ERROR
      Name:
        Fn::Join:
          - ""
          - - operataEventsPipe-
            - Ref: connectInstanceFriendlyName
            - -amazonConnect
      RoleArn:
        Fn::GetAtt:
          - operataEventBridgePipeRole3EA09E25
          - Arn
      Source:
        Ref: ctrKinesisStreamARN
      SourceParameters:
        FilterCriteria:
          Filters:
            - Pattern: '{ "data": {"Channel": ["VOICE"] } }'
        KinesisStreamParameters:
          BatchSize: 1
          MaximumRecordAgeInSeconds: -1
          MaximumRetryAttempts: -1
          StartingPosition: LATEST
      Target:
        Fn::GetAtt:
          - operataApiDestinationFE63AEAB
          - Arn
    DependsOn:
      - cloudcollectorv3redactorBACFAA12
      - cloudcollectorv3redactorServiceRoleDefaultPolicy3AE409B5
      - cloudcollectorv3redactorServiceRole9543ADB8
      - eventBridgePipeLogGroupF7A55BD8
      - operataApiDestinationFE63AEAB
      - operataEventBridgePipeRoleDefaultPolicyDD50B370
      - operataEventBridgePipeRole3EA09E25
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/operataPipe
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/1VQXU/DMAz8LbynhpVJPLOh8YJEtf0A5KWm8to4UT6GUJT/Tloogief7+zzyS202w3c3eBHaHQ/NhOfIZ8i6lHt36VDj4YieVX1txxIe4rBoOBAHurAaWEUo4F8tBPNS0vt7MT6c/FYUFF0JYkB8t6KkI5sZVb/dI+OnyhEFlzF/0xR4R52SY8UdxhITWjOPUI+JPm1W3FRkx3qsRc7PHub3KytuCjHjsIcv6ug/MToeTV5TdGlWJTYnuASbq/tFjYP9UmXwNz4JJENwfG7fgHwFh+ZQQEAAA==
    Metadata:
      aws:cdk:path: CloudCollectorV3Stack/CDKMetadata/Default
    Condition: CDKMetadataAvailable
Conditions:
  HasBucketName:
    Fn::Not:
      - Fn::Or:
          - Fn::Equals:
              - Fn::Length:
                  Ref: agentDataS3BucketName
              - 0
          - Fn::Equals:
              - Fn::Select:
                  - 0
                  - Ref: agentDataS3BucketName
              - ""
  HasPrefix:
    Fn::Equals:
      - Fn::Length:
          Ref: agentDataS3BucketName
      - 2
  CDKMetadataAvailable:
    Fn::Or:
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - af-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-3
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-south-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-3
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-4
          - Fn::Equals:
              - Ref: AWS::Region
              - ca-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ca-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-northwest-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-central-2
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-south-2
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-2
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-3
          - Fn::Equals:
              - Ref: AWS::Region
              - il-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - me-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - me-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - sa-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-2
          - Fn::Equals:
              - Ref: AWS::Region
              - us-west-1
      - Fn::Equals:
          - Ref: AWS::Region
          - us-west-2
Outputs:
  pipeStateOutput:
    Description: The current state of the EventBridge pipe
    Value:
      Fn::GetAtt:
        - operataPipe
        - CurrentState
  secretsManagerSecretARNOutput:
    Description: The Operata API key is stored in AWS Secrets Manager with the following ARN. To change the key create a change set in CloudFormation and update the API Key parameter using the existing template.
    Value:
      Fn::GetAtt:
        - operataConnection322BC7D8
        - SecretArn
  operataGroupIdOutput:
    Description: Events are being sent to the following Operata Group ID
    Value:
      Ref: operataGroupId
  connectInstanceFriendlyNameNameOutput:
    Description: The source of Contact Trace Records is from the following Amazon Connect instance (friendly name)
    Value:
      Ref: connectInstanceFriendlyName
  buildVersionOutput:
    Description: Build version of this template
    Value: v1.2.6

