AWSTemplateFormatVersion: '2010-09-09'
Description: RDS MySQL instance for O11y control plane

Parameters:
  DBName:
    Type: String
    Description: The name of the database to create when the DB instance is created.
  DBInstanceIdentifier:
    Type: String
    Description: A name for the DB instance.
  DBInstanceClass:
    Type: String
    Default: db.t4g.large
    Description: RDS instance class
  AllocatedStorage:
    Type: Number
    Default: 20
    Description: Allocated storage in GB
  MaxAllocatedStorage:
    Type: Number
    Default: 1000
    Description: Maximum allocated storage for autoscaling in GB
  DBUsername:
    Type: String
    Default: admin
    Description: Database master username
  DBPassword:
    Type: String
    NoEcho: true
    Description: Database master password
  VpcId:
    Type: String
    Description: VPC ID
  SubnetIds:
    Type: CommaDelimitedList
    Description: Comma-delimited list of subnet IDs for DB subnet group
  MultiAZ:
    Type: String
    Default: 'true'
    AllowedValues:
      - 'true'
      - 'false'
    Description: Enable Multi-AZ deployment
  BackupRetentionPeriod:
    Type: Number
    Default: 7
    Description: Backup retention period in days
  PreferredBackupWindow:
    Type: String
    Default: '03:00-04:00'
    Description: Preferred backup window
  EKSClusterSecurityGroupId:
    Type: String
    Description: EKS cluster security group ID to allow access from
  WhitelistedCIDR:
    Type: String
    Default: 35.155.73.60/32
    Description: CIDR block allowed to access the RDS instance
  EngineVersion:
    Type: String
    Default: '8.4.9'
    Description: MySQL engine version

Resources:
  DBSubnetGroup:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupName: !Sub '${DBInstanceIdentifier}-subnet-group'
      DBSubnetGroupDescription: !Sub 'Subnet group for ${DBInstanceIdentifier}'
      SubnetIds: !Ref SubnetIds
      Tags:
        - Key: Name
          Value: !Sub '${DBInstanceIdentifier}-subnet-group'

  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub '${DBInstanceIdentifier}-sg'
      GroupDescription: !Sub 'Security group for ${DBInstanceIdentifier} RDS instance'
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          SourceSecurityGroupId: !Ref EKSClusterSecurityGroupId
          Description: Allow MySQL access from EKS cluster nodes and pods
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: !Ref WhitelistedCIDR
          Description: Allow MySQL access from the o11y whitelist IP
      Tags:
        - Key: Name
          Value: !Sub '${DBInstanceIdentifier}-sg'

  DBInstance:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Snapshot
    Properties:
      DBInstanceIdentifier: !Ref DBInstanceIdentifier
      DBName: !Ref DBName
      Engine: mysql
      EngineVersion: !Ref EngineVersion
      DBInstanceClass: !Ref DBInstanceClass
      AllocatedStorage: !Ref AllocatedStorage
      MaxAllocatedStorage: !Ref MaxAllocatedStorage
      StorageType: gp3
      StorageEncrypted: true
      MasterUsername: !Ref DBUsername
      MasterUserPassword: !Ref DBPassword
      DBSubnetGroupName: !Ref DBSubnetGroup
      VPCSecurityGroups:
        - !Ref DBSecurityGroup
      DBParameterGroupName: default.mysql8.0
      MultiAZ: !Ref MultiAZ
      BackupRetentionPeriod: !Ref BackupRetentionPeriod
      PreferredBackupWindow: !Ref PreferredBackupWindow
      EnableCloudwatchLogsExports:
        - error
        - slowquery
      DeletionProtection: true
      PubliclyAccessible: false
      AutoMinorVersionUpgrade: false
      CopyTagsToSnapshot: true
      Tags:
        - Key: Name
          Value: !Ref DBInstanceIdentifier

Outputs:
  DBInstanceEndpoint:
    Description: RDS instance endpoint
    Value: !GetAtt DBInstance.Endpoint.Address
  DBInstancePort:
    Description: RDS instance port
    Value: !GetAtt DBInstance.Endpoint.Port
  DBName:
    Description: Database name
    Value: !Ref DBName
  DBUsername:
    Description: Database username
    Value: !Ref DBUsername
  DBSecurityGroupId:
    Description: Security group ID
    Value: !Ref DBSecurityGroup
