# Aws Rds Database

> 🗄️ **Quick Start**: Managed database service yang membuat setup, operasi, dan scaling relational database di cloud menjadi mudah

## 📋 Table of Contents

* [🎯 RDS Overview](#-rds-overview)
* [🗄️ Supported Database Engines](#️-supported-database-engines)
* [🔧 RDS Deployment Options](#-rds-deployment-options)
* [🏗️ Creating RDS Instance](#️-creating-rds-instance)
* [🔄 Multi-AZ Configuration](#-multi-az-configuration)
* [📊 Read Replicas](#-read-replicas)
* [🔒 Security Configuration](#-security-configuration)
* [💾 Backup & Recovery](#-backup--recovery)
* [📈 Monitoring & Performance](#-monitoring--performance)
* [🚀 Scaling Options](#-scaling-options)
* [⚙️ Advanced Features](#️-advanced-features)

## 🎯 RDS Overview

Amazon RDS adalah managed relational database service yang menyediakan:

* **🔧 Automated Administration**: Patching, backup, dan maintenance
* **📈 Scalability**: Scale storage dan compute dengan mudah
* **🔒 High Availability**: Multi-AZ deployment untuk failover
* **🛡️ Security**: Encryption, VPC isolation, dan IAM integration
* **💰 Cost Optimization**: Pay-as-you-go pricing model
* **🔄 Migration**: Easy database migration tools

## 🗄️ Supported Database Engines

### MySQL

```bash
# Supported versions: 5.7, 8.0
# Use cases: Web applications, content management, e-commerce

# Create MySQL instance
aws rds create-db-instance \
  --db-instance-identifier mysql-webapp \
  --db-instance-class db.t3.micro \
  --engine mysql \
  --engine-version 8.0.35 \
  --master-username admin \
  --master-user-password $DB_PASSWORD \
  --allocated-storage 20 \
  --storage-type gp2 \
  --vpc-security-group-ids sg-12345678 \
  --db-subnet-group-name my-db-subnet-group
```

### PostgreSQL

```bash
# Supported versions: 13, 14, 15
# Use cases: Enterprise applications, data warehousing

# Create PostgreSQL instance
aws rds create-db-instance \
  --db-instance-identifier postgres-analytics \
  --db-instance-class db.t3.small \
  --engine postgres \
  --engine-version 15.4 \
  --master-username postgres \
  --master-user-password $DB_PASSWORD \
  --allocated-storage 100 \
  --storage-type gp3 \
  --vpc-security-group-ids sg-12345678 \
  --db-subnet-group-name my-db-subnet-group
```

### SQL Server

```bash
# Supported versions: 2016, 2017, 2019, 2022
# Use cases: Windows applications, .NET enterprise apps

# Create SQL Server instance
aws rds create-db-instance \
  --db-instance-identifier sqlserver-app \
  --db-instance-class db.t3.small \
  --engine sqlserver-se \
  --engine-version 15.00.4073.23.v1 \
  --master-username admin \
  --master-user-password $DB_PASSWORD \
  --allocated-storage 50 \
  --license-model license-included \
  --vpc-security-group-ids sg-12345678 \
  --db-subnet-group-name my-db-subnet-group
```

### Oracle

```bash
# Supported versions: 19c, 21c
# Use cases: Enterprise applications, ERP systems

# Create Oracle instance
aws rds create-db-instance \
  --db-instance-identifier oracle-erp \
  --db-instance-class db.t3.medium \
  --engine oracle-se2 \
  --engine-version 19.0.0.0.ru-2023-10.rur-2023-10.r1 \
  --master-username admin \
  --master-user-password $DB_PASSWORD \
  --allocated-storage 100 \
  --license-model license-included \
  --vpc-security-group-ids sg-12345678 \
  --db-subnet-group-name my-db-subnet-group
```

## 🔧 RDS Deployment Options

### Single-AZ Deployment

```bash
# Basic setup for development/testing
aws rds create-db-instance \
  --db-instance-identifier dev-db \
  --db-instance-class db.t3.micro \
  --engine mysql \
  --engine-version 8.0 \
  --allocated-storage 20 \
  --master-username admin \
  --master-user-password $DB_PASSWORD \
  --no-multi-az \
  --backup-retention-period 0
```

### Multi-AZ Deployment

```bash
# Production setup with high availability
aws rds create-db-instance \
  --db-instance-identifier prod-db \
  --db-instance-class db.t3.medium \
  --engine postgres \
  --engine-version 15.4 \
  --allocated-storage 100 \
  --storage-type gp3 \
  --master-username postgres \
  --master-user-password $DB_PASSWORD \
  --multi-az \
  --backup-retention-period 7 \
  --preferred-backup-window "03:00-04:00" \
  --preferred-maintenance-window "sun:04:00-sun:05:00"
```

### Aurora Cluster

```bash
# Aurora MySQL cluster
aws rds create-db-cluster \
  --db-cluster-identifier aurora-cluster \
  --engine aurora-mysql \
  --engine-version 8.0.mysql_aurora.3.02.0 \
  --master-username admin \
  --master-user-password $DB_PASSWORD \
  --backup-retention-period 7 \
  --preferred-backup-window "03:00-04:00"

# Add instance to cluster
aws rds create-db-instance \
  --db-instance-identifier aurora-instance-1 \
  --db-cluster-identifier aurora-cluster \
  --db-instance-class db.t3.medium \
  --engine aurora-mysql
```

## 🏗️ Creating RDS Instance

### Using AWS Management Console

```bash
1. Navigate to RDS Dashboard
2. Click "Create database"
3. Choose creation method: "Standard Create"
4. Engine options: Select database engine
5. Templates: Production, Dev/Test, or Free tier
6. Settings:
   - DB instance identifier
   - Master username and password
7. Connectivity:
   - VPC
   - Subnet group
   - Security group
8. Database authentication: Password or IAM
9. Additional configuration:
   - Backup
   - Maintenance
   - Monitoring
10. Click "Create database"
```

### Using AWS CLI

```bash
# Create DB subnet group
aws rds create-db-subnet-group \
  --db-subnet-group-name my-db-subnet-group \
  --db-subnet-group-description "Database subnet group" \
  --subnet-ids subnet-12345678 subnet-87654321

# Create security group for RDS
aws ec2 create-security-group \
  --group-name rds-sg \
  --description "Security group for RDS" \
  --vpc-id vpc-12345678

# Allow application servers to connect
aws ec2 authorize-security-group-ingress \
  --group-id sg-rds-id \
  --protocol tcp \
  --port 3306 \
  --source-group sg-app-servers-id

# Create RDS instance
DB_INSTANCE_ID="myapp-database"
DB_PASSWORD="YourSecurePassword123!"

aws rds create-db-instance \
  --db-instance-identifier $DB_INSTANCE_ID \
  --db-instance-class db.t3.micro \
  --engine mysql \
  --engine-version 8.0.35 \
  --allocated-storage 20 \
  --storage-type gp2 \
  --master-username admin \
  --master-user-password $DB_PASSWORD \
  --vpc-security-group-ids sg-rds-id \
  --db-subnet-group-name my-db-subnet-group \
  --backup-retention-period 7 \
  --preferred-backup-window "03:00-04:00" \
  --preferred-maintenance-window "sun:04:00-sun:05:00" \
  --tags Key=Environment,Value=production Key=Application,Value=webapp

# Wait for instance to be available
aws rds wait db-instance-available \
  --db-instance-identifier $DB_INSTANCE_ID
```

### Using Terraform

```hcl
# variables.tf
variable "db_name" {
  description = "Database name"
  type        = string
  default     = "webapp"
}

variable "db_username" {
  description = "Database username"
  type        = string
  default     = "admin"
}

variable "db_password" {
  description = "Database password"
  type        = string
  sensitive   = true
}

variable "db_instance_class" {
  description = "RDS instance class"
  type        = string
  default     = "db.t3.micro"
}

# main.tf
resource "aws_db_subnet_group" "main" {
  name       = "${var.project_name}-db-subnet-group"
  subnet_ids = aws_subnet.private[*].id

  tags = {
    Name        = "${var.project_name}-db-subnet-group"
    Environment = var.environment
  }
}

resource "aws_security_group" "database" {
  name_prefix = "${var.project_name}-db-"
  vpc_id      = aws_vpc.main.id

  ingress {
    from_port       = 3306
    to_port         = 3306
    protocol        = "tcp"
    security_groups = [aws_security_group.app.id]
    description     = "MySQL from application servers"
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name        = "${var.project_name}-database"
    Environment = var.environment
  }
}

resource "aws_db_instance" "mysql" {
  identifier = "${var.project_name}-mysql"

  engine         = "mysql"
  engine_version = "8.0"
  instance_class = var.db_instance_class

  allocated_storage     = 20
  max_allocated_storage = 100
  storage_encrypted     = true
  storage_type          = "gp3"

  db_name  = var.db_name
  username = var.db_username
  password = var.db_password

  db_subnet_group_name   = aws_db_subnet_group.main.name
  vpc_security_group_ids = [aws_security_group.database.id]

  backup_retention_period = 7
  backup_window          = "03:00-04:00"
  maintenance_window     = "sun:04:00-sun:05:00"

  skip_final_snapshot       = var.environment == "development"
  final_snapshot_identifier = var.environment == "production" ? "${var.project_name}-mysql-final-snapshot" : null

  tags = merge(
    local.common_tags,
    {
      Name = "${var.project_name}-mysql"
    }
  )
}

# outputs.tf
output "db_instance_endpoint" {
  description = "RDS instance endpoint"
  value       = aws_db_instance.mysql.endpoint
  sensitive   = true
}

output "db_instance_port" {
  description = "RDS instance port"
  value       = aws_db_instance.mysql.port
}

output "db_instance_status" {
  description = "RDS instance status"
  value       = aws_db_instance.mysql.status
}
```

## 🔄 Multi-AZ Configuration

### Create Multi-AZ Instance

```bash
# Create with Multi-AZ enabled
aws rds create-db-instance \
  --db-instance-identifier prod-db-mysql \
  --db-instance-class db.t3.medium \
  --engine mysql \
  --engine-version 8.0.35 \
  --allocated-storage 100 \
  --storage-type gp3 \
  --storage-encrypted \
  --master-username admin \
  --master-user-password $DB_PASSWORD \
  --multi-az \
  --backup-retention-period 7 \
  --preferred-backup-window "03:00-04:00" \
  --vpc-security-group-ids sg-12345678 \
  --db-subnet-group-name my-db-subnet-group

# Monitor Multi-AZ status
aws rds describe-db-instances \
  --db-instance-identifier prod-db-mysql \
  --query 'DBInstances[0].[DBInstanceIdentifier,DBInstanceStatus,MultiAZ]'
```

### Failover Testing

```bash
# Initiate manual failover
aws rds reboot-db-instance \
  --db-instance-identifier prod-db-mysql \
  --force-failover

# Monitor failover
aws rds describe-db-instances \
  --db-instance-identifier prod-db-mysql \
  --query 'DBInstances[0].[DBInstanceIdentifier,DBInstanceStatus,AvailabilityZone]'

# Check endpoint remains the same
aws rds describe-db-instances \
  --db-instance-identifier prod-db-mysql \
  --query 'DBInstances[0].Endpoint.Address'
```

## 📊 Read Replicas

### Create Read Replica

```bash
# Create read replica from source instance
aws rds create-db-instance-read-replica \
  --db-instance-identifier prod-db-mysql-replica \
  --source-db-instance-identifier prod-db-mysql \
  --db-instance-class db.t3.micro \
  --availability-zone us-east-1b \
  --publicly-accessible \
  --tags Key=Environment,Value=production Key=Type,Value=read-replica

# Monitor replica creation
aws rds describe-db-instances \
  --db-instance-identifier prod-db-mysql-replica \
  --query 'DBInstances[0].[DBInstanceIdentifier,DBInstanceStatus,ReadReplicaSourceDBInstanceIdentifier]'

# Promote read replica to standalone
aws rds promote-read-replica \
  --db-instance-identifier prod-db-mysql-replica \
  --backup-retention-period 7
```

### Configure Application for Read Replica

```python
# Python application with read/write splitting
import mysql.connector
from mysql.connector import pooling

# Connection configuration
source_config = {
    'host': 'prod-db-mysql.xxxx.us-east-1.rds.amazonaws.com',
    'user': 'admin',
    'password': 'password',
    'database': 'webapp'
}

replica_config = {
    'host': 'prod-db-mysql-replica.xxxx.us-east-1.rds.amazonaws.com',
    'user': 'admin',
    'password': 'password',
    'database': 'webapp'
}

class DatabaseManager:
    def __init__(self):
        self.source_pool = mysql.connector.pooling.MySQLConnectionPool(
            pool_name="source_pool",
            pool_size=5,
            **source_config
        )

        self.replica_pool = mysql.connector.pooling.MySQLConnectionPool(
            pool_name="replica_pool",
            pool_size=10,
            **replica_config
        )

    def execute_read(self, query, params=None):
        """Execute SELECT queries on read replica"""
        connection = self.replica_pool.get_connection()
        cursor = connection.cursor(dictionary=True)

        try:
            cursor.execute(query, params or ())
            result = cursor.fetchall()
            return result
        finally:
            cursor.close()
            connection.close()

    def execute_write(self, query, params=None):
        """Execute INSERT/UPDATE/DELETE on source database"""
        connection = self.source_pool.get_connection()
        cursor = connection.cursor()

        try:
            cursor.execute(query, params or ())
            connection.commit()
            return cursor.lastrowid
        except:
            connection.rollback()
            raise
        finally:
            cursor.close()
            connection.close()

# Usage
db = DatabaseManager()

# Read operations (go to replica)
users = db.execute_read("SELECT * FROM users WHERE active = %s", (1,))

# Write operations (go to source)
user_id = db.execute_write("INSERT INTO users (name, email) VALUES (%s, %s)",
                          ("John Doe", "john@example.com"))
```

## 🔒 Security Configuration

### Encryption at Rest

```bash
# Create encrypted instance
aws rds create-db-instance \
  --db-instance-identifier secure-db \
  --db-instance-class db.t3.micro \
  --engine mysql \
  --engine-version 8.0.35 \
  --allocated-storage 20 \
  --storage-encrypted \
  --kms-key-id alias/aws/rds \
  --master-username admin \
  --master-user-password $DB_PASSWORD \
  --vpc-security-group-ids sg-12345678 \
  --db-subnet-group-name my-db-subnet-group

# Copy snapshot with encryption
aws rds copy-db-snapshot \
  --source-db-snapshot-identifier original-snapshot \
  --target-db-snapshot-identifier encrypted-snapshot \
  --kms-key-id alias/aws/rds
```

### Encryption in Transit

```bash
# Enable SSL/TLS in MySQL
# MySQL configuration parameter group
aws rds create-db-parameter-group \
  --db-parameter-group-name mysql-ssl-group \
  --db-parameter-group-family mysql8.0 \
  --description "Parameter group for SSL"

# Modify SSL parameters
aws rds modify-db-parameter-group \
  --db-parameter-group-name mysql-ssl-group \
  --parameters "ParameterName=require_secure_transport,ParameterValue=ON,ApplyMethod=immediate"

# Associate with instance
aws rds modify-db-instance \
  --db-instance-identifier secure-db \
  --db-parameter-group-name mysql-ssl-group \
  --apply-immediately
```

### IAM Database Authentication

```bash
# Enable IAM authentication
aws rds modify-db-instance \
  --db-instance-identifier secure-db \
  --enable-iam-database-authentication \
  --apply-immediately

# Create IAM policy for database access
cat > db-access-policy.json << EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "rds-db:connect"
      ],
      "Resource": [
        "arn:aws:rds-db:us-east-1:123456789012:dbuser:db-ABCDEFGHIJKLmnopqrstuvwxyz/database-user"
      ]
    }
  ]
}
EOF

aws iam create-policy \
  --policy-name RDS-Database-Access \
  --policy-document file://db-access-policy.json
```

## 💾 Backup & Recovery

### Automated Backups

```bash
# Configure backup settings
aws rds modify-db-instance \
  --db-instance-identifier prod-db \
  --backup-retention-period 30 \
  --preferred-backup-window "03:00-04:00" \
  --copy-tags-to-snapshot \
  --apply-immediately

# Create manual snapshot
aws rds create-db-snapshot \
  --db-instance-identifier prod-db \
  --db-snapshot-identifier prod-db-manual-$(date +%Y%m%d-%H%M%S) \
  --tags Key=Environment,Value=production Key=BackupType,Value=manual

# List snapshots
aws rds describe-db-snapshots \
  --db-instance-identifier prod-db \
  --query 'DBSnapshots[].{SnapshotId:DBSnapshotIdentifier,Type:SnapshotType,CreatedAt:SnapshotCreateTime}'
```

### Point-in-Time Recovery

```bash
# Restore to specific point in time
aws rds restore-db-instance-to-point-in-time \
  --source-db-instance-identifier prod-db \
  --target-db-instance-identifier prod-db-restored \
  --restore-time 2024-01-15T10:00:00Z \
  --db-instance-class db.t3.micro \
  --availability-zone us-east-1a \
  --multi-az \
  --publicly-accessible \
  --tags Key=Environment,Value=production Key=Purpose,Value=restored

# Restore from snapshot
aws rds restore-db-instance-from-db-snapshot \
  --db-instance-identifier prod-db-from-snapshot \
  --db-snapshot-identifier prod-db-manual-20240115-100000 \
  --db-instance-class db.t3.micro \
  --availability-zone us-east-1a \
  --multi-az
```

### Cross-Region Backup

```bash
# Copy snapshot to different region
aws rds copy-db-snapshot \
  --source-db-snapshot-identifier prod-db-manual-20240115-100000 \
  --target-db-snapshot-identifier prod-db-manual-20240115-100000-us-west-2 \
  --source-region us-east-1 \
  --region us-west-2 \
  --kms-key-id alias/aws/rds

# Configure cross-region backup automation
aws rds modify-db-instance \
  --db-instance-identifier prod-db \
  --copy-automated-backups \
  --destination-region us-west-2
```

## 📈 Monitoring & Performance

### Enhanced Monitoring

```bash
# Enable enhanced monitoring
aws rds modify-db-instance \
  --db-instance-identifier prod-db \
  --monitoring-interval 1 \
  --monitoring-role-arn arn:aws:iam::123456789012:role/rds-monitoring-role \
  --apply-immediately

# Create IAM role for enhanced monitoring
aws iam create-role \
  --role-name rds-monitoring-role \
  --assume-role-policy-document file://trust-policy.json

aws iam attach-role-policy \
  --role-name rds-monitoring-role \
  --policy-arn arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole
```

### Performance Insights

```bash
# Enable Performance Insights
aws rds modify-db-instance \
  --db-instance-identifier prod-db \
  --enable-performance-insights \
  --performance-insights-retention-period 7 \
  --apply-immediately

# Query Performance Insights
aws rds describe-performance-issues \
  --db-instance-identifier prod-db \
  --start-time 2024-01-15T10:00:00Z \
  --end-time 2024-01-15T12:00:00Z
```

### CloudWatch Metrics & Alarms

```bash
# CPU utilization alarm
aws cloudwatch put-metric-alarm \
  --alarm-name "RDS-CPU-High" \
  --alarm-description "RDS CPU utilization is high" \
  --metric-name CPUUtilization \
  --namespace AWS/RDS \
  --statistic Average \
  --period 300 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2 \
  --dimensions Name=DBInstanceIdentifier,Value=prod-db \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:database-alerts

# Free storage space alarm
aws cloudwatch put-metric-alarm \
  --alarm-name "RDS-FreeStorage-Low" \
  --alarm-description "RDS free storage space is low" \
  --metric-name FreeStorageSpace \
  --namespace AWS/RDS \
  --statistic Average \
  --period 300 \
  --threshold 2000000000 \
  --comparison-operator LessThanThreshold \
  --evaluation-periods 2 \
  --dimensions Name=DBInstanceIdentifier,Value=prod-db \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:database-alerts

# Database connections alarm
aws cloudwatch put-metric-alarm \
  --alarm-name "RDS-DatabaseConnections-High" \
  --alarm-description "RDS database connections are high" \
  --metric-name DatabaseConnections \
  --namespace AWS/RDS \
  --statistic Average \
  --period 300 \
  --threshold 50 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2 \
  --dimensions Name=DBInstanceIdentifier,Value=prod-db \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:database-alerts
```

## 🚀 Scaling Options

### Vertical Scaling (Instance Scaling)

```bash
# Scale up instance size
aws rds modify-db-instance \
  --db-instance-identifier prod-db \
  --db-instance-class db.t3.large \
  --apply-immediately

# Scale up storage
aws rds modify-db-instance \
  --db-instance-identifier prod-db \
  --allocated-storage 200 \
  --max-allocated-storage 500 \
  --apply-immediately

# Storage type migration
aws rds modify-db-instance \
  --db-instance-identifier prod-db \
  --storage-type gp3 \
  --apply-immediately
```

### Horizontal Scaling (Read Replicas)

```bash
# Add multiple read replicas
aws rds create-db-instance-read-replica \
  --db-instance-identifier prod-db-replica-1 \
  --source-db-instance-identifier prod-db \
  --db-instance-class db.t3.micro \
  --availability-zone us-east-1a

aws rds create-db-instance-read-replica \
  --db-instance-identifier prod-db-replica-2 \
  --source-db-instance-identifier prod-db \
  --db-instance-class db.t3.micro \
  --availability-zone us-east-1b

# Create Aurora cluster for auto-scaling
aws rds create-db-cluster \
  --db-cluster-identifier aurora-auto-scaling \
  --engine aurora-mysql \
  --engine-version 8.0.mysql_aurora.3.02.0 \
  --master-username admin \
  --master-user-password $DB_PASSWORD \
  --serverlessv2-scaling-configuration MinCapacity=1,MaxCapacity=16
```

## ⚙️ Advanced Features

### RDS Proxy

```bash
# Create RDS proxy
aws rds create-db-proxy \
  --db-proxy-name myapp-proxy \
  --engine-family MYSQL \
  --auth auth-1 SecretArn=arn:aws:secretsmanager:us-east-1:123456789012:secret:db-credentials-abcdef,AuthScheme=SECRETS
  --role-arn arn:aws:iam::123456789012:role/rds-proxy-role \
  --vpc-subnet-ids subnet-12345678 subnet-87654321 \
  --vpc-security-group-ids sg-12345678

# Register database with proxy
aws rds register-db-proxy-targets \
  --db-proxy-name myapp-proxy \
  --db-instance-identifiers prod-db \
  --target-group-name default
```

### Database Cloning

```bash
# Create database clone
aws rds create-db-instance-read-replica \
  --db-instance-identifier prod-db-clone \
  --source-db-instance-identifier prod-db \
  --db-instance-class db.t3.micro \
  --availability-zone us-east-1a \
  --copy-automated-backups \
  --use-custom-parameter-group \
  --no-multi-az
```

### Database Migration Service (DMS)

```bash
# Create replication instance
aws dms create-replication-instance \
  --replication-instance-identifier dms-instance \
  --replication-instance-class dms.t3.medium \
  --allocated-storage 50 \
  --vpc-security-group-ids sg-12345678 \
  --availability-zone us-east-1a

# Create migration task
aws dms create-replication-task \
  --replication-task-identifier migrate-to-rds \
  --source-endpoint-arn source-endpoint-arn \
  --target-endpoint-arn target-endpoint-arn \
  --migration-type full-load-and-cdc \
  --table-mappings file://table-mappings.json
```

## 📚 References

* [RDS Documentation](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/)
* [RDS Pricing](https://aws.amazon.com/rds/pricing/)
* [RDS Security Best Practices](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Security.html)
* [RDS Performance Guidelines](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Performance.html)

***

*🗄️ Generated with ❤️ using Catatan Seekor Documentation Framework*
