service: 'click-staging-rds'

provider:
  name: aws
  runtime: python3.7
  profile: 'click-test-cpt'
  stackName: 'click-staging-rds'
  region: 'af-south-1'
  stage: ${self:provider.profile}
  deploymentBucket:
    name: ${self:custom.ServerlessBucketName}
    serverSideEncryption: AES256
    blockPublicAccess: true

plugins:
  - serverless-parameters

custom:
  CustomerName: click
  StageName: staging
  # Combination of profile and function name used as bucket name:
  ResourceName: serverless-framework # Only lowercase letters and numbers allowed. Used to populate bucket name.
  ServerlessBucketName: '${self:custom.ResourceName}-${self:provider.stage}-${self:provider.region}'
  PrivateSubnetA2:
    Fn::ImportValue: !Sub '${self:custom.CustomerName}-${self:custom.StageName}-PrivateSubnetA2'
  PrivateSubnetB2:
    Fn::ImportValue: !Sub '${self:custom.CustomerName}-${self:custom.StageName}-PrivateSubnetB2'
  PrivateSubnetA1CidrIp:
    Fn::ImportValue: !Sub '${self:custom.CustomerName}-${self:custom.StageName}-PrivateSubnetA1CidrIp'
  PrivateSubnetB1CidrIp:
    Fn::ImportValue: !Sub '${self:custom.CustomerName}-${self:custom.StageName}-PrivateSubnetB1CidrIp'

  # CloudFormation parameters templates
  parameters:
    paramCustomerName:
      Description: Enter the Customer Name, used to tag everything
      Type: String
      Default: '${self:custom.CustomerName}'

    # RDS Settings
    DatabaseInstanceIdentifier:
      AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
      ConstraintDescription: Must start with a letter and contain only alphanumeric characters
      Default: myAuroraPsqlDb
      Description: Instance identifier name
      MaxLength: 60
      MinLength: 1
      Type: String

    DatabaseName:
      AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
      ConstraintDescription: Must start with a letter and contain only alphanumeric characters
      Default: applicationDb
      Description: PostgreSQL database name
      MaxLength: 64
      MinLength: 1
      Type: String

    DBClusterIdentifier:
      AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
      ConstraintDescription: Must start with a letter and contain only alphanumeric characters
      Default: applicationDb
      Description: Aurora PostgreSQL cluster name
      MaxLength: 64
      MinLength: 1
      Type: String

    DatabaseUser:
      AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
      ConstraintDescription: Must start with a letter and contain only alphanumeric characters
      Default: dbadmin
      Description: Username for PostgreSQL database
      MaxLength: 16
      MinLength: 1
      #    NoEcho: true
      Type: String

    DatabasePassword:
      AllowedPattern: '[a-zA-Z0-9]*'
      ConstraintDescription: Must contain only alphanumeric characters
      Default: password
      Description: Password for PostgreSQL database access
      MaxLength: 41
      MinLength: 8
      #    NoEcho: true
      Type: String

    DatabaseBackupRetentionPeriod:
      ConstraintDescription: Database backup retention period must be between 0 and 35 days
      Default: 35
      Description: The number of days for which the automatic DB snapshots are mainitained
      MaxValue: 35
      MinValue: 1
      Type: Number

    DatabasePreferredBackupWindow:
      ConstraintDescription: ddd:hh24:mi-ddd:hh24:mi
      Description: The number of days for which the automatic DB snapshots are mainitained
      Type: String
      Default: '01:00-03:00'

    DatabaseAllocatedStorage:
      ConstraintDescription: Must be between 5 and 1024
      Default: 5
      Description: The size of the database
      MaxValue: 1024
      MinValue: 5
      Type: Number

    DatabaseInstanceClass:
      AllowedValues:
        - db.t3.medium
      ConstraintDescription: Must select a valid database instance class
      Default: db.t3.medium
      Description: The database instance class
      Type: String

resources:

  # CloudFormation resource templates

  #Conditions:

  Resources:

    # RDS

    # Create DataBase Security Group

    DataBaseSecurityGroup:
      Type: 'AWS::EC2::SecurityGroup'
      Properties:
        GroupDescription: Open database for access for EC2 subnet
        SecurityGroupIngress:
          - CidrIp: '${self:custom.PrivateSubnetA1CidrIp}'
            IpProtocol: tcp
            FromPort: 5432
            ToPort: 5432
          - CidrIp: '${self:custom.PrivateSubnetB1CidrIp}'
            IpProtocol: tcp
            FromPort: 5432
            ToPort: 5432
        #          SourceSecurityGroupId: (The EC2 instance in A1)
        VpcId:
          Fn::ImportValue: !Sub '${self:custom.CustomerName}-${self:custom.StageName}-VPC'
        Tags:
          - Key: Name
            Value: !Join
              - '-'
              - - '${self:custom.CustomerName}'
                - '${self:custom.StageName}'
                - 'AuroraDB'
                - 'SecurityGroup'

    # Create DataBase Subnet Group

    DatabaseSubnetGroup:
      Type: AWS::RDS::DBSubnetGroup
#      DependsOn:
#        - PrivateSubnetA2
#        - PrivateSubnetB2
      Properties:
        DBSubnetGroupDescription: Subnet group for RDS database
        SubnetIds:
          - '${self:custom.PrivateSubnetA2}'
          - '${self:custom.PrivateSubnetB2}'
        Tags:
          - Key: Name
            Value: !Join
              - '-'
              - - '${self:custom.CustomerName}'
                - '${self:custom.StageName}'
                - 'AuroraDB'
                - 'SubnetGroup'

    # KMS RDS encryption key

    rdsKey:
      Type: AWS::KMS::Key
      Properties:
        KeyPolicy:
          Version: '2012-10-17'
          Id: key-rds
          Statement:
            - Sid: 'Enable IAM User Permissions'
              Effect: 'Allow'
              Principal:
                AWS: !Join
                  - ''
                  - - 'arn:aws:iam::'
                    - !Ref 'AWS::AccountId'
                    - ':root'
              Action: 'kms:*'
              Resource: '*'

    # KMS RDS encryption key alias

    rdsAlias:
      Type: AWS::KMS::Alias
      Properties:
        AliasName: alias/rds
        TargetKeyId:
          Ref: rdsKey

    # Aurora DB Cluster

    AuroraDBCluster:
      Type: AWS::RDS::DBCluster
      DependsOn:
        - DatabaseSubnetGroup
        - DataBaseSecurityGroup
      Properties:
        DBClusterIdentifier: !Join
          - '-'
          - - '${self:custom.CustomerName}'
            - '${self:custom.StageName}'
            - 'AuroraDB'
            - 'Cluster'
        StorageEncrypted: true
        KmsKeyId: !Ref rdsKey
        Engine: aurora-postgresql
        DatabaseName: !Ref DatabaseName
        MasterUsername: !Ref DatabaseUser
        MasterUserPassword: !Ref DatabasePassword
        DBSubnetGroupName: !Ref DatabaseSubnetGroup
        Port: 5432
        VpcSecurityGroupIds:
          - !Ref DataBaseSecurityGroup
        BackupRetentionPeriod: !Ref DatabaseBackupRetentionPeriod
        PreferredBackupWindow: !Ref DatabasePreferredBackupWindow
        Tags:
          - Key: Name
            Value: !Join
              - '-'
              - - '${self:custom.CustomerName}'
                - '${self:custom.StageName}'
                - 'AuroraDB'
                - 'Cluster'
          - Key: backup
            Value: daily

    AuroraDBFirstInstance:
      Type: AWS::RDS::DBInstance
      DependsOn:
        - AuroraDBCluster
      Properties:
        DBInstanceClass:
          Ref: DatabaseInstanceClass
        DBClusterIdentifier: !Ref AuroraDBCluster
        DBInstanceIdentifier: Primary
        Engine: aurora-postgresql
        DBSubnetGroupName: !Ref DatabaseSubnetGroup
        PubliclyAccessible: false
        EnablePerformanceInsights: true
        Tags:
          - Key: Name
            Value: !Join
              - '-'
              - - '${self:custom.CustomerName}'
                - '${self:custom.StageName}'
                - 'AuroraDB'
                - 'FirstInstance'

    AuroraDBSecondInstance:
      Type: AWS::RDS::DBInstance
      DependsOn:
        - AuroraDBFirstInstance
      Properties:
        DBInstanceClass:
          Ref: DatabaseInstanceClass
        DBClusterIdentifier: !Ref AuroraDBCluster
        DBInstanceIdentifier: Read-Replica
        Engine: aurora-postgresql
        DBSubnetGroupName: !Ref DatabaseSubnetGroup
        PubliclyAccessible: false
        EnablePerformanceInsights: true
        Tags:
          - Key: Name
            Value: !Join
              - '-'
              - - '${self:custom.CustomerName}'
                - '${self:custom.StageName}'
                - 'AuroraDB'
                - 'SecondInstance'

  ## Outputs

#-----------------------------------------------------------------------#
