RDS supprime la gestion du moteur de base de données — patching, sauvegardes, réplication. Mais “managé” ne signifie pas “zéro configuration”. Un RDS mal dimensionné ou mal configuré peut être aussi problématique qu’une base auto-hébergée.
Multi-AZ : haute disponibilité automatique
Multi-AZ maintient un réplica synchrone dans une zone de disponibilité différente. En cas de panne de l’AZ primaire, le basculement est automatique en 1 à 2 minutes, sans intervention.
resource "aws_db_instance" "main" {
identifier = "myapp-production"
engine = "postgres"
engine_version = "16.2"
instance_class = "db.t3.medium"
allocated_storage = 100
storage_type = "gp3"
storage_encrypted = true
kms_key_id = aws_kms_key.rds.arn
# Haute disponibilité
multi_az = true
db_name = "myapp"
username = "myapp_admin"
password = var.db_password # jamais en dur dans le code
# Maintenance
backup_retention_period = 14 # 14 jours de snapshots
backup_window = "03:00-04:00" # fenêtre de backup en heures creuses
maintenance_window = "Mon:04:00-Mon:05:00"
auto_minor_version_upgrade = true
# Réseau
db_subnet_group_name = aws_db_subnet_group.main.name
vpc_security_group_ids = [aws_security_group.rds.id]
publicly_accessible = false # jamais exposé sur Internet
# Suppression accidentelle
deletion_protection = true
skip_final_snapshot = false
final_snapshot_identifier = "myapp-production-final-snapshot"
# Monitoring
monitoring_interval = 60
monitoring_role_arn = aws_iam_role.rds_enhanced_monitoring.arn
enabled_cloudwatch_logs_exports = ["postgresql", "upgrade"]
performance_insights_enabled = true
performance_insights_retention_period = 7
}
Read Replicas : scaler les lectures
Les Read Replicas sont des copies asynchrones en lecture seule. Utiles pour délester la primary des requêtes analytiques ou des rapports.
resource "aws_db_instance" "replica" {
identifier = "myapp-production-replica"
replicate_source_db = aws_db_instance.main.identifier
instance_class = "db.t3.small" # peut être plus petit que la primary
auto_minor_version_upgrade = true
publicly_accessible = false
# Les Read Replicas n'ont pas de backup propre (répliqué depuis la primary)
skip_final_snapshot = true
}
# Dans votre application : router lectures et écritures
import os
from sqlalchemy import create_engine
# Connexion primaire pour les écritures
write_engine = create_engine(os.environ['DATABASE_PRIMARY_URL'])
# Connexion replica pour les lectures lourdes
read_engine = create_engine(os.environ['DATABASE_REPLICA_URL'])
def get_user(user_id: int):
with read_engine.connect() as conn: # lecture → replica
return conn.execute(select(User).where(User.id == user_id)).first()
def create_order(data: dict):
with write_engine.connect() as conn: # écriture → primary
conn.execute(insert(Order).values(**data))
conn.commit()
Parameter Groups : tuning du moteur
Les Parameter Groups permettent d’ajuster la configuration PostgreSQL sans accès au système d’exploitation.
resource "aws_db_parameter_group" "postgres16" {
name = "myapp-postgres16"
family = "postgres16"
# Mémoire pour le cache (25-40% de la RAM recommandé)
parameter {
name = "shared_buffers"
value = "{DBInstanceClassMemory/4}" # 25% de la RAM
}
# Connexions
parameter {
name = "max_connections"
value = "200"
}
# Logging des requêtes lentes (> 1s)
parameter {
name = "log_min_duration_statement"
value = "1000"
apply_method = "immediate"
}
# Autovacuum agressif pour éviter le bloat
parameter {
name = "autovacuum_vacuum_scale_factor"
value = "0.05" # 5% au lieu de 20% par défaut
}
}
Performance Insights : identifier les requêtes lentes
Performance Insights visualise la charge de la base de données par requête, utilisateur et host. Pour identifier une requête problématique :
- Ouvrez l’instance dans la console RDS → Performance Insights
- Filtrez par “Top SQL” sur la période incriminée
- Identifiez la requête avec le
DB Loadle plus élevé - Examinez le plan d’exécution avec
EXPLAIN ANALYZE
-- Dans psql, analyser la requête identifiée
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT * FROM orders
JOIN users ON orders.user_id = users.id
WHERE orders.status = 'pending'
AND orders.created_at > NOW() - INTERVAL '24 hours';
Sécurité : principe du moindre privilège
-- Créer un utilisateur applicatif avec droits limités
CREATE USER myapp_app WITH PASSWORD 'strong-password';
-- Accès uniquement aux tables nécessaires
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO myapp_app;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO myapp_app;
-- Pas d'accès aux tables d'audit ou d'administration
REVOKE ALL ON TABLE audit_logs FROM myapp_app;
Notre formation AWS couvre RDS avec des ateliers Terraform sur des comptes AWS réels.