AWSTemplateFormatVersion: '2010-09-09'
Conditions:
  IsProd:
    Fn::Equals:
      - Ref: StageName
      - production
Globals:
  Function:
    Environment:
      Variables:
        TABLE_ACCOUNT:
          Ref: TableAccount
        TABLE_SUBSCRIPTION:
          Ref: TableSubscription
    Handler: index.handler
    MemorySize: 256
    Runtime: nodejs18.x
    Timeout: 30
    Tracing: Active
Outputs:
  TableAccount:
    Description: The name of the DynamoDB table for TableAccount
    Export:
      Name:
        Fn::Sub: ${AWS::StackName}-TableAccount
    Value:
      Ref: TableAccount
  TableSubscription:
    Description: The name of the DynamoDB table for TableSubscription
    Export:
      Name:
        Fn::Sub: ${AWS::StackName}-TableSubscription
    Value:
      Ref: TableSubscription
Parameters:
  LogRetentionInDays:
    Default: 3
    Description: Log retention in days
    Type: Number
  StageName:
    AllowedValues:
      - development
      - production
      - test
    Default: development
    Description: The name of the stage
    Type: String
Resources:
  FnHandlerSInsertAa23d7fc7:
    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        EntryPoints:
          - ./index
        External:
          - '@aws-sdk/*'
        Minify: false
        Sourcemap: true
        Target: es2020
    Properties:
      CodeUri: enricher--subscription--insert--account
      Events:
        Stream:
          Properties:
            BatchSize: 10
            FunctionResponseTypes:
              - ReportBatchItemFailures
            Queue:
              Fn::GetAtt:
                - FnHandlerSInsertAa23d7fc7Queue
                - Arn
          Type: SQS
      MemorySize: 256
      Policies:
        - AWSLambdaBasicExecutionRole
        - AWSLambda_ReadOnlyAccess
        - AWSXrayWriteOnlyAccess
        - CloudWatchLambdaInsightsExecutionRolePolicy
        - CloudWatchPutMetricPolicy: {}
        - DynamoDBCrudPolicy:
            TableName:
              Ref: TableAccount
        - SQSSendMessagePolicy:
            QueueName:
              Fn::GetAtt:
                - FnHandlerSInsertAa23d7fc7DLQ
                - QueueName
      Timeout: 90
    Type: AWS::Serverless::Function
  FnHandlerSInsertAa23d7fc7DLQ:
    Properties:
      KmsMasterKeyId:
        Fn::If:
          - IsProd
          - Ref: FnHandlerSInsertAa23d7fc7QueueKey
          - AWS::NoValue
    Type: AWS::SQS::Queue
  FnHandlerSInsertAa23d7fc7LogGroup:
    Properties:
      LogGroupName:
        Fn::Sub: /aws/lambda/${FnHandlerSInsertAa23d7fc7}
      RetentionInDays:
        Ref: LogRetentionInDays
    Type: AWS::Logs::LogGroup
  FnHandlerSInsertAa23d7fc7Queue:
    Properties:
      Fn::If:
        - IsProd
        - KmsMasterKeyId:
            Ref: FnHandlerSInsertAa23d7fc7QueueKey
          RedrivePolicy:
            deadLetterTargetArn:
              Fn::GetAtt:
                - FnHandlerSInsertAa23d7fc7DLQ
                - Arn
            maxReceiveCount: 3
          VisibilityTimeout: 320
        - RedrivePolicy:
            deadLetterTargetArn:
              Fn::GetAtt:
                - FnHandlerSInsertAa23d7fc7DLQ
                - Arn
            maxReceiveCount: 3
          VisibilityTimeout: 320
    Type: AWS::SQS::Queue
  FnHandlerSInsertAa23d7fc7QueueKey:
    Condition: IsProd
    Properties:
      KeyPolicy:
        Statement:
          - Action:
              - kms:Decrypt
              - kms:GenerateDataKey
            Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Resource: '*'
            Sid: Allow EventBridge to use the Key
          - Action:
              - kms:Create*
              - kms:Describe*
              - kms:Enable*
              - kms:List*
              - kms:Put*
              - kms:Update*
              - kms:Revoke*
              - kms:Disable*
              - kms:Get*
              - kms:Delete*
              - kms:ScheduleKeyDeletion
              - kms:CancelKeyDeletion
            Effect: Allow
            Principal:
              AWS:
                Fn::Sub: arn:aws:iam::${AWS::AccountId}:root
            Resource: '*'
            Sid: Allow administration of the key
          - Action:
              - kms:Encrypt
              - kms:Decrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
              - kms:CreateGrant
              - kms:DescribeKey
            Condition:
              StringEquals:
                kms:CallerAccount:
                  Fn::Sub: ${AWS::AccountId}
                kms:ViaService: sqs.us-east-1.amazonaws.com
            Effect: Allow
            Principal:
              AWS: '*'
            Resource: '*'
            Sid: >-
              Allow access through Simple Queue Service (SQS) for all principals
              in the account that are authorized to use SQS
          - Action:
              - kms:Describe*
              - kms:Get*
              - kms:List*
              - kms:RevokeGrant
            Effect: Allow
            Principal:
              AWS:
                Fn::Sub: arn:aws:iam::${AWS::AccountId}:root
            Resource: '*'
            Sid: Allow direct access to key metadata to the account
        Version: '2012-10-17'
      PendingWindowInDays: 7
    Type: AWS::KMS::Key
  FnHandlerSInsertAa23d7fc7QueuePolicy:
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - sqs:SendMessage
            Condition:
              ArnEquals:
                aws:SourceArn:
                  Fn::GetAtt:
                    - FnHandlerSInsertAa23d7fc7Rule
                    - Arn
            Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Resource:
              Fn::GetAtt:
                - FnHandlerSInsertAa23d7fc7Queue
                - Arn
            Sid: Allow EventBridge to send messages to the queue
      Queues:
        - Ref: FnHandlerSInsertAa23d7fc7Queue
    Type: AWS::SQS::QueuePolicy
  FnHandlerSInsertAa23d7fc7Rule:
    Properties:
      EventBusName: default
      EventPattern:
        detail:
          dynamodb:
            NewImage:
              _et:
                S:
                  - Subscription
        detail-type:
          - INSERT
        resources:
          - Fn::GetAtt:
              - TableSubscription
              - Arn
        source:
          - TableSubscription.Subscription
      Targets:
        - Arn:
            Fn::GetAtt:
              - FnHandlerSInsertAa23d7fc7Queue
              - Arn
          Id: FnHandlerSInsertAa23d7fc7
    Type: AWS::Events::Rule
  TableAccount:
    Properties:
      AttributeDefinitions:
        - AttributeName: pk
          AttributeType: S
        - AttributeName: sk
          AttributeType: S
        - AttributeName: lsi1sk
          AttributeType: S
      BillingMode: PAY_PER_REQUEST
      KeySchema:
        - AttributeName: pk
          KeyType: HASH
        - AttributeName: sk
          KeyType: RANGE
      LocalSecondaryIndexes:
        - IndexName: lsi1
          KeySchema:
            - AttributeName: pk
              KeyType: HASH
            - AttributeName: lsi1sk
              KeyType: RANGE
          Projection:
            ProjectionType: ALL
      PointInTimeRecoverySpecification:
        PointInTimeRecoveryEnabled:
          Fn::If:
            - IsProd
            - true
            - false
      SSESpecification:
        SSEEnabled:
          Fn::If:
            - IsProd
            - true
            - false
      Tags:
        - Key: StageName
          Value:
            Ref: StageName
        - Key: TableName
          Value: TableAccount
    Type: AWS::DynamoDB::Table
  TableSubscription:
    Properties:
      AttributeDefinitions:
        - AttributeName: pk
          AttributeType: S
        - AttributeName: sk
          AttributeType: S
      BillingMode: PAY_PER_REQUEST
      KeySchema:
        - AttributeName: pk
          KeyType: HASH
        - AttributeName: sk
          KeyType: RANGE
      PointInTimeRecoverySpecification:
        PointInTimeRecoveryEnabled:
          Fn::If:
            - IsProd
            - true
            - false
      SSESpecification:
        SSEEnabled:
          Fn::If:
            - IsProd
            - true
            - false
      StreamSpecification:
        StreamViewType: NEW_AND_OLD_IMAGES
      Tags:
        - Key: StageName
          Value:
            Ref: StageName
        - Key: TableName
          Value: TableSubscription
    Type: AWS::DynamoDB::Table
  TableSubscriptionCDCDispatcher:
    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        EntryPoints:
          - ./index
        External:
          - '@aws-sdk/*'
        Minify: false
        Sourcemap: true
        Target: es2020
    Properties:
      CodeUri: dispatcher-table-subscription
      Events:
        Stream:
          Properties:
            BatchSize: 10
            FunctionResponseTypes:
              - ReportBatchItemFailures
            MaximumRetryAttempts: 3
            StartingPosition: TRIM_HORIZON
            Stream:
              Fn::GetAtt:
                - TableSubscription
                - StreamArn
          Type: DynamoDB
      MemorySize: 384
      Policies:
        - AWSLambdaBasicExecutionRole
        - AWSLambda_ReadOnlyAccess
        - AWSXrayWriteOnlyAccess
        - CloudWatchLambdaInsightsExecutionRolePolicy
        - CloudWatchPutMetricPolicy: {}
        - EventBridgePutEventsPolicy:
            EventBusName: default
      Timeout: 60
    Type: AWS::Serverless::Function
  TableSubscriptionCDCDispatcherLogGroup:
    Properties:
      LogGroupName:
        Fn::Sub: /aws/lambda/${TableSubscriptionCDCDispatcher}
      RetentionInDays:
        Ref: LogRetentionInDays
    Type: AWS::Logs::LogGroup
Transform: AWS::Serverless-2016-10-31
