Guia completo: Como criar um Lambda AWS com Terraform e Java
Para este post, vamos criar um AWS Lambda com Terraform e Java como linguagem de programação. Mas antes de tudo, você já ouviu falar de Lambda? Caso não, recomendo ver este post sobre Lambda. E sobre Terraform? Neste post eu mostro os primeiros passos usando Terraform, é só clicar aqui . A ideia deste post é criar um AWS Lambda que será trigado através do CloudWatch Events por meio de um agendamento automatizado usando uma expression cron . Normalmente, podemos criar qualquer recurso da AWS usando o console, mas aqui usaremos o Terraform como uma ferramenta IaC (Infraestrutura como código) que criará qualquer recurso necessário para executar nosso AWS Lambda. Como runtime ou linguagem de programação, escolhemos Java. Lembre-se de que você pode executar o Lambda usando diferentes linguagens de programação, como Java, Python, .NET, Node.js e muito mais. Mesmo que seja um projeto Java, a parte mais importante deste post é tentar entender sobre o Lambda e como você pode cria-lo através do Terraform. Introdução O Terraform será responsável por criar todos os recursos para este post, como o prórprio Lambda, roles, policies, CloudWatch Events e S3 Bucket, onde manteremos o arquivo JAR de nosso aplicativo. Nosso Lambda será invocado pelo CloudWatch Events a cada 3 minutos executando um método simples em Java no qual imprimirá uma mensagem. Você pode observar na imagem acima que estamos usando S3 para armazenar nosso pacote de implantação, arquivo JAR neste caso. É uma recomendação da AWS fazer upload de pacotes de implantação maiores diretamente para o S3, em vez de manter no próprio Lambda. Isso acontece pois o S3 oferece suporte para armazenar arquivos maiores. Não se preocupe em carregar arquivos manualmente, o Terraform também será responsável por fazer isso durante a fase de build. Criando o projeto Para este post vamos usar Java como linguagem e Maven como gerenciador de dependências. Portanto é necessário gerar um projeto Maven que irá criar a estrutura do nosso projeto. Se você não sabe como gerar um projeto Maven, recomendo ver este tutorial onde mostro como gerar. Estrutura do projeto Após gerar o projeto Maven, vamos criar os mesmos arquivos e pacotes conforme imagem ao lado, exceto o pom.xml que foi criado pelo gerador maven. É uma característica dos projetos Maven gerar essas estruturas de pastas como mostrado src/main/java/. Dentro da pasta java/ , crie um pacote chamado coffee.tips.lambda e crie uma classe Java chamada Handler.java dentro deste mesmo pacote. Alterando o pom.xml Para este tutorial, adicione as seguintes dependências e também copie a fase de build abaixo: Criando o Handler Uma classe handler é basicamente o controlador Lambda. O Lambda sempre procura um handler para iniciar seu processo, resumindo, é o primeiro código a ser invocado. Criamos um handler básico apenas para "printar" mensagens quando invocadas pelo CloudWatch Events. Obeserve que implementamos a interface RequestHandler permitindo receber como parâmetro um objeto Map<String, Object>. Mas para este exemplo não vamos explorar os dados deste parâmetro. Entendendo os arquivos Terraform Agora vamos entender como os recursos serão criados usando o Terraform. vars.tf No arquivo vars.tf é onde declaramos as variáveis. As variáveis fornecem flexibilidade quando precisamos trabalhar com diferentes recursos e ambientes de execução. vars.tfvars Agora precisamos definir os valores dessas variáveis. Então, vamos criar uma pasta chamada /development dentro da pasta terraform . Após a criação da pasta. Crie um arquivo chamado vars.tfvars como na imagem ao lado e cole o conteúdo abaixo. Observe que no campo for bucket , você deve especificar o nome do seu próprio bucket. O nome do bucket deve ser único. main.tf Para o arquivo main.tf , apenas declaramos o provedor. Provider é o serviço de nuvem que usaremos para criar nossos recursos. Neste caso, estamos usando a AWS como provider e o Terraform fará o download dos pacotes necessários para criar os recursos. Observe que, para o campo region , estamos usando a palavra-chave var para obter o valor da região já declarado no arquivo vars.tfvars . s3.tf É no s3.tf que vamos declarar os recursos relacionados ao S3 em geral. Nesse caso, criamos apenas o bucket S3. Mas se você quiser criar mais recursos relacionados ao S3, como policies, roles ou qualquer recurso relacionado, pode declarar aqui. É uma forma de separar os arquivos Terraform por recurso. Observe novamente que estamos usando a palavra-chave var para a variável bucket declarada no arquivo var.tf. lambda.tf Finalmente nosso último arquivo terraform, neste arquivo estamos declarando recursos relacionados ao Lambda e ao próprio Lambda. Agora acho que vale a pena explicar alguns detalhes sobre o arquivo acima. 1. Declaramos 2 objetos do tipo data aws_iam_policy_document , que definem quais ações os recursos que serão atribuídos a essas policies podem executar. 2. aws_iam_role: recurso que fornece a função IAM e que também controlará algumas ações do Lambda. 3. aws_iam_role_policy: fornece IAM role inline policy e r egistrará a role e as policies anteriores relacionadas ao aws_iam_policy_document.aws_iam_policy_coffee_tips_aws_lambda_iam_policy_document . 4. Declaramos o recurso aws_s3_object porque queremos armazenar nosso arquivo jar no S3. Assim, durante a fase de deploy, o Terraform obterá o arquivo jar que será criado na pasta target/ do projeto e fará o upload para o S3. depends_on : T erraform deve criar este recurso antes do atual. bucket : É o nome do bucket onde irá armazenar o arquivo jar. key : nome da jar. source : localização do arquivo de origem. etag : aciona atualizações quando acontecem alterações. 5. aws_lambda_function is the resource responsible to create Lambda and we need to fill some fields such as: function_name : Nome do Lambda role : role declarada nas etapas anteriores que fornece acesso aos serviços e recursos da AWS. handler : Neste campo você precisa especificar o diretório da classe principal. source_code_hash : Este campo é responsável por acionar as atualizações do lambda. s3_bucket : É o nome do bucket onde irá armazenar o arquivo jar gerado durante o deploy. s3_key : Nome do jar runtime : Aqui você pode especificar a linguagem de programação suportada pelo Lambda. Para este exemplo, java 11 . timeout : Tempo limite de execução do Lambda. 6. aws_cloudwatch_event_rule é a regra relacionada à execução do evento do CloudWatch. Neste caso, podemos definir o cron através do campo schedule_expression para definir quando o lambda será executado. Neste caso, definimos que o Lambda será executado a cada 2 minutos - rate(2 minutes) , especificado no arquivo vars.tfvars. 7. aws_cloudwatch_event_target é o recurso responsável por acionar o Lambda usando eventos do CloudWatch. 8. aws_lambda_permission permite execuções do CloudWatch. Packaging Agora que você está familiarizado com o Lambda e o Terraform, vamos empacotar nosso projeto via Maven antes da criação do Lambda. A ideia é criar um arquivo jar que será usado para execuções do Lambda e armazenado no S3. Para este exemplo, vamos empacotar localmente. Vale lembrar que para um ambiente de produção, poderíamos utilizar ferramentas de integrações contínuas como Jenkins, Drone ou até Github actions para automatizar esse processo. Primeiro, abra o terminal e verifique se você está no diretório raiz do projeto e execute o seguinte comando maven: mvn clean install -U Este comando além de empacotar o projeto, irá baixar e instalar as dependências declaradas no arquivo pom.xml . Depois de executar o comando acima, um arquivo jar será gerado dentro da pasta target/ também criada. Executando Terraform Bem, estamos quase lá. Agora, vamos provisionar nosso Lambda via Terraform. Então, vamos executar alguns comandos do Terraform. Dentro da pasta terraform , execute os seguintes comandos no terminal: terraform init O comando acima iniciará o terraform, baixando as bibliotecas do terraform e também validará os arquivos do terraform. Para o próximo comando, vamos executar o comando plan para checar quais recursos serão criados. terraform plan -var-file=development/vars.tfvars Após a execução, você verá logs semelhantes no console: Por fim, podemos solicitar a criação definitiva dos recursos através do seguinte comando: terraform apply -var-file=development/vars.tfvars Após a execução, você deve confirmar para executar as ações, digite "sim". Agora a provisão foi concluída! Execução do Lambda Vá e acesse o console da AWS para ver a execução do Lambda que acabamos de criar. Acesse a aba monitor Acesse a aba Logs dentro da seção Monitor Veja as mensagens abaixo que serão impressas a cada 2 minutos. Destroy As cobranças de faturamento da AWS ocorrerão se você não destruir esses recursos. Portanto, recomendo destruí-los evitando algumas cobranças desnecessárias. Para evitar, execute o comando abaixo. terraform destroy -var-file=development/vars.tfvars
Lembre-se que você precisa confirmar essa operação, ok? Conclusão Neste tutorial, criamos um AWS Lambda provisionado através do Terraform. Lambda é um serviço da AWS que podemos usar para diferentes casos de uso trazendo facilidade para compor uma arquitetura de software.
Pudemos notar que o Terraform traz flexibilidade criando recursos para diferentes serviços em nuvem e fácil de implementar em projetos de softwares. Github repository Espero que tenha curtido!