예전에 flask 사용할 때 zappa를 이용해서 lambda에 올렸던 기억이 있는데, (내가 서치한 자료에 의하면) fastapi는 zappa를 이용할 수 없는 것 같다..! FastAPI는 mangum를 사용해서 lambda에 올리는 것 같아 이번에 mangum과 SAM을 사용해보려고 한다.
Mangum공식 문서 or Mangum 깃허브를 보면 API Gateway를 처리하기 위해 AWS Lambda에서 ASGI 애플리케이션을 설정하기 위한 어댑터라고 설명되어 있습니다.
[특징]
AWS Serverless Application Model (AWS SAM)은 AWS에서 Serverless Application을 구축하는 데 사용할 수 있는 오픈 소스 프레임워크입니다.
Serverless Application은 작업을 수행하기 위해 함께 작동하는 Lambda 함수, 이벤트 소스 및 기타 리소스의 조합입니다. Serverless Application은 단순한 Lambda 함수가 아니라 API, DB 및 이벤트 소스 매핑과 같은 추가 리소스를 포함하 수 있습니다.
AWS SAM을 사용하여 Serverless Application을 정의할 수 있습니다.
디렉토리 생성 및 이동
$ mkdir fastapi-lambda-mangum-sam-test
$ cd fastapi-lambda-mangum-sam-test
가상환경 생성 및 실행
$ pyenv virtualenv 3.9.11 venv-fastapi-test
$ pyenv activate venv-fastapi-test
FastAPI 설치
$ pip install fastapi
$ pip install uvicorn
작업 폴더 및 파일 생성
fastapi-lambda-mangum-sam-test
└── app
├── __init__.py
└── main.py
$ pip install mangum
from fastapi import FastAPI
from mangum import Mangum
app = FastAPI()
@app.get("/")
def read_root():
return {"test": "FastAPI Running"}
handler = Mangum(app)
$ pip freeze > requirements.txt
requirements.txt 파일은 해당 경로에 위치시킵니다. (app 디렉토리와 같은 위치에 존재하면 안 되는 것 같음)
fastapi-lambda-mangum-sam-test
└── app
├── __init__.py
├── main.py
└── requirements.txt
$ sam ~~
을 사용할 수 있도록 설치합니다.
$ brew tap aws/tap
$ brew install aws-sam-cli
설치 확인을 합니다.
$ sam --version
SAM CLI, version 1.46.0
AWS SAM CLI를 사용하여 어플리케이션을 배포하기 위해 template.yaml
파일을 생성합니다.
SAM은 기본적으로 Lambda와 API Gateway 배포를 지원합니다. Lambda Function과 관련된 내용을 template.yaml
에 먼저 작성하고, API Gateway 정보가 담긴 내용을 추가하고 Lambda Function과 API Gateway와 연결되도록 내용을 추가합니다.
fastapi-lambda-mangum-sam-test
├── app
│ ├── __init__.py
│ ├── main.py
│ └── requirements.txt
└── template.yaml
# template.yaml
# https://intrepidgeeks.com/tutorial/fast-api-to-aws-part-1-lambda-and-api-gateway-deployment
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: FastAPI on Lambda
Resources:
Function: # SAM Local에서 호출하는 함수
Type: AWS::Serverless::Function
Properties:
FunctionName: "FastAPILambda" # Lambda Function Name
CodeUri: app # Lambda Function이 담겨 있는 위치
Handler: main.handler # Lambda Handler 함수의 위치
Runtime: python3.9
Events:
Api:
Type: HttpApi
Properties:
ApiId: !Ref Api
Api:
Type: AWS::Serverless::HttpApi
Outputs:
ApiUrl:
Description: URL of your API
Value:
Fn::Sub: 'https://${Api}.execute-api.${AWS::Region}.${AWS::URLSuffix}/'
[참고 문서]
$ sam build
.aws-sam
폴더가 생긴 것을 볼 수 있습니다.
fastapi-lambda-mangum-sam-test
├── .aws-sam
├── app
│ ├── __init__.py
│ ├── main.py
│ └── requirements.txt
└── template.yaml
hello_world 예제로 하면 아래 오류가 발생한다 무슨 오류일까..?
Your template contains a resource with logical ID "ServerlessRestApi", which is a reserved logical ID in AWS SAM. It could result in unexpected behaviors and is not recommended.
SAM을 이용하여 AWS Lambda에 올리기 위해서는 AWS 계정이 필요하고, 로컬 환경에서 세팅을 해야합니다.
$ aws ~~
명령어를 실행하기 위해서는 awscli
를 설치해야 합니다.
$ brew install awscli
설치 후 아래 명령어를 통해 credencial을 설정합니다.
$ aws configure
$ sam deploy --guided
해당 명령어를 입력하면 아래와 같이 나오는데, 우선 임의로 모두 작성했고 Yes를 선택했습니다.
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Not found
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]: test-sam-app
AWS Region [us-east-1]: ap-northeast-2
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: y
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: y
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]: y
MyFunction may not have authorization defined, Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]: Y
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
진행되던 중간에 다시 아래와 같은 문구가 나왔는데 이 또한 Yes를 선택했습니다.
Deploy this changeset? [y/N]: y
시간이 조금 걸린 후에 완료되었다는 메시지와 함께 samconfig.toml
파일이 생성되었습니다.
Successfully created/updated stack - test-sam-app in ap-northeast-2
# samconfig.toml
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "test-sam-app"
s3_bucket = ###
s3_prefix = "test-sam-app"
region = "ap-northeast-2"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
disable_rollback = true
image_repositories = []
AWS에 접속해 Lambda > Application 탭에 들어가보면 함수가 생성된 것을 볼 수 있습니다.
Lambda > Function 탭에 들어가보면 함수가 생성된 것을 볼 수 있습니다.
함수 이름을 클릭해 들어오면 아래와 같은 이미지가 나옵니다.
API 게이트웨이를 클릭하게 되면 아래와 같이 "API 엔드포인트" 값이 나오게 됩니다.
API 엔드포인트 링크를 웹브라우저에서 열게 되면 아래와 같이 제가 작성한 코드가 나오는 것을 볼 수 있습니다.
FastAPI + Mangum + Lambda + SAM 을 사용해 배포를 진행해보았다.
간단하게 테스트를 해본거라, 완벽하게 구조를 이해하지는 못했다.
지금 생각으로는 template.yaml
파일을 잘 작성해야겠다는 생각이 드는데, SAM에 대해 작성된 해당 페이지를 통해 작성된 내용을 자세히 알아봐야할 것 같다.