Creating an RDS Database (Step by Step)
Amazon RDS (Relational Database Service) is a managed service that runs a relational database for you, so you do not have to patch the operating system, install the database engine, or set up backups by hand. In this guide you will launch a real RDS instance from start to finish: pick an engine, choose how much compute and storage it gets, place it safely inside your private network, and turn on automated backups. We will do every step twice, once in the AWS Management Console (the web dashboard) and once with the AWS CLI (Command Line Interface, the tool that runs AWS commands in a terminal), so you can pick whichever you prefer.
Before you start: the pieces you need
RDS does not live on its own. It runs inside a VPC (Virtual Private Cloud, your own isolated network in AWS), and it needs a few supporting resources. Get these ready first and the launch is painless.
| Piece | What it is | Why RDS needs it |
|---|---|---|
| VPC | Your private network in AWS | The database has to live in a network |
| DB subnet group | A named set of subnets (sub-networks) across at least two Availability Zones (AZs) | RDS uses it to decide where to place the database, and Multi-AZ needs a second AZ |
| Security group | A virtual firewall attached to the database | Controls which machines can connect on the database port |
| Master password | The admin login for the database | You set it once at creation |
Gotcha: A DB subnet group must contain subnets in at least two Availability Zones, even for a single-AZ database. If all your subnets are in one AZ, RDS refuses to create the instance.
Choosing an engine
The “engine” is the database software RDS runs. Pick the one your application already speaks.
| Engine | Good for | Notes |
|---|---|---|
| PostgreSQL | New apps, rich SQL features | Popular default, open source |
| MySQL / MariaDB | Web apps, wide compatibility | Very common, open source |
| Amazon Aurora | High performance, auto-scaling storage | AWS-built, costs more, see Aurora pages |
| Oracle / SQL Server | Existing enterprise apps | Commercial, license costs apply |
When to use plain RDS (this page): standard apps where a normal managed database is enough. When NOT to: if you need automatic storage scaling and faster failover, look at Amazon Aurora instead.
Step 1 — Create a DB subnet group
This tells RDS which subnets it may use. Use private subnets (subnets with no direct route to the internet).
Console:
- Open the RDS console and choose Subnet groups in the left menu.
- Click Create DB subnet group.
- Give it a name like
app-db-subnets, pick your VPC, then add at least two private subnets in different Availability Zones. - Click Create.
CLI:
aws rds create-db-subnet-group \
--db-subnet-group-name app-db-subnets \
--db-subnet-group-description "Private subnets for app database" \
--subnet-ids subnet-0a1b2c3d subnet-0e4f5a6b
Output:
{
"DBSubnetGroup": {
"DBSubnetGroupName": "app-db-subnets",
"VpcId": "vpc-0a1b2c3d",
"SubnetGroupStatus": "Complete"
}
}
Step 2 — Create a security group for the database
The security group is the firewall. The safe pattern is to allow traffic only from your application servers’ security group, not from the open internet.
CLI:
# Create the database security group
aws ec2 create-security-group \
--group-name app-db-sg \
--description "Allow app servers to reach the database" \
--vpc-id vpc-0a1b2c3d
Output:
{
"GroupId": "sg-0db1c2d3"
}
Now allow PostgreSQL’s port (5432) from the app server security group (sg-0a1b2c3d) instead of from an IP range. This “security group reference” means only machines wearing that app security group can connect, no matter how their IP changes.
aws ec2 authorize-security-group-ingress \
--group-id sg-0db1c2d3 \
--protocol tcp \
--port 5432 \
--source-group sg-0a1b2c3d
Security warning: Never set the database to “publicly accessible” with a guessable password. An RDS instance open to
0.0.0.0/0(the whole internet) is one of the most common ways databases get breached. Keep--no-publicly-accessibleand only open the port to your app’s security group.
Step 3 — Launch the RDS instance
Now the main event. The instance class is the size of the server (CPU and memory). db.t3.micro is tiny and cheap for testing; db.m6g.large and up are for production. Storage uses gp3 (general purpose SSD) by default. Multi-AZ keeps a hot standby copy in a second AZ and fails over automatically if the main one dies. Backup retention is how many days of automatic backups RDS keeps.
Console:
- In the RDS console, click Create database.
- Choose Standard create, then pick your engine (e.g. PostgreSQL) and version.
- Under Templates, pick Production (turns on Multi-AZ) or Dev/Test.
- Set the DB instance identifier (e.g.
app-prod-db), the master username, and a strong master password. - Under Instance configuration, choose the instance class (e.g.
db.t3.micro). - Under Storage, set type gp3 and size (e.g. 20 GiB), and turn on storage autoscaling if you want.
- Under Connectivity, choose your VPC, the subnet group
app-db-subnets, set Public access = No, and select security groupapp-db-sg. - Under Additional configuration, set Backup retention (e.g. 7 days).
- Click Create database.
CLI:
aws rds create-db-instance \
--db-instance-identifier app-prod-db \
--engine postgres \
--engine-version 16.4 \
--db-instance-class db.t3.micro \
--allocated-storage 20 \
--storage-type gp3 \
--master-username appadmin \
--master-user-password 'Ch4ngeMe-Str0ng!' \
--db-subnet-group-name app-db-subnets \
--vpc-security-group-ids sg-0db1c2d3 \
--multi-az \
--backup-retention-period 7 \
--no-publicly-accessible
Output:
{
"DBInstance": {
"DBInstanceIdentifier": "app-prod-db",
"DBInstanceClass": "db.t3.micro",
"Engine": "postgres",
"DBInstanceStatus": "creating",
"MultiAZ": true,
"PubliclyAccessible": false
}
}
Creation takes several minutes. Wait for it and then read the connection endpoint:
aws rds wait db-instance-available --db-instance-identifier app-prod-db
aws rds describe-db-instances \
--db-instance-identifier app-prod-db \
--query "DBInstances[0].Endpoint.Address" \
--output text
Output:
app-prod-db.abcd1234.us-east-1.rds.amazonaws.com
Your app connects to that endpoint on port 5432. Because the instance is private, only machines inside the VPC with the right security group can reach it.
Cost note
A db.t3.micro with 20 GiB gp3 storage runs only a few US dollars per month, and is Free Tier eligible for the first 12 months. Turning on Multi-AZ roughly doubles the instance cost because you pay for the standby copy too, so use it for production but skip it for throwaway dev databases.
Best practices
- Always place RDS in private subnets with
--no-publicly-accessible; reach it from app servers via a security group reference, not an IP range. - Use a DB subnet group spanning at least two AZs so you can enable Multi-AZ failover later without rebuilding.
- Store the master password in AWS Secrets Manager rather than hard-coding it; RDS can even rotate it for you.
- Turn on automated backups (a non-zero retention period) and enable deletion protection on production instances.
- Right-size the instance class and use gp3 with storage autoscaling so you do not over-provision or run out of disk.
- Tag instances with owner and environment so cost and ownership stay clear.