Lambda + FastAPI 를 활용한 간단한 서버리스 앱 개발 과정을 공유합니다.
(MacOS 기준)
1. 가상환경 생성
Lambda 에 FastAPI 서버 Script를 업로드 하는 것 외에도 관련 Dependency 파일을 함께 업로드 해야 합니다. 이때 개발 환경을 가상환경으로 관리하는 것이 유리하므로 Python 내장 모듈인 venv 를 활용해 보겠습니다.
ദ്ദി ˉ͈̀꒳ˉ͈́ )✧ 참고로, venv 는 로컬 파이썬 버전이 적용되기 때문에 버전 변경이 필요한 경우는 pyenv 패키지를 추가로 활용해야 합니다.
# 가상환경 생성할 경로 이동
$ cd lambda-test
# 가상환경 생성
$ python -m venv lambda-test
Pycharm 에서 FastAPI 프로젝트를 생성합니다. Environment - Select existing 을 선택하여 생성한 lambda-test 환경을 적용합니다.
bin 하위에서 Python Interpreter 를 지정합니다.
ദ്ദി ˉ͈̀꒳ˉ͈́ )✧ 더 간단하게는, 아래 이미지와 같이 Pycharm 프로젝트 생성 단계에서 Generate new 를 통해 Poetry, Conda 와 같은 가상환경 관리 도구를 사용할 수 있습니다.
이때는 pyenv, venv 모듈을 통해 미리 가상환경을 생성해 둘 필요가 없겠죠!
2. API 작성 및 업로드
Lambda 를 통해 배포할 API 코드입니다. response body 에 response header 를 반환합니다.
실행을 위해 pip 로 mangum, uvicorn, fastapi 설치를 진행합니다.
api 실행 후 postman 으로 호출 테스트를 해 보니 정상 호출이 확인됩니다.
정상 동작하는 python 코드를 lambda에 업로드합니다. 런타임 설정 시 가상환경의 python 버전과 맞춰 주어야 합니다.
lambda 생성 후 작성해 둔 코드를 업로드, Deploy 합니다.
추가로 런타임 설정 편집이 필요합니다. lambda_function.py 파일을 업로드했고, mangum 으로 fastapi app 객체를 변환하여 handler 객체에 넣어 주었기 때문에 아래와 같이 설정합니다.
lambda_function.handler
테스트를 위해 test event 를 정의합니다. 작성한 api 는 get method 의 "/" 호출 내용만 정의해 두었지 때문에 http method와 path를 맞춰서 작성 하였습니다.
Test 를 실행해 보아도 아직 dependency 가 주입되지 않아서 fastapi 모듈을 찾지 못합니다.
3. 계층 적용
lambda 의 계층(layer) 탭에서 dependency를 주입해야 합니다.
lambda-test 가상환경의 경로로 이동해서 python 환경 하위의 site-packages 내용을 추출합니다.
$ mkdir python && cp -rf site-packages/* ./python
$ zip -r python-dependency.zip python
계층(layer) 탭 - 계층 생성
추출한 python-dependency.zip 파일을 업로드합니다. 아키텍처와 런타임을 생성한 lambda 함수와 동일하게 설정합니다.
lambda 함수로 돌아와서 계층을 추가합니다.
계층을 추가하고 Test 를 다시 실행해 보니 테스트가 여전히 실패합니다. ☠️☠️☠️
Response
{
"errorMessage": "Unable to import module 'lambda_function': No module named 'pydantic_core._pydantic_core'",
"errorType": "Runtime.ImportModuleError",
"requestId": "0027364d-fdd9-4c86-9506-6a61d535aada",
"stackTrace": []
}
해당 에러는 pydantic_core 가 지정한 lambda 아키텍처와 호환되지 않기 때문에 발생합니다. 아래 명령어로 설정과 동일한 런타임(python 3.9), 아키텍처(x86_64)를 지정하여 pydantic-core 를 다시 설치합니다.
$ pip install pydantic-core --platform manylinux2014_x86_64 --target=python3 --python-version 3.9 --only-binary=:all: --upgrade
이후에 site-packages 하위에서 python-dependency.zip 추출을 반복하고, 신규 버전으로 계층을 편집해 줍니다.
수정을 마친 후 다시 테스트를 진행해 보면 정상 호출이 확인 됩니다.