# Serverless Framework com Lambda: deploy e stop de EC2 na prática

> Crie um projeto com o Serverless Framework, faça deploy de uma Lambda e use o SDK para listar e parar uma EC2. Aulas de 2019 e 2020; confira a doc atual.

- Autor: Henrylle Maia, consultor AWS
- Publicado em: 2026-10-15
- Assuntos: Serverless
- URL: https://pages.formacaoaws.com.br/blog/serverless-framework-com-lambda/
- Aula de origem: "Aula 01 - Como usar o Serverless Framework com o Lambda na prática" (https://www.youtube.com/watch?v=QURog3YhikA)

Publicar uma Lambda à mão significa empacotar o código, gerar o zip, subir para o S3 e montar as permissões. Com o Serverless Framework, um comando faz o empacotamento, o upload e a infraestrutura. Abaixo, o ciclo inteiro: criar o projeto, testar local, fazer o deploy e usar o SDK da AWS para listar e parar uma instância EC2.

> **Importante:** as aulas que originam este texto foram gravadas em dezembro de 2019 e janeiro de 2020. Comandos, perguntas do assistente de criação, versões de Node.js e o estilo do código (callbacks) podem ter mudado. Antes de repetir qualquer passo, confira a [documentação atual do Serverless Framework](https://www.serverless.com/framework/docs).

## O que é o Serverless Framework e por que usar

É uma ferramenta de linha de comando multiplataforma: serve para AWS, para Azure e para o Google Cloud. A vantagem que ele destaca é que o código que você escreve ali pode ser levado para outra nuvem.

No nosso caso, ele cuida do deploy e da execução da função, local ou remota, e também de levantar na AWS tudo o que a função precisa para rodar.

Um cuidado antes de começar: entenda o que acontece por baixo. Quem só aperta o botão não sabe o que fazer quando algo quebra em produção. Por isso, ao longo do texto eu mostro o que cada comando cria na AWS.

## Passo 1: criar o projeto

Com o framework já instalado, confirme a versão com `sls --version` (na gravação, a 1.60.0). Para criar o projeto, basta rodar `serverless` numa pasta vazia, sem argumento:

```bash
serverless
```

O assistente pergunta se você quer criar um projeto novo (respondi Yes) e qual template usar: escolhi **AWS Node.js**, e **AWS Python** aparece ao lado. Depois pede o nome. Chamei de `automacao-lambda`; com sublinhado no nome ele recusou, por isso o hífen. Por último pergunta se você quer ativar o monitoramento do próprio framework. Respondi que não, e dá para mudar isso depois.

![O terminal do VS Code após rodar serverless: criar projeto novo, template AWS Node.js, nome automacao-lambda e a pergunta de monitoramento respondida com No](https://pages.formacaoaws.com.br/blog/assets/posts/serverless-framework-com-lambda/criar-projeto-serverless.webp)

O resultado é uma estrutura simples, com `handler.js`, `serverless.yml` e uma função de exemplo chamada `hello` já pronta. O `serverless.yml` descreve o serviço. Nele ficam as funções e, mais adiante, as permissões de cada uma.

## Passo 2: configurar as credenciais da AWS

O framework precisa de uma conta AWS para publicar. Na aula, criei um usuário no IAM com acesso programático e, para simplificar, dei a ele a permissão de administrador. Em uso real, procure a permissão mais adequada ao seu cenário.

Depois, rodei o comando de configuração de credenciais do framework, informando AWS como provedor, a chave de acesso e a chave secreta:

```bash
serverless config credentials --provider aws --key <chave-de-acesso> --secret <chave-secreta>
```

Como a minha máquina já tinha um perfil `default` em `~/.aws/credentials`, ele recusou e pediu a flag `--overwrite`. Acrescentei e a configuração passou.

> **Importante:** eu mostrei as credenciais na tela de propósito e as invalidei ao fim da gravação. Faça o mesmo se mostrar chaves em tela: não deixe chave de administrador ativa depois do teste.

## Passo 3: testar a função localmente

Dentro da pasta do projeto, chame a função com `--local`, passando o nome dela em `--function`:

```bash
sls invoke --local --function hello
```

Ele simula a execução na sua máquina e devolve o retorno. Dois tropeços meus na gravação: rodei fora da pasta do projeto e o framework avisou que o comando só roda dentro de um diretório de serviço; depois esqueci o `--function`, e ele disse que o comando exige a função.

O mesmo comando sem o `--local` chama a função na nuvem. Antes do deploy, ele reclama que a função não foi encontrada, porque ainda não há nada publicado.

## Passo 4: fazer o deploy

```bash
sls deploy
```

Esse comando empacota a função e remove pacotes que não são necessários. Cria uma stack no CloudFormation e envia o zip da função para o S3. É a parte que antes era manual: empacotar, gerar o zip, subir para o S3.

**Fluxo:** Projeto (sls cria o template) → Invoke local (testa na sua máquina) → Deploy (CloudFormation e S3) → Lambda na AWS (invoke remoto) → SDK (lista e para a EC2)

O que ele criou vem do `serverless.yml`. A função `hello` aponta para o handler `handler.hello`:

![O serverless.yml do projeto: na seção functions, a função hello com handler handler.hello](https://pages.formacaoaws.com.br/blog/assets/posts/serverless-framework-com-lambda/serverless-yml-handler.webp)

Confira no console. A função `automacao-lambda-dev-hello` aparece no Lambda (runtime Node.js 12.x, handler `handler.hello`) com o código gerado, e a chamada remota (`sls invoke --function hello`) devolve o mesmo retorno da local. O que muda é o ambiente: a execução deixa registro no monitoramento (CloudWatch), que pode demorar um pouco para atualizar.

O `serverless.yml` também controla as permissões específicas de cada função, e layers permitem compartilhar bibliotecas entre funções. Eu cito os dois como o caminho para o projeto crescer de forma mais saudável, mas não os detalho nestas aulas.

## Passo 5: listar as instâncias EC2 com o SDK

Na [aula 2](https://www.youtube.com/watch?v=d0dLZI1MUlQ), gravada em janeiro de 2020, o objetivo é listar as instâncias EC2 da conta e criar uma função que para uma instância. Não é preciso nenhuma máquina para isso: quem executa é a Lambda.

Primeiro, limpei o que a aula 1 criou, com `sls remove`. Isso apaga a stack inteira da AWS. Depois renomeei a função para `stop_ec2`, no `serverless.yml` (`stop_ec2:` com `handler: handler.stop_ec2`) e no `handler.js`.

No código, a sequência é esta:

1. Importe o AWS SDK.
2. Configure a região. Na aula usei a Virgínia (`us-east-1`).
3. Crie o cliente do EC2.
4. Chame `describeInstances`, tratando o erro no callback.

```js
'use strict';
var AWS = require('aws-sdk');
AWS.config.update({ region: 'us-east-1' });
var ec2 = new AWS.EC2({ apiVersion: '2016-11-15' });

module.exports.stop_ec2 = (event, context, callback) => {
  var params = { DryRun: false };
  ec2.describeInstances(params, function (err, data) {
    if (err) {
      console.log("Erro", err.stack);
      callback(err, "Erro ao executar operação de describe");
    } else {
      console.log("Sucesso", JSON.stringify(data));
      callback(null, "Sucesso");
    }
  });
};
```

O `DryRun: false` fica de propósito: é um teste de permissão do SDK, e aqui eu quero a execução de verdade. O cliente `ec2` fica fora do handler de propósito, porque a função de parada vai reaproveitá-lo.

Fiz um novo deploy e invoquei a função. Veio um erro de autorização, "você não está autorizado a executar esta operação". A função não tinha permissão para falar com o EC2.

## Passo 6: dar permissão à função

A role que o framework criou para a Lambda não dava acesso ao EC2. No console do IAM, localizei essa role e anexei a policy gerenciada `AmazonEC2FullAccess`. Depois repeti o deploy e a chamada remota retornou sucesso.

> **Importante:** `AmazonEC2FullAccess` deixou a aula objetiva, mas dá à função muito mais do que ela usa. O recomendado é a permissão mínima: só `ec2:DescribeInstances` (que exige `*`) e `ec2:StopInstances`, restrita às instâncias que a função pode parar. No Serverless Framework isso pode ir no próprio `serverless.yml`, na role da função, em vez de anexar policy pelo console. Veja [Apply least-privilege permissions](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege) na documentação do IAM.

Nos logs da função (CloudWatch), o retorno traz `Reservations` e, dentro delas, `Instances`. Dali dá para pegar o ID da instância e usá-lo no comando seguinte. Como os dois são arrays, peguei a primeira posição de cada um:

```js
let instanceID = data.Reservations[0].Instances[0].InstanceId;
```

## Passo 7: parar a instância

Com o ID em mãos, escrevi uma função que chama `stopInstances`, do SDK de EC2, passando o ID num array em `InstanceIds`. O callback trata o erro e imprime o sucesso:

![O código no editor: params com InstanceIds recebendo o instanceID e DryRun false, a chamada ec2.stopInstances e o callback que imprime data.StoppingInstances](https://pages.formacaoaws.com.br/blog/assets/posts/serverless-framework-com-lambda/codigo-stop-instances.webp)

Errei parênteses e a chamada à função, ajustei, fiz outro deploy e mais uma chamada. No log, o campo do retorno vinha `undefined`: o nome certo é `StoppingInstances`, com S maiúsculo.

O deploy de atualização leva menos de um minuto. O log mostra a transição de estado: `CurrentState` "stopping" e `PreviousState` "running". No console do EC2, a instância aparece parando.

Também liguei a instância de novo e chamei a função com `sls invoke --local --function stop_ec2`: o comportamento foi o mesmo, sem novo deploy. Isso é útil para testar a lógica sem publicar a cada mudança.

## O que fazer em seguida

Fecho a aula com ideias para quem quiser seguir: agendar a parada da instância para um horário e fazer outros serviços da AWS chamarem a Lambda. Para um caminho com script, veja [Ligar e desligar EC2 automaticamente com o AWS CLI](https://pages.formacaoaws.com.br/blog/ligar-e-desligar-ec2-automaticamente/).

## Checklist

- Confira a documentação atual do Serverless Framework antes de repetir os comandos de 2019 e 2020.
- Crie um usuário no IAM só para o framework e invalide as chaves depois do teste.
- Teste com `sls invoke --local --function <nome>` antes de publicar.
- Publique com `sls deploy` e confira a função no console.
- Se a função receber erro de autorização, anexe a policy necessária à role que o framework criou para ela.
- Rode `sls remove` para apagar a stack quando terminar de testar.

Com esse ciclo você publica, testa, ajusta e remove uma função com poucos comandos, sem perder de vista o que a AWS cria por baixo. Se quiser aprender AWS com prática guiada, a conversa abaixo é o próximo passo.
