AWS Lambda/CDK - Docker - Fastapi를 통해 서버리스 백앤드 배포하기(2)

Joey Kim·2023년 6월 3일
0

지난 포스트

에서는 로컬 환경을 세팅하고, python 예시 API를 작성하는 것까지 진행했습니다.

이번 포스트에서는 Dockerfile을 통해 도커를 빌드하고, CDK를 통해 코드로 람다를 배포하는 것까지 진행 해 보겠습니다.

Part2: Docker

현재까지 잘 따라왔다면 아래와 같은 폴더 구조입니다.

└── cdk
└── python
    ├── poetry.lock
    ├── pyproject.toml
    └── app
        ├── __init__.py
        ├── main.py
        └── api
            ├── __init__.py
            └── order.py

먼저 python루트에 빌드할 Dockerfile를 작성해줍시다.

# Python 람다 함수를 위한 Dockerfile(Linux/ARM64)
FROM public.ecr.aws/lambda/python:3.9

# Poetry 버전 정의
ENV POETRY_VERSION=1.3.2

# Poetry 설치
RUN pip install "poetry==$POETRY_VERSION"

# 경로 정의
WORKDIR ${LAMBDA_TASK_ROOT}

# 로컬에 있는 pyproject.toml, poetry.lock 파일을 컨테이너로 복사
COPY poetry.lock pyproject.toml ${LAMBDA_TASK_ROOT}/

# Poetry를 이용하여 의존성 설치
RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi --no-root

# 로컬에 있는 소스코드를 컨테이너로 복사
COPY app ${LAMBDA_TASK_ROOT}/

# 람다 함수의 핸들러를 지정
CMD [ "main.handler" ]

Poetry를 설치하고 환경을 생성하는 데 필요한 파일을 복사하고 환경을 설치한 다음 Lambda 함수를 복사합니다.
보통은 하나의 handler에 하나의 api를 담지만, 우리는 Mangum 모듈을 통해 FastAPI 모듈을 담아서 호출합니다.

다음을 터미널에서 실행하여 Dockerfile 및 Lambda 함수가 작동하는지 테스트 해 봅시다.

docker build --platform linux/arm64 -t lambda-docker-fastapi .
docker run -p 9000:8080 lambda-docker-fastapi

그 다음 아래 url을 postman등의 API플랫폼으로 POST를 호출하면(aws 공식 테스트 API)
http://localhost:9000/2015-03-31/functions/function/invocations

위와 같은 에러가 나올텐데, Mangum모듈과 handler테스트 API와의 호환이 잘 되지 않는 것 같습니다. 하지만, 실제 API를 생성할 때는 정상적으로 동작하니 넘어가도록 합시다.

Part3: CDK

지난 포스트에서 정상적으로 npm모듈에서 cdk를 설치했다면

npm -g list

호출 시 다음과 같이 cdk 모듈이 보일겁니다.

혹시 설치가 안되었다면,

npm install -g aws-cdk

해 줍니다.

이제 이전에 생성한 cdk 디렉토리로 이동하여 cdk 프로젝트를 인스턴스화하겠습니다.

cd ../cdk # 아직 `python` 하위 디렉토리에 있다고 가정합니다.
cdk init --language typescript

구분을 위해 일부 파일명을 변경 해 줍시다.

mv bin/cdk.ts bin/lambda-docker-fastapi.ts
mv lib/cdk-stack.ts lib/lambda-docker-fastapi.ts

다음 cdk 설정을 위한 json 파일들을 수정한 파일명으로 변경해 줍시다.

cdk.json

{
  "app": "npx ts-node --prefer-ts-exts bin/lambda-docker-fastapi.ts",
  // 파일 이름을 수정한 파일명으로 변경.
  ...
}

package.json

...
  "bin": {
    "cdk": "bin/lambda-docker-fastapi.ts"
    // 파일 이름을 수정한 파일명으로 변경.
  },
...

bin/lambda-docker-fastapi.ts 파일을 아래와 같이 수정 해 줍니다.

#!/usr/bin/env node
import "source-map-support/register";
import * as cdk from "aws-cdk-lib";
import { CdkLambdaDockerFastapiStack } from "../lib/lambda-docker-fastapi";

const app = new cdk.App();
new CdkLambdaDockerFastapiStack(app, "CdkLambdaDockerFastapiStack", {});

lib/lambda-docker-fastapi.ts 파일을 아래와 같이 수정 해 줍니다.

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import { aws_lambda as lambda } from "aws-cdk-lib";
import * as path from "path";
import { Architecture } from "aws-cdk-lib/aws-lambda";

export class CdkLambdaDockerFastapiStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new lambda.DockerImageFunction(this, "LambdaFunction_1", {
      code: lambda.DockerImageCode.fromImageAsset(
        path.join(__dirname, "../../python"),
        {
          cmd: ["main.handler"],
        }
      ),
      architecture: Architecture.ARM_64,
    });
  }
}

위에서 생성한 Docker 이미지에서 Lambda 함수를 생성하고 CMD를 통해 호출할 Lambda 함수를 지정하기 위한 인수를 덮어씁니다.


이제 스택을 배포하기 전 AWS계정에 권한을 부여 해 줍시다.

AWS홈페이지에서 IAM페이지에 들어가 줍니다.

정책탭에서 정책 생성 버튼을 클릭 해 줍니다.

JSON탭을 누르고 아래 코드를 붙여넣어줍니다.

{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Sid": "AllowCreateChangeSet",
          "Effect": "Allow",
          "Action": [
              "*"
          ],
          "Resource": "*"
      }
  ]
}


정책 이름을 지어주고 최하단에 정책 생성 버튼을 눌러줍니다.
다음 사용자탭에서 지난포스트에서 등록한 IAM사용자에 권한을 연결 해 줍니다.(사진으론 생략)


모든 AWS세팅은 끝났습니다. 스택을 배포 해 봅시다.

터미널에서 아래 명령어를 실행합니다.

cdk bootstrap
cdk synth
cdk deploy

명령어가 잘 작동 했다면, AWS Lambda 페이지에 가서 함수가 잘 생성됐는지 확인 해 봅시다.

IaaS를 통해 함수가 잘 생성된 모습을 볼 수 있습니다.

다음포스트에서는 만들어진 함수를 API Gateway를 통해 API주소를 생성하고 연결하여, 호출해보는 과정을 진행 해 보겠습니다.

profile
Software Engineer

0개의 댓글