Implantar código TypeScript transcompilado no Lambda com imagens de contêiner
Você pode implantar seu código TypeScript em uma função do AWS Lambda como imagem de contêiner Node.js. A AWS fornece imagens base para Node.js para ajudar você a criar a imagem do contêiner. Essas imagens base são pré-carregadas com um runtime de linguagem e outros componentes necessários para executar a imagem no Lambda. A AWS fornece um Dockerfile para cada uma das imagens base para ajudar a criar sua imagem de contêiner.
Se você usa uma imagem base pertencente a uma comunidade ou empresa privada, é necessário adicionar um cliente de interface de runtime (RIC) Node.js à imagem base para torná-la compatível com o Lambda.
O Lambda oferece um emulador de interface de runtime para testes locais. As imagens base da AWS para o Node.js incluem o emulador de interface de runtime. Caso use uma imagem base alternativa, como uma imagem Alpine Linux ou Debian, você poderá criar o emulador na sua imagem
Usar uma imagem base Node.js para criar e empacotar código da função TypeScript
Para executar as etapas desta seção, você deve ter o seguinte:
-
Node.js 20.x
Para criar uma imagem a partir de uma imagem base da AWS para o Lambda
-
Em sua máquina local, crie um diretório de projeto para sua nova função.
-
Crie um novo projeto Node.js com
npm
ou um gerenciador de pacotes de sua escolha.npm init
-
Adicione pacotes @types/aws-lambda
e esbuild como dependência de desenvolvimento. O pacote @types/aws-lambda
contém as definições de tipo para o Lambda.npm install -D @types/aws-lambda esbuild
-
Adicione um script de construção
ao arquivo package.json
."scripts": { "build": "esbuild index.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outfile=dist/index.js" }
-
Crie um novo arquivo chamado
index.ts
. Adicione o código de exemplo a seguir ao novo arquivo. Este é o código da função do Lambda. A função retorna uma mensagemhello world
.nota
A instrução
import
importa as definições de tipo de @types/aws-lambda. Ela não importa o pacote aws-lambda
do NPM, que é uma ferramenta de terceiros não relacionada. Para obter mais informações, consulte aws-lambdano repositório DefinitelyTyped do GitHub. import { Context, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda'; export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => { console.log(`Event: ${JSON.stringify(event, null, 2)}`); console.log(`Context: ${JSON.stringify(context, null, 2)}`); return { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }; };
-
Crie um novo Dockerfile com a seguinte configuração:
-
Defina a propriedade
FROM
como o URI da imagem base. -
Defina o argumento
CMD
para especificar o manipulador de funções do Lambda.
O exemplo de Dockerfile a seguir usa uma compilação em várias etapas. A primeira etapa transcompila o código TypeScript em JavaScript. A segunda etapa produz uma imagem de contêiner contendo somente arquivos JavaScript e dependências de produçã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çãoUSER
é fornecida.exemplo Dockerfile
FROM public.ecr.aws/lambda/nodejs:20 as builder WORKDIR /usr/app COPY package.json index.ts ./ RUN npm install RUN npm run build FROM public.ecr.aws/lambda/nodejs:20 WORKDIR ${LAMBDA_TASK_ROOT} COPY --from=builder /usr/app/dist/* ./ CMD ["index.handler"]
-
-
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 tagtest
.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.
-
Inicie a imagem do Docker com o comando docker run. Neste exemplo,
docker-image
é o nome da imagem etest
é a tag.docker run --platform linux/amd64 -p 9000:8080
docker-image
:test
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/
, em vez dearm64
--platform linux/
.amd64
-
Em uma nova janela de terminal, publique um evento no endpoint local.
-
Obtenha o ID do contêiner.
docker ps
-
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
-
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-stdin111122223333
.dkr.ecr.us-east-1
.amazonaws.com -
-
Crie um repositório no Amazon ECR usando o comando create-repository
. aws ecr create-repository --repository-name
hello-world
--regionus-east-1
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLEnota
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" } } }
-
Copie o
repositoryUri
da saída na etapa anterior. -
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 tagda sua imagem do Docker. Esse é o nome e a tag da imagem que você especificou no comando docker build
. -
Substitua
<ECRrepositoryUri>
pelorepositoryUri
que você copiou. Certifique-se de incluir:latest
no final do URI.
docker tag docker-image:test
<ECRrepositoryUri>
:latestExemplo:
docker tag
docker-image
:test
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
-
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 -
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.
-
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 \ --rolearn: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.
-
Invoque a função.
aws lambda invoke --function-name
hello-world
response.jsonVocê obterá uma resposta parecida com esta:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
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
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--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-uri111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
\ --publish