모두의연구소 & Tech4Impact 활동으로 <누구나리포터 Lab> 활동을 진행하고 있습니다. 누구나 리포터 Lab은 비영리 단체들이 데이터 기반의 의사결정을 통해 선한 영향력을 펼칠 수 있도록 지원하기 위해 기획자, 개발자, 분석가 등이 모인 Lab 입니다. 저는 누구나리포터 Lab 의 개발자로 참여하게 되었고 카카오톡 챗봇의 API 개발과 CICD 파이프라인 배포의 역할을 담당하게 되었습니다.
서버리스 서비스가 가져온 혁신
누구나 리포터 랩은 누구나 데이터 팀이 실제로 운영중이던 일 단위의 데이터 기반 레포트 서비스를 발전시켜서 Text-to-SQL 기반으로 마치 주니어 데이터 분석가를 고용한 것과 같은 효과를 LLM 으로 대체해보자는 목표를 가지고 있습니다.
누구나 데이터 팀은 사회적 기업으로 비영리 단체 (ex. 초록우산, 굿네이버스… ) 들이 모금 활동을 데이터 기반으로 할 수 있도록 레포팅 서비스를 하고 있지만, 실제 팀에는 개발자가 없는 상황입니다. 그러다보니 기술적인 진입장벽이 낮은 Lambda 와 API Gateway 와 같은 Cloud Serverless 서비스를 기반으로 서비스를 운영하고 있습니다. 저는 평소 AWS 기반 클라우드 서비스를 다루면서 ‘서버리스’는 빠르게 새로운 기능을 배포할 수 있다는 장점이 있으나, 깊게 쓰면 쓸 수록 개발의 자유도가 떨어져서 한계가 있다는 것이었습니다.
그렇지만 개발자가 없는 스타트업에서, 비개발자가 AWS Lambda와 같은 서버리스 서비스를 사용하여 직접 새로운 서비스를 만들었다는 것이 인상깊었습니다. 서버리스 서비스가 정말로 기술적인 진입장벽을 낮추었고 사회적 기업이 서비스를 하는데 사용되고 있습니다. 클라우드 서비스 중에서도 특히 서버리스 서비스가 기술 장벽을 낮추고 새로운 기회를 줄 수 있다는 인사이트를 얻을 수 있었습니다.
Lambda 를 더 ‘잘’ 쓰기 위한 아키텍처를 고민하다
누구나 리포트 랩에서 LLM 기반의 Text-to-SQL 을 도입하여 챗봇을 키워나가면서, 기존에 운영되는 Lambda 기반의 서비스에서 시스템을 확장해야 합니다. 기존 시스템에서 API 를 더 붙이기로 하면서 변화가 생겼습니다.
- Javascript 기반의 Node.js 에서 Typescript 기반으로 변경
- CICD 파이프라인 도입
- Lambda 를 컨테이너 방식으로 배포하기
이중에서 Lambda 를 컨테이너 방식으로 배포하는 CI/CD 파이프라인에 대해 중점적으로 설명하겠습니다. Lambda 에 CICD를 적용한 아키텍처는 아래와 같습니다.
각 과정은 다음과 같이 동작합니다.
- Git Repository 에서 main branch에 새로운 변경사항이 push 됩니다.
- main branch 에 새로운 코드가 push된 것이 trigger 가 되어 GitHub Action 이 동작합니다. 이 과정에서 AWS CodeBuild 프로젝트가 트리거됩니다.
- CodeBuild 프로젝트에서 Docker Image를 빌드한 후, 이를 Amazon ECR 에 새로운 버전으로 등록합니다.
- Amazon ECR에 등록된 새로운 버전의 이미지를 Lambda 에서 컨테이너로 배포합니다.
그렇다면, 왜 Lambda 를 컨테이너로 배포하기로 했을까요 ? 서버리스 서비스 Lambda 를 컨테이너로 배포하게 되면 기존에 Lambda가 가지고 있던 한계점들을 피해갈 수 있는 대안점이 될 수 있습니다.
- Lambda 기본 용량 제한은 250MB로 경량의 API 배포에 적합하다. 그렇지만 Docker 사용 시 10GB 이미지까지 배포 가능
- Lambda 라이브러리 개수 제한을 Docker Container 기반으로 이미지화 하면 해결할 수 있다.
- 새로운 변경 사항을 Docker Image로 관리할 수 있어서, CI/CD 파이프라인 적용에 적합하다.
CI/CD 파이프라인 구축하기
좀 더 구체적으로 예시 코드를 살펴봅시다. CI/CD는 간단하고 빠르게 파이프라인을 구축하기 위해서, GitHub Action 을 선택하였습니다. 프로젝트의 CI 과정에서는 Typescript의 code formatting 과 linter 역할을 하는 Biome 의 검토를 거친 후, 변경 사항이 target branch 에 merge됩니다.
name: Deploy to AWS Lambda
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run TypeScript build
run: npm run build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: 'ap-northeast-2'
- name: Trigger AWS CodeBuild
run: |
aws codebuild start-build --project-name "LambdaDeploy"
AWS Console 에서 Lambda 함수를 생성할 때에는 컨테이너 이미지를 선택해야 하는 것에 주의합니다. Lambda 함수를 코드 기반으로 작성한 경우, 추후에 컨테이너 이미지 사용 옵션으로 변경할 수 없으므로 주의해야 합니다.
AWS CodeBuild 설정파일(buildspec.yml)의 내용은 다음과 같습니다. 명령어를 살펴보면, aws ecr에 로그인을 한 후, lambda 함수 코드를 Docker Image로 빌드합니다. 빌드에 성공하면, Docker Image 를 AWS ECR (Elastic Container Registry) 에 등록하고, Lambda 함수를 업데이트 합니다.
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
- REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/nodejs-lambda
- IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
build:
commands:
- echo Building Docker image...
- docker build -t $REPOSITORY_URI:$IMAGE_TAG .
post_build:
commands:
- echo Pushing Docker image to ECR...
- docker push $REPOSITORY_URI:$IMAGE_TAG
- echo Updating Lambda function...
- aws lambda update-function-code --function-name simpleLambda --image-uri $REPOSITORY_URI:$IMAGE_TAG
CodeBuild buildspec.yml 파일 내용을 보면, CodeBuild에서 제공하는 환경변수 이외에 직접적으로 넣어주어야 하는 환경변수들이 있습니다. 아래와 같이, CodeBuild에서 환경 변수를 추가적으로 설정해줄 수 있습니다.
Docker Image 빌드에 사용되는 Dockerfile의 내용은 아래와 같습니다. AWS 에서 공식적으로 제공하는 Lambda 컨테이너 배포용 이미지(public.ecr.aws/lambda/nodejs)를 Base Image로 사용해야 합니다. 또한 ENTRYPOINT 로 실행시키는 shell 파일은 Base Image 내부에 이미 정의된 내용이므로 따로 설정할 필요는 없습니다. xxx.handler 를 실행시켜야 lambda 함수가 동작합니다.
FROM public.ecr.aws/lambda/nodejs:16
COPY src/app.ts package*.json ./
RUN npm install
ENTRYPOINT ["/lambda-entrypoint.sh", "app.handler"]
CI/CD 파이프라인이 정상적으로 작동한다면, 아래와 같이 이미지 URI 가 새로운 버전으로 업데이트 된 것을 확인할 수 있습니다.
다음에는 실제로 Text-to-SQL 이 기반이 되는 챗봇 서비스를 개발하면서 겪은 경험들에 대해서 포스팅 할 예정입니다. 글 읽어주셔서 감사합니다!
'Cloud Engineering > AWS' 카테고리의 다른 글
AWS 의 기업문화, Leadership Principles (2) | 2024.09.18 |
---|---|
[AWS] EBS 볼륨 늘리기 및 파일시스템 파티션 확장하기 (0) | 2024.08.20 |
[AWS] EC2 인스턴스 사양 바꾸기 (scale up & scale down) (0) | 2024.06.02 |
[AWS] Lambda 와 API Gateway 로 서버리스 API 구축하기 - GET 요청에서 parameter 보내기 (1) | 2023.11.19 |
[AWS] AWS Data Analytics Specialty 합격 및 시험 후기 (0) | 2023.10.15 |