DEV Community

Cover image for Serverless Framework: Anatomia do arquivo YAML
Eduardo Rabelo
Eduardo Rabelo

Posted on

Serverless Framework: Anatomia do arquivo YAML

Nos últimos anos, a criação de uma infraestrutura serverless tornou-se mais acessível do que nunca. Com as plataformas AWS, Azure e Google Cloud, os desenvolvedores e engenheiros têm recursos quase ilimitados ao implantar sites e aplicativos. O Serverless Framework, uma estrutura popular para criar arquitetura serverless, tornou ainda mais fácil a utilização das maiores plataformas de computação em nuvem disponíveis. Eles fizeram isso abstraindo a configuração da arquitetura de nuvem para uma forma mais direta usando um arquivo YAML. Neste artigo, veremos o arquivo serverless.yml em mais detalhes para ver como ele é usado para configurar uma arquitetura serverless.

O arquivo "serverless.yml"

O serverless.yml é o coração de um aplicativo serverless. Este arquivo descreve toda a infraestrutura de aplicativos, desde a linguagem de programação até o acesso a recursos.

A seção principal deste arquivo YAML é o provider. Na configuração do serverless.yml, você tem a opção de usar o AWS, o Google Cloud ou o Microsoft Azure como seu provedor serverless. Você também pode especificar a linguagem de programação que deseja usar. No exemplo abaixo, eu especifico que vou usar o AWS com o Python 3.7.

Exemplo de um serverless.yml:

service: my-first-serverless-app
provider:
  name: aws
  runtime: python3.7

O arquivo serverless.yml acima é a base do que poderia ser um poder ilimitado de computação, centenas de funções serverless e uma infraestrutura de banco de dados que potencializa seu site ou aplicativo. Vamos nos aprofundar nessa configuração. Eu vou estar usando o AWS e python para o meu exemplo de base.

Variáveis de Ambiente

Configurar variáveis ​​de ambiente para usar em seu aplicativo é realmente fácil com o arquivo serverless.yml. Dentro da chave provider, você adiciona uma seção de ambiente e uma lista de valores de chave/valor. Usando o nosso exemplo acima um passo adiante, vamos adicionar uma variável de ambiente que especifica um nome de tabela para uma tabela de usuários.

provider:
  name: aws
  runtime: python3.7
  environment:
    USER_TABLE: users_table

Agora, em qualquer função serverless que utilizamos, a variávei ​​de ambiente USER_TABLE estará disponível para uso. Também podemos usar essa variável em outras partes do nosso arquivo serverless.yml para nomear recursos ou prefixar caminhos HTTP.

Para usar essa variável de ambiente no serverless.yml mais tarde, use a seguinte sintaxe. Observe que é semelhante a percorrer um objeto em outras linguagens de programação.

${self:provider.environment.USER_TABLE}

Dividindo em múltiplos arquivos

Muitas vezes você precisa separar a configuração de seu aplicativo em múltiplos arquivos. O Serverless Framework possui uma sintaxe muito legal para incluir variáveis ​​de outros arquivos. Digamos, por exemplo, que você queira que a tabela do usuário seja denominada dev_users_table para um ambiente de desenvolvimento. Há muitas maneiras para isso, mas para ilustrar o fornecimento de outros arquivos, mostrarei uma maneira.

Você pode ter vários arquivos de configuração que são usados ​​para ambientes específicos. Digamos que você tenha dois arquivos de configuração YAML na pasta raiz do seu projeto:

Exemplo dev.config.yml:

table_name: 'dev_users_table'

Exemplo prod.config.yml:

table_name: 'prod_users_table'

Seu aplicativo de produção usaria prod.config.yml. Para obter esse arquivo em produção, você pode usar a seguinte sintaxe:

provider:
  name: aws
  runtime: python3.7
  environment:
    USER_TABLE: ${file(./prod.config.yml):table_name}

Mas espere, como você implementa este aplicativo em dev? Você tem que mudar o arquivo para especificar dev certo? Não, podemos atualizar essa configuração para utilizar a variável stage. A variável stage é uma variável especial na estrutura do arquivo yaml que pode ser usada para especificar qual ambiente você está usando. Por padrão, a variável stage é dev.

Variáveis stage

Vamos consertar nosso serverless.yml para que possamos usar a configuração dev sem modificar o arquivo manualmente. Para fazer isso, usamos ${opt: stage, self: provider.stage}.

Exemplo do serverless.yml com variável stage:

provider:
  name: aws
  runtime: python3.7
  environment:
    USER_TABLE: ${opt:stage, self:provider.stage}_users_table

Agora que estamos usando a variável stage. Nós não precisamos do arquivo prod.config.yml. Podemos facilmente prefixar todos os nossos serviços com a variável stage para que, quando implantarmos nosso aplicativo para testar um novo serviço ou recurso, não afetemos os serviços de produção.

Se nós quiséssemos usar arquivos de configuração separados, poderíamos usar nossa variável stage para separar a configuração em arquivos separados como este:

provider:
  name: aws
  runtime: python3.7
  environment:
    USER_TABLE: ${file(./${opt:stage, self:provider.stage}.config.yml):table_name}

Separar suas variáveis ​​de ambiente em arquivos é uma ótima maneira de organizar aplicativos maiores que usam muitos recursos, como buckets do S3, tabelas de banco de dados, caminhos de versão da API etc.

Declarações de IAM Roles

Se você usou os serviços da AWS, provavelmente precisou criar um usuário do IAM ou Role. Com o serverless, você pode conceder permissões às suas aplicações para utilizar recursos através do arquivo serverless.yml. A configuração de permissão é basicamente o AWS Cloudformation escrito em YAML. As permissões vão sob a seção iamRoleStatements sob dentro de provider.

Dando acesso ao S3

Se você tiver um bucket S3 chamado awesome-bucket-name. O exemplo a seguir dará ao seu aplicativo acesso completo (Read, Write, List, etc) ao bloco especificado.

provider:
  name: aws
  runtime: python3.7
  environment:
    USER_TABLE: users_table 
 iamRoleStatements:
    -  Effect: "Allow"
       Action:
         - "s3:*"
       Resource:
          - arn:aws:s3:::awesome-bucket-name

Dando acesso ao SES

Se você tem um aplicativo que precisa enviar e-mails. Você pode dar acesso ao Amazon SES da seguinte forma: (Observação: você precisa configurar o SES com um domínio verificado separadamente.) O exemplo a seguir dá ao seu aplicativo acesso para usar todos os recursos do SES para enviar emails.

provider:
  name: aws
  runtime: python3.7
  environment:
    USER_TABLE: users_table 
 iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "ses:SendEmail"
      Resource: "*"

Funções

Eu tenho escrito sobre esse misterioso "aplicativo", mas não expliquei o que ele é. Em seu arquivo serverless.yml, você configura as funções a serem criadas na plataforma serverless do provider. Para AWS, é possível dizer ao serverless para criar funções do Lambda que possam ser anexadas a um endpoint HTTP. Vamos dar uma olhada rápida em como definir um endpoint HTTP através do arquivo serverless.yml .

Sem funções, você não possui um aplicativo. Lembre-se da linguagem de programação que especificamos no provider? Isso diz ao nosso provider com qual linguagem de programação iremos criar nossas funções. (Nota: as linguagens de programação são determinadas pelo provider. Você não pode escolher qualquer idioma.)

Como exemplo, vamos criar um endpoint HTTP que retorne o hash md5 de um endereço de email, juntamente com a URL do Gravatar para esse email.

Para definir uma função, precisamos de duas coisas:

  1. Um arquivo com a função chamada getHash, chamaremos o arquivo de handler.py
  2. Uma definição de função em serverless.yml

Exemplo da definição no serverless.yml:

functions:
  myCustomFunctionName:
    handler: handler.getHash

Na primeira linha, temos functions. Esta é uma seção do arquivo YAML que vive na seção do provider. Na seção de funções, temos myCustomFunctionName. Esse nome será o nome da função Lambda no AWS Lambda, não o usado no código.

Em seguida, definimos o handler . O handler é o caminho para a função usando a notação de ponto. Essa notação de ponto é semelhante a como as importações funcionam no Python. handler é o nome do arquivo e getHash é o nome da função nesse arquivo.

Aqui está o nosso handler.py:

import hashlib
import json
CORS = {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Credentials': True,
}
def getHash(event, context):
    string = event['pathParameters']['string']
    h = hashlib.md5(string.encode('utf8'))
    h = h.hexdigest()
    return {
        "statusCode": 200,
        "headers": CORS,
        "body": json.dumps({
            "hash": h,
            "avatar": "http://gravatar.com/avatar/{}".format(h)
        })
    }

Com o arquivo definido e a função chamada getHash dentro, nosso serverless.yml está pronto para criar nossa função no AWS Lambda. Antes de implantar isso, precisamos ativar o acesso a essa função via HTTP. Para tornar isso um endpoint HTTP, vamos adicionar uma seção de eventos.

Exemplo de funções com eventos:

functions:
  myCustomFunctionName:
    handler: handler.getHash
    events:
      - http:
          path: md5/{email}
          method: get
          cors: true

A seção events vincula nossa função ao API Gateway fornecido pela AWS. Nesta seção, especificamos o caminho e o método do endpoint HTTP. Com esta configuração de evento, você poderá acessar sua função do Lambda através do caminho /md5/some@email.com. A resposta seria um objeto JSON com o hash md5 e um URL para a imagem gravatar.

Exemplo de saída com meu email:

{
  "hash": "97fbef641c6e4669b6a1ad4ffb3342f5",
  "avatar": "http://gravatar.com/avatar/97fbef641c6e4669b6a1ad4ffb3342f5"
}

Você pode ir ainda mais longe com isso, exigindo autenticação e limitação de taxa nesse endpoint. Mais na documentação.

Agora que temos nossos eventos, podemos enviar pedidos para essa função a partir de um aplicativo frontend e ela executará nossa função serverless.

Conclusão

Esta postagem arranha a superfície do arquivo serverless.yml. Espero que você entenda um pouco mais sobre serverless e mergulhe mais fundo nessa estrutura e tecnologia. O Serverless Framework, junto com as plataformas de nuvem disponíveis, permite que as pessoas criem produtos escaláveis ​​a um baixo custo. Construir a infraestrutura para um aplicativo é muito mais fácil do que nunca e pode ser criado usando um arquivo de configuração simples como serverless.yml.

Obrigado pela leitura!

Créditos

Top comments (0)