Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Amazon Aurora MySQL Cluster mit Terraform bereitstellen

By TylerAug 5, 20246 min read

Diese Seite ist auch in English, Español, Français, Italiano, 日本語 und Português verfügbar.

Datenbanken in der Cloud zu betreiben, verlangt eine sorgfältige Abwägung von Sicherheit, Skalierbarkeit und Wartbarkeit. Eine Fehlkonfiguration oder ein suboptimales Setup führt schnell zu erheblichem technischem Aufwand, technischen Schulden und im schlimmsten Fall – bei einem Ausfall oder einer schwachen Datenbank-Performance – zu spürbaren Folgen fürs Geschäft. Amazon Aurora MySQL bietet hierfür einen hochskalierbaren und sicheren relationalen Datenbankdienst.

In diesem Beitrag zeigen wir, wie sich die Bereitstellung eines Amazon Aurora MySQL Clusters mit Terraform automatisieren lässt – mit Fokus auf eine hochverfügbare Konfiguration mit mehreren Reader-Instanzen zur Lese-Skalierung.

Voraussetzungen:

  • Ein AWS-Konto
  • Terraform lokal installiert
  • Grundkenntnisse in AWS-Diensten und Terraform
  • Terraform-Code aus dem GitHub-Repo

Aufbau des Projekts: Unser Terraform-Projekt ist für mehr Übersicht und Wiederverwendbarkeit in Module gegliedert. Die wichtigsten sind:

  • KMS-Modul: Verwaltet die Verschlüsselungsschlüssel für die Datenbank.
  • Aurora-Cluster-Modul: Übernimmt Bereitstellung und Konfiguration des Aurora MySQL Clusters.

Überblick über die modulare Verzeichnisstruktur

Diese Verzeichnisstruktur organisiert den Terraform-Code für die Bereitstellung eines Amazon Aurora MySQL Clusters mit über AWS KMS verwalteter Verschlüsselung effizient und übersichtlich.

Stammverzeichnis

Enthält main.tf, providers.tf, terraform.tfvars, variables.tf und outputs.tf.

  • main.tf: Enthält die Hauptkonfiguration, in der die Module aufgerufen werden.
  • providers.tf: Definiert Provider-Einstellungen und Versionsanforderungen.
  • variables.tf: Deklariert die Variablen, die in allen Konfigurationen verwendet werden.
  • terraform.tfvars: Setzt Override-Werte für anderswo definierte Variablen.
  • outputs.tf: Definiert die Ausgaben der Terraform-Konfiguration.

Modulverzeichnis

Enthält Unterverzeichnisse für jedes im Projekt verwendete Modul.

KMS-Modul: Übernimmt Erstellung und Verwaltung von AWS-KMS-Schlüsseln zur Verschlüsselung ruhender Daten.

  • main.tf: Enthält die Ressourcen zur Erstellung der KMS-Schlüssel.
  • variables.tf: Definiert die KMS-spezifischen Eingabevariablen.
  • outputs.tf: Stellt Ausgabewerte der KMS-Ressourcen bereit.

Aurora-Cluster-Modul: Verwaltet die Bereitstellung des Aurora MySQL Clusters.

  • main.tf: Konfiguriert den Aurora MySQL Cluster und die zugehörigen Ressourcen.
  • variables.tf: Listet die Eingabevariablen für den Aurora MySQL Cluster.
  • outputs.tf: Gibt Attribute wie den Datenbank-Endpoint aus.

Diese Struktur sorgt für eine saubere und übersichtliche Codebasis, steigert Wiederverwendbarkeit und Wartbarkeit des Terraform-Codes – und macht das Management von Cloud-Ressourcen deutlich einfacher.

1\. Einrichtung des KMS-Moduls

Verschlüsselung ruhender Daten ist essenziell für deren Schutz. Der Aurora MySQL Cluster nutzt dafür AWS KMS – konkret einen AWS Customer Managed Key (CMK), den Sie selbst erstellen, verwalten und besitzen, um Ihren Aurora-Cluster zu verschlüsseln. Ein eigener KMS-Schlüssel bietet gegenüber einem von AWS verwalteten Schlüssel mehrere Vorteile: CMKs erlauben feingranulare Zugriffsrichtlinien – inklusive der Festlegung, wer sie nutzen und verwalten darf. Jede Verwendung eines CMK wird zu Audit-Zwecken in CloudTrail protokolliert – unverzichtbar für regulatorische Compliance –, und über die geografische Steuerung lässt sich die Schlüsselnutzung auf bestimmte AWS-Regionen einschränken. Auch die Kosten für CMKs – abgerechnet für Speicherung und API-Nutzung – sind im Vergleich zu AWS-verwalteten Schlüsseln planbarer und transparenter, was Budgetierung und Kostenkontrolle erleichtert.

Das KMS-Modul ist für Erstellung und Verwaltung dieser Schlüssel zuständig; die Datei outputs.tf des Moduls liefert den Namen des KMS-Schlüssels, den das Aurora-Modul nutzt.

# 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
}

Erläuterung:

  • Schlüsselrotation: Die automatisierte Rotation erhöht die Sicherheit, da der zugrunde liegende Verschlüsselungsschlüssel regelmäßig gewechselt wird.
  • Deletion Window: Legt den Zeitraum fest, bevor ein gelöschter Schlüssel endgültig vernichtet wird – so bleibt im Bedarfsfall eine Wiederherstellung möglich.

2\. Konfiguration des Aurora-Cluster-Moduls

Das Aurora-Cluster-Modul ist das Herzstück unserer Bereitstellung. Es richtet die Datenbank mit den Vorgaben für Performance und Verfügbarkeit ein. Konfigurierbar ist alles – von der eingesetzten Datenbank-Engine über die zu nutzende vorhandene VPC und Security Groups bis hin zum Schutz vor versehentlichem Löschen des Clusters per Terraform, sofern die Lifecycle-Klausel prevent_destroy = true nicht ausdrücklich aus dem Modul entfernt wird:

# 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 ]
  }
}

Wichtige Konfigurationsparameter (in terraform.tfvars bereitstellen):

  • Cluster Identifier: Eindeutige Kennung für den Aurora-Cluster – entscheidend für das Cluster-Management.
  • Engine-Konfiguration: Legt Datenbank-Engine und -Version fest und sichert Kompatibilität sowie Funktionsumfang. Möglich sind Aurora MySQL 5.7.x oder MySQL 8.0.x – aktuell wird jedoch dringend zu 8.0.x geraten, da AWS die Version 5.7.x abgekündigt hat und nur noch erweiterten (kostenpflichtigen) Support anbietet.
  • Anzahl der Instanzen: Steuert die Zahl der zusätzlich zum Writer angelegten Reader-Instanzen und ermöglicht so die Lese-Skalierung.
  • Sicherheit und Netzwerk: Bindet den Cluster an konkrete VPC- und Security-Group-Einstellungen, sodass er in einer sicheren und isolierten Netzwerkumgebung läuft. Verwenden Sie dafür die Subnet-IDs und weitere Werte einer bestehenden VPC, in der Ihr neuer Aurora MySQL Cluster platziert werden soll.
  • Credentials Management: Nutzt Secrets Manager, um Benutzername und Passwort der Datenbank gemäß Best Practices sicher abzulegen.

3\. Outputs und Verwaltung

Outputs sind unverzichtbar, um Verbindungsdetails abzurufen, den Cluster nach der Bereitstellung zu verwalten und – falls nötig – Laufzeitwerte zwischen Modulen weiterzugeben.

# 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\. Fazit

Mit Terraform wird die Bereitstellung von Amazon Aurora MySQL Clustern deutlich einfacher – mit konsistenten und reproduzierbaren Ergebnissen über alle Umgebungen hinweg. Durch separate Module für die KMS-Kundenschlüssel und die feingranulare Konfiguration des Aurora-Clusters bleibt das Setup modular und leicht anpassbar. Die Lösung greift dabei auf die neuen, in AWS integrierten Funktionen zurück, mit denen sich das MySQL-Master-Passwort direkt im Secrets Manager erzeugen und ablegen lässt. Dieser Ansatz folgt Best Practices der Cloud-Architektur – etwa bei Sicherheit, Skalierbarkeit und Disaster Recovery. Ob Sie zusätzliche Reader hinzufügen, um steigende Last zu bewältigen, oder Verschlüsselungsschlüssel sicher verwalten möchten: Terraform bietet eine robuste Grundlage – von einfachen bis hin zu hochkomplexen Konfigurationen von AWS Aurora MySQL Clustern für die unterschiedlichsten Anwendungsfälle.

Haben Sie noch Fragen, wie Sie auf Basis dieser Empfehlungen einen passgenau konfigurierten Aurora MySQL Cluster mit Terraform in Ihrer AWS-Umgebung bereitstellen?

Sprechen Sie uns an bei DoiT International. Unser Team besteht ausschließlich aus erfahrenen Senior Engineers – wir sind spezialisiert auf anspruchsvolle Cloud-Beratung, Architekturdesign, Debugging-Support und Consulting-Leistungen.