[AWS] AWS CDK를 이용한 Lambda Docker 함수 구현

NewNewDaddy·2023년 9월 5일
1

AWS

목록 보기
2/13
post-thumbnail

0. INTRO

Lambda 서비스는 서버리스라 간편하게 코드를 작동시켜 간단한 서비스를 구현할 수 있다는 장점이 있다. 만약 기본적으로 지원하는 라이브러리들만 사용해서 코드를 구현할 수 있으면 제일 좋겠지만 외부 모듈을 끌어와야 동작되는 코드라면 일반적으로는 Lambda Layer를 추가하거나 Library 및 코드 파일이 함께 있는 zip 파일을 만들어 Lambda에 업로드하는 방법으로 해결이 가능하다.

위의 과정들이 조금 번거롭긴 하지만 그렇게 추가해서 해결이 되면 다행이다. 하지만 만약 실행시간이 오래 걸리거나 리소스를 많이 잡아먹거나 또 설치되어야 할 라이브러리들이 많을 때는 이 모든 것들을 최적화하여 코드를 돌리는 과정이 상당히 번거롭다.

이럴 때 Lambda Docker Image 기능을 사용할 수 있다. 이는 코드와 그에 필요한 requirements들을 Dockerfile을 통해 이미지로 만들어 ECR에 저장한 후 해당 이미지를 바탕으로 람다 함수를 실행해준다. 이렇게 되면 기존에는 무거워서 실행시키지 못했던 작업들을 큰 제약없이(이미지 최대 10GB) 실행시킬 수 있으며 사용하는 라이브러리들이 많아도 손쉽게 코드를 구현시킬 수 있다.

  • 전체적인 과정은 아래와 같다.
    1. ECR Repository 생성
    2. Dockerfile, requirement.txt, function.py 등 Docker Image 만들 때 필요한 것들을 디렉토리에 넣고 Docker Image 생성 후 Push
    3. Lambda에서 Container Image 선택하여 Function 생성 후 실행
    4. 위의 과정들을 자동화 할 수 있도록 AWS CDK로 기능 구현

1. Dockerfile 경로 구성 및 코드

1. Dockerfile 경로

lambda_image
|
├── Dockerfile
├── lambda_function.py
├── requirements.txt
└── titanic.csv

2. Dockerfile

FROM public.ecr.aws/lambda/python:3.8

WORKDIR ${LAMBDA_TASK_ROOT}

COPY . ${LAMBDA_TASK_ROOT}

RUN  pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}"

CMD [ "app.handler" ]

3. requirements.txt

pandas==2.0.3

2. Lambda Function 작성

1. lambda_function.py

import json
import pandas as pd

def handler(event, context):
    df = pd.read_csv("titanic.csv")
    cols = df.columns
    print(cols)
    return {
        'statusCode': 200,
        'body': json.dumps(f"hello everyone!\n\n{cols}")
    }

3. AWS CDK Function 작성

1. lambdaContainer_csk_stack.py

import os
import typing

from aws_cdk import (
	aws_lambda,
	aws_ecr,
	Aws, Duration, Stack
)
from constructs import Construct

class LambdaContainerFunctionStack(Stack):
	def __init__(self, scope: Construct, id: str, **kwargs) -> None:
		super().__init__(scope, id, **kwargs)

		image_name    = "lambdaContainerFunction"
		use_pre_existing_image = False


		if (use_pre_existing_image):

			ecr_repository = aws_ecr.Repository.from_repository_attributes(self,
				id              = "ECR",
				repository_arn  ='arn:aws:ecr:{0}:{1}'.format(Aws.REGION, Aws.ACCOUNT_ID),
				repository_name = image_name
			) ## aws_ecr.Repository.from_repository_attributes

			ecr_image = typing.cast("aws_lambda.Code", aws_lambda.EcrImageCode(
				repository = ecr_repository,
				tag='latest'
			)) ## aws_lambda.EcrImageCode

		else:
			ecr_image = aws_lambda.EcrImageCode.from_asset_image(
				directory = "/home/ubuntu/AWS-Training/CDK-Python/cdk_python/lambda-image",
			)
		
		# Lambda 함수의 IAM Role 정의   
		role_arn = 'arn:aws:iam::646664498184:role/LambdaEC2FullAccessRole'
		role = iam.Role.from_role_arn(
									self, 
									"Role", 
									role_arn, 
									# mutable=False
									)

		# 람다 함수 부분
		aws_lambda.Function(self,
		id            = "lambdaContainerFunction",
		description   = "Lambda Container Function",
		role          = role,
		code          = ecr_image,
		handler       = aws_lambda.Handler.FROM_IMAGE,
		runtime       = aws_lambda.Runtime.FROM_IMAGE,
		environment   = {"hello":"world"},
		function_name = "LambdaDockerImage",
		memory_size   = 128,
		reserved_concurrent_executions = 10,
		timeout       = Duration.seconds(30)
		)

4. CDK 코드 실행 및 결과 확인

cdk synth  >  Cloudformation Template으로 변환
cdk bootstrap  >  코드 에러를 확인하고 변환된 cloudformation JSON이 저장될 S3 경로 생성
cdk deploy  >  배포 시작
  • 결과 확인
    • 아래와 같이 함수가 잘 만들어졌다.
      image
    • 테스트 결과 역시 아래와 같이 문제 없이 잘 나오는 것을 확인할 수 있다.
      image

5. OUTRO

  • 라이브러리들의 설치 과정 없이 Lambda로 원하는 코드를 실행시킬 수 있는건 아주 매력적인 기능인 것 같다. 최초 실행시 Docker Image Build로 인해 시간이 약간 걸리긴하고 Lambda 함수의 Timeout 시간인 15분 후에 또 실행하게 되면 Image를 또 새롭게 Build해야 하지만 그래도 큰 리소스를 필요로 하거나 여러개의 라이브러리가 사용된 함수를 실행시킬 때는 상당히 유용할 듯하다.
  • 코드를 수정하기 위해서는 매 번 Docker Image를 다시 올려줘야하는 번거로움이 있기 때문에 디버깅이나 코드 수정을 모두 끝낸 코드를 업로드해주는 것이 좋겠다.
profile
데이터 엔지니어의 작업공간 / #PYTHON #CLOUD #SPARK #AWS #GCP #NCLOUD

0개의 댓글