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:
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
npmou 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-lambdaconté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
importimporta as definições de tipo de @types/aws-lambda. Ela não importa o pacote aws-lambdado 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
FROMcomo o URI da imagem base. -
Defina o argumento
CMDpara 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 rootcomo padrão quando nenhuma instruçãoUSERé fornecida.exemplo Dockerfile
FROM public.ecr.aws/lambda/nodejs:22 as builder WORKDIR /usr/app COPY package.json index.ts ./ RUN npm install RUN npm run build FROM public.ecr.aws/lambda/nodejs:22 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-imagee atribui a ela a tagtest. Para tornar sua imagem compatível com o Lambda, é necessário usar a opção--provenance=false.docker buildx build --platform linux/amd64 --provenance=false -tdocker-image:test.nota
O comando especifica a opção
--platform linux/amd64para 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/arm64em 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:8080docker-image:testEsse 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 3766c4ab331cpelo ID do contêiner da etapa anterior.docker kill3766c4ab331c
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
--regionpara a Região da AWS onde você deseja criar o repositório do Amazon ECR. -
Substituir
111122223333por seu ID da Conta da AWS.
aws ecr get-login-password --regionus-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-namehello-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
repositoryUrida 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>pelorepositoryUrique você copiou. Certifique-se de incluir:latestno final do URI.
docker tag docker-image:test<ECRrepositoryUri>:latestExemplo: .
docker tagdocker-image:test111122223333.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 :latestno final do URI do repositório.docker push111122223333.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:latestno final do URI.aws lambda create-function \ --function-namehello-world\ --package-type Image \ --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \ --rolearn:aws:iam::111122223333:role/lambda-exnota
É 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-namehello-worldresponse.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-namehello-world\ --image-uri111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest\ --publish