Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Como implantar um cluster Amazon Aurora MySQL com Terraform

By TylerAug 5, 20246 min read

Esta página também está disponível em English, Deutsch, Español, Français, Italiano e 日本語.

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.