회사에서 Lambda와 API Gateway를 이용해서 간단한 API들을 꽤나 여러개 만들 일이 있었다. 처음에는 API 엔드포인트 하나당 하나의 Lambda 함수를 생성하고, API Gateway의 리소스/메소드도 생성해서 연동시켜주는 방식으로 작업했다.
한두개의 API를 만들어서 배포할때에는 좋은 방법이겠지만... 여러개를 만들어야 하는 상황에서는 매우 번거롭고 작업 속도가 나지 않았다.
좀 더 효율적인 방법을 찾아보던 중, Fast API를 생성해서 서버리스로 AWS Lambda에 등록하고 API Gateway에 배포할 수 있는 방법이 있어 시도해 보았다. 결과적으로는 이전에 3개 만들던 시간에 6개정도를 만들 정도로 효율이 좋았고 관리에도 용이했다.
Fast API를 Lambda에 올리는 방법은 npm Serverless를 사용할 수 도 있고 AWS SAM을 사용할 수도 있는 듯 하다. 나는 후자의 방식, AWS SAM을 사용하는 방식을 선택했다!
AWS SAM이란? AWS Serverless Application Model(AWS SAM) 은 AWS에서 서버리스 어플리케이션을 빌드하는 데 사용할 수 있는 오픈 소스 프레임워크이다. SAM 템플릿과 CLI를 사용하여 서버리스 어플리케이션을 정의 할 수 있다.
최종적으로 생성되는 파일 및 디렉토리 구성은 아래와 같다.
아래 트리로 출력된 경로에 맞게 파일들을 생성해준다.
(Dockerfile은 도커환경에서 테스트하기 위한 용도이므로 이번 AWS배포에는 필요 없다.)
$ tree
.
├── app
│ ├── __init__.py
│ └── main.py
├── Dockerfile
├── requirements.txt
└── template.yml
파일 작성 전에, AWS SAM CLI를 설치한다.
#설치파일 다운로드
$ wget <https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip>
#무결성 확인
$ sha256sum aws-sam-cli-linux-x86_64.zip
<64-character SHA256 hash value> aws-sam-cli-linux-x86_64.zip
#압축해제 및 설치
$ unzip aws-sam-cli-linux-x86_64.zip -d sam-installation
$ sudo ./sam-installation/install
#버전확인
$ sam --version
SAM CLI, version 1.56.0
SAM CLI 설치가 정상적으로 되었다면, 배포할 API를 생성해보자.
람다에서 실행할 handler가 포함된 main.py 코드를 작성한다.
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
from mangum import Mangum
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
#여기서 root_path는 API Gateway stage. 추가하지 않으면 swaager UI 접속 안된다.
app = FastAPI(
root_path="/dev/"
)
@app.get("/check")
def read_root():
return {"test":"FastAPI start"}
@app.get("/items/{item_id}")
def read_item(item_id):
return {"item_id": item_id}
#query parameter - optional
@app.get("/query/items")
def read_item_and_q(item_id: str = "default", q: Union[int, None] = None):
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}
@app.post("/items")
async def create_item(item: Item):
return item
#handler 작성
handler = Mangum(app)
requirements.txt는 아래와 같다.
fastapi==0.82.0
uvicorn==0.18.3
mangum==0.15.1
pydantic==1.10.2
위의 파일 구성을 보면 __init__.py이 main.py와 함께 위치해 있는데, 여기서는 init 파일의 내용은 비워두었다.
이제, SAM Template을 생성한다.
AWSTemplateFormatVersion: '2010-09-09'
Description: Fast API on lambda for OTA
Transform: AWS::Serverless-2016-10-31
Resources:
otaApiFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./ #app 경로
Handler: app.main.handler #main.py의 Lambda handler
Runtime: python3.9
FunctionName: "fastApiTest"
Events:
Api:
Type: Api
Properties:
RestApiId:
Ref: ApiGateway
Path: /{proxy+}
Method: ANY
#생성해둔 IAM역할이 없으면 지정 안해도 자동생성됨.
Role: !Sub arn:aws:iam::${AWS::AccountId}:role/defaultLambdaBasicExecutionRole
ApiGateway:
Type: AWS::Serverless::Api
Properties:
StageName: dev
Outputs:
apiEndpoint:
Description: "API Gateway endpoint URL for dev stage"
Value: !Sub "<https://$>{ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/dev/"
API 생성과 템플릿 파일 작성이 다 되었으면, 이제 빌드 후 배포해주면 된다.
#템플릿파일 유효성 검사
$ sam validate
#빌드, 템플릿 파일이 위치하는 경로에서 진행
$ sam build
#로컬에서 테스트
$ sam local start-api
**$ curl localhost:3000
{"test":"FastAPI start"}**
#cloudformation으로 배포
$ sam deploy --guided
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Found
Reading default arguments : Success
Setting default arguments for 'sam deploy'
=========================================
Stack Name [deploy-lambda-api]:
AWS Region [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
otaApiFunction 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]:
💡 templatem.yml 수정을 통한 속성값 변경시에는 Disable rollback [Y/n]: y 으로 하여 롤백 불가로 해놓으면 업데이트 실패한다. 업데이트 시에는 rollback 가능하게 해야한다.
이제 AWS에 접속해서 Cloudformation의 output을 확인 하면, 생성한 API의 Base 주소가 출력된것을 확인 할 수 있다.
또한, Lambda와 API Gateway에서도 함수와 API가 정상적으로 생성된 것을 확인 할 수 있을 것이다.
참고:
'Amazon AWS' 카테고리의 다른 글
Amazon QuickSight에서 RDS/Redshift에 Private 연결 (0) | 2024.06.16 |
---|---|
Amazon DocumentDB 인스턴스 사이즈 계산기 (0) | 2023.10.08 |
리눅스(Ubuntu 20.04)에 AWS CLI 설치, 자동완성 설정하기 (0) | 2022.07.03 |
AWS에서 VPC Peering 연결을 통해 다른 리전에 접근하기 (0) | 2022.06.21 |
Opensearch 생성 시, vpc access 불가로 인한 생성 불가 오류 해결 (0) | 2022.06.19 |