Migração de serverless framework v1 para v2
Tags: aws, devops, serverless, javascript
Published: 2021-11-08 18:41:43

Recentemente em alguns projetos que participei tive alguns desafios com relação a mudança do serverless framework de v1 para v2. No projeto utilizei NodeJS com Typescript, toda infra na AWS.

Estava utilizando a versão 1.83.2 juntamente com a imagem do docker softinstigate/serverless:1.83.0

**Link da imagem:** [Docker Hub](https://hub.docker.com/layers/softinstigate/serverless/1.83.0/images/sha256-b5a30b60ade46b74b42114001256ffb502fc4cd501ffc5e5193001c6e0b1f991?context=explore)

**Queríamos utilizar a imagem:** [Docker Hub](https://hub.docker.com/layers/softinstigate/serverless/2.43.1/images/sha256-6db65e1456ad7ad49944e45e7635cd13a728d3d3038df902d4ca343046dfe81e?context=explore)

Que no momento era a mais atual. Porém tivemos alguns desafios e é sobre isto que falarei hoje

## Porque?

Primeiramente, porque quisemos mudar? Simplesmente porque queríamos mexer com tecnologias mais modernas, usar features novas e nos atualizarmos afim de não termos um projeto depreciado ao longo do tempo.

Queriamos estar disponíveis para testar novas features da versão v2, aumentar a versão do node, que estava a 10 e iria começar a parar de ter suporte, etc.

## Como?

Para mudar tudo precisávamos atualizar nosso **pipeline** de **CI/CD** que optamos pelo **bitbucket pipeline**, assim como as dependências de cada microserviço, juntamente com as **imagens** do **docker** utilizadas para rodar o pipeline.

Além de mudar a versão do serverless framework queríamos atualizar nossos plugins, afim de usar a **última versão LTS** de todas as dependências.

Então primeiramente atualizamos todos os pacotes relacionados ao serverless no **package.json**. Sejam estes os pacotes do **serverless** normal, **plugins** ou libs adicionais para rodar o **serverless-offline**

**Atualizamos** tudo, **instalamos** novamente as deps e **mudamos** os **scripts** do **package.json** para ficarem compatíveis com a nova versão (precisamos adicionar coisas de package para funcionar com o artifacts do serverless v2)

Nosso scripts de rodar local tinha algumas configs a mais para outros fins, mas poderia ser algo parecido com isto:

```jsx
"scripts": {
	"debug:dev": "tsc && ./node_modules/serverless/bin/serverless.js dynamodb install && ./node_modules/serverless/bin/serverless.js offline start --noAuth --noTimeout --noPrependStageInUrl"
}
```

Neste caso utilizamos a **dependência** do **dynamodb** e o **serverless-offline**. Colocamos as flags:

 --noAuth = Para não chamar o authorizer da lambda quando roda local

--noTimeout  = Sem timeout fixo

--noPrependStageInUrl = Para não ter prefixo do stage nas urls, por exemplo: **/dev/<endpoint-http>**

Aleḿ disto a versão do node no serverless para a mais recente suportada pelo framework. E também a versão da imagem no pipeline, que optamos pelo que integra com o bitbucket.

Além disto, pesquisamos e vimos que seria bom adicionar isto no **serverless.yml** acima da declaração do **plugins**

```jsx
frameworkVersion: ^2.64.1
useDotenv: true
variablesResolutionMode: 20210326
```

Também vimos que graças a esta atualização poderíamos remover os ~true ou ~split das enviroments chamadas lá no s3. Dado que agora ele resolve sozinho

**DISCLAIMER:**

Com a atualização do serverless de v1 para v2, algumas variáveis de ambiente como a LAMBDA_TASK_ROOT, tem alguns comportamentos um pouco diferentes, alguns erros que venham a acontecer podem ser graças a isto.

Depois disto tudo, rodamos nosso projeto e finalmente conseguimos ver ele funcionando no **postman**, isto foi muito legal, sentimos que deu tudo certo, então subimos o PR e na hora de fazer o **deploy** em **HLG** ele rolou com sucesso. Porém fomos revisar tudo e vimos que o nosso **swagger** tinha parado de funcionar.

## A documentação no swagger foi um desafio

Para o **swagger** utilizávamos a biblioteca: [serverless-aws-documentation](https://www.npmjs.com/package/serverless-aws-documentation)

Quando fizemos o deploy pela primeira vez, nada se alterou no **swagger**, então apagamos o mesmo do nosso **s3**, e rodamos o pipeline novamente, mas não funcionou.

Então depois de muita pesquisa, descobrimos um fork desta mesma lib que é compatível com o **serverless v2** : 
 [@kakkuk/serverless-aws-apigateway-documentation](https://www.npmjs.com/package/@kakkuk/serverless-aws-apigateway-documentation)

A ideia é que conseguissemos mudar a versão mexendo o mínimo possível no código, visto que temos muitos projetos é difícil migrar em todo e ficar fazendo várias coisas pra funcionar. Esta lib é 100% compatível com a que utilizávamos, assim a única coisa que tivemos que fazer pra resolver este desafio foi:

Mudar a dependência no package.json e mudar o plugin do serverless.yml do antigo para este, conforme está na descrição da dependência

Mudando isto e um pouco na parte do deploy do swagger no nosso s3 (deu problema com o staging, mas mudando um pouco resolvemos) conseguimos resolver o problema e deployar o projeto com sucesso

## Mais um problema

No primeiro projeto que fizemos estávamos mexendo com **Jenkins**, e deu certo de primeira. Fomos replicar para os que mexiam com o **bitbucket pipeline** e ele começou a dar alguns erros que não estava achando as **credenciais** da **AWS** para resolver as **variáveis** do **parameter store** declaradas no **serverless.yml**

Investigamos e vimos que tinhamos adicionado um job a mais fora do step de deploy e isto fazia com que o bitbucket não conseguisse resolver a variável de ambiente, dado que ele só exporta as variáveis aonde tem o deployment igual ao setado nas variáveis de ambiente do repositório

Para ficar mais claro, o bitbucket pipeline tinha um step de deploy assim:

```jsx
- step: &DeployHomolog
    deployment: staging
    image: softinstigate/serverless:2.43.1
    name: 'Deploy to Homolog'
    script:
      - 'DEBIAN_FRONTEND=noninteractive apt-get install -y jq'
      - 'npm run deploy:hlg'
      - 'npm run publish:reports'
```

E queríamos adicionar um script que usava as credencias setadas na variáveis de ambiente do projeto no ambiente de staging, porém adicionamos em outro step, porém ele não reconhecia as credenciais porque o step que tem o ambiente de staging é este, podemos ver isto pela tag deployment. Ai bastou adicionar o script neste step que funcionou

## Dúvidas

De primeira pode não ser algo tão simples de resolver esta migração, mas com pesquisa e estudo vai ficando mais fácil, se alguma coisa não ficou clara e quiserem que eu esclareça podem me chamar no Linkedin e esclarecer:

[Thiago Crespo Felippi - FullstackDeveloper - NTConsult | LinkedIn](https://www.linkedin.com/in/thiago-crespo-felippi/)