Meu primeiro projeto com AWS Cloudformation - Automatizando a criação da arquitetura
Walter Alleyz
Posted on June 26, 2022
0. Objetivo do projeto
1. Desenho da arquitetura
2. Código e explicação
3. Conclusão
Objetivo do projeto
A motivação por trás desse projeto foi me capacitar em AWS, principalmente nos serviços Cloudformation, S3, Lambda, VPC, RDS e IG e nos conhecimentos de políticas de acesso para crescer profissionalmente. O objetivo do projeto é ser um registrador de arquivos excluídos, sempre que um arquivo for deletado manualmente, ou por meio de políticas de um bucket, o S3 deverá alertar um Lambda para realizar um registro no RDS (MySQL). Pode ser uma boa solução para quem pretende sincronizar arquivos de um bucket com seu conteúdo em um banco RDS.
Todo o projeto pode ser encontrado nesse repositorio.
Desenho da arquitetura
A arquitetura é autoexplicativa: Vamos precisar de um S3 para enviar notificações à um Lambda que vai se comunicar com um RDS. Mas nada é tão simples, já que a comunicação entre esses serviços depende de rede e permissões. Por isso vamos precisar de uma VPC, duas subnets (que serão associadas ao RDS e ao Lambda) e uma Role com permissão do evento do bucket para o Lambda.
Código e explicação
Inicialmente vamos criar uma VPC para proteger o acesso ao nosso RDS:
SimpleVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: stack
Value: des
Começamos definindo o tipo de recurso com a palavra-chave "Type" e associamos ao valor "AWS::EC2::VPC", pois a VPC se encontra dentro do grupo EC2. Também precisamos definir o CidrBlock que é o conjunto de IP disponível dentro da VPC.
Agora precisamos criar duas subnets, associadas a nossa VPC e um grupo de subnets que será usado pelo RDS.
SimpleSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: SimpleVPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: "us-east-1a"
Tags:
- Key: stack
Value: des
SimpleSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: SimpleVPC
CidrBlock: 10.0.2.0/24
AvailabilityZone: "us-east-1b"
Tags:
- Key: stack
Value: des
SimpleDBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
SubnetIds:
- Ref: SimpleSubnet1
- Ref: SimpleSubnet2
DBSubnetGroupDescription: Subnet para o RDS
Podemos criar o nosso RDS com uma máquina micro, que será suficiente para o nosso projeto pessoal, 4 GB de storage (mais do que o suficiente), com uma engine MySQL, e utilizando do nosso grupo de subnets.
SQLDemoDbInstance:
Type: AWS::RDS::DBInstance
Properties:
DBName: !Ref pDbName
MasterUsername: !Ref pDbUser
MasterUserPassword: !Ref pDbPass
Engine: MySQL
DBInstanceClass: db.t2.micro
StorageType: gp2
PubliclyAccessible: False
DBSubnetGroupName:
Ref: SimpleDBSubnetGroup
AllocatedStorage: "4"
DBInstanceIdentifier: !Join ["-", [ "SQLDemoDbInstance", !Ref "AWS::Region" ]]
AvailabilityZone: !Select [1, !GetAZs ""]
Agora, vamos criar nosso bucket com uma política de notificação. Nesse caso, eu quero que meu bucket notifique o Lambda sempre que um objeto for removido, independente de seu estado anterior (versionado, taggeado, etc).
É importante definir que o bucket terá uma dependência com a criação do Lambda e apontar a propriedade "Function" para o Arn do nosso Lambda, usando a função !GetAtt.
Perceba que eu estou definindo um filtro no S3 para notificar somente arquivos terminados em ".txt".
MyBucket:
Type: AWS::S3::Bucket
DependsOn: LambdaS3Permissao
Properties:
BucketName: !Ref BucketName
NotificationConfiguration:
LambdaConfigurations:
- Event: s3:ObjectRemoved:*
Function: !GetAtt LambdaS3Processamento.Arn
Filter:
S3Key:
Rules:
- Name: suffix
Value: .txt
Por fim, vamos criar a Lambda com um código simples que pode ser atualizado depois no console. Você também poderia apontar o seu código para um arquivo zip dentro de um bucket S3, mas vamos deixar mais simples para o nosso caso.
O nosso Lambda terá a simples tarefa de receber o evento de notificação, extrair o nome do arquivo e salvar na base RDS com um timestamp associado. É importante lembrar de utilizar as mesmas subnets e o security group da nossa VPC.
LambdaS3Processamento:
Type: AWS::Lambda::Function
Properties:
Handler: index.execute
Role: !GetAtt LambdaS3Role.Arn
Runtime: nodejs12.x
MemorySize: 128
Timeout: 45
VpcConfig:
SecurityGroupIds:
- sg-0c094b8e5f85ae4b3
SubnetIds:
- !Ref SimpleSubnet1
- !Ref SimpleSubnet2
Code:
ZipFile: >
exports.execute = (event, context) => {
console.log(event);
}
Você pode, facilmente, criar a sua infraestrutura por meio do console AWS, no serviço cloudformation, importando o template que a gente acabou de criar.
Depois de criado com sucesso, precisamos alterar o código da nossa Lambda com o nosso projeto do github. Para isso, precisamos baixar o projeto e compactar no formato zip. No serviço de Lambda do console AWS, escolha upload e o formato zip. Depois de atualizar o código, podemos testar enviando um arquivo ao nosso bucket e apagando logo em seguida.
Conclusão
O AWS Cloudformation nos permitiu construir uma estrutura simples, de fácil deploy utilizando apenas um arquivo. Sempre que for necessário replicar a mesma estrutura, podemos usar o mesmo arquivo alterando poucos parâmetros.
Posted on June 26, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.