상세 컨텐츠

본문 제목

Express 앱을 고치지 않고 AWS 람다에 올린다 | Lambda Web Functions 배포법·요금·서울 리전 여부

서버·개발/서버 만지기

by 사이 (SAI) 2026. 10. 15. 12:15

본문

728x90
반응형

서버리스로 옮기고 싶은데 Express 코드를 이벤트 핸들러로 다시 짜야 한다는 이야기에 멈칫한 적이 있다면, AWS가 10월 12일 내놓은 Lambda Web Functions가 그 장벽을 낮춥니다. 코드가 포트를 열고 HTTP 요청을 직접 받는 형태 그대로 람다에 올리는 방식이고, AWS는 어댑터나 별도 설정 없이 Express나 Hono 같은 프레임워크를 쓸 수 있다고 밝혔습니다.

다만 "그대로"에는 조건이 있습니다. 서버가 듣는 주소는 람다가 환경 변수로 정해 주고, 지원 리전은 5곳이며 서울은 없습니다. 요금도 기존 람다와 세는 방법이 다릅니다. 아래에서 배포 순서, 올리기 전에 고칠 곳, 요금 계산, 한도를 순서대로 정리합니다.

Lambda Web Functions는 Node.js 웹 서버를 핸들러 수정 없이 올리는 람다의 새 형태다. 배포는 aws lambda-web deploy 한 줄이고, 서버는 AWS_LAMBDA_HTTP_ENDPOINT로 받은 주소에서 listen해야 한다. 요금은 요청 100만 건당 $0.30에 활성 CPU 시간과 메모리를 더한 방식이며, 지원 리전은 버지니아 북부·오하이오·오레곤·도쿄·아일랜드 5곳으로 서울은 없다.

1. Lambda Web Functions는 무엇이고 기존 람다와 뭐가 다른가

밤 책상 위 열린 노트북 화면에 주황색 가로선이 흐르고, 옆에 끈으로 묶은 상자 두 개와 "그대로"라고 적힌 종이 꼬리표가 놓인 장면

AWS는 이번 발표로 람다를 세 가지 형태로 나눴습니다. 지금까지 쓰던 이벤트 핸들러 방식은 Event Functions라는 이름이 붙었고, 이름만 바뀌어 기존 함수에 코드 변경이나 재배포는 필요 없다고 AWS는 설명합니다. 새로 생긴 Web Functions는 포트에서 HTTP 요청을 기다리는 서버를 올리는 형태이고, MicroVMs는 믿을 수 없는 코드를 격리해 돌리는 용도입니다.

람다의 세 가지 형태 도식: 이벤트를 받는 Event Functions, HTTP 서버를 올리는 Web Functions, 격리 실행용 MicroVMs

Web Functions의 가장 큰 차이는 한 실행 환경이 요청을 한 번에 하나가 아니라 여러 개 처리한다는 점입니다. 환경 하나가 최대 128개의 동시 요청을 맡을 수 있고, AWS는 이 때문에 콜드 스타트를 크게 줄일 수 있다고 설명합니다. 이 숫자의 정확한 뜻은 뒤의 한도 부분에서 다시 짚습니다.

아래는 AWS 공식 블로그의 예제입니다. 평범한 Express 서버인데, 듣는 주소를 환경 변수 AWS_LAMBDA_HTTP_ENDPOINT에서 읽는 한 줄이 로컬 실행과의 유일한 차이이고, 그 아래에 배포 명령이 나옵니다.

AWS News Blog의 Express 예제 코드: AWS_LAMBDA_HTTP_ENDPOINT에서 host와 port를 읽어 listen하고, 아래에 aws lambda-web deploy 명령이 있다
출처: AWS News Blog 'Announcing AWS Lambda Web Functions' 갈무리

핵심 Hono와 Fastify도 같은 방식입니다. AWS 발표문은 Express, Hono, Fastify, Next.js 같은 Node.js 프레임워크를 예로 들었고, 런타임 문서는 어댑터를 따로 쓸 필요가 없다고 적었습니다. 다만 지금 지원하는 런타임은 Node.js 24(nodejs24.x, Arm64) 하나뿐입니다.

2. 로컬에서 돌려 보고, 한 줄로 배포하기

먼저 내 컴퓨터에서 같은 방식으로 돌려 봅니다. 람다는 환경 변수를 알아서 채워 주지만, 로컬에서는 직접 넣어야 합니다. AWS 블로그가 안내한 방법은 아래 한 줄입니다.

로컬에서 Lambda와 같은 시작 경로로 실행하기

AWS_LAMBDA_HTTP_ENDPOINT=127.0.0.1:3000 node index.js

맥 터미널에서 AWS_LAMBDA_HTTP_ENDPOINT를 넣고 node index.js를 실행한 뒤, 다른 탭에서 curl로 Hello from Lambda Web Functions! 응답을 받는 재구성 화면
재구성한 예시 화면(명령과 응답은 AWS 문서·블로그의 예시. 직접 실행한 결과가 아님)

배포 명령은 AWS CLI 버전 2에 aws lambda-web 명령이 들어 있어야 쓸 수 있습니다. aws lambda-web help가 동작하는지 먼저 확인하고, 공식 설치 프로그램으로 깔았다면 aws update로 올리라고 문서가 안내합니다. 처음이라면 시작용 예제부터 배포해 보는 편이 안전합니다.

시작용 예제를 배포하기 (문서의 형식)

aws lambda-web deploy --name my-web-app --hello-world

이 명령은 ./my-web-app 폴더에 시작 파일(server.ts, package.json 등)을 쓰고 배포한 다음, HTTPS 엔드포인트 주소를 알려 줍니다. 내 코드를 올릴 때는 폴더를 --code로 넘깁니다.

내 코드를 배포하기

aws lambda-web deploy --name my-web-app --code ./my-app

맥 터미널에서 aws lambda-web deploy --hello-world를 실행해 엔드포인트 주소를 받고, curl로 Hello from Lambda Web! 응답을 확인하는 재구성 화면
재구성한 예시 화면(명령은 AWS 문서의 형식. 주소와 응답은 문서에 나온 예시이며 직접 실행한 결과가 아님)

처음 배포할 때 이 명령이 만들어 주는 것도 문서에 나옵니다. 버전 관리가 켜진 S3 버킷, CloudWatch Logs 권한이 있는 IAM 실행 역할, Web Function과 첫 리비전, 그리고 dev라는 이름의 엔드포인트입니다. 이후 같은 명령을 다시 실행하면 새 리비전이 만들어지고 주소는 그대로 유지됩니다. 여러 리전에 한꺼번에 올리려면 블로그 예시처럼 --regions에 리전을 쉼표로 적습니다.

주의 시작용 엔드포인트는 기본으로 인증 없이 요청을 받습니다. 문서는 IAM 인증이 필요하면 --auth-type IamAuth를 붙이라고 안내합니다. 공개하면 안 되는 앱이라면 처음부터 붙이세요.

주의 람다는 서버가 실제로 listen을 시작했는지 리비전을 만들 때 확인하지 않습니다. 그래서 리비전과 엔드포인트가 Active로 보여도 요청이 실패할 수 있습니다. 배포 직후 curl로 응답을 꼭 확인하세요.

시험이 끝나면 정리도 해야 합니다. aws lambda-web delete-web-function --function-name my-web-app은 함수와 엔드포인트, 리비전을 지우지만, 배포가 만든 IAM 실행 역할, S3의 배포 패키지, CloudWatch 로그 그룹은 지우지 않는다고 문서가 밝힙니다. 필요 없으면 따로 지워야 합니다.

3. 올리기 전에 고칠 곳 5가지

올리기 전에 고칠 곳 다섯 가지 체크 도식: 듣는 주소, index.js, Arm64 빌드, 10초 안 listen, 요청 간 상태 공유

"코드를 안 고친다"는 말은 핸들러로 다시 짜지 않아도 된다는 뜻이지, 모든 줄을 그대로 둬도 된다는 뜻이 아닙니다. 가장 흔한 함정은 포트를 3000으로 못 박아 둔 코드입니다. 람다가 정해 준 주소와 다르면 요청이 앱에 닿지 않습니다.

듣는 주소를 환경 변수에서 읽기 (문서의 패턴)

const [host, port] = (process.env.AWS_LAMBDA_HTTP_ENDPOINT || 'localhost:3000').split(':');
app.listen(port, host);

나머지 네 가지도 문서에 나온 조건입니다. 기본 시작 파일은 패키지 맨 위의 index.js이고 다르면 AWS_LAMBDA_NODEJS_ENTRYPOINT로 알려 줍니다. 서버는 시작 후 10초 안에 듣기를 시작해야 합니다. 네이티브 모듈이 있다면 Arm64로 설치해야 하며, 문서는 docker run --platform linux/arm64 ... node:24 npm ci --omit=dev 같은 방법을 예로 듭니다. 마지막으로 한 환경이 여러 요청을 동시에 처리하므로 요청별 데이터를 전역 변수에 두면 섞입니다.

핵심 CPU를 오래 쓰는 코드는 따로 점검하세요. Node.js는 메인 스레드 하나로 요청을 처리하므로, 큰 JSON 파싱이나 동기 계산이 이벤트 루프를 막으면 같은 환경의 다른 요청도 멈춥니다. 문서는 이런 작업을 워커 스레드로 넘기거나 maxConcurrencyPerEnvironment를 낮추라고 안내합니다.

4. 요금: 요청, 활성 CPU, 메모리 세 가지를 센다

요금 구성 도식: 요청 100만 건당 0.30달러, 활성 vCPU 초당 0.0000276944달러, 메모리 GB 초당 0.0000036667달러, 데이터 전송은 표준 요금

AWS 요금 페이지의 Web Functions 요금은 요청 수, 활성 CPU 시간, 환경이 쓰는 메모리, 데이터 전송으로 나뉩니다. 계산은 1ms 단위입니다. 표의 숫자는 미국 동부(버지니아 북부) Arm 기준이며, 다른 리전의 요금은 요금 페이지에서 리전을 골라 확인해야 합니다.

항목 단가 (USD, 세금 별도) 기준
요청 100만 건당 $0.30 엔드포인트로 들어온 요청 수
활성 CPU vCPU 초당 $0.0000276944 코드가 CPU를 실제로 쓴 시간
메모리 GB 초당 $0.0000036667 환경이 살아 있는 시간 동안 쓰는 메모리

기존 람다와 가장 다른 점은 CPU입니다. 코드가 DB나 외부 API 응답을 기다리는 동안은 CPU를 거의 쓰지 않으므로 거의 과금되지 않습니다. 반대로 메모리는 요청 사이에 쉬는 동안에도 환경이 살아 있으면 계속 쌓입니다. AWS 요금 페이지의 예시는 이 구조를 보여 줍니다. 월 1,000만 건, 요청당 총 200ms 중 CPU 50ms, 메모리 0.29GB인 API 백엔드는 합계가 $19.61입니다.

같은 방식으로 제가 가정을 바꿔 계산해 봤습니다. AWS 예시처럼 환경 1개가 한 달 내내 떠 있고(30일, 2,592,000초), 무료 구간과 데이터 전송은 뺀 값입니다.

한 달 요금 어림 도식: 월 300만 건 CPU 60ms는 약 8.74달러, 같은 건수에 CPU 300ms는 약 28.68달러, 월 30만 건은 약 3.44달러

주의 위 세 가지 경우는 제 가정입니다. 실제 환경 수는 트래픽에 따라 늘고 줄며, 사용하지 않는 환경은 AWS가 제거합니다. 요금 페이지에 Web Functions의 무료 구간이 적혀 있는지는 확인하지 못했습니다. 실제 요금은 소량 트래픽으로 먼저 돌려 청구서의 사용량으로 확인하세요.

5. 한도와 429, 그리고 리전

발표문의 "환경당 최대 128 동시 요청"은 상한입니다. 개발자 가이드를 보면 maxConcurrencyPerEnvironment는 1에서 128 사이이고 기본값은 64이며, 람다가 자원 사용량에 맞춰 실제 한도를 동적으로 조절합니다. 환경이 가득 차면 요청이 대기하고, 새 환경이 뜨는 동안에도 대기합니다. 429는 아래처럼 다른 조건에서 나옵니다.

설정·한도 값 넘으면
rateLimit (엔드포인트, 선택) 초당 요청 0~10,000 초과분에 HTTP 429
maxEnvironments (엔드포인트, 선택) 환경 2~10,000개 더 못 늘면 가득 찼을 때 429
리전별 계정 한도 엔드포인트당 10,000 RPS, 계정 전체 100,000 RPS, vCPU 2,000개(환경당 2 vCPU) 한도 도달 시 429

429를 받는 클라이언트에는 지수 백오프와 지터를 쓰라고 문서가 안내합니다. 어떤 한도가 원인인지는 응답 헤더 lambda-web-error-type으로 구분합니다. 이 헤더 없이 오는 503은 일시적인 부하 차단이나 내부 오류일 수 있어 따로 기록하라는 설명도 있습니다.

리전은 이번 발표에서 가장 눈에 띄는 제약입니다. AWS는 지금 미국 동부(버지니아 북부), 미국 동부(오하이오), 미국 서부(오레곤), 아시아 태평양(도쿄), 유럽(아일랜드)에서 쓸 수 있다고 밝혔고, 서울은 목록에 없습니다. 발표문에는 서울 지원 시점이 나와 있지 않습니다.

AWS What's New 한국어판 발표 본문: Lambda Web Functions가 미국 동부(버지니아 북부), 미국 동부(오하이오), 미국 서부(오레곤), 아시아 태평양(도쿄), 유럽(아일랜드) 리전에서 사용할 수 있다는 문단
출처: AWS What's New(한국어판) 갈무리

반응형

한국 사용자는 도쿄 리전을 우선 후보로 보게 됩니다. 여러 리전에 같이 올리면 AWS가 지연 시간 기준으로 요청을 나눠 보내지만, 문서는 항상 가장 빠른 리전으로 간다고 보장하지는 않는다고 적었습니다. 내 도메인이나 AWS WAF를 쓰려면 CloudFront를 엔드포인트 앞에 두라고 안내합니다.

6. 어디에 맞고, 어디에 안 맞나

맞는 곳과 안 맞는 곳 도식: Express·Hono API와 SSR, 스트리밍은 맞고, Node.js 외 런타임과 서울 리전 필수, 큐·파일 이벤트 처리는 맞지 않음

상황 권장
Express·Hono·Fastify로 만든 API, SSR 웹 앱, 스트리밍 응답 Web Functions가 맞음. 대기 시간이 긴 I/O 위주일수록 활성 CPU 과금이 유리
Python·Java·.NET 서비스 지금은 기존 Event Functions를 사용
큐 메시지, 파일 업로드 같은 이벤트 처리 AWS가 Event Functions를 쓰라고 안내
서울 리전이 꼭 필요한 서비스 아직 지원하지 않음. 도쿄 리전의 지연 시간을 먼저 측정

핵심 처음 시작한다면 운영 서비스 말고 작은 내부 도구 하나를 도쿄 리전에 올려 보세요. 시작용 예제로 배포 흐름을 익힌 뒤 내 앱의 listen 주소 코드를 고치고, 사용량을 며칠 지켜보며 위 계산과 청구서를 비교하면 됩니다. 비슷한 방식으로 새 API를 붙이는 글로는 OpenAI Decisions API 정리가 있고, 환경을 클라우드에 두는 설정은 코덱스 클라우드 처음 설정에서 다뤘습니다.

Q. 서울 리전에서 쓸 수 있나요?

지금은 못 씁니다. AWS가 밝힌 지원 리전은 버지니아 북부, 오하이오, 오레곤, 도쿄, 아일랜드 5곳이고 발표문에는 서울 지원 시점이 나와 있지 않습니다.

Q. Express 코드를 한 줄도 안 고쳐도 되나요?

핸들러로 다시 짤 필요는 없지만, 서버가 듣는 주소는 AWS_LAMBDA_HTTP_ENDPOINT 환경 변수에서 읽어야 합니다. 시작 파일 이름, Arm64 빌드, 10초 안에 listen을 시작하는 조건도 확인해야 합니다.

Q. Python이나 Java로도 되나요?

현재 Web Functions는 Node.js만 지원합니다. 런타임은 nodejs24.x(Arm64)이고, 다른 언어는 기존 Event Functions나 MicroVMs를 쓰라고 문서가 안내합니다.

Q. 요금이 기존 람다보다 싼가요?

일률적으로 말할 수 없습니다. 기존 람다는 요청과 실행 시간(GB-초)으로, Web Functions는 요청과 활성 CPU 시간, 메모리로 셉니다. DB 대기가 긴 앱은 CPU 요금이 줄 수 있지만 메모리는 환경이 살아 있는 동안 쌓이므로 내 트래픽으로 직접 계산해야 합니다.

Q. 128개 동시 요청이 넘으면 바로 거절되나요?

아닙니다. 128은 환경 하나가 받을 수 있는 동시 요청의 상한 설정값이고 기본은 64입니다. 환경이 가득 차면 요청은 대기하고, 429는 rateLimit 초과나 환경을 더 못 늘릴 때처럼 다른 조건에서 나옵니다.

3줄 핵심 요약

  1. Lambda Web Functions는 포트를 여는 Node.js 웹 서버를 핸들러 수정 없이 올리는 람다의 새 형태이고, aws lambda-web deploy 한 줄로 배포한다.
  2. 서버는 AWS_LAMBDA_HTTP_ENDPOINT 주소에서 listen해야 하고, 요금은 요청 100만 건당 $0.30에 활성 CPU와 메모리를 더해 센다. 환경당 128은 상한값이지 거절 기준이 아니다.
  3. 지원 리전은 5곳으로 서울이 없고 런타임은 Node.js 24뿐이다. 작은 내부 도구를 도쿄 리전에 먼저 올려 청구서를 확인해 보자.

마치며

서버리스의 오래된 불만은 "내 코드를 람다 모양으로 바꿔야 한다"였습니다. Web Functions는 그 방향을 거꾸로 돌려 서버 모양 그대로 받겠다는 시도입니다. 그 대신 서울 리전, Node.js 한정, 새로운 요금 계산이라는 조건이 붙었습니다. 오늘 할 일은 하나, 내 Express 앱에서 포트를 정하는 줄을 찾아 AWS_LAMBDA_HTTP_ENDPOINT를 읽도록 바꿔 보는 것입니다. 로컬에서 그 한 줄로 돌아간다면 배포의 절반은 끝난 셈입니다.

NEXT READ

이어서 읽어 볼 글

01  OpenAI Decisions API 공개 베타 · 글 말고 확률만 받는 API의 요청 형식과 비용

02  코덱스 클라우드 처음 설정 · 노트북을 덮어도 코딩이 이어지는 환경 만들기

03  OpenAI API 종료 일정 2026 · 10월 23일부터 꺼지는 모델과 내 코드 찾는 법

#AWSLambda,#LambdaWebFunctions,#Express,#Hono,#서버리스,#AWS배포,#활성CPU과금,#NodeJS,#클라우드,#서버만지기

728x90
반응형

관련글 더보기

댓글 영역