Olá pessoal, sejam muito bem-vindos a mais uma aula. E nessa aula nós falaremos sobre funções. A ideia aqui é que eu mostre para vocês algumas funções que o Terraform nos disponibiliza. Claro que não tem como eu mostrar todas as funções, não faz muito sentido. Até porque à medida que nós vamos utilizando o Terraform no nosso dia a dia, surge a necessidade de nós manipularmos algum valor, alguma informação, e nós temos a documentação para nós consultarmos, não dá para nós lembrarmos a sintaxe de todas as funções que o Terraform nos oferece. Mas eu vou mostrar algumas funções para que vocês tenham ideia daquilo que nós podemos utilizar, daquilo que nós podemos fazer com algumas das funções mais comuns. Enquanto nós desenvolvemos o nosso projeto, nós fizemos uso de algumas funções, como por exemplo aqui no módulo de Network, nós temos a função Length, que nos retorna a quantidade de itens dentro de uma coleção, no nosso caso dentro de uma lista. Nós temos também no módulo de Cluster a função Base64, que recebe um string e faz o encode para a Base64. string e faz o encode para a base 64. Esses são somente dois exemplos de funções, mas que já nos mostram como nós podemos utilizar essas funções. Nós referenciamos aqui, por exemplo, variáveis e isso é algo bem normal, bem tranquilo de nós fazermos em Terraform. Para os exemplos que eu vou mostrar, eu não vou trabalhar aqui no projeto. Eu vou utilizar, ao invés disso, uma ferramenta que o próprio Terraform nos oferece que é o Terraform Console então nós temos aqui um console interativo onde nós podemos colocar expressões, expressions do Terraform e verificar quais são os resultados dessas expressões então nós temos aqui Terraform Console, beleza já está disponível, se eu colocar aqui o mais um por exemplo, ele já interpreta. E se for uma expressão válida, nós teremos o resultado. Então, nós poderíamos aqui utilizar um exemplo da função length. Como nós já utilizamos, nós podemos passar uma lista aqui. Um, dois, três. E ele vai se tornar três, que é o tamanho dessa lista. Agora, eu vou sair aqui do console, eu vou mostrar algo que pode ser interessante, que pode ser muito útil. É o seguinte, eu vou navegar até o diretório do nosso projeto, daquele projeto que nós já desenvolvemos, e eu vou rodar Terraform Console novamente. E aqui, nós vamos observar que vai demorar um pouquinho e nós temos a mensagem de erro, obtendo, não a mensagem de erro, na verdade, é uma mensagem informativa, dizendo, obtendo o state lock. Por quê? Quando nós rodamos Terraform Console no diretório de um projeto, num diretório que possui arquivos de configuração .pf, ele vai carregar o estado, então ele vai carregar o state daquele projeto para permitir que a gente manipule ou que a gente consulte as informações daquele state, tá? Então aqui ele obtém um state lock para que a gente trabalhe tranquilo e não tenha nenhum risco de uma outra pessoa fazer alteração de state, tá? Então enquanto nós estivermos trabalhando no console do Terraform dentro do diretório do nosso projeto, ninguém mais vai conseguir fazer nenhuma alteração no state. Nós estamos aqui com o state lock e quando nós damos um exit, então ele libera o state lock. Isso daqui é interessante porque nós podemos, por exemplo, fazer o seguinte, nós podemos aqui acessar o módulo network foi o nome do módulo que nós criamos então se nós navegarmos aqui de novo só para relembrarmos no arquivo main.tf da raiz do projeto nós temos aqui o módulo network quando nós digitamos aqui módulo.network nós vamos receber o output desse módulo e nós temos acesso aqui ao security group id, subnet id, subnet ids e ao vpc id. Então nós podemos trabalhar com esses outputs, nós poderíamos projetar somente subnet ids e beleza, temos aqui esses valores, poderíamos utilizar as funções inclusive para fazer testes com esses valores que nós já temos. Então, network.subnetids. Ah, sim, eleito eu coloquei errado. Isso aqui é algo bem comum, sempre eu inverto esse TH. Beleza? Temos aqui já funcionando. E além disso, nós temos acesso também às variáveis do nosso projeto. Então, ele carrega as variáveis também. Nós temos aqui, por exemplo, a variável prefixo, que nós criamos, e nós podemos acessar essa variável. Beleza? Então, aqui já dá para a gente brincar um pouquinho. Vamos lá. Eu vou falar sobre algumas categorias de funções que nós temos no Terraform. A primeira categoria é a categoria de funções numéricas, onde nós temos, como o próprio nome sugere, funções que manipulam números, que trabalham com números, que é o caso da função mínimo. Nós temos aqui a função min, que recebe uma série ou uma sequência de números e vai retornar o valor mínimo, no nosso caso aqui, 4. de números e vai retornar o valor mínimo, no nosso caso aqui, 4. Nós poderíamos, evidentemente, passar também uma lista, passar uma collection, mas para isso nós precisamos utilizar os três pontos para que ele desestruture esse array e consiga trabalhar com esses números. Então, nós utilizamos essa sintaxe quando nós estamos trabalhando com collections. Beleza? Nós poderíamos, claro, utilizar essa mesma sintaxe se nós estivéssemos trabalhando com variáveis, com variáveis numéricas, onde nós teríamos algo do tipo min, nós teríamos aqui nums, e aí nós poderíamos utilizar algo como se fosse o spread operator lá do JavaScript para quem já está habituado com o JavaScript. Temos evidentemente a função max que funciona da mesma forma, só que agora vai retornar o valor máximo. Temos a função for que vai arredondar o número, só que aqui ele vai arredondar para baixo. Então se nós arredondarmos 4.9 para baixo ele vai arredondar para baixo, então se nós arredondarmos 4.9 para baixo, ele vai arredondar para 4. E temos a função SEAL, que faz o contrário, ele arredonda para cima. Então, se nós temos 4.1, ele vai arredondar para 5. Beleza? Esses são exemplos de funções numéricas, mas é claro que nós temos muitas outras funções disponíveis. Além disso, uma outra categoria muito especial e muito utilizada de funções é a categoria de funções de manipulação de string. Então nós temos, por exemplo, o join, onde nós passamos um primeiro argumento, que seria o separador, e um terceiro argumento, que seria uma collection de strings. E ele vai juntar todas essas strings, utilizando como separador o primeiro argumento que nós passamos. Então, se eu coloco terraform fullcycle e o separador é um hífen, ele vai me retornar terraform e hífen fullcycle como uma única string. Temos as funções também de lower para transformar aqui uma string em letras minúsculas. Temos a função upper, que faz o contrário. E temos a função title, que transforma somente a primeira letra de cada palavra em maiúscula. Temos também a função replace, que como o próprio nome sugere, substitui um carácter por outro. Então se nós temos uma expressão matemática desse tipo, 1 mais 2 mais 3, e eu quero substituir o mais, melhor dizendo, por menos, basta utilizar essa função replace e eu tenho aqui o meu retorno, o meu resultado. Temos também uma função muito comum em toda linguagem de programação, que é a função split, que nós passamos um separador e ele vai separar aquela string que nós passamos no segundo argumento, de acordo com aquele separador. Então nós temos aqui uma lista, porque ele gerou três elementos a partir dessa string que possui essas duas vírgulas. E a vírgula é o nosso separador. E por fim nós temos uma função que extrai uma substring da nossa string. Então nós podemos aqui extrair da string hello world a partir do índice 1 com tamanho de 4 strings e nós teremos aqui o retorno como sendo ELLO. Essa função também é muito utilizada, tá? E beleza, novamente temos outras funções do tipo string, mas essas daqui são uma das mais utilizadas, são as mais utilizadas aí nessa categoria. Temos as funções do tipo collection, as collection functions, e nós podemos aqui mencionar a função contents, que dada uma lista verifica se um determinado item existe dentro daquela lista. Então aqui nós temos que o item A ele existe dentro dessa lista que nós passamos, porém se nós colocarmos aqui D, nós vamos ter um retorno falso. Porém, se nós colocarmos aqui D, nós vamos ter um retorno falso. Nós temos também a função keys, que ele vai retornar simplesmente as chaves dos nossos objetos, dos nossos maps. Então, se eu passo aqui esse objeto, esse map, ele vai me retornar uma lista contendo A, C e D, que são as chaves desse map. Claro que temos também a função values, que vai fazer o contrário, ao invés de retornar as keys, vai retornar os valores do nosso map. Temos o lookup, que ele vai verificar, que ele vai retornar o valor de um mapa de acordo com uma determinada propriedade, de acordo com uma determinada key. Então eu tenho aqui, por exemplo, eu vou apagar este último argumento, que ele é opcional, só para nós verificarmos aqui sem este argumento. Dado este map, eu quero obter o valor do item com aqui A. Quando nós fazemos isso, ele vai retornar aqui o valor AY. Agora, se eu passo aqui um valor que não existe, como por exemplo C, ele vai me retornar um erro. Porém, nós podemos passar aqui um outro valor, que seria o valor default. Caso ele não encontre aquela key no map, ele vai me retornar esse valor default, ao invés de me dar um erro. Então, é uma função também que pode auxiliar bastante, dependendo do nosso cenário. que pode auxiliar bastante dependendo do nosso cenário. Por fim, nós veremos aqui a função slice, que divide, que corta um determinado array, uma determinada lista. Nós temos aqui que ele vai pegar este array e vai cortar do índice 1 até o índice 3, mas sem incluir de fato o índice 3. Ele pegou aqui os elementos B e C. Perfeito, falamos aqui então sobre algumas funções que manipulam collections, e agora falaremos sobre algumas funções de forma bem simples, bem resumida, que trabalham com o file system, como por exemplo temos a função file, então nós podemos aqui ler um arquivo, temos o arquivo main.tf aqui nesse diretório, então quando nós utilizamos a função file, ele vai nos retornar o conteúdo daquele arquivo. Temos também a função fileExist, que vai verificar se um arquivo existe naquele diretório. Então, nós podemos colocar aqui main.txt, esse arquivo não existe, então, ele vai me retornar aqui, deveria me retornar um false, porque eu coloquei o nome da função errada, essa função não existe, é fileExists. Então aqui ele me retorna false, agora se eu colocar tf, aí sim ele vai me retornar true. Então eu trouxe essas duas funções como exemplo da categoria File System. Agora nós temos algumas funções do tipo Encoding, como nós vimos ali o Base64 Encode, tá? Que nós já utilizamos. Então só pra nós vermos aqui novamente, ele faz o Encode em Base64. Agora se nós quisermos o contrário, a operação reversa, nós utilizamos o Base64 Decode, tá? Que ele vai fazer o Decode dessa string de Base64. E por fim, nós podemos fazer o decode também de CSV de JSON. Como exemplo, eu trouxe aqui do CSV. Dado essa string, considerando que está no formato de CSV, ele vai transformar esse valor numa lista, onde nós temos aqui um map, onde nós temos maps com as colunas sendo as keys e os seus respectivos valores. Isso aqui também pode ser bastante útil. E agora nós teremos também funções de date time. Nós podemos, por exemplo, obter aqui o horário atual. Então, utilizando o timestamp, nós recebemos o horário atual e nós podemos formatar uma data. Então, nós passamos como primeiro argumento o formato desejado. Aqui eu estou passando o mês, o dia e o ano, e estou passando aqui em timestamp, e ele vai formatar, ele vai retornar essa data de acordo com o formato que eu especifiquei. Agora para nós finalizarmos esses exemplos, eu vou mostrar aqui algumas funções de conversão. Inclusive em algumas das aulas anteriores eu mostrei alguns desses exemplos no nosso projeto, mas aqui nós vamos relembrar a função toSet, que dada uma lista, ele vai transformar essa lista num set. E os set, os conjuntos, eles não permitem valores duplicados. Então, se nós tivermos valores duplicados, como é o caso dessa lista, onde o elemento b aparece duas vezes, ele vai remover os valores duplicados, como é o caso dessa lista, onde o elemento B aparece duas vezes, ele vai remover os valores duplicados. Nós temos também uma função que transforma um string em número, bem simples, e temos aqui uma função que transforma um número em string. E beleza, esses daqui são alguns exemplos de funções que nós podemos utilizar. Novamente, eu sugiro que você consulte a documentação, existem muitas outras funções que podem te auxiliar nos seus projetos, existem funções inclusive para trabalhar com IP, com máscaras e esse tipo de coisa, então pode ser que ali você tenha algo que pode facilitar a sua vida eu espero que você tenha gostado, eu vou colocar aqui um exit para ele liberar o lock, caso você saia do terminal sem dar esse exit caso você force aqui a saída do terminal, o lock vai ficar preso e nesse caso a gente tem uma função que nós podemos utilizar para liberar este lock deixa eu verificar se eu consigo achar essa daqui, a função force unlock, então vamos aproveitar que nós estamos trabalhando com esse cenário porque isso pode acontecer com você se nós temos aqui um lock preso, então vou pegar aqui o lock, beleza ele está obtendo aqui o lock, ok agora eu não vou sair, tá, eu vou forçar aqui a interrupção do processo e eu vou abrir novamente o terminal, Quando eu fizer isso, quando eu tentar aqui obter um lock novamente, isso poderia ser feito rodando, por exemplo, o comando terraform apply, mas no caso nós vamos utilizar o console, nós teremos um erro, mas eu preciso estar no diretório do projeto. Então deixa eu navegar aqui até o diretório do projeto, source, mba, beleza. Agora eu vou rodar aqui o Terraform console novamente. Nós teremos um erro porque o lock estará preso, né? Então, houve um erro aqui ao obter o state lock. Nesse caso, como a gente não consegue, a gente já perdeu aquele terminal, a gente não consegue sair daquele console, nós temos que utilizar aquele comando, tá? Que eu havia mostrado. Deixa eu ver se eu consigo obter ele por aqui, tá? Que é o force unlock e aqui nós passamos o ID do lock, tá? Então terraform force unlock e nós podemos passar esse ID aqui que ele vai liberar este lock. Agora nós temos que dar uma confirmação aqui, colocar yes e beleza. Agora nós temos que dar uma confirmação aqui. Colocar yes. E beleza. Agora sim nós podemos rodar Terraform console sem nenhum problema. Porque agora ele vai obter o lock com sucesso. Certo? Espero que você tenha gostado. Espero que você tenha aprendido. Vejo você na nossa próxima aula.