Il deploy di soluzioni database in cloud richiede un'attenta valutazione di sicurezza, scalabilità e facilità di gestione. Una configurazione errata o non ottimale può tradursi in seri grattacapi tecnici, debito tecnico e, nel peggiore dei casi, un impatto rilevante sul business in caso di outage o di un database poco performante. Amazon Aurora MySQL offre un servizio di database relazionale altamente scalabile e sicuro.
In questo articolo vediamo come automatizzare il deploy di un cluster Amazon Aurora MySQL con Terraform, concentrandoci sulla creazione di una configurazione ad alta disponibilità con più istanze reader per scalare le letture.
Prerequisiti:
- Un account AWS
- Terraform installato sulla propria macchina
- Familiarità con i servizi AWS e con Terraform
- Codice Terraform disponibile sul repository GitHub
Struttura del progetto: il nostro progetto Terraform è organizzato in moduli per garantire chiarezza e riutilizzo. I moduli principali sono:
- Modulo KMS: gestisce le chiavi di crittografia del database.
- Modulo Aurora Cluster: si occupa del deploy e della configurazione del cluster Aurora MySQL.
Panoramica della struttura modulare delle directory
Questa struttura di directory è pensata per organizzare e gestire in modo efficiente il codice Terraform necessario al deploy di un cluster Amazon Aurora MySQL con crittografia gestita tramite AWS KMS.
Directory principale
Include main.tf, providers.tf, terraform.tfvars, variables.tf e outputs.tf.
main.tf: contiene la configurazione principale, in cui vengono richiamati i moduli.providers.tf: definisce le impostazioni dei provider e i requisiti di versione.variables.tf: dichiara le variabili usate nelle configurazioni.terraform.tfvars: imposta i valori di override per le variabili definite altrove.outputs.tf: definisce gli output della configurazione Terraform.
Directory dei moduli
Contiene una sottodirectory per ciascun modulo distinto utilizzato nel progetto.
Modulo KMS: gestisce la creazione e l'amministrazione delle chiavi AWS KMS per cifrare i dati a riposo.
main.tf: contiene le risorse per la creazione delle chiavi KMS.variables.tf: definisce le variabili di input specifiche per KMS.outputs.tf: fornisce gli attributi di output delle risorse KMS.
Modulo Aurora Cluster: gestisce il deploy del cluster Aurora MySQL.
main.tf: configura il cluster Aurora MySQL e le risorse correlate.variables.tf: elenca le variabili di input specifiche per il cluster Aurora MySQL.outputs.tf: restituisce attributi come l'endpoint del database.
Questa struttura garantisce un codice pulito e ben organizzato, ne migliora riusabilità e manutenibilità e rende più semplice gestire in modo efficace le risorse cloud.
1\. Configurazione del modulo KMS
La cifratura a riposo è fondamentale per proteggere i dati. Il cluster Aurora MySQL usa AWS KMS per la gestione delle chiavi e, in particolare, una AWS Customer Managed Key (CMK), che lei stesso crea, gestisce e possiede per cifrare il proprio cluster Aurora. Gestire una propria chiave KMS per la cifratura del cluster Aurora offre diversi vantaggi rispetto a una chiave KMS gestita da AWS: le CMK consentono policy di controllo accessi a grana fine, inclusa la possibilità di stabilire chi può utilizzarle e amministrarle; ogni utilizzo di una CMK viene tracciato in CloudTrail a fini di auditing — un aspetto cruciale per la compliance normativa — oltre al controllo geografico, che permette di limitarne l'uso a specifiche region AWS. Anche i costi delle CMK — fatturati per archiviazione e utilizzo delle API — risultano più prevedibili e trasparenti, semplificando budgeting e gestione della spesa rispetto alle chiavi gestite da AWS.
Il modulo KMS si occupa di creare e gestire queste chiavi: tramite il file outputs.tf del modulo viene esposto il nome della chiave KMS che il modulo Aurora utilizzerà.
# KMS Module - variables.tf
variable "rds" {
description = "Enable customer managed KMS key for RDS"
default = true
type = bool
}
# KMS Module - main.tf
resource "aws_kms_key" "rds" {
description = "KMS key for RDS"
enable_key_rotation = true
deletion_window_in_days = 30
}
Spiegazione:
- Rotazione delle chiavi: la rotazione automatica rafforza la sicurezza modificando periodicamente la chiave di cifratura sottostante.
- Finestra di eliminazione: indica l'intervallo di tempo che precede la distruzione irrevocabile di una chiave eliminata, lasciando margine per il recupero in caso di necessità.
2\. Configurazione del modulo Aurora Cluster
Il modulo Aurora Cluster è il cuore del nostro deploy: configura il database con le specifiche per performance e disponibilità e consente di definire impostazioni che vanno dal motore di database da utilizzare alla VPC e ai Security Group esistenti da associare, fino a opzioni come la prevenzione della cancellazione accidentale del cluster tramite Terraform — a meno che la clausola di lifecycle prevent_destroy = true non venga esplicitamente rimossa dal modulo:
# Aurora Cluster Module - variables.tf
variable "read_replica_count" {
description = "Number of Read Replicas in addition to Writer instance"
type = number
}
# Aurora MySQL Cluster config
resource "aws_rds_cluster" "aurora_mysql_cluster" {
cluster_identifier = var.name
engine = var.engine
engine_mode = var.engine_mode
engine_version = var.aurora_mysql_cluster_engine_version
database_name = var.database_name
master_username = var.aurora_mysql_cluster_master_username
# Create and store password in Secrets Manager
manage_master_user_password = true
final_snapshot_identifier = "${var.name}-snapshot"
skip_final_snapshot = var.skip_final_snapshot
deletion_protection = var.deletion_protection
backup_retention_period = var.backup_retention_period
preferred_backup_window = var.backup_window
preferred_maintenance_window = var.maintenance_window
port = var.port
db_subnet_group_name = aws_db_subnet_group.db_subnet_group.name
vpc_security_group_ids = concat(var.security_group_ids, [aws_security_group.aurora_mysql_sg.id])
apply_immediately = true
iam_database_authentication_enabled = false
copy_tags_to_snapshot = true
storage_encrypted = true
kms_key_id = var.kms_key_id
db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.cluster_param_group.name
enabled_cloudwatch_logs_exports = var.engine_mode == "serverless" ? [] : var.enabled_cloudwatch_logs_exports
tags = merge(var.tags, { "Name" = var.name })
lifecycle {
ignore_changes = [ engine_version, scaling_configuration, engine_mode ]
prevent_destroy = true
}
}
# Aurora MySQL Instances within Cluster - one Writer and "read_replica_count" Readers
resource "aws_rds_cluster_instance" "aurora_mysql_instance" {
count = var.engine_mode == "serverless" ? 0 : (1 + var.read_replica_count)
identifier = "${var.name}-${count.index}"
cluster_identifier = aws_rds_cluster.aurora_mysql_cluster.id
engine = var.engine
engine_version = var.aurora_mysql_cluster_engine_version
instance_class = var.instance_type
db_subnet_group_name = aws_db_subnet_group.db_subnet_group.name
db_parameter_group_name = aws_db_parameter_group.db_param_group.name
monitoring_role_arn = var.create_monitoring_role && var.monitoring_interval > 0 ? aws_iam_role.rds_enhanced_monitoring[0].arn : null
monitoring_interval = var.create_monitoring_role && var.monitoring_interval > 0 ? var.monitoring_interval : null
auto_minor_version_upgrade = true
performance_insights_enabled = true
tags = var.tags
lifecycle {
ignore_changes = [ engine_version ]
}
}
Parametri di configurazione importanti (da fornire in terraform.tfvars):
- Cluster Identifier: identificatore univoco del cluster Aurora; fondamentale per la sua gestione.
- Configurazione del motore: definisce motore di database e versione, garantendo compatibilità e disponibilità delle funzionalità. Può essere Aurora MySQL 5.7.x oppure 8.0.x, ma oggi è fortemente consigliato l'uso della 8.0.x, dato che AWS ha deprecato la 5.7.x e ne offre solo un supporto esteso (a pagamento).
- Numero di istanze: controlla quante istanze reader vengono create accanto alla writer, abilitando lo scaling delle letture.
- Sicurezza e networking: associa il cluster a impostazioni specifiche di VPC e security group, assicurando che operi in un ambiente di rete sicuro e isolato. Si utilizzano gli ID delle subnet e gli altri valori associati di una VPC esistente nella quale collocare il nuovo cluster Aurora MySQL.
- Gestione delle credenziali: sfrutta Secrets Manager per archiviare username e password del database, in modo da gestire le credenziali secondo le best practice.
3\. Output e gestione
Gli output sono fondamentali per recuperare i dettagli di connessione e gestire il cluster dopo il deploy, oltre che per passare valori a runtime tra moduli, quando necessario.
# Outputs - outputs.tf
output "aurora_cluster_endpoint" {
description = "The endpoint at which the Aurora cluster is accessible"
value = aws_rds_cluster.aurora.endpoint
}
# Outputs - outputs.tf
output "aurora_cluster_reader_endpoint" {
description = "The reader endpoint for the Aurora cluster"
value = aws_rds_cluster.aurora.reader_endpoint
}
4\. Conclusione
Usare Terraform per il deploy di cluster Amazon Aurora MySQL semplifica il processo e garantisce coerenza e ripetibilità tra gli ambienti. Grazie a moduli dedicati alle chiavi di cifratura KMS gestite dal cliente e alla configurazione puntuale del cluster Aurora, il setup resta modulare e facile da adattare. Questa soluzione sfrutta le nuove funzionalità native di AWS per creare e conservare la master password MySQL direttamente in Secrets Manager: un approccio in linea con le best practice dell'architettura cloud, tra cui sicurezza, scalabilità e disaster recovery. Che si tratti di aggiungere reader per gestire un carico maggiore o di proteggere le chiavi di cifratura, Terraform è una soluzione solida per amministrare configurazioni di cluster AWS Aurora MySQL — dalle più semplici alle più complesse — su una vasta gamma di casi d'uso.
Ha ancora dubbi su come applicare questi consigli per effettuare il deploy, tramite Terraform, di un cluster Aurora MySQL configurato sul suo caso d'uso nel suo ambiente AWS?
Ci contatti su DoiT International. Il nostro team è composto esclusivamente da Engineers senior e siamo specializzati in consulenza cloud avanzata, progettazione architetturale, supporto al debugging e servizi di consulenza.