Implantar bancos de dados na nuvem exige atenção a segurança, escalabilidade e facilidade de gestão. Qualquer configuração mal feita ou pouco otimizada pode virar uma grande dor de cabeça técnica, gerar dívida técnica e, no pior dos casos, causar impacto significativo ao negócio em uma indisponibilidade ou queda de desempenho do banco. O Amazon Aurora MySQL oferece um serviço de banco de dados relacional altamente escalável e seguro.
Neste post, vamos mostrar como automatizar a implantação de um cluster Amazon Aurora MySQL com Terraform, com foco em uma configuração de alta disponibilidade com várias instâncias de leitura para escalar a carga de leitura.
Pré-requisitos:
- Uma conta AWS
- Terraform instalado na sua máquina
- Familiaridade com serviços AWS e Terraform
- Código Terraform do repositório no GitHub
Estrutura do projeto: nosso projeto Terraform é organizado em módulos para ganhar clareza e reuso. Os principais módulos são:
- Módulo KMS: gerencia as chaves de criptografia do banco.
- Módulo do cluster Aurora: cuida da implantação e da configuração do cluster Aurora MySQL.
Resumo da estrutura modular de diretórios
Essa estrutura de diretórios foi pensada para organizar e gerenciar o código Terraform de forma eficiente na implantação de um cluster Amazon Aurora MySQL com criptografia gerenciada pelo AWS KMS.
Diretório raiz
Inclui main.tf, providers.tf, terraform.tfvars, variables.tf e outputs.tf.
main.tf: contém a configuração principal, onde os módulos são chamados.providers.tf: define as configurações do provider e os requisitos de versão.variables.tf: declara as variáveis usadas em todas as configurações.terraform.tfvars: define valores que sobrescrevem variáveis declaradas em outros arquivos.outputs.tf: define as saídas da configuração Terraform.
Diretório de módulos
Tem subdiretórios para cada módulo distinto usado no projeto.
Módulo KMS: cuida da criação e do gerenciamento das chaves do AWS KMS para criptografar os dados em repouso.
main.tf: contém os recursos para criar as chaves KMS.variables.tf: define as variáveis de entrada específicas do KMS.outputs.tf: fornece os atributos de saída dos recursos KMS.
Módulo do cluster Aurora: gerencia a implantação do cluster Aurora MySQL.
main.tf: configura o cluster Aurora MySQL e os recursos associados.variables.tf: lista as variáveis de entrada específicas do cluster Aurora MySQL.outputs.tf: gera saídas como o endpoint do banco.
Essa organização mantém a base de código limpa e bem estruturada, além de melhorar o reuso e a manutenibilidade do código Terraform, facilitando o gerenciamento eficiente dos recursos na nuvem.
1\. Configurando o módulo KMS
A criptografia em repouso é essencial para proteger os dados. O cluster Aurora MySQL usa o AWS KMS para o gerenciamento de chaves, mais especificamente uma AWS Customer Managed Key (CMK), na qual você cria, gerencia e é dono da chave que criptografa o seu cluster Aurora. Gerenciar a sua própria chave KMS para a criptografia do cluster Aurora traz várias vantagens em relação a usar uma chave KMS gerenciada pela AWS: as CMKs permitem políticas de controle de acesso granulares, incluindo a possibilidade de definir quem pode usá-las e administrá-las; cada uso de uma CMK fica registrado no CloudTrail para fins de auditoria — algo crucial para conformidade regulatória — e ainda oferecem controle geográfico, permitindo restringir o uso da chave a regiões AWS específicas. Os custos das CMKs — cobrados por armazenamento e uso de API — também são mais previsíveis e transparentes, o que ajuda no orçamento e na gestão de custos em comparação às chaves gerenciadas pela AWS.
O módulo KMS é responsável por criar e gerenciar essas chaves; o arquivo outputs.tf do módulo fornece o nome da chave KMS que será usada pelo módulo do Aurora.
# 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
}
Explicação:
- Rotação de chaves: a rotação automática reforça a segurança ao trocar periodicamente a chave de criptografia subjacente.
- Janela de exclusão: define o intervalo entre a exclusão e a destruição definitiva da chave, permitindo recuperá-la caso necessário.
2\. Configurando o módulo do cluster Aurora
O módulo do cluster Aurora é o coração da nossa implantação. Ele provisiona o banco com as especificações de desempenho e disponibilidade. Dá para configurar desde o engine do banco que você vai implantar, passando pela VPC e pelos Security Groups existentes que serão utilizados, até opções como impedir a exclusão acidental do cluster via Terraform — a menos que a cláusula de ciclo de vida prevent_destroy = true seja explicitamente removida do módulo:
# 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 ]
}
}
Parâmetros de configuração importantes (informe-os no terraform.tfvars):
- Cluster Identifier: identificador único do cluster Aurora; fundamental para a gestão do cluster.
- Configuração do engine: define o engine do banco e a versão, garantindo compatibilidade e disponibilidade de recursos. Pode ser Aurora MySQL 5.7.x ou MySQL 8.0.x, mas o recomendado é usar 8.0.x neste momento, já que a AWS descontinuou o 5.7.x e oferece apenas suporte estendido (pago).
- Quantidade de instâncias: controla quantas instâncias de leitura são criadas junto à instância de escrita, viabilizando o escalonamento de leitura.
- Segurança e rede: associa o cluster a configurações específicas de VPC e Security Groups, garantindo que ele opere em um ambiente de rede seguro e isolado. Você vai usar os IDs de subnet e demais valores de uma VPC já existente onde quer posicionar o seu novo cluster Aurora MySQL.
- Gestão de credenciais: usa o Secrets Manager para armazenar usuário e senha do banco, mantendo as credenciais seguindo as melhores práticas.
3\. Saídas e gerenciamento
As saídas são essenciais para recuperar detalhes de conexão e gerenciar o cluster depois da implantação, além de servirem para passar valores em tempo de execução entre módulos quando necessário.
# 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\. Conclusão
Usar Terraform para implantar clusters Amazon Aurora MySQL simplifica o processo e garante consistência e repetibilidade entre ambientes. Ao aproveitar módulos para as chaves de criptografia gerenciadas pelo cliente no KMS e para a configuração ajustada do cluster Aurora, a implantação fica modular e fácil de adaptar. Essa solução aproveita os novos recursos nativos da AWS para criar e armazenar a senha master do MySQL diretamente no Secrets Manager. A abordagem segue as melhores práticas de arquitetura em nuvem, incluindo segurança, escalabilidade e recuperação de desastres. Seja para escalar instâncias de leitura e absorver picos de carga, seja para gerenciar chaves de criptografia com segurança, o Terraform oferece uma solução robusta para administrar configurações de clusters AWS Aurora MySQL — das mais simples às mais complexas — atendendo aos mais variados casos de uso.
Ainda ficou com dúvidas sobre como aplicar essas recomendações para implantar um cluster Aurora MySQL configurado para o seu caso de uso no seu ambiente AWS com Terraform?
Fale com a gente na DoiT International. Nosso time é formado exclusivamente por engenheiros sêniores e somos especializados em consultoria avançada em nuvem, design de arquitetura, orientação em debugging e serviços de consultoria.