Implantar funções do Lambda em Go com imagens de contêiner - AWS Lambda

Implantar funções do Lambda em Go com imagens de contêiner

Existem duas maneiras de criar uma imagem de contêiner para uma função do Lambda do Go:

  • Usar uma imagem base somente para sistema operacional da AWS

    O Go é implementado de forma diferente de outros runtimes gerenciados. Como o Go é compilado nativamente com um binário executável, ele não requer um runtime de linguagem dedicado. Use uma imagem de base somente do sistema operacional para criar imagens do Go para o Lambda. Para tornar a imagem compatível com o Lambda, você deve incluir o pacote aws-lambda-go/lambda na imagem.

  • Usar uma imagem base que não é da AWS

    Você também pode usar uma imagem base alternativa de outro registro de contêiner, como Alpine Linux ou Debian. Você também pode usar uma imagem personalizada criada por sua organização. Para tornar a imagem compatível com o Lambda, você deve incluir o pacote aws-lambda-go/lambda na imagem.

dica

Para reduzir o tempo necessário para que as funções do contêiner do Lambda se tornem ativas, consulte Use multi-stage builds na documentação do Docker. Para criar imagens de contêiner eficientes, siga as Melhores práticas para gravar Dockerfiles.

Esta página explica como criar, testar e implantar imagens de contêiner para o Lambda.

Imagens de base da AWS para implantar funções do Go

O Go é implementado de forma diferente de outros runtimes gerenciados. Como o Go é compilado nativamente com um binário executável, ele não requer um runtime de linguagem dedicado. Use uma imagem de base somente do sistema operacional para implantar funções do Go no Lambda.

Somente SO
Nome Identificador Sistema operacional Data da substituição Bloquear a criação de funções Bloquear a atualização de funções

Runtime somente para sistema operacional

provided.al2023

Amazon Linux 2023

Runtime somente para sistema operacional

provided.al2

Amazon Linux 2

Galeria pública do Amazon Elastic Container Registry: gallery.ecr.aws/lambda/provided

Clientes de interface de runtime do Go

O pacote aws-lambda-go/lambda inclui uma implementação da interface de runtime. Para obter exemplos de como usar aws-lambda-go/lambda na sua imagem, consulte Usar uma imagem base somente para sistema operacional da AWS ou Usar uma imagem base que não é da AWS.

Usar uma imagem base somente para sistema operacional da AWS

O Go é implementado de forma diferente de outros runtimes gerenciados. Como o Go é compilado nativamente com um binário executável, ele não requer um runtime de linguagem dedicado. Use uma imagem de base somente do sistema operacional para criar imagens de contêiner para as funções do Go.

Tags Runtime Sistema operacional Dockerfile Desaprovação

al2023

Runtime somente para sistema operacional Amazon Linux 2023 Dockerfile para runtime somente para sistema operacional no GitHub

al2

Runtime somente para sistema operacional Amazon Linux 2 Dockerfile para runtime somente para sistema operacional no GitHub

Para obter mais informações sobre esta imagem base, consulte fornecido na galeria pública do Amazon ECR.

Você deve incluir o pacote aws-lambda-go/lambda com seu manipulador de Go. Esse pacote implementa o modelo de programação para Go, incluindo a interface de runtime.

Para executar as etapas desta seção, você deve ter o seguinte:

Criar e implantar uma função do Go com a imagem base provided.al2023
  1. Crie um diretório para o projeto e depois mude para esse diretório.

    mkdir hello cd hello
  2. Inicialize um novo módulo do Go.

    go mod init example.com/hello-world
  3. Adicione a biblioteca lambda como uma dependência do seu novo módulo.

    go get github.com/aws/aws-lambda-go/lambda
  4. Crie um arquivo denominado main.go e abra-o em um editor de texto. Este é o código da função  do Lambda. É possível usar o código de exemplo a seguir para fins de teste ou substituí-lo pelo seu próprio código.

    package main import ( "context" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { response := events.APIGatewayProxyResponse{ StatusCode: 200, Body: "\"Hello from Lambda!\"", } return response, nil } func main() { lambda.Start(handler) }
  5. Use um editor de texto para criar um Dockerfile no diretório do projeto.

    • O exemplo de Dockerfile a seguir usa uma compilação em várias etapas. Isso permite que você use uma imagem base diferente em cada etapa. É possível usar uma imagem, como uma imagem base Go, para compilar seu código e construir o binário executável. Em seguida, é possível usar uma imagem diferente, como provided.al2023, na declaração FROM final, para definir a imagem implantada no Lambda. O processo de construção é separado da imagem final de implantação, portanto, a imagem final contém apenas os arquivos necessários para executar a aplicação.

    • Você pode usar a tag lambda.norpc opcional para excluir o componente Remote Procedure Call (RPC) da biblioteca do Lambda. O componente RPC só será necessário se você estiver usando o runtime do Go 1.x. descontinuado. A exclusão do RPC reduz o tamanho do pacote de implantação.

    • Observe que o Dockerfile de exemplo não inclui uma instrução USER. Quando você implanta uma imagem de contêiner no Lambda, o Lambda define automaticamente um usuário padrão do Linux com permissões de privilégio mínimo. Isso é diferente do comportamento padrão do Docker, que adota o usuário root como padrão quando nenhuma instrução USER é fornecida.

    exemplo — Dockerfile de construção em vários estágios
    nota

    Certifique-se de que a versão do Go que você especifica em seu Dockerfile (por exemplo, golang:1.20) seja a mesma versão do Go que você usou para criar sua aplicação.

    FROM golang:1.20 as build WORKDIR /helloworld # Copy dependencies list COPY go.mod go.sum ./ # Build with optional lambda.norpc tag COPY main.go . RUN go build -tags lambda.norpc -o main main.go # Copy artifacts to a clean image FROM public.ecr.aws/lambda/provided:al2023 COPY --from=build /helloworld/main ./main ENTRYPOINT [ "./main" ]
  6. Crie a imagem do Docker com o comando docker build. O exemplo a seguir nomeia a imagem como docker-image e atribui a ela a tag test.

    docker build --platform linux/amd64 -t docker-image:test .
    nota

    O comando especifica a opção --platform linux/amd64 para garantir que seu contêiner seja compatível com o ambiente de execução do Lambda, independentemente da arquitetura da sua máquina de compilação. Se você pretende criar uma função do Lambda usando a arquitetura do conjunto de instruções ARM64, certifique-se de alterar o comando para usar a opção --platform linux/arm64 em vez disso.

Use o emulador de interface de runtime para testar sua imagem localmente. A imagem base provided.al2023 inclui o emulador de interface de runtime.

Para executar o emulador de interface de runtime na sua máquina local
  1. Inicie a imagem do Docker com o comando docker run. Observe o seguinte:

    • docker-image é o nome da imagem e test é a tag.

    • ./main é o ENTRYPOINT do seu Dockerfile.

    docker run -d -p 9000:8080 \ --entrypoint /usr/local/bin/aws-lambda-rie \ docker-image:test ./main

    Esse comando executa a imagem como um contêiner e cria um endpoint local em localhost:9000/2015-03-31/functions/function/invocations.

  2. Em uma nova janela de terminal, publique um evento no seguinte endpoint usando um comando curl:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

    Esse comando invoca a função com um evento vazio e retorna uma resposta. Algumas funções podem exigir uma carga útil JSON. Exemplo:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
  3. Obtenha o ID do contêiner.

    docker ps
  4. Use o comando docker kill para parar o contêiner. Nesse comando, substitua 3766c4ab331c pelo ID do contêiner da etapa anterior.

    docker kill 3766c4ab331c
Para enviar a imagem ao Amazon ECR e criar a função do Lambda
  1. Execute o comando get-login-password para autenticar a CLI do Docker no seu registro do Amazon ECR.

    • Defina o valor --region para a Região da AWS onde você deseja criar o repositório do Amazon ECR.

    • Substituir 111122223333 por seu ID da Conta da AWS.

    aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
  2. Crie um repositório no Amazon ECR usando o comando create-repository.

    aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
    nota

    O repositório do Amazon ECR deve estar na mesma Região da AWS que a função do Lambda.

    Se tiver êxito, você verá uma resposta como esta:

    { "repository": { "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
  3. Copie o repositoryUri da saída na etapa anterior.

  4. Execute o comando docker tag para aplicar uma tag na sua imagem local em seu repositório do Amazon ECR como a versão mais recente. Neste comando:

    • docker-image:test é o nome e a tag da sua imagem do Docker. Esse é o nome e a tag da imagem que você especificou no comando docker build.

    • Substitua <ECRrepositoryUri> pelo repositoryUri que você copiou. Certifique-se de incluir :latest no final do URI.

    docker tag docker-image:test <ECRrepositoryUri>:latest

    Exemplo:

    docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  5. Execute o comando docker push para implantar a imagem local no repositório do Amazon ECR. Certifique-se de incluir :latest no final do URI do repositório.

    docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  6. Crie um perfil de execução para a função, caso ainda não tenha um. Você precisará do nome do recurso da Amazon (ARN) do perfil na próxima etapa.

  7. Criar a função do Lambda. Em ImageUri, especifique o URI do repositório anterior. Certifique-se de incluir :latest no final do URI.

    aws lambda create-function \ --function-name hello-world \ --package-type Image \ --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \ --role arn:aws:iam::111122223333:role/lambda-ex
    nota

    É possível criar uma função usando uma imagem em uma conta da AWS diferente desde que a imagem esteja na mesma região da função do Lambda. Para ter mais informações, consulte Permissões entre contas do Amazon ECR.

  8. Invoque a função.

    aws lambda invoke --function-name hello-world response.json

    Você obterá uma resposta parecida com esta:

    { "ExecutedVersion": "$LATEST", "StatusCode": 200 }
  9. Para ver a saída da função, verifique o arquivo response.json.

Para atualizar o código da função, você deve criar a imagem novamente, fazer upload da nova imagem no repositório do Amazon ECR e, em seguida, usar o comando update-function-code para implantar a imagem na função do Lambda.

O Lambda resolve a tag de imagem em um resumo de imagem específico. Isso significa que, se você apontar a tag de imagem que foi usada para implantar a função em uma nova imagem no Amazon ECR, o Lambda não atualizará automaticamente a função para usar a nova imagem.

Para implantar a nova imagem na mesma função do Lambda, você deverá usar o comando update-function-code, mesmo que a tag da imagem no Amazon ECR permaneça a mesma. No exemplo a seguir, a opção --publish cria uma nova versão da função usando a imagem de contêiner atualizada.

aws lambda update-function-code \ --function-name hello-world \ --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \ --publish

Usar uma imagem base que não é da AWS

Você pode criar uma imagem de contêiner para Go baseada em uma imagem base que não seja da AWS. O Dockerfile de exemplo das etapas a seguir usa uma imagem base do Alpine.

Você deve incluir o pacote aws-lambda-go/lambda com seu manipulador de Go. Esse pacote implementa o modelo de programação para Go, incluindo a interface de runtime.

Para executar as etapas desta seção, você deve ter o seguinte:

Para criar e implantar uma função do Go com uma imagem base do Alpine
  1. Crie um diretório para o projeto e depois mude para esse diretório.

    mkdir hello cd hello
  2. Inicialize um novo módulo do Go.

    go mod init example.com/hello-world
  3. Adicione a biblioteca lambda como uma dependência do seu novo módulo.

    go get github.com/aws/aws-lambda-go/lambda
  4. Crie um arquivo denominado main.go e abra-o em um editor de texto. Este é o código da função  do Lambda. É possível usar o código de exemplo a seguir para fins de teste ou substituí-lo pelo seu próprio código.

    package main import ( "context" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { response := events.APIGatewayProxyResponse{ StatusCode: 200, Body: "\"Hello from Lambda!\"", } return response, nil } func main() { lambda.Start(handler) }
  5. Use um editor de texto para criar um Dockerfile no diretório do projeto. O Dockerfile de exemplo a seguir usa uma imagem base do Alpine. Observe que o Dockerfile de exemplo não inclui uma instrução USER. Quando você implanta uma imagem de contêiner no Lambda, o Lambda define automaticamente um usuário padrão do Linux com permissões de privilégio mínimo. Isso é diferente do comportamento padrão do Docker, que adota o usuário root como padrão quando nenhuma instrução USER é fornecida.

    exemplo Dockerfile
    nota

    Certifique-se de que a versão do Go que você especifica em seu Dockerfile (por exemplo, golang:1.20) seja a mesma versão do Go que você usou para criar sua aplicação.

    FROM golang:1.20.2-alpine3.16 as build WORKDIR /helloworld # Copy dependencies list COPY go.mod go.sum ./ # Build COPY main.go . RUN go build -o main main.go # Copy artifacts to a clean image FROM alpine:3.16 COPY --from=build /helloworld/main /main ENTRYPOINT [ "/main" ]
  6. Crie a imagem do Docker com o comando docker build. O exemplo a seguir nomeia a imagem como docker-image e atribui a ela a tag test.

    docker build --platform linux/amd64 -t docker-image:test .
    nota

    O comando especifica a opção --platform linux/amd64 para garantir que seu contêiner seja compatível com o ambiente de execução do Lambda, independentemente da arquitetura da sua máquina de compilação. Se você pretende criar uma função do Lambda usando a arquitetura do conjunto de instruções ARM64, certifique-se de alterar o comando para usar a opção --platform linux/arm64 em vez disso.

Use o emulador de interface de runtime para testar a imagem localmente. Você pode compilar o emulador em sua imagem ou usar o procedimento a seguir instalá-lo na sua máquina local.

Para instalar o emulador de interface de runtime na sua máquina local
  1. No diretório do projeto, execute o comando a seguir para baixar o emulador de interface de runtime (arquitetura x86-64) do GitHub e instalá-lo na sua máquina local.

    Linux/macOS
    mkdir -p ~/.aws-lambda-rie && \ curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \ chmod +x ~/.aws-lambda-rie/aws-lambda-rie

    Para instalar o emulador arm64, substitua o URL do repositório do GitHub no comando anterior pelo seguinte:

    https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
    PowerShell
    $dirPath = "$HOME\.aws-lambda-rie" if (-not (Test-Path $dirPath)) { New-Item -Path $dirPath -ItemType Directory } $downloadLink = "https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie" $destinationPath = "$HOME\.aws-lambda-rie\aws-lambda-rie" Invoke-WebRequest -Uri $downloadLink -OutFile $destinationPath

    Para instalar o emulador de arm64, substitua $downloadLink pelo seguinte:

    https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
  2. Inicie a imagem do Docker com o comando docker run. Observe o seguinte:

    • docker-image é o nome da imagem e test é a tag.

    • /main é o ENTRYPOINT do seu Dockerfile.

    Linux/macOS
    docker run --platform linux/amd64 -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \ --entrypoint /aws-lambda/aws-lambda-rie \ docker-image:test \ /main
    PowerShell
    docker run --platform linux/amd64 -d -v "$HOME\.aws-lambda-rie:/aws-lambda" -p 9000:8080 ` --entrypoint /aws-lambda/aws-lambda-rie ` docker-image:test ` /main

    Esse comando executa a imagem como um contêiner e cria um endpoint local em localhost:9000/2015-03-31/functions/function/invocations.

    nota

    Se você criou a imagem do Docker para a arquitetura do conjunto de instruções ARM64, certifique-se de usar a opção --platform linux/arm64, em vez de --platform linux/amd64.

  3. Publique um evento no endpoint local.

    Linux/macOS

    No Linux e no MacOS, execute o seguinte comando curl:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

    Esse comando invoca a função com um evento vazio e retorna uma resposta. Caso esteja usando seu próprio código de função em vez do código de função de exemplo, você talvez queira invocar a função com uma carga útil JSON. Exemplo:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
    PowerShell

    No PowerShell, execute o seguinte comando Invoke-WebRequest:

    Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"

    Esse comando invoca a função com um evento vazio e retorna uma resposta. Caso esteja usando seu próprio código de função em vez do código de função de exemplo, você talvez queira invocar a função com uma carga útil JSON. Exemplo:

    Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
  4. Obtenha o ID do contêiner.

    docker ps
  5. Use o comando docker kill para parar o contêiner. Nesse comando, substitua 3766c4ab331c pelo ID do contêiner da etapa anterior.

    docker kill 3766c4ab331c
Para enviar a imagem ao Amazon ECR e criar a função do Lambda
  1. Execute o comando get-login-password para autenticar a CLI do Docker no seu registro do Amazon ECR.

    • Defina o valor --region para a Região da AWS onde você deseja criar o repositório do Amazon ECR.

    • Substituir 111122223333 por seu ID da Conta da AWS.

    aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
  2. Crie um repositório no Amazon ECR usando o comando create-repository.

    aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
    nota

    O repositório do Amazon ECR deve estar na mesma Região da AWS que a função do Lambda.

    Se tiver êxito, você verá uma resposta como esta:

    { "repository": { "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
  3. Copie o repositoryUri da saída na etapa anterior.

  4. Execute o comando docker tag para aplicar uma tag na sua imagem local em seu repositório do Amazon ECR como a versão mais recente. Neste comando:

    • docker-image:test é o nome e a tag da sua imagem do Docker. Esse é o nome e a tag da imagem que você especificou no comando docker build.

    • Substitua <ECRrepositoryUri> pelo repositoryUri que você copiou. Certifique-se de incluir :latest no final do URI.

    docker tag docker-image:test <ECRrepositoryUri>:latest

    Exemplo:

    docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  5. Execute o comando docker push para implantar a imagem local no repositório do Amazon ECR. Certifique-se de incluir :latest no final do URI do repositório.

    docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  6. Crie um perfil de execução para a função, caso ainda não tenha um. Você precisará do nome do recurso da Amazon (ARN) do perfil na próxima etapa.

  7. Criar a função do Lambda. Em ImageUri, especifique o URI do repositório anterior. Certifique-se de incluir :latest no final do URI.

    aws lambda create-function \ --function-name hello-world \ --package-type Image \ --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \ --role arn:aws:iam::111122223333:role/lambda-ex
    nota

    É possível criar uma função usando uma imagem em uma conta da AWS diferente desde que a imagem esteja na mesma região da função do Lambda. Para ter mais informações, consulte Permissões entre contas do Amazon ECR.

  8. Invoque a função.

    aws lambda invoke --function-name hello-world response.json

    Você obterá uma resposta parecida com esta:

    { "ExecutedVersion": "$LATEST", "StatusCode": 200 }
  9. Para ver a saída da função, verifique o arquivo response.json.

Para atualizar o código da função, você deve criar a imagem novamente, fazer upload da nova imagem no repositório do Amazon ECR e, em seguida, usar o comando update-function-code para implantar a imagem na função do Lambda.

O Lambda resolve a tag de imagem em um resumo de imagem específico. Isso significa que, se você apontar a tag de imagem que foi usada para implantar a função em uma nova imagem no Amazon ECR, o Lambda não atualizará automaticamente a função para usar a nova imagem.

Para implantar a nova imagem na mesma função do Lambda, você deverá usar o comando update-function-code, mesmo que a tag da imagem no Amazon ECR permaneça a mesma. No exemplo a seguir, a opção --publish cria uma nova versão da função usando a imagem de contêiner atualizada.

aws lambda update-function-code \ --function-name hello-world \ --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \ --publish