AWSTemplateFormatVersion: "2010-09-09"
Description: Lambda used to implement the various task need in the process of increasing the price of subscriptions

Parameters:
  Stage:
    Description: Stage name
    Type: String
    AllowedValues:
      - PROD
      - CODE
      - DEV
    Default: CODE

Mappings:
  StageMap:
    DEV:
      SecretsVersion: "NArGcZ"
      BucketName: price-migration-engine-dev
      SQSQueueName: direct-mail-CODE
      ExportBucketName: price-migration-engine-dev
    CODE:
      SecretsVersion: "CoDz8f"
      BucketName: price-migration-engine-code
      SQSQueueName: direct-mail-CODE
      ExportBucketName: price-migration-engine-code
    PROD:
      SecretsVersion: "TTMSyJ"
      BucketName: price-migration-engine-prod
      SQSQueueName: direct-mail-PROD
      ExportBucketName: ophan-clean-price-migration-engine-cohort-items

Resources:

  ReadFromSecretsManager:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: ReadFromSecretsManager
      PolicyDocument:
        Statement:
          - Effect: Allow
            Action:
              - secretsmanager:DescribeSecret
              - secretsmanager:GetSecretValue
            Resource: !Sub 
                      - "arn:aws:secretsmanager:eu-west-1:865473395570:secret:price-migration-engine-lambda-${Stage}-${SecretsVersion}"
                      - SecretsVersion: !FindInMap [StageMap, !Ref Stage, SecretsVersion]
      Roles:
        - Ref: PriceMigrationEngineTableCreateLambdaRole
        - Ref: PriceMigrationEngineSubscriptionIdUploadLambdaRole
        - Ref: PriceMigrationEngineEstimationLambdaRole
        - Ref: PriceMigrationEngineSalesforcePriceCreationLambdaRole
        - Ref: PriceMigrationEngineAmendmentLambdaRole
        - Ref: PriceMigrationEngineNotificationLambdaRole
        - Ref: PriceMigrationEngineSalesforceNotificationDateUpdateLambdaRole
        - Ref: PriceMigrationEngineSalesforceAmendmentUpdateLambdaRole
        - Ref: PriceMigrationEngineCohortTableDatalakeExportLambdaRole

  ReadFromDistBucketPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: ReadFromDistBucketPolicy
      PolicyDocument:
        Statement:
          - Effect: Allow
            Action: s3:GetObject
            Resource:
              - arn:aws:s3::*:membership-dist/*
      Roles:
        - Ref: PriceMigrationEngineTableCreateLambdaRole
        - Ref: PriceMigrationEngineSubscriptionIdUploadLambdaRole
        - Ref: PriceMigrationEngineEstimationLambdaRole
        - Ref: PriceMigrationEngineSalesforcePriceCreationLambdaRole
        - Ref: PriceMigrationEngineAmendmentLambdaRole
        - Ref: PriceMigrationEngineNotificationLambdaRole
        - Ref: PriceMigrationEngineSalesforceNotificationDateUpdateLambdaRole
        - Ref: PriceMigrationEngineSalesforceAmendmentUpdateLambdaRole
        - Ref: PriceMigrationEngineCohortTableDatalakeExportLambdaRole

  CohortTableAccessPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: CohortTableAccessPolicy
      PolicyDocument:
        Statement:
          - Effect: Allow
            Action:
              - dynamodb:Query
              - dynamodb:Scan
              - dynamodb:UpdateItem
              - dynamodb:PutItem
            Resource:
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/PriceMigrationEngine${Stage}"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/PriceMigrationEngine${Stage}/*"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/PriceMigration-${Stage}-*"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/PriceMigration-${Stage}-*/*"
      Roles:
        - Ref: PriceMigrationEngineEstimationLambdaRole
        - Ref: PriceMigrationEngineSalesforcePriceCreationLambdaRole
        - Ref: PriceMigrationEngineAmendmentLambdaRole
        - Ref: PriceMigrationEngineNotificationLambdaRole
        - Ref: PriceMigrationEngineSalesforceNotificationDateUpdateLambdaRole
        - Ref: PriceMigrationEngineSalesforceAmendmentUpdateLambdaRole
        - Ref: PriceMigrationEngineCohortTableDatalakeExportLambdaRole
        - Ref: PriceMigrationEngineSubscriptionIdUploadLambdaRole

  PriceMigrationEngineTableCreateLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: LambdaPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - lambda:InvokeFunction
                Resource:
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/price-migration-engine-table-create-lambda-${Stage}:log-stream:*"
        - PolicyName: CohortTablePolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:DescribeTable
                  - dynamodb:CreateTable
                  - dynamodb:UpdateContinuousBackups
                Resource:
                  - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/PriceMigration*"
                  - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/PriceMigration*/*"

  PriceMigrationEngineEstimationLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: LambdaPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - lambda:InvokeFunction
                Resource:
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/price-migration-engine-estimation-lambda-${Stage}:log-stream:*"

  PriceMigrationEngineSalesforcePriceCreationLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: LambdaPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - lambda:InvokeFunction
                Resource:
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/price-migration-engine-salesforce-price-rise-lambda-${Stage}:log-stream:*"

  PriceMigrationEngineAmendmentLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: LambdaPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - lambda:InvokeFunction
                Resource:
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/price-migration-engine-amendment-lambda-${Stage}:log-stream:*"

  PriceMigrationEngineSubscriptionIdUploadLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: LambdaPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - lambda:InvokeFunction
                Resource:
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/price-migration-engine-subscription-id-upload-lambda-${Stage}:log-stream:*"
        - PolicyName: S3BucketPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - s3:ListBucket
                  - s3:GetObject
                  - s3:DeleteObject
                Resource:
                  - !Sub
                    - "arn:aws:s3:::${BucketName}"
                    - {BucketName: !FindInMap [StageMap, !Ref Stage, BucketName]}
                  - !Sub
                    - "arn:aws:s3:::${BucketName}/*"
                    - {BucketName: !FindInMap [StageMap, !Ref Stage, BucketName]}
    DependsOn:
      - S3Bucket

  PriceMigrationEngineNotificationLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: LambdaPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - lambda:InvokeFunction
                Resource:
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/price-migration-engine-notification-lambda-${Stage}:log-stream:*"
        - PolicyName: SendNotificationRequestSQSMessage
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - sqs:GetQueueUrl
                  - sqs:SendMessage
                Resource: !Sub
                  - "arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:${QueueName}"
                  - { QueueName: !FindInMap [ StageMap, !Ref Stage, SQSQueueName ] }

  PriceMigrationEngineSalesforceNotificationDateUpdateLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: LambdaPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - lambda:InvokeFunction
                Resource:
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/price-migration-engine-salesforce-notification-date-lambda-${Stage}:log-stream:*"

  PriceMigrationEngineSalesforceAmendmentUpdateLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: LambdaPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - lambda:InvokeFunction
                Resource:
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/price-migration-engine-salesforce-amendment-update-lambda-${Stage}:log-stream:*"

  PriceMigrationEngineCohortTableDatalakeExportLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: LambdaPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - lambda:InvokeFunction
                Resource:
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/price-migration-engine-cohort-table-datalake-export-lambda-${Stage}:log-stream:*"
        - PolicyName: S3BucketPolicy
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - s3:PutObject
                  - s3:PutObjectAcl
                Resource:
                  - !Sub
                    - "arn:aws:s3:::${ExportBucketName}/*"
                    - {ExportBucketName: !FindInMap [StageMap, !Ref Stage, ExportBucketName]}
    DependsOn:
      - S3Bucket

  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !FindInMap [StageMap, !Ref Stage, BucketName]
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        IgnorePublicAcls: true
        BlockPublicPolicy: true
        RestrictPublicBuckets: true

  PriceMigrationEngineTableCreateLambda:
    Type: AWS::Lambda::Function
    Properties:
      Description: Creates cohort table, if it doesn't already exist.
      FunctionName:
        !Sub price-migration-engine-table-create-lambda-${Stage}
      Code:
        S3Bucket: membership-dist
        S3Key: !Sub membership/${Stage}/price-migration-engine-lambda/price-migration-engine-lambda.jar
      Handler: pricemigrationengine.handlers.CohortTableCreationHandler::handleRequest
      Environment:
        Variables:
          stage: !Ref Stage
      Role:
        Fn::GetAtt:
          - PriceMigrationEngineTableCreateLambdaRole
          - Arn
      MemorySize: 1536
      Runtime: java11
      Timeout: 900
    DependsOn:
      - PriceMigrationEngineTableCreateLambdaRole

  PriceMigrationEngineSubscriptionIdUploadLambda:
    Type: AWS::Lambda::Function
    Properties:
      Description: Uploads subscription id CSV files into price migration engine.
      FunctionName:
        !Sub price-migration-engine-subscription-id-upload-lambda-${Stage}
      Code:
        S3Bucket: membership-dist
        S3Key: !Sub membership/${Stage}/price-migration-engine-lambda/price-migration-engine-lambda.jar
      Handler: pricemigrationengine.handlers.SubscriptionIdUploadHandler::handleRequest
      Environment:
        Variables:
          stage: !Ref Stage
          batchSize: 100
      Role:
        Fn::GetAtt:
          - PriceMigrationEngineSubscriptionIdUploadLambdaRole
          - Arn
      MemorySize: 1536
      Runtime: java11
      Timeout: 900
    DependsOn:
      - PriceMigrationEngineSubscriptionIdUploadLambdaRole
      - S3Bucket

  PriceMigrationEngineEstimationLambda:
    Type: AWS::Lambda::Function
    Properties:
      Description: Lambda used to create estimated price, start date and other details of a price rise.
      FunctionName:
        !Sub price-migration-engine-estimation-lambda-${Stage}
      Code:
        S3Bucket: membership-dist
        S3Key: !Sub membership/${Stage}/price-migration-engine-lambda/price-migration-engine-lambda.jar
      Handler: pricemigrationengine.handlers.EstimationHandler::handleRequest
      Environment:
        Variables:
          stage: !Ref Stage
          batchSize: 100
      Role:
        Fn::GetAtt:
          - PriceMigrationEngineEstimationLambdaRole
          - Arn
      MemorySize: 1536
      Runtime: java11
      Timeout: 900
    DependsOn:
      - PriceMigrationEngineEstimationLambdaRole

  PriceMigrationEngineSalesforcePriceCreationLambda:
    Type: AWS::Lambda::Function
    Properties:
      Description: Lambda used to create Price_Rise__c objects in salesforce relating to the price rise.
      FunctionName:
        !Sub price-migration-engine-salesforce-price-rise-lambda-${Stage}
      Code:
        S3Bucket: membership-dist
        S3Key: !Sub membership/${Stage}/price-migration-engine-lambda/price-migration-engine-lambda.jar
      Handler: pricemigrationengine.handlers.SalesforcePriceRiseCreationHandler::handleRequest
      Environment:
        Variables:
          stage: !Ref Stage
          batchSize: 100
      Role:
        Fn::GetAtt:
          - PriceMigrationEngineSalesforcePriceCreationLambdaRole
          - Arn
      MemorySize: 1536
      Runtime: java11
      Timeout: 900
    DependsOn:
      - PriceMigrationEngineSalesforcePriceCreationLambdaRole

  PriceMigrationEngineAmendmentLambda:
    Type: AWS::Lambda::Function
    Properties:
      Description: Adds price-rise amendments to subscriptions.
      FunctionName:
        !Sub price-migration-engine-amendment-lambda-${Stage}
      Code:
        S3Bucket: membership-dist
        S3Key: !Sub membership/${Stage}/price-migration-engine-lambda/price-migration-engine-lambda.jar
      Handler: pricemigrationengine.handlers.AmendmentHandler::handleRequest
      Environment:
        Variables:
          stage: !Ref Stage
          batchSize: 100
      Role:
        Fn::GetAtt:
          - PriceMigrationEngineAmendmentLambdaRole
          - Arn
      MemorySize: 1536
      Runtime: java11
      Timeout: 900
    DependsOn:
      - PriceMigrationEngineAmendmentLambdaRole

  PriceMigrationEngineNotificationLambda:
    Type: AWS::Lambda::Function
    Properties:
      Description: Sends notification mails to users telling them about the price rise
      FunctionName:
        !Sub price-migration-engine-notification-lambda-${Stage}
      Code:
        S3Bucket: membership-dist
        S3Key: !Sub membership/${Stage}/price-migration-engine-lambda/price-migration-engine-lambda.jar
      Handler: pricemigrationengine.handlers.NotificationHandler::handleRequest
      Environment:
        Variables:
          stage: !Ref Stage
          batchSize: 100
          sqsEmailQueueName:
            !FindInMap [ StageMap, !Ref Stage, SQSQueueName ]
      Role:
        Fn::GetAtt:
          - PriceMigrationEngineNotificationLambdaRole
          - Arn
      MemorySize: 1536
      Runtime: java11
      Timeout: 900
    DependsOn:
      - PriceMigrationEngineNotificationLambdaRole

  PriceMigrationEngineSalesforceNotificationDateUpdateLambda:
    Type: AWS::Lambda::Function
    Properties:
      Description: Lambda used to update Price_Rise__c objects in salesforce with the notification sent date.
      FunctionName:
        !Sub price-migration-engine-salesforce-notification-date-lambda-${Stage}
      Code:
        S3Bucket: membership-dist
        S3Key: !Sub membership/${Stage}/price-migration-engine-lambda/price-migration-engine-lambda.jar
      Handler: pricemigrationengine.handlers.SalesforceNotificationDateUpdateHandler::handleRequest
      Environment:
        Variables:
          stage: !Ref Stage
          batchSize: 100
      Role:
        Fn::GetAtt:
          - PriceMigrationEngineSalesforceNotificationDateUpdateLambdaRole
          - Arn
      MemorySize: 1536
      Runtime: java11
      Timeout: 900
    DependsOn:
      - PriceMigrationEngineSalesforceNotificationDateUpdateLambdaRole

  PriceMigrationEngineSalesforceAmendmentUpdateLambda:
    Type: AWS::Lambda::Function
    DependsOn:
      - PriceMigrationEngineSalesforceAmendmentUpdateLambdaRole
    Properties:
      Description: Updates Salesforce with evidence of the price-rise amendment that was applied in Zuora.
      FunctionName:
        !Sub price-migration-engine-salesforce-amendment-update-lambda-${Stage}
      Code:
        S3Bucket: membership-dist
        S3Key: !Sub membership/${Stage}/price-migration-engine-lambda/price-migration-engine-lambda.jar
      Handler: pricemigrationengine.handlers.SalesforceAmendmentUpdateHandler::handleRequest
      Environment:
        Variables:
          stage: !Ref Stage
          batchSize: 100
      Role:
        Fn::GetAtt:
          - PriceMigrationEngineSalesforceAmendmentUpdateLambdaRole
          - Arn
      MemorySize: 1536
      Runtime: java11
      Timeout: 900

  PriceMigrationEngineCohortTableDatalakeExportLambda:
    Type: AWS::Lambda::Function
    Properties:
      Description: Exports the cohort table to s3 for so it is available for import into the datalake.
      FunctionName:
        !Sub price-migration-engine-cohort-table-datalake-export-lambda-${Stage}
      Code:
        S3Bucket: membership-dist
        S3Key: !Sub membership/${Stage}/price-migration-engine-lambda/price-migration-engine-lambda.jar
      Handler: pricemigrationengine.handlers.CohortTableDatalakeExportHandler::handleRequest
      Environment:
        Variables:
          stage: !Ref Stage
          batchSize: 100
          exportBucketName: !FindInMap [StageMap, !Ref Stage, ExportBucketName]
      Role:
        Fn::GetAtt:
          - PriceMigrationEngineCohortTableDatalakeExportLambdaRole
          - Arn
      MemorySize: 1536
      Runtime: java11
      Timeout: 900
    DependsOn:
      - PriceMigrationEngineCohortTableDatalakeExportLambdaRole
      - S3Bucket

Outputs:
  PriceMigrationEngineTableCreateLambdaOutput:
    Value: !GetAtt PriceMigrationEngineTableCreateLambda.Arn
    Export:
      Name: !Sub "${AWS::StackName}-CreatingCohortTableLambda"
  PriceMigrationEngineSubscriptionIdUploadLambdaOutput:
    Value: !GetAtt PriceMigrationEngineSubscriptionIdUploadLambda.Arn
    Export:
      Name: !Sub "${AWS::StackName}-ImportingLambda"
  PriceMigrationEngineEstimationLambdaOutput:
    Value: !GetAtt PriceMigrationEngineEstimationLambda.Arn
    Export:
      Name: !Sub "${AWS::StackName}-EstimatingLambda"
  PriceMigrationEngineSalesforcePriceCreationLambdaOutput:
    Value: !GetAtt PriceMigrationEngineSalesforcePriceCreationLambda.Arn
    Export:
      Name: !Sub "${AWS::StackName}-CreatingSalesforceRecordsLambda"
  PriceMigrationEngineNotificationLambdaOutput:
    Value: !GetAtt PriceMigrationEngineNotificationLambda.Arn
    Export:
      Name: !Sub "${AWS::StackName}-NotifyingSubscribersLambda"
  PriceMigrationEngineSalesforceNotificationDateUpdateLambdaOutput:
    Value: !GetAtt PriceMigrationEngineSalesforceNotificationDateUpdateLambda.Arn
    Export:
      Name: !Sub "${AWS::StackName}-UpdatingSalesforceWithNotificationsLambda"
  PriceMigrationEngineAmendmentLambdaOutput:
    Value: !GetAtt PriceMigrationEngineAmendmentLambda.Arn
    Export:
      Name: !Sub "${AWS::StackName}-AmendingLambda"
  PriceMigrationEngineSalesforceAmendmentUpdateLambdaOutput:
    Value: !GetAtt PriceMigrationEngineSalesforceAmendmentUpdateLambda.Arn
    Export:
      Name: !Sub "${AWS::StackName}-UpdatingSalesforceWithAmendsLambda"
  PriceMigrationEngineCohortTableDatalakeExportLambdaOutput:
    Value: !GetAtt PriceMigrationEngineCohortTableDatalakeExportLambda.Arn
    Export:
      Name: !Sub "${AWS::StackName}-ExportingCohortTableToDatalakeLambda"
