[FastAPI] 16. Pulumi를 이용해 FastAPI Serverless 환경 구축해보기
우리는 지난 글에서 FastAPI, Magnum, AWS Serverless Stack(Lambda, API Gateway)을 이용하여 FastAPI 서버리스 환경을 구축했습니다.
2022.05.22 - [Programming/Python] - [FastAPI] 15. FastAPI를 Serverless로 배포하는 방법 - Mangum
[FastAPI] 15. FastAPI를 Serverless로 배포하는 방법 - Mangum
이번 포스트에서는 FastAPI와 Serverless(서버리스) 조합에 대해 알아보도록 하겠습니다. 제가 초기 서버리스를 배웠을 때는 AWS의 Lambda라는 서비스가 나왔을 때였는데요. 당시 사용할 때는 별도의 프
blog.neonkid.xyz
하지만 AWS Lambda와 API Gateway를 통해 서버리스 환경을 일일이 구축하는 것은 우리가 AWS GUI Console을 익히고, 적응하는데 많은 러닝 커브 요소를 필요로 했고, 설령 그런 게 이미 숙달된 상태였다. 하더라도 손이 많이 가는 작업 (자주 오고 가는 콘솔 메뉴)들 때문에 오히려 비효율적인 구축 배경이라고 생각하셨던 분들도 계셨을 것입니다.
Automation
그러나 굳이 마우스를 클릭하지 않고도 YAML 코드나 프로그래밍 언어의 코드를 사용해서 구축할 수 있는 방법들이 있습니다.
- AWS SAM CLI
- Terraform (테라폼)
- Pulumi (풀루미)
AWS SAM은 Serverless Application Model의 약자로 AWS의 서버리스 플랫폼을 명령어로 구축하는 프레임워크입니다.
Terraform은 서버리스 외에 AWS, GCP, Azure 등의 클라우드 리소스를 HCL 언어로 작성해 배포하는 도구입니다.
Pulumi는 Terraform와 그 기능이 유사하지만 HCL이 프로그래밍 언어(Go, Python 등)로 작성해 배포하는 도구입니다.
우리는 여기서 Pulumi를 이용해 Python 언어를 이용하여 AWS 서버리스 환경을 구축해보도록 하겠습니다.
AWS IAM
먼저 배포 도구(Pulumi)가 AWS 리소스를 이용해 서버리스 환경을 만들어줄 수 있는 권한이 필요합니다. AWS 콘솔에 로그인 한 후 IAM에 접속합니다.
Pulumi가 내 AWS 리소스에 접근할 수 있도록 새로운 유저를 추가할 것입니다. Add users를 클릭합니다.
유저 이름을 입력하고 access type을 Access Key로 지정합니다.
다음으로 넘어가면 User Group을 지정해야 합니다. 우리는 만들어둔 User Group이 없으므로 Create group을 통해 새로운 사용자 그룹을 만들어줍니다.
사용자 그룹에는 해당 그룹이 가질 권한을 지정하고, 그 권한을 소속된 사용자가 상속 받는 구조입니다.
서버리스 구축에는 아래의 3가지 권한 정책이 필요합니다.
- IAMFullAccess
- AmazonAPIGatewayAdministrator
- AWSLambdaFullAccess
위의 정책이 필요한 이유를 간략히 설명하자면 지난 글에서 우리는 Lambda를 통해 애플리케이션 코드를 배포하였고, API Gateway를 사용해 Lambda와 Proxy로 연결하였습니다. 그들을 연결하는데, API Gateway가 Lambda의 리소스를 사용할 수 있도록 권한을 부여했었죠. 따라서 IAMFullAccess 정책까지 필요로 합니다.
그렇게 3가지 정책을 주고 사용자 그룹을 만들면 위와 같이 생성된 사용자 그룹이 나올 것입니다. 해당 그룹의 체크 박스를 클릭한 후 다음 과정으로 넘어갑니다.
3단계 과정은 선택 사항이므로 생략하고 4단계로 넘어갑니다. access type이 access key이고, User Group이 잘 설정되어 있는지 확인한 후 사용자 생성을 진행합니다.
유저 생성이 완료되면 Access Key ID와 Secret Access Key가 부여됩니다. 한 번 생성된 Secret access key는 콘솔에서 두 번 다시 볼 수 없으므로 .csv 파일을 다운로드 받아 별도로 저장해놓으시는 걸 추천합니다.
Set environment Access Key
Pulumi에서 방금 부여한 AWS 계정을 사용할 수 있도록 환경 변수에 Access Key와 Secret Access Key 값을 추가해야 합니다.
$ export AWS_ACCESS_KEY_ID=${ACCESS_KEY_ID}
$ export AWS_SECRET_ACCESS_KEY=${SECRET_ACCESS_KEY}
OS X, Linux에서 터미널을 열고 export 명령어를 통해 환경 변수를 추가할 수 있습니다.
> $Env:AWS_ACCESS_KEY_ID = ${ACCESS_KEY_ID}
> $Env:AWS_SECRET_ACCESS_KEY = ${SECRET_ACCESS_KEY}
Windows에서는 PowerShell 혹은 Windows Terminal을 열고 $Env 스크립트를 이용해 환경 변수를 추가할 수 있습니다.
Install Pulumi
이제 AWS에 대한 셋팅은 모두 끝났습니다. 자신의 컴퓨터에 pulumi CLI를 설치하고, 새로운 Pulumi 프로젝트를 만들면 됩니다.
https://www.pulumi.com/docs/get-started/install/
Download and Install
This page contains detailed instructions for installing Pulumi.
www.pulumi.com
$ curl -sSL https://get.pulumi.com | sh
Linux에서는 curl을 통해 최신 버전의 pulumi를 설치할 수 있습니다.
$ brew install pulumi/tap/pulumi
OS X에서는 Homebrew를 이용하여 pulumi를 설치합니다.
> choco install pulumi
Windows에서는 Chocolatey 혹은 WinGet 패키지 관리자에서 pulumi를 제공합니다.
Create Project
Pulumi는 프로젝트 단위로 클라우드 리소스를 관리할 수 있습니다. 이전 글에서 우리는 FastAPI 프로젝트를 생성했고, 해당 프로젝트 상위 디렉터리에 infra 디렉터리에 pulumi 프로젝트를 만들어보도록 하겠습니다.
api 밑으로 infra 디렉터리를 만듭니다. 우리는 여기서 AWS를 사용할 것이므로 AWS 폴더를 한 개 더 추가합니다. 그리고 이전 글에서 만들어두었던 프로젝트 모듈 압축 파일을 fastapi-serverless-layer.zip 이름으로 수정한 후 최상위 디렉터리에 이동시킵니다.
$ pulumi new aws-python
infra/aws 디렉터리 경로에서 위 명령어를 입력하면 새로운 Pulumi 프로젝트를 생성합니다.
그러면 __main__.py, Pulumi.yaml, Pulumi.${stack}.yaml 이렇게 3개가 생성됩니다. 물론 venv 폴더 등도 생성되겠지만 우리가 살펴볼 것은 이 3가지 파일입니다.
Pulumi stack 파일에서는 해당 스택에 대한 클라우드 환경을 설정합니다. 우리는 AWS를 사용할 것이고 서울 리전(ap-northeast-2)에 환경을 구축합니다.
코드 작성
aws 서버리스 환경을 만드는 코드를 작성하기 전에, 우리가 어떤 것을 어떤 방법으로 서버리스 환경을 구축했는지 이해해야 합니다. 먼저 Lambda 프로젝트는 AWS의 Cloudwatch로 이벤트 로그를 만들고 관리하기 때문에 이에 대한 권한을 부여해줘야 합니다.
aws 디렉터리에 iam.py 파일을 만들고 위처럼 LambdaRole과 Role 정책에 Cloudwatch로 로그 그룹을 만들고 이벤트를 기록하는 권한을 주도록 합니다.
위에서 만들어뒀던 iam.py를 import하여 Lambda_ 인스턴스에 주입합니다. 그래야만 Pulumi에서 해당 권한을 위임받고 Lambda 함수를 만들 때 Cloudwatch에 해당 함수에 대한 로그 그룹을 만들 수 있습니다.
Deploy
이제 마지막으로 위에서 작성한 코드를 AWS에 배포만 하면 됩니다.
$ pulumi preview
Pulumi는 배포하기 전 내가 작성한 코드에 문제가 없는지를 검사해주는 유효성 체크 기능이 있습니다. preview 명령을 통해 우리가 작성한 코드가 어떤 이벤트가 발생하는지 코드에 문제가 없는지를 살펴봅니다.
PASSPHRASE는 처음 Pulumi 프로젝트를 생성했을 때 설정한 PASSPHRASE 값을 넣어주면 됩니다.
위와 같이 lambda Role로 시작하여 Lambda Layer를 생성하고, 함수를 넣고, API Gateway를 만드는 순서대로 진행하면 잘 된 것입니다.
$ pulumi up
모든 검증이 끝났으면 up 명령어를 통해 자신의 AWS에 배포하도록 합니다.
이 때, 위 과정이 맞는지를 다시 물어봅니다. 맞으면 yes 잘못된 것이 있다면 no를 하시면 됩니다.
위와 같이 API Gateway 엔드포인트 주소가 생성이 되었으면 정상적으로 서버리스 스택이 완성된 것입니다.
API가 잘 호출된 모습입니다.
마치며...
여기까지 Pulumi를 사용해서 AWS 환경을 코드로 작성하는 것까지 진행해봤습니다.
개인적으로 FastAPI를 Serverless로 구축하는 것에 대해서는 기존의 FaaS 환경의 유지보수에 대한 불편함을 많이 덜어줬다고 생각합니다.
이전의 FaaS는 함수별로 API를 만들고 이를 API Gateway EndPoint에 일일이 대입하는 형태였다면 지금은 API Gateway에서 Lambda 코드 하나를 Proxy로 걸어두고, 엔드포인트를 해당 코드에게 맡기겠다는 것이 됩니다.
이렇게 함으로써 추가 API를 만들 때마다 Lambda 함수를 별도로 만드는 것을 하지 않아도 하나의 Lambda 프로젝트에서 진행할 수 있고, 더 나아가서는 CI/CD에 적용할 때 Lambda 코드 파일을 재배포하는 형태로만 구현하면 되기 때문에 과정 자체가 간소화 될 수 있습니다.
추가로 현재 Lambda는 코드를 직접 파일로 올리는 것 뿐 아니라 Docker Image로도 작성할 수 있는 방법이 있습니다. 사실 굳이 Docker Image까지 써야 하나라는 입장이지만 파일 업로드가 아직 어색하다면 Docker Image를 사용하는 것도 나쁘지 않다고 생각합니다.
'Programming > Python' 카테고리의 다른 글
[FastAPI] 15. FastAPI를 Serverless로 배포하는 방법 - Mangum (5) | 2022.05.22 |
---|---|
[FastAPI] 14. SQLAlchemy의 One-to-Many, Many-to-Many, Self referential relationship (0) | 2022.04.24 |
[Python] Python Database API - Python에서는 어떻게 DB와 연결할까? (2) | 2022.02.25 |
[Python] anyio - 한 층 더 강화된 비동기 패러다임 (4) | 2022.01.09 |
[FastAPI] 13. SQLAlchemy와 Pydantic을 이용한 관계 데이터 매핑 (0) | 2021.11.09 |