Amazon RDS Basics: Create and Connect to a Database
Databases are essential in application development, but setting up servers, applying OS patches, and managing backups takes real effort. Amazon RDS (Relational Database Service) is a managed relational database service where AWS handles most of that operational work for you. Let's walk through the core RDS concepts and the steps to create and connect to an instance.
What is Amazon RDS?
RDS is a fully managed relational database service from AWS. AWS handles database engine installation, OS patching, automated backups, and failover — so developers can focus on building applications rather than managing infrastructure.
Compared to running a database yourself on EC2, RDS significantly reduces day-to-day operational overhead. The trade-off is that OS-level access and fine-grained engine customization are limited — if you need that level of control, a self-managed database on EC2 is an option.
What is Amazon Relational Database Service (Amazon RDS)? - Amazon Relational Database Service
Set up, operate, and scale a relational database in the AWS Cloud easily using the Amazon RDS web se...
Supported Database Engines
RDS supports multiple database engines, making it easier to migrate existing systems without changing the engine you're already using.
| Engine | Overview |
|---|---|
| MySQL | The most widely used open-source relational database |
| PostgreSQL | Feature-rich open-source DB with JSON support and extensive data types |
| MariaDB | A MySQL fork with high compatibility with MySQL |
| Oracle | Commercial enterprise-grade database |
| Microsoft SQL Server | Microsoft's DB, well-suited for Windows environments and .NET apps |
| Amazon Aurora | AWS's own engine, MySQL/PostgreSQL-compatible with higher throughput and availability |
Amazon Aurora is purpose-built for RDS and delivers higher throughput and availability than equivalent MySQL/PostgreSQL. It's worth considering when performance and reliability are priorities.
What is Amazon Aurora? - Amazon Aurora
Learn Aurora concepts and do initial Aurora planning.
Key Features
RDS includes several features to improve availability, security, and performance. Choose the right options based on your use case and budget.
| Feature | Overview | Main Benefit |
|---|---|---|
| Automated backups / snapshots | Enabled by default. Supports point-in-time recovery for up to 35 days. Manual snapshots are retained until explicitly deleted. | Restore to any point in time after a failure |
| Multi-AZ deployment | Automatically creates a standby replica in another AZ. Failover completes in 1–2 minutes with no endpoint change required. | Eliminates single points of failure and ensures high availability |
| Read replicas | Offloads read queries to separate instances. Supports cross-region replication. Can be promoted to a standalone DB. | Improves performance for read-heavy workloads |
Introduction to backups - Amazon Relational Database Service
Conceptual information about automated and manual backups. Enable and disable automated backups of y...
Configuring and managing a Multi-AZ deployment for Amazon RDS - Amazon Relational Database Service
Get high availability and failover support for your DB instances with Amazon RDS using a Multi-AZ de...
Working with DB instance read replicas - Amazon Relational Database Service
Create a read replica from a source Amazon RDS DB instance to scale out read operations.
Trying RDS with the AWS CLI
Let's use the AWS CLI to create a MySQL RDS instance and connect to it. The basic flow is: create a subnet group and security group, then create the instance. This guide assumes a VPC and subnets are already in place.
Creating a Subnet Group
RDS instances live inside a VPC, so first create a database subnet group. The subnet group must include subnets in at least two AZs.
❯ aws rds create-db-subnet-group \
--db-subnet-group-name exrecord-rds-subnet-group \
--db-subnet-group-description "Subnet group for exrecord RDS" \
--subnet-ids subnet-0a1b2c3d4e5f67890 subnet-0a1b2c3d4e5f67891
{
"DBSubnetGroup": {
"DBSubnetGroupName": "exrecord-rds-subnet-group",
"DBSubnetGroupDescription": "Subnet group for exrecord RDS",
"VpcId": "vpc-0a1b2c3d4e5f67890",
"SubnetGroupStatus": "Complete",
"Subnets": [
{
"SubnetIdentifier": "subnet-0a1b2c3d4e5f67891",
"SubnetAvailabilityZone": {
"Name": "us-east-1b"
},
"SubnetOutpost": {},
"SubnetStatus": "Active"
},
{
"SubnetIdentifier": "subnet-0a1b2c3d4e5f67890",
"SubnetAvailabilityZone": {
"Name": "us-east-1a"
},
"SubnetOutpost": {},
"SubnetStatus": "Active"
}
],
"DBSubnetGroupArn": "arn:aws:rds:us-east-1:123456789012:subgrp:exrecord-rds-subnet-group",
"SupportedNetworkTypes": [
"IPV4"
]
}
}
Creating a Security Group
Create a security group to control access to the RDS instance. Here we allow inbound connections on MySQL's default port 3306. In production, restrict the source to specific IP addresses or the security group of your EC2 instance.
❯ aws ec2 create-security-group \
--group-name exrecord-rds-sg \
--description "Security group for exrecord RDS" \
--vpc-id vpc-0a1b2c3d4e5f67890
{
"GroupId": "sg-0a1b2c3d4e5f67890",
"SecurityGroupArn": "arn:aws:ec2:us-east-1:123456789012:security-group/sg-0a1b2c3d4e5f67890"
}
Add an inbound rule for MySQL (port 3306). Here we use the default VPC CIDR (172.31.0.0/16). If you're using a custom VPC, update this to match your VPC's CIDR.
❯ aws ec2 authorize-security-group-ingress \
--group-id sg-0a1b2c3d4e5f67890 \
--protocol tcp \
--port 3306 \
--cidr 172.31.0.0/16
{
"Return": true,
"SecurityGroupRules": [
{
"SecurityGroupRuleId": "sgr-0a1b2c3d4e5f67890",
"GroupId": "sg-0a1b2c3d4e5f67890",
"GroupOwnerId": "123456789012",
"IsEgress": false,
"IpProtocol": "tcp",
"FromPort": 3306,
"ToPort": 3306,
"CidrIpv4": "172.31.0.0/16",
"SecurityGroupRuleArn": "arn:aws:ec2:us-east-1:123456789012:security-group-rule/sgr-0a1b2c3d4e5f67890"
}
]
}
Creating the RDS Instance
With the subnet group and security group ready, create the RDS instance. Using --no-publicly-accessible restricts direct connections from outside the VPC for a more secure setup.
❯ aws rds create-db-instance \
--db-instance-identifier exrecord-mysql \
--db-instance-class db.t3.micro \
--engine mysql \
--engine-version 8.0 \
--master-username admin \
--master-user-password MyPassword123! \
--allocated-storage 20 \
--db-subnet-group-name exrecord-rds-subnet-group \
--vpc-security-group-ids sg-0a1b2c3d4e5f67890 \
--no-publicly-accessible \
--backup-retention-period 7
Output
{
"DBInstance": {
"DBInstanceIdentifier": "exrecord-mysql",
"DBInstanceClass": "db.t3.micro",
"Engine": "mysql",
"DBInstanceStatus": "creating",
"MasterUsername": "admin",
"AllocatedStorage": 20,
"PreferredBackupWindow": "14:39-15:09",
"BackupRetentionPeriod": 7,
"DBSecurityGroups": [],
"VpcSecurityGroups": [
{
"VpcSecurityGroupId": "sg-0a1b2c3d4e5f67890",
"Status": "active"
}
],
"DBParameterGroups": [
{
"DBParameterGroupName": "default.mysql8.0",
"ParameterApplyStatus": "in-sync"
}
],
"DBSubnetGroup": {
"DBSubnetGroupName": "exrecord-rds-subnet-group",
"DBSubnetGroupDescription": "Subnet group for exrecord RDS",
"VpcId": "vpc-0a1b2c3d4e5f67890",
"SubnetGroupStatus": "Complete",
"Subnets": [
{
"SubnetIdentifier": "subnet-0a1b2c3d4e5f67891",
"SubnetAvailabilityZone": {
"Name": "us-east-1b"
},
"SubnetOutpost": {},
"SubnetStatus": "Active"
},
{
"SubnetIdentifier": "subnet-0a1b2c3d4e5f67890",
"SubnetAvailabilityZone": {
"Name": "us-east-1a"
},
"SubnetOutpost": {},
"SubnetStatus": "Active"
}
]
},
"PreferredMaintenanceWindow": "sat:17:16-sat:17:46",
"UpgradeRolloutOrder": "second",
"PendingModifiedValues": {
"MasterUserPassword": "****"
},
"MultiAZ": false,
"EngineVersion": "8.0.45",
"AutoMinorVersionUpgrade": true,
"ReadReplicaDBInstanceIdentifiers": [],
"LicenseModel": "general-public-license",
"StorageThroughput": 0,
"OptionGroupMemberships": [
{
"OptionGroupName": "default:mysql-8-0",
"Status": "in-sync"
}
],
"PubliclyAccessible": false,
"StorageType": "gp2",
"DbInstancePort": 0,
"StorageEncrypted": false,
"DbiResourceId": "db-0a1b2c3d4e5f67890",
"CACertificateIdentifier": "rds-ca-rsa2048-g1",
"DomainMemberships": [],
"CopyTagsToSnapshot": false,
"MonitoringInterval": 0,
"DBInstanceArn": "arn:aws:rds:us-east-1:123456789012:db:exrecord-mysql",
"IAMDatabaseAuthenticationEnabled": false,
"DatabaseInsightsMode": "standard",
"PerformanceInsightsEnabled": false,
"DeletionProtection": false,
"AssociatedRoles": [],
"TagList": [],
"CustomerOwnedIpEnabled": false,
"NetworkType": "IPV4",
"BackupTarget": "region",
"CertificateDetails": {
"CAIdentifier": "rds-ca-rsa2048-g1"
},
"DedicatedLogVolume": false,
"EngineLifecycleSupport": "open-source-rds-extended-support"
}
}
Instance creation takes a few minutes. Poll until the status shows available:
❯ aws rds describe-db-instances \
--db-instance-identifier exrecord-mysql \
--query "DBInstances[0].DBInstanceStatus"
"available"
Checking the Endpoint
Once the instance is available, get the endpoint you'll use to connect. The endpoint is a DNS name automatically assigned at creation time — you'll use it from your application or MySQL client.
❯ aws rds describe-db-instances \
--db-instance-identifier exrecord-mysql \
--query "DBInstances[0].Endpoint"
{
"Address": "exrecord-mysql.c0a1b2c3d4e5.us-east-1.rds.amazonaws.com",
"Port": 3306,
"HostedZoneId": "Z35SXDOTRQ7X7K"
}
Connecting with a MySQL Client
From an EC2 instance or bastion host in the same VPC, connect using the endpoint. Since the instance is not publicly accessible, direct connections from the internet are not allowed. The mysql client must be installed on the source server.
[ec2-user@ip-172-31-x-x ~]$ mysql -h exrecord-mysql.c0a1b2c3d4e5.us-east-1.rds.amazonaws.com \
-u admin \
-p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 39
Server version: 8.0.45 Source distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
Once connected, you can use standard MySQL commands to interact with the database.
Deleting the Instance
Delete instances you no longer need. Using --skip-final-snapshot deletes the instance without creating a final snapshot — for production environments, omit this flag to keep a snapshot.
❯ aws rds delete-db-instance \
--db-instance-identifier exrecord-mysql \
--skip-final-snapshot
Output
{
"DBInstance": {
"DBInstanceIdentifier": "exrecord-mysql",
"DBInstanceClass": "db.t3.micro",
"Engine": "mysql",
"DBInstanceStatus": "deleting",
"MasterUsername": "admin",
"Endpoint": {
"Address": "exrecord-mysql.c0a1b2c3d4e5.us-east-1.rds.amazonaws.com",
"Port": 3306,
"HostedZoneId": "Z35SXDOTRQ7X7K"
},
"AllocatedStorage": 20,
"InstanceCreateTime": "2026-04-17T19:41:16.201000+00:00",
"PreferredBackupWindow": "14:39-15:09",
"BackupRetentionPeriod": 7,
"DBSecurityGroups": [],
"VpcSecurityGroups": [
{
"VpcSecurityGroupId": "sg-0a1b2c3d4e5f67890",
"Status": "active"
}
],
"DBParameterGroups": [
{
"DBParameterGroupName": "default.mysql8.0",
"ParameterApplyStatus": "in-sync"
}
],
"AvailabilityZone": "us-east-1b",
"DBSubnetGroup": {
"DBSubnetGroupName": "exrecord-rds-subnet-group",
"DBSubnetGroupDescription": "Subnet group for exrecord RDS",
"VpcId": "vpc-0a1b2c3d4e5f67890",
"SubnetGroupStatus": "Complete",
"Subnets": [
{
"SubnetIdentifier": "subnet-0a1b2c3d4e5f67891",
"SubnetAvailabilityZone": {
"Name": "us-east-1b"
},
"SubnetOutpost": {},
"SubnetStatus": "Active"
},
{
"SubnetIdentifier": "subnet-0a1b2c3d4e5f67890",
"SubnetAvailabilityZone": {
"Name": "us-east-1a"
},
"SubnetOutpost": {},
"SubnetStatus": "Active"
}
]
},
"PreferredMaintenanceWindow": "sat:17:16-sat:17:46",
"UpgradeRolloutOrder": "second",
"PendingModifiedValues": {},
"LatestRestorableTime": "2026-04-17T20:04:38+00:00",
"MultiAZ": false,
"EngineVersion": "8.0.45",
"AutoMinorVersionUpgrade": true,
"ReadReplicaDBInstanceIdentifiers": [],
"LicenseModel": "general-public-license",
"StorageThroughput": 0,
"OptionGroupMemberships": [
{
"OptionGroupName": "default:mysql-8-0",
"Status": "in-sync"
}
],
"PubliclyAccessible": false,
"StorageType": "gp2",
"DbInstancePort": 0,
"StorageEncrypted": false,
"DbiResourceId": "db-0a1b2c3d4e5f67890",
"CACertificateIdentifier": "",
"DomainMemberships": [],
"CopyTagsToSnapshot": false,
"MonitoringInterval": 0,
"DBInstanceArn": "arn:aws:rds:us-east-1:123456789012:db:exrecord-mysql",
"IAMDatabaseAuthenticationEnabled": false,
"DatabaseInsightsMode": "standard",
"PerformanceInsightsEnabled": false,
"DeletionProtection": false,
"AssociatedRoles": [],
"TagList": [],
"CustomerOwnedIpEnabled": false,
"NetworkType": "IPV4",
"BackupTarget": "region",
"DedicatedLogVolume": false,
"EngineLifecycleSupport": "open-source-rds-extended-support"
}
}
Summary
We covered the core concepts of Amazon RDS and how to create and connect to an instance using the AWS CLI.
- RDS is a managed database service where AWS handles OS patching, backups, and other operational tasks
- It supports multiple engines — MySQL, PostgreSQL, Aurora, and more — making it easy to migrate existing systems
- Use Multi-AZ for high availability and read replicas to scale read performance
- Place instances inside a VPC and restrict access via security groups for a secure setup
- Use automated backups and snapshots to enable recovery from failures