Então pessoal, como eu mencionei brevemente na aula anterior, existe uma relação entre o CloudFormation, que é o serviço da AWS, e o AWS CDK, Cloud Development Kit. Sem o CloudFormation nós não conseguimos fazer o deploy do nosso projeto CDK. Então é por isso que eu resolvi dar aqui uma introdução, explicar ali de uma forma bem superficial como funciona o CloudFormation, explicar também sobre os templates, para que a gente consiga entender mais a fundo como funciona o CDK, para que fique mais claro como funciona o CDK quando de fato nós estivermos trabalhando no nosso projeto. Como eu já citei, existe ali um conceito principal dentro do CloudFormation, que é o template. Então esse template nada mais é do que um arquivo em JSON ou em ML, onde nós especificamos todos os recursos que serão criados. Então se eu vou criar uma máquina virtual, se eu vou criar um bucket no S3, seja lá o que eu for criar, eu vou especificar dentro desse arquivo em ML ou JSON, eu posso escolher entre um e outro. Dado que eu tenho esse arquivo, que eu tenho especificação de todos os nossos recursos, eu posso fazer o deploy desses recursos recursos que nós chamamos de stack. Então esse é um outro conceito muito importante de CloudFormation, que são as stacks. As stacks é justamente isso, o conjunto desses recursos relacionados que são criados a partir do nosso template. E essa stack, ela guarda o estado da nossa infraestrutura, assim como nós temos o tfstate lá no nosso terraform, aqui nós temos a stack porém essa stack ela é gerenciada pelo próprio CloudFormation, tá? Então nós vamos entender a fundo como isso funciona, agora com um exemplo, vamos lá, o primeiro passo é nós criarmos o nosso arquivo com a definição de toda a nossa infraestrutura, Então, eu tenho aqui já um diretor aberto no VS Code, onde eu vou criar um arquivo, tá? Que pode ter qualquer nome. Aqui, no nosso caso, o arquivo que eu criarei será o arquivo template.yml, tá? Olha, na minha opinião, na opinião da maioria das pessoas, um arquivo .yml é muito mais fácil de ler do que um arquivo .json. Então, eu recomendo que você também utilize .im quando estiver declarando a sua infraestrutura. O primeiro passo que nós temos aqui neste arquivo, a primeira coisa que nós precisamos definir são os metadata. Eu gostaria de especificar aqui dois metadata principais, que são a WS Template Format Version, que é a versão que nós estamos utilizando do CloudFormation, e eu vou colocar também uma descrição, tá? Então, nós temos aqui a descrição que será CloudFormation Template to create an S3 bucket. Então, nós vamos criar aqui um S3 bucket utilizando este template, tá? Então, eu resolvi criar algo bem simples, o recurso mais simples que eu pensei para nós criarmos, e esse recurso é um bucket no S3. Caso você não saiba o que é S3, é bem tranquilo, é um serviço de storage da AWS, onde nós podemos criar objetos, é um blob storage, e para nós organizarmos esses objetos, nós criamos buckets, que seriam containers, onde nós podemos, por exemplo, especificar configurações para cada um desses buckets de forma independente. Então, nós podemos ter um bucket público, um outro bucket privado, um bucket pode ter o versionamento habilitado, outro pode ter uma política de exclusão de objetos, 180 dias, por exemplo, depois da última modificação desse objeto, então, cada bucket possui suas próprias características, suas próprias configurações e esses buckets armazenam objetos ou arquivos. Então, é isso que nós faremos. Nós vamos especificar, então, agora o nosso recurso que será esse S3 bucket. Então, uma vez que nós temos aqui o metadata, nós podemos colocar outras coisas aqui, como variáveis, parâmetros, mapeamentos, mas isso é algo mais avançado, eu gostaria que você entendesse somente o conceito aqui, basicamente, do CloudFormation. Logo em seguida, nós especificamos a parte mais importante, que de fato são os arquivos. E nós especificamos dentro dessa chave resources. Então sempre que nós formos criar nossos recursos, nós colocamos abaixo de resources. Logo em seguida nós precisamos dar um nome para o nosso recurso, uma chave, um identificador para esse recurso, assim como nós tínhamos ali no Terraform. No Terraform nós tínhamos resource, o tipo do recurso e uma chave que nós dávamos ali de forma arbitrária para aquele recurso específico. Aqui nós especificamos primeiro a chave, então vou colocar aqui myS3Bucket, novamente algo arbitrário. Logo em seguida nós temos o type, que é o tipo do recurso. E aqui nós vamos colocar a WS S3 bucket, esse aqui é o tipo do recurso que identifica que esse recurso será um bucket do S3. Logo em seguida nós precisamos informar aqui as propriedades do nosso recurso e basta nós informarmos aqui a propriedade bucket name, só com isso daqui nós já conseguimos criar um bucket. É claro que existem muitas configurações que nós podemos colocar aqui, mas num primeiro momento nós vamos simplesmente colocar o nome e deixar as outras propriedades com seus valores default. E aqui nós já fazemos algo interessante também. Nós utilizamos uma função que nos permite fazer uma concatenação de strings, onde nós estamos pegando a stack name, então eu mencionei que quando nós fazemos o deploy, nós utilizamos uma stack para fazer o deploy, e em seguida nós concatenamos aqui com bucket, tá? Então esse aqui é um valor dinâmico que será substituído depois quando nós fizermos o deploy. Beleza, temos aqui o nosso primeiro recurso especificado, tá? Simples assim. Mas, assim como nós temos lá no Terraform, nós podemos também colocar Outputs nos nossos templates. E para nós fazermos isso, nós especificamos aqui a palavra-chave Outputs primeiro. Em seguida, nós colocamos o nome do nosso Output, o identificador para esse Output, que eu vou colocar aqui como sendo bucket name, e nós podemos dar uma descrição, tá? Então, caso você queira deixar mais documentado os seus outputs, você pode dar uma descrição, aqui eu vou colocar o nome do nosso bucket S3, e eu vou colocar aqui o valor, tá? Nós temos uma outra função, que é a função ref, que nos permite referenciar um recurso já criado. Então, nós faremos isso, nós vamos referenciar aqui o nosso bucket. E quando nós fazemos isso, nós retornaremos aqui para o value do nosso output o nome do bucket que foi criado, tá? Então, nós temos aqui já o nosso output, beleza? Esse output não é obrigatório, eu estou colocando aqui simplesmente para incrementar um pouco o nosso exemplo e para já mostrar para você a similaridade que nós temos ali de features entre o CloudFormation e o Terraform, tá? Então, beleza, nós temos aqui o nosso recurso, nós temos o nosso output e agora como nós fazemos para fazer o deploy, para provisionar este recurso basta nós executarmos aqui uma linha de comando tá um comando específico que é o seguinte AWS bom eu estou considerando que você já tem o AWS CL instalado nós instalamos o AWS CL eu mostrei como fazer isso como configurar as credenciais quando nós estávamos falando sobre terraform tá então para o terraform nós já tínhamos aqui o AWS ali instalado, temos as nossas credenciais também configuradas. Então, caso você não tenha feito isso, recomendo que você dê uma olhada nessas aulas onde nós falamos sobre as credenciais da AWS e como configurar o seu ambiente. Então, vamos lá. AWS CloudFormation, que é o nome do serviço, e nós utilizamos aqui o comando deploy. Agora nós especificamos stack name, o nome da nossa stack, e que é um nome arbitrário. Caso não haja ainda essa stack criada lá no CloudFormation, uma nova stack será criada com este nome. E aqui nós teremos fc-ac, de infraestrutura como código, você escolhe o nome que você quiser. E aqui nós precisamos passar o nosso template, e o nosso template é o arquivo template.yml, que nós acabamos de criar. Agora, nós vamos passar também o profile, isso aqui não é obrigatório, caso você tenha um único profile, você pode deixar aqui essa informação, pode deixar esse parâmetro sem ser informado, que ele já vai pegar o seu parâmetro default, ou você pode especificar também para garantir, beleza? Então nós temos aqui a nossa stack fca, que deve ser criada quando nós rodarmos este comando, e o bucket será criado com o nome fca-bucket, porque esse aqui é o stack name que nós estamos referenciando. Vou dar um enter aqui e nós vamos esperar que o nosso, aqui nós já temos o log, que o nosso team de set seja criado, então o nosso conjunto de alterações será criado. Sempre que nós damos um deploy, ele cria um team de set que especifica quais são as alterações que acontecerão ali na sua infraestrutura, de acordo com o estado atual e comparando com o template que nós estamos subindo agora, para que ele saiba o que ele precisa fazer. Então, esse Teamset representa as nossas alterações. E agora, nós temos aqui a informação de que nós estamos esperando a criação da stack, ou atualização, ser completada. Nós podemos dar uma olhada aqui na nossa conta, onde nós temos o serviço CloudFormation, tá? Então, você pode pesquisar aqui, CloudFormation, deixa eu até pesquisar, CloudFormation, beleza? Eu vou abrir aqui o serviço CloudFormation e aqui nós temos as stacks, tá? Então, a stack que nós estamos criando é a stack FC-IAC, nós podemos ver aqui que o estado já está como complete, eu vou abrir aqui a nossa stack, nós temos informações detalhadas aqui da stack, e temos os eventos, então deixa eu fechar aqui, nós temos os eventos dizendo o seguinte, olha, criação do nosso bucket está em progresso, e por fim o nosso bucket foi criado com sucesso, nós estamos criando um único recurso, então nós não temos tantas informações aqui no nosso event. Nós podemos navegar até Resources, e nós temos aqui a relação de recursos relacionados a esse stack, no nosso caso, o único recurso com o nosso logical ID MyS3Bucket, e aqui nós temos até um link para o nosso bucket. Então, nós podemos visualizar aqui que foi criado de fato um bucket com o nome que nós especificamos. E nós podemos também verificar que existe aqui output. Em nosso caso, nós temos o bucket name e o valor. Foi o valor que nós especificamos até de acordo com o nome da stack. E aquilo que eu falei sobre a stack ser aquilo que armazena o estado da nossa infraestrutura, está bem claro que em resources, né? Então todos os recursos que nós criamos serão detalhados aqui. Então quando nós rodarmos o comando deploy novamente, especificando essa mesma stack, ele vai comparar o nosso arquivo que nós acabamos de atualizar, vai comparar o template com os recursos já criados e vai identificar aquilo que precisa ser alterado, se algum recurso precisa ser excluído ou outro recurso precisa ser criado, ele vai saber como fazer isso, tá? Então, nós temos aqui o nosso primeiro exemplo, dá para ver que é algo bem simples, lembra muito também o Terraform, uma vez que nós temos ali o nosso arquivo detalhando a infraestrutura, nós rodamos um comando para que a infraestrutura seja criada de fato e nós temos aqui o gerenciamento do estado no CloudFormation dentro da nossa própria stack, enquanto lá no Terraform nós temos o TFState, que nós podemos deixar localmente, ou então nós delegamos para um remote back-end, no nosso caso, por exemplo, foi o S3. Então, temos essas similaridades entre os serviços. Para nós termos outro exemplo, eu gostaria de alterar aqui o nosso bucket, só para nós vermos isso funcionando na prática, só para nós vermos a idempotência funcionando. Nós podemos, por exemplo, especificar um versionamento. Se nós voltarmos aqui no nosso bucket, deixa eu abrir o bucket, aqui em Properties nós veremos que o versionamento está desabilitado. Mas vamos supor que a gente gostaria que houvesse versionamento dos nossos arquivos, dos nossos objetos. Nós podemos especificar essa propriedade aqui dentro. Ah, mas como saber qual propriedade eu preciso alterar? Simples, nós temos a documentação, tá? Então, assim como nós dependemos da documentação para trabalhar com Terraform, nós dependemos também da documentação para trabalhar com CloudFormation e basta nós pesquisarmos aqui, né, CloudFormation e colocarmos S3. Nós já temos aqui a primeira página, então é muito bem documentado todos os recursos, nós temos tudo aquilo que nós podemos alterar. Nós temos aqui a nossa sintaxe, primeiro em JSON e depois em ML. Então nós temos todas essas configurações, você pode observar aqui que o tipo é o mesmo que nós especificamos. Temos as propriedades e nós podemos então pesquisar aqui por versionamento. Eu tenho aqui então version configuration. É uma propriedade do tipo version configuration então quando eu clico aqui eu vou ser direcionado para a descrição sobre sobre essa propriedade eu tenho aqui o type tá nesse caso é um tipo complexo então vou navegar até o tipo e aqui eu já tenho as informações de como trabalhar com esse tipo. Esse tipo específico tem simplesmente uma propriedade, que é a propriedade status. Essa propriedade pode ser enabled ou suspended. E aqui nós temos, inclusive, alguns exemplos. Vou dar uma olhada aqui no exemplo em YAML. A documentação sempre traz também os dois formatos, o formato de JSON e o formato de YAML. E aqui nós temos versioning configuration status enabled. Então nós podemos simplesmente copiar aqui, ó, essa propriedade com este valor. Vou voltar até o nosso arquivo e beleza, copiei aqui. Versioning configuration enabled. E agora basta eu executar o mesmo comando, tá? Eu vou fazendo um deploy. Nós colocamos aqui o stack name como sendo fciac. Precisamos manter o mesmo nome, se nós especificarmos um nome diferente, nós vamos criar uma outra stack e com certeza, ou não, com certeza não, talvez nós teremos um erro, por quê? Porque com outro nome, o nome do bucket será um nome diferente e nós podemos ter ali um conflito de nome, já pode ser um nome existente. Então, só para você entender essa diferença, se eu especifico um outro nome de stack, novos recursos serão criados e eu não vou estar atualizando aqueles recursos que já foram criados anteriormente. Então, eu vou rodar aqui o mesmo comando. Enquanto roda, nós podemos acompanhar o andamento do deploy aqui mesmo, através dos eventos da nossa stack. Nós temos aqui o nosso update in progress. Nós vamos aguardar alguns segundos até que seja concluído aqui o update do nosso bucket. Beleza? Temos primeiro o update da nossa própria stack e em seguida o update do nosso recurso. Beleza? Vamos aguardar aqui. Geralmente não costuma demorar muito, tá? E perfeito, update complete. Então nós vamos navegar até o nosso bucket. Ainda está como desabilitado, mas eu vou dar um refresh aqui na nossa página. E agora nós temos o versionamento habilitado para o nosso bucket. Então, eu acho que agora ficou claro, né? Ficou claro como trabalhar com CloudFormation. É claro que existem muito mais detalhes ali, existem funções, existem parâmetros, nós podemos especificar parâmetros através de arquivos, existe muita coisa que nós podemos fazer com CloudFormation, tá? Mas a ideia aqui é nós focarmos no CDK, mas para isso nós precisávamos entender como funciona essa lógica de template e de stacks em CloudFormation. Beleza? Então, espero que você tenha gostado. Para nós finalizarmos a nossa aula, finalizarmos o assunto sobre CloudFormation, eu gostaria somente de mostrar que nós gerenciamos esses recursos dentro de um stack de uma forma conjunta, que no nosso caso nós temos um único recurso, mas se nós tivéssemos vários e nós excluíssemos a nossa stack, vêssemos aqui e dá-semos um delete, nós já teríamos aqui essa mensagem de erro dizendo que excluindo esse stack, todos os recursos desse stack também serão excluídos. E é isso que nós queremos. Então, nós damos um delete. E aqui fica claro, mais uma vez, como é fácil nós gerenciarmos os recursos através de infraestrutura como código. Então, nós podemos subir todo o nosso ambiente de desenvolvimento ou de teste, testamos, terminamos o desenvolvimento, nós vamos lá e podemos excluir a stack para nós economizarmos os recursos. nós vamos lá e podemos excluir a stack para nós economizarmos os recursos. E essa stack ou esse template que nós criamos para criar a stack, esse template pode ser utilizado também para fazer o deploy em produção, basta nós passarmos os parâmetros de produção. Beleza? Então, eu espero que tenha ficado claro a ideia, o básico por trás do CloudFormation. Na próxima aula nós vamos entender como se relaciona o CloudFormation com o CDK. Portanto, vejo você lá.