FastAPI 앱을 단계별로 서버리스로 마이그레이션하기
Source: Dev.to
Overview

Serverless는 좋고, Serverless는 멋지고, Serverless는 혁신적입니다. 하지만 우리는 그 활용 범위를 얼마나 넓힐 수 있을까요? Serverless 기술의 장단점을 함께 살펴보겠습니다.
누군가가 처음으로 Serverless 개념을 듣고 “이해”하게 되면 보통 다음과 같은 생각을 합니다:
- 모든 애플리케이션을 Serverless로 옮겨 비용을 절감할 수 있겠지?
- 아직도 매우 저렴한 관리형 서비스를 이용할 수 있겠지?
- 이제 유휴 서버에 대한 비용을 더 이상 지불하지 않아도 되겠지?
- DevOps가 필요 없게 되는 걸까?
- 복잡한 설정 없이 자동으로 스케일링할 수 있겠지?
행복해지지 마세요 (^_‑), 실제 상황을 모른 채 가정하고 있는 겁니다. Serverless에 대해 무엇을, 왜, 언제, 어떻게, 누가 하는지를 이해할 때 올바른 질문이 떠오릅니다.

서버리스란?
실행 모델
여러분의 코드는 다음과 같이 실행됩니다:
- 요청 시
- 이벤트에 응답하여 (HTTP 요청, 메시지, 스케줄, 파일 업로드 등)
짧은 시간(보통 몇 초에서 몇 분) 동안 실행됩니다. 서버를 계속 실행하지 않으며, 필요할 때만 플랫폼이 실행 환경을 생성합니다.
비용 모델
| 비용은 다음에 대해 청구됩니다 | 적합한 경우 | 항상 저렴하지 않은 경우 |
|---|---|---|
| 실행 시간 | 급증하는 트래픽 | 지속적인 고처리량 워크로드 |
| 요청/이벤트 수 | 빈도가 낮은 워크로드 | 장기 실행 프로세스 |
| 사용된 리소스(메모리, 실행 시간) | 이벤트 기반 시스템 | 예측 가능하고 안정적인 트래픽 |
스케일링 모델
| 스케일링 이란 | 스케일링 아닌 |
|---|---|
| 자동 – 플랫폼이 필요에 따라 용량을 추가합니다 | 동시성 제한을 이해해야 합니다 |
| 수평 – 더 많은 인스턴스를 병렬로 실행할 수 있습니다 | 역압 및 실패에 대비한 설계가 필요합니다 |
| 이벤트 기반 – 들어오는 이벤트에 의해 트리거됩니다 | 잘못된 아키텍처는 여전히 비용이 많이 드는 스케일링 문제를 일으킬 수 있습니다 |
운영 현실
서버리스는 DevOps를 없애지는 않으며, 형태를 바꿉니다.
| 여전히 필요한 것 | 차이가 나는 부분 |
|---|---|
| 모니터링 및 로깅 | 인프라 운영이 감소 |
| CI/CD 파이프라인 | 플랫폼 중심 파이프라인 증가 |
| 보안 및 IAM | 가시성 필요 증가 |
| 비용 관리 | 아키텍처 작업 증가 |
| 사고 대응 | 호환성 연구 증가 |
올바른 질문은 이해 후에 나온다
흥미가 가라앉으면 실제 질문이 시작됩니다:
- 어떤 워크로드가 서버리스에 적합한가?
- 컨테이너나 VM 대신 서버리스를 사용해야 하는 이유는?
- 언제 비용을 절감하고 언제 그렇지 않은가?
- 규모에 맞게 설계, 테스트, 모니터링, 디버깅을 어떻게 할까?
- 신뢰성, 보안, 비용 관리는 누가 담당하는가?
서버리스는 강력한 도구이지만, 모든 상황에 맞는 해결책은 아닙니다.

마이그레이션 단계
단계 0 – 시작점 (FastAPI 앱)
# app.py
from fastapi import FastAPI, status
app = FastAPI()
@app.get("/health", status_code=status.HTTP_200_OK)
def health():
return {"status": "ok"}
@app.post("/items", status_code=status.HTTP_201_CREATED)
def create_item():
return {"message": "item created"}
@app.put("/items/{item_id}", status_code=status.HTTP_200_OK)
def update_item(item_id: int):
return {"message": f"item {item_id} updated"}
로컬에서 실행:
uvicorn app:app --reload
단계 1 – 서버리스 매핑 이해 (멘탈 모델)

단계 2 – Mangum 추가 (ASGI → Lambda 어댑터)
의존성 설치:
pip install fastapi mangum
app.py 업데이트:
from fastapi import FastAPI, status
from mangum import Mangum
app = FastAPI()
@app.get("/health", status_code=status.HTTP_200_OK)
def health():
return {"status": "ok"}
@app.post("/items", status_code=status.HTTP_201_CREATED)
def create_item():
return {"message": "item created"}
@app.put("/items/{item_id}", status_code=status.HTTP_200_OK)
def update_item(item_id: int):
return {"message": f"item {item_id} updated"}
# Lambda 엔트리 포인트
handler = Mangum(app)
handler는 AWS Lambda가 호출할 엔트리 포인트입니다.
단계 3 – requirements.txt 만들기
fastapi
mangum
단계 4 – Lambda용 애플리케이션 패키징
빌드 디렉터리를 만들고 의존성을 설치합니다:
mkdir package
pip install -r requirements.txt -t package
cp app.py package/
zip 아카이브 생성:
cd package
zip -r app.zip .
이제 app.zip을 AWS Lambda에 업로드하고(또는 선호하는 IaC 도구 사용) API Gateway 트리거를 구성하여 FastAPI 엔드포인트를 노출할 수 있습니다.
단계 5 – Lambda 함수 생성
- AWS Lambda 로 이동합니다.
- 다음 설정으로 함수를 생성합니다:
- 런타임: Python 3.10+
- 아키텍처: x86_64
- 업로드:
app.zip - 핸들러:
app.handler - 메모리: 512 MB (기본값)
- 타임아웃: 10–15 초
단계 6 – API Gateway 생성 (HTTP API)
- API Gateway → Create HTTP API 로 이동합니다.
- Integration
- 유형: Lambda
- 만든 Lambda 함수를 선택합니다.
- Routes
ANY /{proxy+}
- API를 배포합니다.
이 단일 라우트는 FastAPI가 내부적으로 모든 라우팅을 처리하도록 합니다.
단계 7 – 엔드포인트 테스트
이제 완료되었습니다!
