AWSTemplateFormatVersion: 2010-09-09
Description: CF template to create Aurora (postgresql flavor) for Metadata database
Parameters:
  ParentVPCStack:
    Description: Name of the Cloudformation stack created by eksctl (eksctl-<name>-cluster)
    Type: String
    MinLength: 1
    MaxLength: 128
    AllowedPattern: '^[a-zA-Z]+[0-9a-zA-Z\-]*$'
  DBUsername:
    Default: postgres
    NoEcho: 'true'
    Description: Username for database access
    Type: String
    MinLength: '1'
    MaxLength: '16'
    AllowedPattern: '^[a-zA-Z]+[0-9a-zA-Z_]*$'
    ConstraintDescription: Must start with a letter. Only numbers, letters, and _ accepted. max length 16 characters
  DBPassword:
    NoEcho: 'true'
    Description: Password for database access
    Type: String
    MinLength: '8'
    MaxLength: '41'
    AllowedPattern: '^[!#-.0-?A-~]*$'
    ConstraintDescription: must contain only printable characters except "/", """ and "@".
  DBInstanceType:
    Default: db.r5.large
    Description: DB Instance Type.
    Type: String
    AllowedValues:
      - db.t3.medium
      - db.t3.large
      - db.t4g.medium
      - db.t4g.large
      - db.r5.large
      - db.r5.xlarge
      - db.r5.2xlarge
      - db.r5.4xlarge
      - db.r5.8xlarge
      - db.r5.12xlarge
      - db.r5.16xlarge
      - db.r5.24xlarge
      - db.r6g.large
      - db.r6g.xlarge
      - db.r6g.2xlarge
      - db.r6g.4xlarge
      - db.r6g.8xlarge
      - db.r6g.12xlarge
      - db.r6g.16xlarge
  DBEngineVersion:
    Default: '14.4'
    Description: Version of PostgreSQL-complatible engine of Aurora RDS
    Type: String
    AllowedValues:
      - '11.16'
      - '12.11'
      - '13.7'
      - '14.3'
      - '14.4'
  SnapshotARN:
    Default: ''
    Description: ARN of snapshot to be restored during upgrade
    Type: String

Mappings:
  DBFamilyMap:
    "11.16":
      "family": "aurora-postgresql11"
    "12.11":
      "family": "aurora-postgresql12"
    "13.7":
      "family": "aurora-postgresql13"
    "14.3":
      "family": "aurora-postgresql14"
    "14.4":
      "family": "aurora-postgresql14"

Resources:
  MDRDSCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      AvailabilityZones:
        Fn::GetAZs:
          Ref: "AWS::Region"
      BackupRetentionPeriod: 3
      DatabaseName: "md"
      DBSubnetGroupName: !Ref MDDBSubnetGroup
      EnableCloudwatchLogsExports:
      - "postgresql"
      EnableIAMDatabaseAuthentication: true
      Engine: 'aurora-postgresql'
      EngineMode: 'provisioned'
      EngineVersion: !Ref DBEngineVersion
      MasterUsername: !Ref DBUsername
      MasterUserPassword: !Ref DBPassword
      Port: 5432
      VpcSecurityGroupIds:
      - !GetAtt MDVpcSecurityGroup.GroupId
      DBClusterParameterGroupName: !Ref MDDBClusterParameterGroup
      SnapshotIdentifier: !Ref SnapshotARN

  MDInstance1:
    Type: 'AWS::RDS::DBInstance'
    Properties:
      Engine: aurora-postgresql
      EngineVersion: !Ref DBEngineVersion
      DBClusterIdentifier: !Ref MDRDSCluster
      PubliclyAccessible: false
      DBInstanceClass: !Ref DBInstanceType
      DBParameterGroupName: !Ref MDDBParameterGroup
      DBSubnetGroupName: !Ref MDDBSubnetGroup
  MDInstance2:
    Type: 'AWS::RDS::DBInstance'
    Properties:
      Engine: aurora-postgresql
      EngineVersion: !Ref DBEngineVersion
      DBClusterIdentifier: !Ref MDRDSCluster
      PubliclyAccessible: false
      DBInstanceClass: !Ref DBInstanceType
      DBParameterGroupName: !Ref MDDBParameterGroup
      DBSubnetGroupName: !Ref MDDBSubnetGroup

  MDDBClusterParameterGroup:
    Type: AWS::RDS::DBClusterParameterGroup
    Properties:
      Description: "MD Database Cluster Parameter Group"
      Family: !FindInMap [DBFamilyMap, !Ref DBEngineVersion, "family"]
      Parameters:
        rds.force_ssl: 1

  MDDBParameterGroup:
    Type: "AWS::RDS::DBParameterGroup"
    Properties:
      Description: "MD Database Parameter Group"
      Family: !FindInMap [DBFamilyMap, !Ref DBEngineVersion, "family"]
      Parameters:
        shared_preload_libraries: auto_explain,pg_hint_plan
        log_statement: "ddl"
        log_connections: 1
        log_disconnections: 1
        log_lock_waits: 1
        log_min_duration_statement: 5000
        auto_explain.log_min_duration: 5000
        auto_explain.log_verbose: 1
        log_rotation_age: 1440
        log_rotation_size: 102400
        rds.log_retention_period: 10080
        random_page_cost: 1
        track_activity_query_size: 16384
        idle_in_transaction_session_timeout: 7200000
        statement_timeout: 7200000
        search_path: '"$user",public'

  MDVpcSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Open database for access
      VpcId:
        Fn::ImportValue: !Sub "${ParentVPCStack}::VPC"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 5432
          ToPort: 5432
          SourceSecurityGroupId:
            Fn::ImportValue: !Sub "${ParentVPCStack}::SharedNodeSecurityGroup"

  MDDBSubnetGroup:
    Type: 'AWS::RDS::DBSubnetGroup'
    Properties:
      DBSubnetGroupDescription: !Ref 'AWS::StackName'
      SubnetIds: !Split [',', {'Fn::ImportValue': !Sub '${ParentVPCStack}::SubnetsPrivate'}]

Outputs:
  ClusterEndpoint:
    Description: 'Aurora Cluster/Writer Endpoint'
    Value: !GetAtt 'MDRDSCluster.Endpoint.Address'
  ReaderEndpoint:
    Description: 'Aurora Reader Endpoint'
    Value: !GetAtt 'MDRDSCluster.ReadEndpoint.Address'
  Port:
    Description: 'Aurora Endpoint Port'
    Value: !GetAtt 'MDRDSCluster.Endpoint.Port'
  DBUsername:
    Description: 'Database master username'
    Value: !Ref DBUsername
  DBPassword:
    Description: 'Database master password'
    Value: !Ref DBPassword
