Introdução ao AWS CloudFormation

Botao voltar
Banner da página de Blog.
Banner da página de Blog.

Por Alessandro Oliveira, Criado em 07/05/2020


O que é o CloudFormation

CloudFormation é antes de mais nada um serviço gerenciado pela AWS que ajuda a organizar as soluções criadas na núvem, é uma peça fundamental para replicar configurações entre ambientes de desenvolvimento, homologação e produção dos clientes, mas também pode ser utilizado para replicar soluções reutilizáveis entre diversos clientes.

Costumo dizer que o CloudFormation sintetiza conhecimento, provisionamento de infraestrutura e horas de troubleshooting em templates de soluções.

Tecnicamente CloudFormation é a forma oficial de definir infraestrutura como código na nuvem da AWS, portanto, é uma peça fundamental para possibilitar processos de entrega contínua e DevOps.

Organização de um template

Um template de cloudformation pode ser definido em um arquivo yaml ou json. Inicialmente os meus templates eram definidos em json, mas ao longo dos últimos 2 anos utilizei apenas yaml por conta da facilidade de leitura.

Exemplo: Infraestrutura Deployment

Em todas as contas AWS que a CloudDog provisiona executamos esse template ou algum derivado dele criando um stack que cria 3 buckets S3 que são compartilhados entre as outras stacks.

Os recursos provisionados por esse stack são:

  1. LogsBucket: para armazenar logs do Amazon CloudFront ou outro serviço gerenciado que gere logs.
  2. DeployBucket: utilizado nos processos de continuous deployment para armazenar cópias dos templates de CloudFormation e binários de aplicações que eventualmente são acessados durante os deployments.
  3. BackupBucket: guarda arquivos de backup que podem ser gerados por outros processos.

Arquitetura
Arquitetura

CloudFormation template.yml

AWSTemplateFormatVersion: '2010-09-09' Description: Infraestrutura Deployment Resources: LogsBucket: Type: AWS::S3::Bucket
Properties: AccessControl: LogDeliveryWrite DeployBucket: Type: AWS::S3::Bucket
BackupBucket: Type: AWS::S3::Bucket
Outputs: LogsBucketName: Value: !Ref LogsBucket Description: Bucket to store logging in general Export: Name: !Sub ${AWS::StackName}-LogsBucketName DeployBucketName: Value: !Ref DeployBucket Description: Bucket to store deployment artifacts Export: Name: !Sub ${AWS::StackName}-DeployBucketName BackupBucketName: Value: !Ref BackupBucket Description: Bucket to store RDS or any other backup Export: Name: !Sub ${AWS::StackName}-BackupBucketName

As Seções do template

A estrutura completa de um template pode se tornar mais complexa do que essa, mas nesse exemplo já temos as seções mais importantes, que são:

  • AWSTemplateFormatVersion: declara a versão do template
  • Description: define a descrição do template, que pode ajudar a compreender quando existe uma grande quantidade de stacks
  • Resources: onde todos os recursos que devem ser provisionados são declarados
  • Outputs: permite a visualização rápida de atributos de recursos criados utilizando a linha de comando e o console da aws. Quando é utilizado o parâmetro export ainda permite que outros stacks façam referência a esses atributos, permitindo um encadeamento de stacks.

Executando o template.yml via console

Selecionar o Serviço CloudFormation

Buscar no menu do console pelo serviço CloudFormation, caso não tenha criado nenhum stack, irá mostrar uma tela parecida com a tela abaixo:

Passo 1: Selecionar CloudFormation
Passo 1: Selecionar CloudFormation

Criar uma Stack

Selecione a opção 'Create Stack' e siga para a próxima tela.

Na sequência deixe configurada a primeira opção: 'Template is Ready', selecione em template source a opção para carregar um template 'Upload a template file', selecione o arquivo conforme a configuração acima e clique em 'Next'.

Passo 2: Selecionar Arquivo
Passo 2: Selecionar Arquivo

Configure o 'Stack Name', no nosso exemplo utilizamos infra-deployment mas poderia ser qualquer um que atenda os requisitos da expressão regular descrita abaixo do campo, e clique em 'Next' novamente.

Passo 3: Configurando Nome do Stack
Passo 3: Configurando Nome do Stack

Agora deixe todas as opções como estão, sem nenhuma alteração e clique em 'Next' novamente.

Passo 4: Clique em Next
Passo 4: Clique em Next

Você poderá no ultimo passo revisar todas as configurações e selecionar a opção 'Create Stack', em seguida verá uma tela parecida com a imagem abaixo com a lista de eventos que foram gerados pelo CloudFormation. Caso dê algum problema, como por exemplo uma configuração inválida, é feito o rollback automaticamente de todo o stack.

Passo 5: Criando Stack
Passo 5: Criando Stack

Selecionando a aba 'Resources', poderá conferir de forma resumida todos os recursos provisionados.

Passo 6: Selecione Resources
Passo 6: Selecione Resources

Selecionando a aba 'Output', poderá conferir todas as variáveis configuradas na seção 'Output' do template, onde o 'Export Name' irá corresponder aos nomes que poderão ser referenciados em outros stacks.

 Passo 7: Selecione Output
Passo 7: Selecione Output

Verificar Recursos Criados

Após a finalização da criação do 'Stack', na aba 'Stack Info' deverá aparecer o Status como CREATE_COMPLETE, na sequência será possível conferir os recursos criados.

Para isso busque no menu de serviços da AWS por S3 ou Simple Storage Service, nesse momento deverá visualizar uma tela semelhante a tela abaixo:

Passo 8: Busque por S3
Passo 8: Busque por S3

Note que além dos 3 buckets criados pelo template, também foi criado um bucket chamado cf-template-\-us-east-1, esse bucket foi criado pelo próprio CloudFormation no momento em que foi feito o upload do template, caso entre no bucket poderá conferir algo como

Passo 9: Conferir os buckets
Passo 9: Conferir os buckets

Voltando na listagem de buckets e selecionar o bucket de logs, você poderá conferir ele foi criado com uma configuração de 'Permissions' e 'Access Control List' diferenciada onde o S3 Log Delivery Group consta com ambas permissões 'Write Objects' e 'Read Bucket Permissions' como 'yes', conforme pode conferir na próxima imagem:

Passo 10: Voltar para Listagem dos Buckets
Passo 10: Voltar para Listagem dos Buckets

Nomenclatura

A nomenclatura adotada nos buckets é ${StackName}-${LogicalName}-${HashCode}, onde o StackName é o nome do stack conforme definido no processo de criação, o LogicalName é o nome loógico atribuido na seção 'Resources' do template e o HashCode é gerado automaticamente durante a execução.

Essa nomenclatura a priori pode parecer um pouco esquisita, mas ajuda a manter a organização. Existem alguns serviços, como por exemplo o próprio bucket S3 que utiliza um namespace comum, o que impossibilita a utilização de nomes fixos em diferentes contas.

Atualizando a stack criada anteriormente

Imagine que esqueceu de colocar alguma configuração nesse stack ou evoluiu alguma coisa e precisa replicar isso nos ambientes.

Para manter a infraestrutura como código e deixar os templates alinhados com os stacks, devemos fazer a atualização no template e na sequência criar uma 'Change Set' no stack.

Ajustando o template

Utilizaremos o mesmo cenário do exemplo anterior, como pode ter reparado a essa altura, o LogsBucket está com uma configuração diferenciada para permitir o recebimento de arquivos de log, no entanto, nos outros buckets BackupBucket e DeployBucket não foram feitas as configurações corretamente.

CloudFormation template.yml ajustada

É necessário adicionar as seguintes properties no template original.

DeployBucket: Type: AWS::S3::Bucket
Properties: LoggingConfiguration: DestinationBucketName: !Ref LogsBucket LogFilePrefix: !Sub ${AWS::StackName}/deploy-bucket/ BackupBucket: Type: AWS::S3::Bucket
Properties: LoggingConfiguration: DestinationBucketName: !Ref LogsBucket LogFilePrefix: !Sub ${AWS::StackName}/backup-bucket/

Criando uma Change Set

No serviço CloudFormation no console da AWS, selecione a stack criada anteriormente, no nosso caso infra-deployment, no menu 'Stack Actions' selecione a opção 'Create change set for current stack', conforme a imagem abaixo:

 Passo 11: Selecione a Stack Criada
Passo 11: Selecione a Stack Criada

Depois selecione a opção 'Replace current template', para possibilitar o carregamento do template atualizado e faça o carregamento do template utilizando 'Upload a template file' e selecionando o arquivo template.yml.

Passo 12: Carregue o template.yml
Passo 12: Carregue o template.yml

Na sequência clique em 'Next' aceitando as configurações padrão até aparecer o popup abaixo para configurar o nome do change set, pode deixar o nome sugerido e em seguida clique em 'Create Change Set'.

Passo 13: Confirme em Create ChangeSet
Passo 13: Confirme em Create ChangeSet

Após a criação do change set, será possível conferir quais recursos serão alterados por esse change set, se tudo ocorreu bem, deverão aparecer na lista apenas o BackupBucket e o DeployBucket. É importante notar que a coluna 'Replacement' está com valor 'false' para ambos os recursos, isso significa que não haverá perda de dados. Nesse momento, poderá executar a change set com segurança clicando no botão 'Execute'

Passo 14: Aperte para executar ChangeSet
Passo 14: Aperte para executar ChangeSet

A change set começará a ser executada e voltará para a aba eventos da Stack, pode clicar no botão refresh até que apareça no topo a linha 'infra-deployment' com status 'UPDATE_COMPLETE', conforme a imagem abaixo.

Passo 15: Clique em refesh para que apareça o 'infra-deployment'
Passo 15: Clique em refesh para que apareça o 'infra-deployment'

Validando a Change Set

É sempre importante entrar nos recursos atualizados e conferir que o ajuste foi feito de forma satisfatória.

Passo 16: Validar o ChangeSet
Passo 16: Validar o ChangeSet

Protegendo uma Stack

Após a criação e atualização da stack já temos uma base sólida para darmos continuidade e passa a ser importante evitar que alguém exclua essa stack de forma acidental.

Por isso é necessário fazer a configuração selecionando o stack, acesse a opção 'Edit termination protection' no menu 'Stack Actions'

 Passo 17: Protegendo a Stack 1
Passo 17: Protegendo a Stack 1

Selecione a opção 'Enable' e confirme clicando em 'Save'.

Passo 18: Protegendo a Stack 2
Passo 18: Protegendo a Stack 2

Poderá conferir na sequência a notificação em verde dizendo que a alteração foi feita com sucesso. Como essa alteração não gerou alterações nos recursos, não houve alteração no status do stack e não foi lançado nenhum evento novo.

Passo 19: Protegendo a Stack 3
Passo 19: Protegendo a Stack 3

Resumo

Nesse artigo descobrimos o básico de um template AWS CloudFormation, criamos uma Stack e atualizamos utilizando uma Change Set, por fim protegemos a stack contra exclusão.

Tags

#devops #aws #cloudformation #s3 #infra-como-codigo

Sobre o autor

Foto Do Autor.
Foto Do Autor.

Alessandro Oliveira

É fundador da CloudDog, entusiasta na adoção de nuvem desde 2010, AWS Certified Solutions Architect ha mais de 7 anos, realiza projetos com características desafiadoras há mais de 20 anos em diversos segmentos, como varejo, indústria, saúde e serviços.

Comentários