Atualizar AWS RDS PostgresSQL 9.6.22 para 12.7 com Terraform
Histórico
Escrevi inicialmente esse post no github quando o fim do suporte do PostgresSQL 9.6 estava se aproximando (18 Jan 2022).
A ideia desse tutorial é auxiliar na atualização do seu Banco de Dados RDS Postgres da versão 9.6 para 12.7. Dito isso, atualizar para outras versões não deve ser um processo tão diferente.
Pré-Requisitos:
Esse passo-a-passo utiliza as seguintes ferramentas:
- Terraform
- Origem: AWS RDS Postgres v9.6.22
- Destino: AWS RDS Postgres v12.7
*Para saber qual versão do Postgres você pode usar como destino, entre no console RDS na AWS, selecione o seu banco de dados e clique em modificar. Então, na versão da Engine, veja as opções disponíveis. Tome nota da versão de destino apropriada, porém não faça a alteração no console. - AWS CLI (command line interface) versão 2:
# Comando
$ aws --version
# Saída
aws-cli/2.2.16 Python/3.8.8 Linux/5.11.0-25-generic exe/x86_64.ubuntu.20 prompt/off
- E que aws cli v2 esteja configurada para sua conta da AWS.
Passo 1 - Declare suas Variáveis de Ambiente:
No console da AWS, adquira todas as informações que você irá precisar e exporte os valores usando o comando export
do bash (terminal).
Eu as dividi em duas seções:
1.1 - Valores que você já possui na sua conta da AWS:
export NAME_DB_SOURCE="nome-atual-do-seu-bd"
export INSTANCE_PARAMETER_GROUP_NAME="default.postgres9.6"
export ENGINE="postgresql"
export ENGINE_VERSION="9.6"
export DB_SUBNET_GROUP_NAME="nome-da-subnet-atual-do-bd-1234567890123456789"
export AVAILABILITY_ZONE=us-east-1a
export SECURITY_GROUP1="sg-1234567890"
export SECURITY_GROUP2="sg-0987654321"
export DB_INSTANCE_CLASS=db.t3.micro
Para mais informações sobre a subnet do BD: DB_SUBNET_GROUP_NAME
1.2 - Valores novos que serão utilizados para atualização:
export NAME_DB_INSTANCE_SNAPSHOT="snapshot-do-bd-atual-$(date '+%F')"
export NAME_DB_INSTANCE_SNAPSHOT_ENCRYPTED="snapshot-do-bd-atual-$(date '+%F')-encriptado"
export KMS_KEY_ID=xxxx-xxxx-xxxx-xxxx
export INSTANCE_ID="nome-do-novo-bd"
export ENGINE_TARGET_VERSION=12.7
Passo 2 - Crie um Backup (Snapshot) do seu Banco Atual:
# Criando o snapshot
aws rds create-db-snapshot \
--db-instance-identifier $NAME_DB_SOURCE \
--db-snapshot-identifier $NAME_DB_INSTANCE_SNAPSHOT >> log
# Comando para aguardar a criação do snapshot
aws rds wait db-snapshot-available \
--db-snapshot-identifier $NAME_DB_INSTANCE_SNAPSHOT
Passo 2.1 - Encriptando o Snapshot (Opcional):
aws rds copy-db-snapshot \
--source-db-snapshot-identifier $NAME_DB_INSTANCE_SNAPSHOT \
--target-db-snapshot-identifier $NAME_DB_INSTANCE_SNAPSHOT_ENCRYPTED \
--kms-key-id $KMS_KEY_ID \
--copy-tags >> log
# Comando para aguardar a criação do snapshot
aws rds wait db-snapshot-available \
--db-snapshot-identifier $NAME_DB_INSTANCE_SNAPSHOT_ENCRYPTED
Passo 3 - Pegue o ARN do Snapshot e Exporte no Bash:
Quando você concluir o passo 2, pegue o ARN do snapshot no console da AWS e exporte o valor no bash.
*Se você encriptou o snapshot, utilize o arn criado após o passo 2.1.
Exportando valor no bash:
# Exportando o ARN do snapshot no terminal
export ARN_INSTANCE_SNAPSHOT_DEST=arn:aws:rds:us-east-1:1234567890:snapshot:snapshot-of-current-db-2022-01-17-encriptado
Passo 4 - Criando a Nova Instância do BD a Partir do Snapshot:
# Criando nova instância do BD a partir do Snapshot
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier $INSTANCE_ID \
--db-snapshot-identifier $ARN_INSTANCE_SNAPSHOT_DEST \
--db-parameter-group-name $INSTANCE_PARAMETER_GROUP_NAME \
--db-subnet-group-name $DB_SUBNET_GROUP_NAME \
--availability-zone $AVAILABILITY_ZONE \
--vpc-security-group-ids $SECURITY_GROUP1 $SECURITY_GROUP2 \
--no-enable-iam-database-authentication \
--deletion-protection \
--copy-tags-to-snapshot >> log
# Comando para esperar até ela ficar pronta
aws rds wait db-instance-available \
--db-instance-identifier $INSTANCE_ID
Passo 5 - Atualize a Nova Instância Para a Versão Destino Escolhida:
# Atualizar a versão da engine do BD
aws rds modify-db-instance \
--db-instance-identifier $INSTANCE_ID \
--engine-version $ENGINE_TARGET_VERSION \
--allow-major-version-upgrade \
--apply-immediately
# Comando para esperar até ela ficar pronta
aws rds wait db-instance-available \
--db-instance-identifier $INSTANCE_ID
Pós-Atualização
Se tudo ocorreu como esperado, agora você tem 2 cópias do seu BD. A original, na versão 9.6, e a nova, na versão 12.7.
Os próximos passos devem incluir:
- Atualizar a aplicação para apontar para o novo BD
- Importar a nova instância do BD utilizando Terraform
Passo 6 - Atualize a Aplicação para Apontar para o Novo BD
Essa etapa é mais específica para cada projeto. Porém, basta buscar todas as referências que se tinha ao BD antigo (pesquise pelo nome do BD, por exemplo) e troque-as pelas informações novas (novo nome, etc.).
Passo 7 - Importe os Novos Componentes para o Estado do Terraform (Novo BD, KMS, Novo Cluster e o que mais que for Aplicável)
Para importar o novo BD, primeiro você precisa defini-lo no seu código terraform (não substitua por cima do original, apenas crie uma nova instância):
resource "aws_db_instance" "db-postgres-12-7" {
allocated_storage = 50
engine = "postgres"
engine_version = "12.7"
identifier = "nome-do-novo-bd"
instance_class = "db.t3.micro"
username = "db-username"
name = "db-name"
password = "db-password"
parameter_group_name = "default.postgres12.7"
db_subnet_group_name = "subnet-group"
vpc_security_group_ids = "vpc-id"
skip_final_snapshot = true
tags = "tags"
}
Após criada as instâncias no código, teremos que exectuar o método para importar as instâncias ao estado do Terraform. Com base na própria documentação do Terraform (e mesmo que o projeto execute com um backend remoto), o comando de importação roda localmente (diferente de comandos como o Apply
, que rodam no seu ambiente Terraform Cloud).
A própria documentação diz (tradução livre):
"(...) o import command não vai ter acesso à informações do seu backend remoto, tal como variáveis do seu workspace."
Para user o comando Terraform import com seu estado remoto, você precisará configurar localmente variáveis equivalentes à do seu workspace remoto.
Com isso em mente, você está a poucos passos para completar essa atualização do BD.
Rode o seguinte comando do Terraform import:
$ terraform import aws_db_instance.db-postgres-12-7 nome-do-novo-bd
Os 2 últimos passo são:
- Terraform Plan (para validar que suas mudançãs estão corretas):
$ terraform plan
- Terraform Apply (aplicar as mudanças na sua infraestrutura):
$ terraform apply