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

Joey Kim·2023년 6월 3일

지난 포스트

에서는 로컬 환경을 세팅하고, 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개의 댓글