ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AWS] Lambda 적용기
    AWS 2022. 11. 6. 22:04

    회사에서 개발중인 백오피스에 일정한 간격으로 DB의 특정 데이터를 업데이트 해야 되는 요구사항이 생겼다. 이 요구사항을 AWS의 람다를 활용하여 충족시키기로 결정 되었고, 이 업무는 내가 맡게 되었다.

     

    AWS의 람다는 처음 써보는 것이기도 했고, 다음 번의 람다를 사용하게 될 때 똑같은 삽질은 반복하지 않기 위해 기록한다!

     

    람다는 서버리스 함수이다. 찾아보면 정말 자세하고 디테일하게 설명된 곳이 많지만 내가 사용하는 현 수준에서 쉽게 정의하자면 서버가 없이 실행되는 함수이다. 말 그대로 서버가 없이 동작하는 함수다.(사실 엄밀히 말하면 서버가 없는 것은 아니고 함수가 돌아가는 서버는 AWS에서 관리하고, 사용하는 개발자 입장에서는 서버가 없으니 이해하기 쉽게 서버리스라 말함)

     

    1. 서버리스 프로젝트 생성

    npm i -g serverless
    
    serverless create --template aws-nodejs --path [프로젝트 명]

    AWS 콘솔에서 람다를 직접 생성해도 되지만 그렇게 하면 이력 관리와 코드 관리가 어려울 것이기에 프로젝트를 생성하였다.

    https://www.serverless.com/framework/docs/providers/aws/cli-reference/create/
    npm이 있는 환경에서 위 명령어를 사용하여 서버리스 프로젝트를 생성한다.

    위에서 aws-nodejs라는 부분은 람다를 어떤 환경으로 실행할 것인지를 정하는 것인데 나같은 경우는 기존 프로젝트가 nodejs로 작성되어 있기도 했고, 익숙하기도 해서 위와 같이 진행하였다.(다른 많은 언어도 지원한다.)

     

     

    2. 프로젝트 구성

    프로젝트 구성은 이렇게 생겼다. handler.js는 비즈니스 로직이 담겨있는 몸체이고, serverless.yml은 여러 환경설정을 담당하는 파일이고, env는 serverless.yml에서 사용할 각종 환경변수들을 환경별로 나눠논 것이다.

     

    개발을 완료한 후에는 

    serverless deploy -s [환경]

    위와 같은 명령어로 AWS 람다에 람다를 배포할 수 있다.

     

     

    3. env

    sandbox.json

    {
      "STAGE": "...",
      "AWS_PROFILE": "...",
      "AWS_PROFILE_REGION": "...",
      "AWS_IAM_ROLE": "...",
      ...
      "SLACK_WEBHOOK_URL": "..."
    }

    env 파일 중 하나를 샘플로 보면 위와 같이 생겼다. json 포멧이고 key, value 형태로 환경변수를 사용한다.

     

     

    4. handler.js

    // aws 환경 설정을 가져옴
    const client = new AWS.SecretsManager({
      region: process.env.AWS_PROFILE_REGION, // 이처럼 env의 환경설정 값을 사용한다.(nodejs 기준)
    });  
    
    ...
    
    // 슬랙 객체 생성  
    const slack = new IncomingWebhook(process.env.SLACK_WEBHOOK_URL);
    
    ...
    
    // 메인 함수 (람다에서 동작하는 로직)
    module.exports.main = async (e) => {
        try {
        ... 비즈니스 로직 ...
      } catch (err) {
        console.error(err);
        await sendMsgToSlack("main", err.message, "```" + err + "```");
        throw err;
      }
    };

    회사에서 실제로 동작하는 코드라 많이 생략이 되어있다. 위와 같이 env의 환경설정등을 바탕으로 여러 값들을 세팅하고 메인 비즈니스 로직은 main 함수 안에서 동작한다.

     

    비즈니스 로직을 완성하고 배포를 하게 되면 원하는 트리거를 설정하여 해당 트리거 때 비즈니스 로직이 동작하게 된다.

     

     

    5. serverless.yml

    custom:
    ...
      env: ${file(./env/${opt:stage,'local'}.json)} # env 파일 설정
    
    provider:
      lambdaHashingVersion: 20201221
      name: aws
      runtime: nodejs16.x # 런타임 환경
      region: ${self:custom.env.AWS_PROFILE_REGION}
      profile: ${self:custom.env.AWS_PROFILE}
    ...
      iam:
        role: ${self:custom.env.AWS_IAM_ROLE}
    ...
      environment:
        STAGE: ${self:custom.env.STAGE} # 여러 환경 변수들...
        AWS_PROFILE: ${self:custom.env.AWS_PROFILE}
        AWS_PROFILE_REGION: ${self:custom.env.AWS_PROFILE_REGION}
        AWS_SECRET: ${self:custom.env.AWS_SECRET}
        SLACK_WEBHOOK_URL: ${self:custom.env.SLACK_WEBHOOK_URL}
        LAMBDA_NAME: ${self:custom.env.LAMBDA_NAME}
      deploymentBucket:
        name: ${self:custom.env.BUCKET_NAME}
    
    functions:
      main:
        handler: handler.main
    ...
        events:
          - eventBridge:
              schedule: rate(1 minute) # 매 1분마다 동작하는 트리거

    serverless.yml에서는 서버리스 프로젝트의 여러 환경값들을 설정할 수 있고, 람다의 동시 실행개수, 람다가 실패했을 시 재실행하는 횟수등 람다의 실행과 관련된 여러 설정도 할 수 있다. 추가적으로 eventBridge 설정을 통해 트리거를 설정할 수 있다.(물론 AWS 콘솔에서 직접 트리거를 설정할 수도 있다.)

     

    위 과정들을 통해 람다를 설정하고 동작할 수 있게 하였다. 상당히 간략하게 적어논 감이 없지 않아 있지만? 다음번 이 글을 통해 다시 쉽게 리마인드하여 람다를 설정할 수 있을 것 같다.

     

    람다를 직접 설정하기 전에 동료로부터 사전적으로 지식을 습득할 수 있었는데 그게 큰 도움이 되어 쉽게 람다를 설정할 수 있었다. (사전의 경험이 있는 사람의 지식은 큰 도움이 된다는 것을 깨달았다.)

    댓글