Bom pessoal, nessa aula nós criaremos um novo módulo, uma nova classe, que será a classe Cluster, onde nós vamos criar todos os recursos relacionados ao nosso cluster, da mesma forma como nós fizemos no módulo Cluster lá no nosso projeto em Terraform. Então vamos primeiro aqui revisar aquilo que nós fizemos em Terraform. Vamos abrir o módulo Cluster, em Variables nós temos todas as variáveis que são muitas agora, nós temos prefixo VPC, subnets IDs, segredo de grupo IDs, instance count user data, desired capacity min size, max size e temos também as opções de scaling e scale out então temos aqui um nível de customização bem grande, além disso nós temos o nosso arquivo main, onde nós provisionamos primeiro o nosso launch template, que é o template para a instanciação ou para a criação das máquinas virtuais no nosso auto-scaling group, nós passamos o nosso user data, passamos aqui as informações de rede, nós temos o nosso auto-scaling group de fato, onde nós passamos quantas máquinas nós desejamos que tenha nesse auto-scaling, qual que é o min-size, o max-size, a subnet ID desse auto-scaling group. Temos também os targets, então quando nós trabalhamos com load balancer, nós temos aqui um target para o nosso auto-scaling group. Nós temos as policies que indicam quando nós devemos aumentar o capacity do nosso cluster, ou quando nós devemos diminuir, para isso nós precisamos dos alarmes, tá? E nós temos aqui também o scale in, nós tínhamos primeiro o scale out, né, agora nós temos o scale in. E por fim, nós temos o nosso application load balancer e o nosso target group, beleza? Temos um listener também para o nosso balancer,ancer e o nosso Target Group. Beleza? Temos um listener também para o nosso Balancer, para que a gente escute tudo o que vem na porta 80 e a gente consiga direcionar todo esse tráfego para o nosso Target. Beleza, temos todos esses recursos aqui que precisam ser criados agora em CDK. Eu recomendo para que você aprenda, para que você de fato tenha fixado aquilo que nós estamos aprendendo aqui no decorrer deste curso. Eu recomendo que você tente fazer por conta própria, que você crie ali todos esses recursos. Eu farei o provisionamento utilizando os construtores de nível 1, novamente porque oferece uma flexibilidade maior, porém eu sugiro que você dê uma olhada também nos construtores de nível 1, novamente porque oferece uma flexibilidade maior, porém, eu sugiro que você dê uma olhada também nos construtores de nível 2, tente construir, tente definir esses recursos, você verá que será menos verboso, provavelmente dará um nível menor de customização, mas é um exercício que vai garantir um aprendizado bem grande, que você vai realmente aprender bastante sobre AWS, sobre CDK e sobre CloudFormation. Então, tente fazer aí, pause essa aula e quando você terminar, volte aqui e termine de assistir a aula. Combinado? Então, vamos lá. Vamos aqui agora criar o nosso novo módulo. Eu vou, então, criar um novo arquivo aqui dentro de modules, que agora será o arquivo cluster.py. Então eu vou copiar aqui primeiro todas as dependências que nós temos, na verdade não dependências, mas os packages, as classes que nós vamos utilizar. Então eu já vou importar tudo o que eu vou precisar aqui, as classes que nós vamos utilizar. Então, eu já vou importar tudo o que eu vou precisar aqui e eu vou definir o nosso construtor agora com muitas propriedades, com muitos argumentos, melhor dizendo. Então, nós teremos aqui o nosso cluster e aqui eu estou recebendo todos os argumentos, todos os parâmetros, as variáveis que nós tínhamos ali no Terraform, eu estou recebendo como argumentos aqui e não estou utilizando classes ou DTOs em adotivo. Dá para facilitar, eu estou simplesmente definindo dessa forma aqui. Beleza, agora a primeira coisa que nós faremos é definir o nosso Launch Template, o template para a criação das nossas VMs e nós teremos aqui a definição, vou copiar também, não faz muito sentido eu passar linha a linha, já que nós falamos sobre esses Cloud Templates lá no nosso, nas sessões sobre Terraform, então aqui nós faremos de uma forma um pouco mais objetiva e é claro que esse código está lá no nosso repositório está disponível para que você confie e tire as suas dúvidas aqui nós temos então o nosso loudtemplate name, utilizando sempre o nosso prefixo, temos as informações do nosso loudtemplate com o image id o instance type, o user data que nós estamos recebendo aqui como uma string mas nós precisamos converter para a base 64. Temos Network Interfaces, onde nós estamos associando um Public IP, estamos associando também os nossos Security Groups, e passamos aqui também os Tag Specifications. Você pode observar que é bem semelhante com aquilo que nós colocamos lá no Terraform. pode observar que é bem semelhante com aquilo que nós colocamos lá no Terraform. Então, há uma associação bem direta, já que, como eu expliquei, construtores de nível 1 se associam bastante com CloudFormation e o Terraform, claro que, possui ali as mesmas propriedades, basicamente, de CloudFormation. Então, temos aqui o nosso Launch Dayplate já definido. Logo em seguida, nós vamos criar o Target Group, tá? Esse Target Group aqui vai ser utilizado tanto no nosso Load Balancer como também no nosso Auto Scaling Group. Beleza? Temos aqui a porta 80, já que nós estamos trabalhando também com o Load Balancer, teremos o load balancer, e nós receberemos o tráfego aqui na porta 80, utilizando o protocolo HTTP, especificamos a VPC que nós recebemos como parâmetro, que vai vir lá do nosso módulo de network. Também especificamos os parâmetros de health check, então tudo que é relacionado a health check está aqui, beleza, e temos por fim a nossa tag indicando o nome desse Target Group. E agora nós teremos o nosso Auto Scaling Group. Então vamos aqui criar o CFN Auto Scaling Group, informando o nome, informando o Desire de Capacito, Min Size, Max Size, informando aqui as nossas Subnet IDs e os nossos target groups. Então nós apontamos para esse target group aqui, que é o CFN target group, novamente referenciado aqui e será referenciado também lá no nosso load balancer. E utilizamos também o load template. Nós precisamos dizer aqui que esse auto-scaling group vai utilizar o load template que nós definimos anteriormente para saber como criar novas instâncias e nós referenciamos aqui a última versão. Diferente de Terraform, onde nós tínhamos o latest, não sei se vocês se lembram, mas navegando aqui novamente até o nosso cluster, nós colocamos latest aqui como sendo a última versão. É uma palavra-chave, latest, mas em CDK nós não temos esse suporte. Inclusive, há um comentário sobre isso aqui, se nós olharmos na documentação, que especificando latest ou default não vai funcionar. Mas nós podemos referenciar diretamente o nosso template e dizer aqui que nós queremos a última versão deste template. Beleza, temos o nosso auto-scaling group. Agora nós teremos o nosso auto-scaling policy. Primeiro eu vou criar aqui a nossa scale-out policy, beleza. Aqui nós colocamos que é um simple Scaling. Nós vamos alterar em Capacity quando nós estivermos ajustando o nosso Auto Scaling. E o Adjustment será aqui de acordo com esse parâmetro, Scale Out Adjustment, que no nosso caso será 1. Então sempre que nós precisarmos de dar um Scale Out, de aumentar a quantidade de instâncias, nós vamos adicionar uma instância por vez. Nós poderíamos colocar duas, três, seja lá quanto for. Além disso, nós adicionamos de forma explícita uma dependência aqui. Então, nós dizemos que, olha, para que esse auto-scaling policy seja criado, primeiro precisa ser criado esse auto-scaling group. Caso você não coloque, pode ser que você tenha um erro, pode ser que ele tente criar o auto-scscale policy primeiro. Ao invés do scaling policy primeiro, antes de criar de fato o auto-scale em grupo. Agora nós teremos também o nosso scale in, fazendo a mesma coisa e adicionando dependência. A diferença agora são os parâmetros, que agora ao invés de nós aumentarmos uma instância, nós vamos diminuir uma instância, porém isso nós recebemos como parâmetro, adicionamos aqui a dependência beleza, agora nós precisamos dos alarmes, que vão informar quando deve acontecer o scale in ou scale out então nós criaremos este este alarme primeiro temos o alarme de scale out então quando for maior ou igual a determinado threshold, que nós receberemos por parâmetro, evaluation periods igual a 3 e period igual a 30, da mesma forma como nós fizemos em CloudFormation. E agora basta nós criarmos o alarme para scale in. Scale in. Agora nós estamos falando de less ou equal. Então, nós estamos falando aqui de diminuir o nosso capacity. É por isso que nós utilizamos esse operador de less ou equal. Informamos namespace, a métrica que nós utilizaremos. Informamos que nós vamos olhar para a média de utilização do nosso cluster. E aqui nós temos de novo evaluation period e period igual ao outro alarme. Beleza? Temos as dimensions também que nos ajudam a obter as métricas corretas para o nosso auto-scaling group. E por fim, agora já que nós falamos aqui sobre os alarmes, falamos sobre scale in e scale out, nós precisamos do sobre os alarmes, falamos sobre Scale In e Scale Out, nós precisamos do Load Balancer, né? Nós vamos, então, criar esse Load Balancer nas subnetas especificadas nos parâmetros, nos Security Groups também recebidos por parâmetro. Aqui nós temos o Internet Facing, já que nós vamos receber o tráfego da internet. O tipo desse Load Balancer é Application e temos também as Tag tags. E agora nós temos o listener, que de fato indica em qual porta o tráfego será recebido e ele também faz a associação aqui, ele faz o forward para o nosso target group. E é isso, temos aqui então já definido o nosso cluster. Eu passei de forma mais rápida, mais objetiva, mas é claro que para que você entenda mesmo, para que você absorva, é preciso que você dê uma olhada com mais atenção em cada uma dessas propriedades, entenda. E relembrando, a parte mais complexa é entender a AWS, entender os serviços que a AWS oferece, as suas particularidades e não o CDK em si, não o Terraform em si, não o CloudFormation em si. Beleza? Agora vamos verificar se esse cluster está funcionando. Nós vamos então até a nossa stack, nós já temos a nossa network, agora nós vamos ter o nosso cluster. Então, nós teremos aqui cluster, mas obviamente nós precisamos importar de modules.cluster. Vamos importar aqui a classe cluster. Maravilha, cluster. Vamos instanciar. Não precisamos aqui atribuir, por enquanto, já que nós não vamos utilizar os valores desse cluster. Nós teremos aqui self. Teremos o prefixo. O pref aqui self, teremos o prefixo, o prefixo nós podemos utilizar o prefixo que está vendo aqui como parâmetro também, tá? Que vai ser o mesmo prefixo. Beleza? Agora nós teremos o nosso user data, claro que nós poderíamos colocar aqui todo aquele script que nós utilizamos pra gerar aquele arquivo index.html, para a gente verificar qual é o IP da máquina e verificar se o load balancer está funcionando e tudo está ok. Mas eu vou criar aqui, para facilitar, um arquivo. Vou criar aqui um novo arquivo que será o nosso user data. User data, um shell script e aqui nós teremos o conteúdo deste arquivo tá inclusive eu vou pegar aqui do nosso do nosso projeto em cloud formation vamos dar uma olhada aqui terraform e deixa eu ver aqui é esse carinha aqui tá então esse script aqui nós vamos colocar dentro deste arquivo userdata, beleza? E aqui na nossa stack, nós leremos este arquivo, tá? Vamos ler o conteúdo deste arquivo da seguinte forma. Deixa eu pegar aqui, beleza. Nós teremos isso daqui. Nós abrimos o arquivo, o arquivo está em website userdata.sh, nós abrimos em modo de leitura e aqui nós precisamos colocar o website, ainda que a nossa stack esteja nesse mesmo diretório, mas nós temos que lembrar que nós vamos executar aqui a partir do diretório raiz, a partir desse app.py, então nós colocamos website barra userdata.sh, modo leitura, lemos o arquivo, então fechamos o arquivo. E aí logo em seguida nós podemos referenciar esse userdeira aqui, passando userdeira. As demais propriedades nós vamos obter a partir ou do nosso módulo de network, ou então serão valores hardcodes. Primeiro nós vamos aqui colocar a security group IDs, então nós referenciamos o security group que nós criamos, é somente um, então por isso que nós colocamos aqui dentro de um array, beleza? Agora nós vamos especificar parâmetros do nosso outscaling group, o discharge capacity, min size e o max size, vamos também colocar a nossa subnet id as nossas subnet id e a nossa vpc id então nós temos aqui um for eu estou iterando sobre todas as nossas subnets dentro de network eu só tenho acesso a subnet eu só tenho acesso a security group porque nós temos essas propriedades públicas dentro da classe network, tá? Então eu posso fazer esse for aqui e posso projetar somente o atributo ATTR subnet id. Mesma coisa para VPC id. E agora eu vou passar os parâmetros de scale in e de scale out que estarão hardcoded aqui mesmo, tá? E beleza, aparentemente não temos nenhum erro, nenhum erro de compilação, mas nós precisamos testar, nós precisamos aqui fazer o nosso deploy para verificar se tudo está funcionando. Então, beleza, eu vou rodar aqui cdk deploy profile default e nós vamos aguardar que o deploy aconteça e assim que terminar, eu volto com a gravação da aula. O deploy foi finalizado, foi finalizado com sucesso, demorou um pouquinho, mas aparentemente deu tudo certo. Vamos dar uma olhada no CloudFormation. Aqui nós temos a nossa stack, que foi atualizada com sucesso. Temos agora muitos recursos adicionais. E nós vamos navegar até EC2, que é o serviço de máquinas virtuais. Nós podemos ver aqui que existem duas instâncias que já estão rodando. Se nós clicarmos aqui, temos os dois nós do nosso cluster. Nós podemos verificar que há um outscaling group criado, que há um load balancer, perfeito, e aqui para nós testarmos nós vamos verificar qual é o DNS desse load balancer, eu vou abrir uma nova aba e vou acessar aqui HTTP, vou passar o nosso load balancer e beleza, temos aqui hello e eu tenho um número de IP. Agora quando eu der um refresh, nós esperamos que um outro número de IP apareça, que é o número de IP do nosso outro nó. Então à medida que nós vamos navegando aqui, nós temos o tráfego sendo direcionado para um nó diferente dentro desse cluster. Então, nós temos a nossa infraestrutura provisionada da mesma forma como nós fizemos em Terraform, porém agora utilizando uma linguagem de código imperativo. Espero que você tenha aprendido bastante, espero que você tenha gostado e vejo você na nossa próxima aula.