Cloud

Setup AWS RDS MySQL Instance with CloudFormation

AWS RDS (Relational Database Service) removes the heavy lifting of managing MySQL infrastructure – patching, backups, failover, and scaling are all handled by AWS. Defining your RDS instances with AWS CloudFormation takes this further by making your database infrastructure repeatable, version-controlled, and auditable.

This guide walks through creating an AWS RDS MySQL instance using CloudFormation. We cover the full stack – VPC networking, subnet groups, security groups, parameterized templates, Multi-AZ deployments, automated backups, monitoring with Enhanced Monitoring and Performance Insights, and RDS Proxy for connection pooling. Every resource is defined in a single CloudFormation template you can deploy, update, and tear down cleanly.

Prerequisites

Before starting, confirm the following are in place:

  • An active AWS account with permissions to create RDS, VPC, IAM, and CloudFormation resources
  • AWS CLI v2 installed and configured with valid credentials (aws configure)
  • An existing VPC with at least two subnets in different Availability Zones (required for DB subnet groups)
  • A MySQL client installed locally for testing connectivity (mysql CLI or MySQL Workbench)
  • Basic familiarity with CloudFormation YAML template syntax

Step 1: Design the RDS Architecture

An RDS MySQL deployment requires several networking and security components before the database instance itself. Here is what we need:

  • DB Subnet Group – Tells RDS which subnets (and therefore which Availability Zones) it can place the instance in. You need subnets in at least two AZs for high availability
  • Security Group – Controls which IP ranges or security groups can connect to the RDS instance on port 3306 (MySQL default)
  • RDS Instance – The MySQL database engine, instance class, storage, and configuration

The architecture places the RDS instance in private subnets (not publicly accessible) with a security group allowing traffic only from your application servers or a specific CIDR range. This is the standard production pattern – never expose RDS directly to the internet.

Step 2: Create the CloudFormation Template

Create a file called rds-mysql.yaml with the complete CloudFormation template. This template defines the DB subnet group, security group, and the RDS MySQL instance as a single deployable stack.

vi rds-mysql.yaml

Add the following CloudFormation template:

AWSTemplateFormatVersion: '2010-09-09'
Description: RDS MySQL instance with subnet group, security group, and monitoring

Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: VPC where RDS will be deployed

  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
    Description: At least two subnets in different AZs for the DB subnet group

  AllowedCidr:
    Type: String
    Default: 10.0.0.0/16
    Description: CIDR range allowed to connect to MySQL (port 3306)

  DBInstanceClass:
    Type: String
    Default: db.t3.micro
    AllowedValues:
      - db.t3.micro
      - db.t3.small
      - db.t3.medium
      - db.r6g.large
      - db.r6g.xlarge
    Description: RDS instance type

  DBAllocatedStorage:
    Type: Number
    Default: 20
    MinValue: 20
    MaxValue: 1000
    Description: Storage size in GB (gp3)

  DBName:
    Type: String
    Default: appdb
    Description: Initial database name
    AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
    MaxLength: 64

  MasterUsername:
    Type: String
    Default: admin
    Description: Master username for the RDS instance
    AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
    MaxLength: 16

  MasterUserPassword:
    Type: String
    NoEcho: true
    MinLength: 8
    MaxLength: 41
    Description: Master password (8-41 characters)

  MultiAZ:
    Type: String
    Default: 'false'
    AllowedValues:
      - 'true'
      - 'false'
    Description: Enable Multi-AZ deployment for high availability

  BackupRetentionPeriod:
    Type: Number
    Default: 7
    MinValue: 0
    MaxValue: 35
    Description: Number of days to retain automated backups (0 disables backups)

  EngineVersion:
    Type: String
    Default: '8.0'
    AllowedValues:
      - '8.0'
      - '8.4'
    Description: MySQL engine version

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

  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for RDS MySQL access
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: !Ref AllowedCidr
          Description: MySQL access from allowed CIDR
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-rds-sg'

  RDSMonitoringRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: monitoring.rds.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole

  MySQLInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: !Sub '${AWS::StackName}-mysql'
      Engine: mysql
      EngineVersion: !Ref EngineVersion
      DBInstanceClass: !Ref DBInstanceClass
      AllocatedStorage: !Ref DBAllocatedStorage
      StorageType: gp3
      DBName: !Ref DBName
      MasterUsername: !Ref MasterUsername
      MasterUserPassword: !Ref MasterUserPassword
      DBSubnetGroupName: !Ref DBSubnetGroup
      VPCSecurityGroups:
        - !GetAtt DBSecurityGroup.GroupId
      MultiAZ: !Ref MultiAZ
      BackupRetentionPeriod: !Ref BackupRetentionPeriod
      PreferredBackupWindow: '03:00-04:00'
      PreferredMaintenanceWindow: 'sun:05:00-sun:06:00'
      AutoMinorVersionUpgrade: true
      PubliclyAccessible: false
      StorageEncrypted: true
      MonitoringInterval: 60
      MonitoringRoleArn: !GetAtt RDSMonitoringRole.Arn
      EnablePerformanceInsights: true
      PerformanceInsightsRetentionPeriod: 7
      DeletionProtection: false
      CopyTagsToSnapshot: true
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-mysql'
        - Key: Environment
          Value: production
    DeletionPolicy: Snapshot

Outputs:
  RDSEndpoint:
    Description: RDS MySQL endpoint address
    Value: !GetAtt MySQLInstance.Endpoint.Address
    Export:
      Name: !Sub '${AWS::StackName}-endpoint'

  RDSPort:
    Description: RDS MySQL port
    Value: !GetAtt MySQLInstance.Endpoint.Port

  SecurityGroupId:
    Description: RDS security group ID
    Value: !GetAtt DBSecurityGroup.GroupId

  DBSubnetGroupName:
    Description: DB subnet group name
    Value: !Ref DBSubnetGroup

This template defines everything in one file. The DeletionPolicy: Snapshot on the RDS instance ensures a final snapshot is taken if the stack is deleted – protecting against accidental data loss.

Step 3: Understand the Template Parameters

The template uses parameters to keep the configuration flexible across environments. Here is what each parameter controls:

ParameterPurposeDefault
VpcIdTarget VPC for the RDS deploymentNone (required)
SubnetIdsSubnets in 2+ AZs for the DB subnet groupNone (required)
AllowedCidrCIDR range permitted to connect on port 330610.0.0.0/16
DBInstanceClassCompute and memory capacitydb.t3.micro
DBAllocatedStorageStorage in GB (gp3 SSD)20
MasterUserPasswordRoot password (NoEcho – hidden in console)None (required)
MultiAZEnable standby replica in another AZfalse
BackupRetentionPeriodDays to keep automated backups7

The NoEcho: true property on MasterUserPassword prevents the password from appearing in CloudFormation console output or event logs. For production deployments, store the password in AWS Secrets Manager and reference it with a dynamic reference instead of passing it as a plain parameter.

Step 4: Deploy the CloudFormation Stack

Before deploying, identify your VPC ID and subnet IDs. List your VPCs first:

aws ec2 describe-vpcs --query "Vpcs[*].[VpcId,Tags[?Key=='Name'].Value|[0],CidrBlock]" --output table

Then list subnets in your target VPC (replace the VPC ID with yours):

aws ec2 describe-subnets \
  --filters "Name=vpc-id,Values=vpc-0abc123def456" \
  --query "Subnets[*].[SubnetId,AvailabilityZone,CidrBlock,Tags[?Key=='Name'].Value|[0]]" \
  --output table

Deploy the stack with your actual VPC and subnet values. The CAPABILITY_NAMED_IAM capability is required because the template creates an IAM role for Enhanced Monitoring:

aws cloudformation create-stack \
  --stack-name rds-mysql-prod \
  --template-body file://rds-mysql.yaml \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameters \
    ParameterKey=VpcId,ParameterValue=vpc-0abc123def456 \
    ParameterKey=SubnetIds,ParameterValue="subnet-0aaa111,subnet-0bbb222" \
    ParameterKey=AllowedCidr,ParameterValue=10.0.0.0/16 \
    ParameterKey=DBInstanceClass,ParameterValue=db.t3.micro \
    ParameterKey=DBAllocatedStorage,ParameterValue=20 \
    ParameterKey=DBName,ParameterValue=appdb \
    ParameterKey=MasterUsername,ParameterValue=admin \
    ParameterKey=MasterUserPassword,ParameterValue=YourStr0ngP4ssword \
    ParameterKey=MultiAZ,ParameterValue=false \
    ParameterKey=BackupRetentionPeriod,ParameterValue=7 \
    ParameterKey=EngineVersion,ParameterValue=8.0

RDS instance creation takes 10-15 minutes. Monitor the stack progress:

aws cloudformation wait stack-create-complete --stack-name rds-mysql-prod

Once the wait command returns, verify the stack was created successfully:

aws cloudformation describe-stacks \
  --stack-name rds-mysql-prod \
  --query "Stacks[0].StackStatus" \
  --output text

The output should show the stack status as complete:

CREATE_COMPLETE

Retrieve the RDS endpoint from the stack outputs:

aws cloudformation describe-stacks \
  --stack-name rds-mysql-prod \
  --query "Stacks[0].Outputs[?OutputKey=='RDSEndpoint'].OutputValue" \
  --output text

This returns the DNS endpoint for your RDS instance, which looks like:

rds-mysql-prod-mysql.c9abcdef12gh.us-east-1.rds.amazonaws.com

Step 5: Connect to the RDS MySQL Instance

Connect to the RDS instance using the MySQL client from a host within the allowed CIDR range (such as an EC2 instance in the same VPC). Replace the endpoint with the value from the previous step:

mysql -h rds-mysql-prod-mysql.c9abcdef12gh.us-east-1.rds.amazonaws.com \
  -u admin -p \
  --ssl-mode=REQUIRED

After entering the master password, run a quick verification query to confirm the connection and check the MySQL version:

SELECT VERSION();
SHOW DATABASES;

The output confirms MySQL is running and your initial database exists:

+-----------+
| VERSION() |
+-----------+
| 8.0.39    |
+-----------+
1 row in set (0.01 sec)

+--------------------+
| Database           |
+--------------------+
| appdb              |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

If the connection times out, check that your security group allows traffic from the source IP and that the source host is in a subnet that can route to the RDS subnets. RDS instances with PubliclyAccessible: false are only reachable from within the VPC.

Step 6: Enable Multi-AZ for High Availability

Multi-AZ creates a synchronous standby replica in a different Availability Zone. If the primary instance fails, RDS automatically fails over to the standby – typically within 60-120 seconds. No application code changes are needed because the DNS endpoint stays the same.

To enable Multi-AZ on an existing stack, update the MultiAZ parameter:

aws cloudformation update-stack \
  --stack-name rds-mysql-prod \
  --use-previous-template \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameters \
    ParameterKey=VpcId,UsePreviousValue=true \
    ParameterKey=SubnetIds,UsePreviousValue=true \
    ParameterKey=AllowedCidr,UsePreviousValue=true \
    ParameterKey=DBInstanceClass,UsePreviousValue=true \
    ParameterKey=DBAllocatedStorage,UsePreviousValue=true \
    ParameterKey=DBName,UsePreviousValue=true \
    ParameterKey=MasterUsername,UsePreviousValue=true \
    ParameterKey=MasterUserPassword,UsePreviousValue=true \
    ParameterKey=MultiAZ,ParameterValue=true \
    ParameterKey=BackupRetentionPeriod,UsePreviousValue=true \
    ParameterKey=EngineVersion,UsePreviousValue=true

The modification takes 10-20 minutes and involves a brief I/O suspension while RDS provisions the standby. Verify Multi-AZ is active:

aws rds describe-db-instances \
  --db-instance-identifier rds-mysql-prod-mysql \
  --query "DBInstances[0].[MultiAZ,AvailabilityZone,SecondaryAvailabilityZone]" \
  --output table

The output shows Multi-AZ enabled with the primary and standby in different zones:

---------------------------------------------
|          DescribeDBInstances              |
+-------+-------------+--------------------+
|  True |  us-east-1a |  us-east-1b        |
+-------+-------------+--------------------+

Multi-AZ roughly doubles the cost of the RDS instance. For non-production environments, keep it disabled to save costs.

Step 7: Configure Automated Backups

The template already configures automated backups with a 7-day retention period and a preferred backup window of 03:00-04:00 UTC. These are point-in-time recovery (PITR) backups – RDS continuously saves transaction logs, allowing you to restore to any second within the retention period.

Check the current backup configuration:

aws rds describe-db-instances \
  --db-instance-identifier rds-mysql-prod-mysql \
  --query "DBInstances[0].[BackupRetentionPeriod,PreferredBackupWindow,LatestRestorableTime]" \
  --output table

To change the retention period (for example, to 14 days for production), update the stack parameter:

aws cloudformation update-stack \
  --stack-name rds-mysql-prod \
  --use-previous-template \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameters \
    ParameterKey=VpcId,UsePreviousValue=true \
    ParameterKey=SubnetIds,UsePreviousValue=true \
    ParameterKey=AllowedCidr,UsePreviousValue=true \
    ParameterKey=DBInstanceClass,UsePreviousValue=true \
    ParameterKey=DBAllocatedStorage,UsePreviousValue=true \
    ParameterKey=DBName,UsePreviousValue=true \
    ParameterKey=MasterUsername,UsePreviousValue=true \
    ParameterKey=MasterUserPassword,UsePreviousValue=true \
    ParameterKey=MultiAZ,UsePreviousValue=true \
    ParameterKey=BackupRetentionPeriod,ParameterValue=14 \
    ParameterKey=EngineVersion,UsePreviousValue=true

To create a manual snapshot before a major change (such as a version upgrade), use:

aws rds create-db-snapshot \
  --db-instance-identifier rds-mysql-prod-mysql \
  --db-snapshot-identifier rds-mysql-prod-pre-upgrade-$(date +%Y%m%d)

Manual snapshots persist until you explicitly delete them and are not affected by the retention period. Always create a manual snapshot before engine upgrades or major configuration changes.

Step 8: Configure Monitoring

The CloudFormation template already enables two monitoring features – Enhanced Monitoring and Performance Insights. Here is what each provides and how to use them.

Enhanced Monitoring

Enhanced Monitoring collects OS-level metrics (CPU, memory, swap, disk I/O, network) from the RDS instance at 60-second intervals. These metrics go to CloudWatch Logs under the RDSOSMetrics log group. The template sets MonitoringInterval: 60 and creates the required IAM role automatically.

View Enhanced Monitoring metrics from the CLI:

aws logs get-log-events \
  --log-group-name RDSOSMetrics \
  --log-stream-name rds-mysql-prod-mysql \
  --limit 1 \
  --query "events[0].message" \
  --output text | python3 -m json.tool | head -30

This returns detailed OS metrics including process lists, memory breakdowns, and disk utilization – data that standard CloudWatch RDS metrics don’t capture.

Performance Insights

Performance Insights identifies database performance bottlenecks by analyzing wait events, top SQL queries, and resource usage. The template enables it with a 7-day retention period (free tier). For production workloads that need historical analysis, increase retention to 731 days (2 years) in the template by changing PerformanceInsightsRetentionPeriod.

Query Performance Insights data to identify the top wait events over the last hour:

aws pi get-resource-metrics \
  --service-type RDS \
  --identifier db-ABCDEFGHIJKLMNOP \
  --metric-queries '[{"Metric":"db.load.avg","GroupBy":{"Group":"db.wait_event"}}]' \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period-in-seconds 300

Replace the --identifier value with your DbiResourceId. Find it with:

aws rds describe-db-instances \
  --db-instance-identifier rds-mysql-prod-mysql \
  --query "DBInstances[0].DbiResourceId" \
  --output text

Set up a CloudWatch alarm to alert when CPU exceeds 80% for 5 minutes. This catches runaway queries or undersized instances before they impact your application:

aws cloudwatch put-metric-alarm \
  --alarm-name rds-mysql-prod-high-cpu \
  --metric-name CPUUtilization \
  --namespace AWS/RDS \
  --dimensions Name=DBInstanceIdentifier,Value=rds-mysql-prod-mysql \
  --statistic Average \
  --period 300 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 1 \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:ops-alerts

Replace the SNS topic ARN with your own. If you’re running Prometheus monitoring for MySQL, you can also scrape RDS metrics through the CloudWatch exporter for a unified dashboard.

Step 9: Update and Delete the Stack

One of the main benefits of CloudFormation is making controlled changes through stack updates instead of manual console clicks. To change the instance class (for example, scaling up from db.t3.micro to db.r6g.large):

aws cloudformation update-stack \
  --stack-name rds-mysql-prod \
  --use-previous-template \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameters \
    ParameterKey=VpcId,UsePreviousValue=true \
    ParameterKey=SubnetIds,UsePreviousValue=true \
    ParameterKey=AllowedCidr,UsePreviousValue=true \
    ParameterKey=DBInstanceClass,ParameterValue=db.r6g.large \
    ParameterKey=DBAllocatedStorage,UsePreviousValue=true \
    ParameterKey=DBName,UsePreviousValue=true \
    ParameterKey=MasterUsername,UsePreviousValue=true \
    ParameterKey=MasterUserPassword,UsePreviousValue=true \
    ParameterKey=MultiAZ,UsePreviousValue=true \
    ParameterKey=BackupRetentionPeriod,UsePreviousValue=true \
    ParameterKey=EngineVersion,UsePreviousValue=true

Instance class changes require a reboot (brief downtime). If Multi-AZ is enabled, RDS performs the change on the standby first, then fails over – reducing downtime to under 60 seconds.

Check which resources CloudFormation would change before applying, using a change set:

aws cloudformation create-change-set \
  --stack-name rds-mysql-prod \
  --change-set-name scale-up-instance \
  --use-previous-template \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameters \
    ParameterKey=DBInstanceClass,ParameterValue=db.r6g.large \
    ParameterKey=VpcId,UsePreviousValue=true \
    ParameterKey=SubnetIds,UsePreviousValue=true \
    ParameterKey=AllowedCidr,UsePreviousValue=true \
    ParameterKey=DBAllocatedStorage,UsePreviousValue=true \
    ParameterKey=DBName,UsePreviousValue=true \
    ParameterKey=MasterUsername,UsePreviousValue=true \
    ParameterKey=MasterUserPassword,UsePreviousValue=true \
    ParameterKey=MultiAZ,UsePreviousValue=true \
    ParameterKey=BackupRetentionPeriod,UsePreviousValue=true \
    ParameterKey=EngineVersion,UsePreviousValue=true

Review what would change, then execute or delete the change set:

aws cloudformation describe-change-set \
  --stack-name rds-mysql-prod \
  --change-set-name scale-up-instance \
  --query "Changes[*].ResourceChange.{Resource:LogicalResourceId,Action:Action,Replacement:Replacement}" \
  --output table

To delete the entire stack when it is no longer needed:

aws cloudformation delete-stack --stack-name rds-mysql-prod

Because the template has DeletionPolicy: Snapshot, CloudFormation creates a final DB snapshot before deleting the RDS instance. This snapshot persists and can be used to restore the database later if needed. Verify the snapshot was created:

aws rds describe-db-snapshots \
  --query "DBSnapshots[?DBInstanceIdentifier=='rds-mysql-prod-mysql'].[DBSnapshotIdentifier,Status,SnapshotCreateTime]" \
  --output table

Step 10: Add RDS Proxy for Connection Pooling

RDS Proxy sits between your application and the database, maintaining a pool of persistent connections. This is important for applications that open and close database connections frequently – such as Lambda functions, microservices, or any application with bursty connection patterns. Without a proxy, each new connection incurs TCP handshake and MySQL authentication overhead.

RDS Proxy requires the database credentials stored in AWS Secrets Manager. Create the secret first:

aws secretsmanager create-secret \
  --name rds-mysql-prod/credentials \
  --secret-string '{"username":"admin","password":"YourStr0ngP4ssword"}'

Add the following resources to your CloudFormation template under the Resources section to create the RDS Proxy, its IAM role, and target group:

  RDSProxyRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: rds.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: RDSProxySecretsAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - secretsmanager:GetSecretValue
                Resource: !Sub 'arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:rds-mysql-prod/credentials*'

  MySQLProxy:
    Type: AWS::RDS::DBProxy
    Properties:
      DBProxyName: !Sub '${AWS::StackName}-proxy'
      EngineFamily: MYSQL
      RequireTLS: true
      RoleArn: !GetAtt RDSProxyRole.Arn
      Auth:
        - AuthScheme: SECRETS
          SecretArn: !Sub 'arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:rds-mysql-prod/credentials'
          IAMAuth: DISABLED
      VpcSubnetIds: !Ref SubnetIds
      VpcSecurityGroupIds:
        - !GetAtt DBSecurityGroup.GroupId

  MySQLProxyTargetGroup:
    Type: AWS::RDS::DBProxyTargetGroup
    Properties:
      DBProxyName: !Ref MySQLProxy
      TargetGroupName: default
      DBInstanceIdentifiers:
        - !Ref MySQLInstance
      ConnectionPoolConfigurationInfo:
        MaxConnectionsPercent: 90
        MaxIdleConnectionsPercent: 50
        ConnectionBorrowTimeout: 120

After adding the proxy resources and updating the stack, retrieve the proxy endpoint:

aws rds describe-db-proxies \
  --db-proxy-name rds-mysql-prod-proxy \
  --query "DBProxies[0].Endpoint" \
  --output text

Connect through the proxy instead of directly to RDS. The proxy endpoint replaces the RDS endpoint in your application connection string:

mysql -h rds-mysql-prod-proxy.proxy-c9abcdef12gh.us-east-1.rds.amazonaws.com \
  -u admin -p \
  --ssl-mode=REQUIRED

The proxy handles connection multiplexing transparently. Your application connects to the proxy endpoint, and the proxy reuses existing database connections from its pool. This reduces connection overhead and protects the database from connection storms during traffic spikes.

Conclusion

We deployed a fully managed RDS MySQL instance using CloudFormation with proper networking, security groups, encrypted storage, automated backups, Multi-AZ failover, and monitoring through Enhanced Monitoring and Performance Insights. The entire stack is defined in a single template that can be version-controlled, reviewed in pull requests, and deployed consistently across environments.

For production hardening, store the master password in AWS Secrets Manager with automatic rotation, enable deletion protection (DeletionProtection: true), and set up CloudWatch alarms for storage space, replication lag, and connection counts. Use RDS Proxy to manage connection pooling for serverless or high-concurrency workloads, and consider read replicas if your application is read-heavy.

Related Articles

Databases How To Install OpenSearch on Ubuntu 22.04|20.04|18.04 Containers How To Run PostgreSQL Server in Docker Container Cloud Install OpenStack on Debian 12 with Kolla-Ansible Cloud What Is Azure Cost Optimization?

Press ESC to close