DEV Community

Cover image for Usando AWS RDS Blue/Green deployment para atualizações com zero downtime
Raziel Rodrigues
Raziel Rodrigues

Posted on

Usando AWS RDS Blue/Green deployment para atualizações com zero downtime

Introdução

Neste post, eu gostaria de escrever sobre uma feature do RDS da AWS chamada Blue/Green deployment. Fiz uso dessa feature há um tempo atrás e eu gostaria de trazer um passo a passo de como utilizar e de algumas coisas que aprendi durante o caminho.

Quando estamos trabalhando com sistemas de alta disponibilidade, um downtime no banco de dados se torna inaceitável. Isso significa serviços parados, clientes reclamando e, muitas vezes, perda de dinheiro.

Solução

Para mitigar esse problema de forma elegante, uma das estratégias consiste em blue/green deployment. As implantações blue/green criam dois ambientes: um ambiente possui a versão atual do banco de dados, este é o ambiente azul. Em seguida, cria um ambiente verde, que contém uma cópia exata do seu banco de dados.

Para manter ambos sincronizados, a AWS cria uma replicação em tempo real que tem uma taxa de replica lag muito baixa, evitando a perda de dados. O banco de dados green nasce apenas como leitura, para evitar dados corrompidos entre blue/green.

Entretanto, é possível remover essa trava e fazer operações de escrita no banco green também, mas tome cuidado com isso e saiba que isso irá gerar uma divergência entre as tabelas de bancos, então somente use em casos que seja realmente necessário.

Imagem Blue green deployment AWS

O banco de dados green pode ser criado com alguns parâmetros diferentes do banco de dados blue: você pode provisionar mais poder computacional ou menos poder computacional, também pode alterar os parâmetros do banco de dados e alterar a versão do ambiente green, tudo isso ainda na tela de criação do ambiente, já criando o seu novo banco de dados com os novos parâmetros. Isso evita que você tenha algum reboot no seu banco de dados de produção.

Lembre-se que você precisará resolver o drift do Terraform com a AWS caso você altere coisas que não estão no Terraform. Por isso, eu aconselho a alterar parâmetros de instância somente quando necessário e alinhar isso no Terraform, ou, depois que você fizer o switchover, mudar parâmetros que são de instância.

Laboratório

Vamos criar um projeto Terraform com um banco de dados:

terraform {

  required_providers {

    aws = {

      source  = "hashicorp/aws"

      version = "~> 6.0"

    }
  }
}

provider "aws" {

  region = "us-east-1"
}

module "vpc" {

  source  = "terraform-aws-modules/vpc/aws"

  version = "6.6.0"

  name = "database_test"

  cidr = "10.0.0.0/16"

  azs = ["us-east-1a", "us-east-1b"]

  sub-redes_públicas  = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"]
  enable_dns_hostnames = true

  enable_dns_support   = true
}

resource "aws_db_subnet_group" "this" {

  name       = "database_test"

  subnet_ids = module.vpc.public_subnets
}

resource "aws_db_parameter_group" "this" {

  name   = "test"

  family = "mysql8.0"
}

resource "aws_db_instance" "this" {
  allocated_storage = 5

  db_name = "mydb"

  engine = "mysql"

  engine_version = "8.0"

  instance_class = "db.t3.micro"

  username = "master"

  password = var.db_password

  parameter_group_name = aws_db_parameter_group.this.name

  db_subnet_group_name = aws_db_subnet_group.this.name

  skip_final_snapshot = true

  publically_accessible = false
}

Enter fullscreen mode Exit fullscreen mode

Após a criação, vá ao painel da AWS e basta clicar em Ações; em seguida, crie a implantação seguindo a interface do usuário.

Painel usuario AWS

Depois de ter os dois ambientes, confira se as configurações estão da forma que você quer e clique em criar. No meu caso, eu alterei a versão para 8.4, e para que não haja Terraform drift eu vou precisar atualizar no meu IaC também.

Painel Blue green AWS

No entanto, para alterações de DML/DDL, tome cuidado para não introduzir alterações que quebrem a compatibilidade; analise cuidadosamente antes de fazê-las.

Por exemplo, você não pode remover uma coluna do banco de dados verde enquanto ela ainda existir no azul, e não deve alterar a estrutura de forma que possa corromper os dados, como converter um campo do tipo inteiro para um campo do tipo string.

Além disso, se você quiser fazer isso, precisará alterar um grupo de parâmetros no banco de dados verde para definir read_only como falso, já que o banco de dados verde geralmente é usado apenas para leitura.

Assim que estiver pronto para fazer o switchover, no mesmo menu de ações você verá a opção. Após apertar a opção de switchover, a Amazon vai fazer uma checagem de saúde nos dois DBs e internamente vai fazer a alteração do banco de dados. Você não precisa alterar DNS, nem mudar endpoint em aplicação, nada. A alteração dura menos de um minuto.

Após a alteração bem-sucedida, apague o banco de dados antigo e exclua o deployment; a interface te me guiará nesse passo a passo.

Caso você queira fazer via Terraform é possível, mas você não poderá controlar o momento do switchover. Para fazer com Terraform, basta usar o módulo RDS do terraform entretanto se lembre de que não tera controle sobre o momento so switchover, ele sera feito direto assim que o status do parametro blue_green_deployment for true.

module "db" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "demodb"

  engine            = "mysql"
  engine_version    = "8.0"
  instance_class    = "db.t3a.large"
  allocated_storage = 5

  db_name  = "demodb"
  username = "user"
  port     = "3306"

  iam_database_authentication_enabled = true

  vpc_security_group_ids = ["sg-12345678"]

  maintenance_window = "Mon:00:00-Mon:03:00"
  backup_window      = "03:00-06:00"

  # Enhanced Monitoring - see example for details on how to create the role
  # by yourself, in case you don't want to create it automatically
  monitoring_interval    = "30"
  monitoring_role_name   = "MyRDSMonitoringRole"
  create_monitoring_role = true

  tags = {
    Owner       = "user"
    Environment = "dev"
  }

  # DB subnet group
  create_db_subnet_group = true
  subnet_ids              = ["subnet-12345678", "subnet-87654321"]

  # DB parameter group
  family = "mysql8.0"

  # DB option group
  major_engine_version = "8.0"

  # Database Deletion Protection
  deletion_protection = true

  parameters = [
    {
      name  = "character_set_client"
      value = "utf8mb4"
    },
    {
      name  = "character_set_server"
      value = "utf8mb4"
    }
  ]

  blue_green_update = {
    enabled = true
  }

  options = [
    {
      option_name = "MARIADB_AUDIT_PLUGIN"

      option_settings = [
        {
          name  = "SERVER_AUDIT_EVENTS"
          value = "CONNECT"
        },
        {
          name  = "SERVER_AUDIT_FILE_ROTATIONS"
          value = "37"
        },
      ]
    },
  ]
}

Enter fullscreen mode Exit fullscreen mode

Blue/green deployment é uma técnica muito boa para atualizações que necessitam de um downtime muito baixo, sendo a técnica perfeita para várias empresas, e não tenho dúvidas de que isso vai te ajudar caso precise encarar um desafio como o meu.

Top comments (0)