[AWS] AWS CDK를 이용한 Lambda함수 작성과 배포

아홉번째태양·2023년 6월 27일
0

API 서버에서 특정 로직을 큐로 컨트롤하여 처리하고 있는데, 큐에 많은 부하가 걸려도 동작이 정상적으로 이루어지는지 확인하기 위해 테스트를 하기로 했다. 이 과정에서 다수의 API 요청이 연쇄적으로 이루어져야 하기에 AWS Lambda 함수로 묶고 이를 외부에서 요청하여 다수의 큐 요청을 일괄적으로 컨트롤할 수 있도록 구현하기로 했다.

1. AWS-CLI 설정

적절한 권한이 설정된 IAM User 혹은 root User의 access key와 secret access key를 준비해놓는다. IAM User를 만든다면, CloudFormation, Lambda, IAMRole에 대한 권한이 필요하고, 그 이외에는 구현하려는 lambda 기능에 맞게 추가하면 된다.

aws configure를 실행하여 로그인을 하고, 현재 로그인한 user 정보는 다음의 명령어로 확인가능하다.

lambda % cat ~/.aws/c
config       credentials

2. 프로젝트 생성

mkdir lambda && cd lambda
npx cdk init app --language typescript
npm run cdk bootstrap
npm i -D esbuild

cdk는 esbuild를 통해서 타입스크립트 파일을 빌드하기 때문에 따로 설치해줘야한다.

이렇게 실행하고나면 다음과 같은 형태의 프로젝트가 생성된다.

📦 
├─ bin
├─ cdk.out
├─ lib
│  └─ app-stack.ts
├─ node_modules
└─ test
   ├─ cdk.json
   ├─ package.json
   └─ tsconfig.json

3. handler 작성

먼저 lib 아래에 Lambda 함수의 본체가 되는 핸들러를 작성한다. lib/handler.ts

핸들러를 작성할 때는 반드시 Promise를 반환하는 함수의 형태로 작성하며, 응답 양식도 정해져있으니 주의가 필요하다.

interface LambdaResponse {
  statusCode: number;
  headers: Record<string, string>;
  body: string;
}

export const handler = async (): Promise<LambdaResponse> => {
  try {
    // lambda 함수가 실행할 기능
  
    return {
      statusCode: 200,
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(result),
    }
    
  } catch (error) {
    const message = error instanceof Error ? `${error.name}: ${error.message}` : 'Unknown error';
    return {
      statusCode: 500,
      headers: {},
      body: message,
    }
  }
}

4. stack 작성

handler 작성이 끝났다면, 배포를 위해 stack을 작성해야한다. 이때, 핸들러의 경로와 핸들러 이름 등에 주의한다.

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as path from 'path';
// import * as sqs from 'aws-cdk-lib/aws-sqs';

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

    new cdk.aws_lambda_nodejs.NodejsFunction(this, 'imageQueueTest', {
      entry: path.join(__dirname, 'handler.ts'),
      handler: 'handler',
    });
  }
}

5. 배포

작성이 끝났다면 이제 배포를 한다.

npm run cdk deploy

배포한 lambda 함수는 AWS 콘솔에서 직접 테스트해볼 수도 있지만, 함수 URL을 생성하거나 sdk를 이용해서 사용할 수 있다.

함수 URL 생성

만든 Lambda함수를 외부에서 사용하려면 접근하기 위한 URL이 필요하다. 이는 Lambda함수 콘솔에서 Configuration > Function URL에서 만들 수 있다.

sdk를 통한 접근

아래는 sdk v3를 이용한 예시이다.

import { LambdaClient, InvokeCommand } from '@aws-sdk/client-lambda';

const imageQueueTest = async () => {
  const client = new LambdaClient({
    region: 'ap-northeast-2',
  });
  const command = new InvokeCommand({
    FunctionName: 'FuncName',
    LogType: 'Tail',
  });

  const { Payload, LogResult } = await client.send(command);
  if (Payload === undefined || LogResult === undefined) {
    throw new Error();
  }
  
  const result = Buffer.from(Payload).toString();
  const logs = Buffer.from(LogResult, 'base64').toString();

  return {
    result,
    logs,
  }
}

timeout 설정

만약 Lambda함수 실행 중 지연이 있어서 timeout 에러가 발생한다면 timeout 설정을 확인해봐야한다. 해당 Lambda함수의 AWS 콘솔에서 Configuration > General Configuration에서 timeout 설정을 바꿔주자.

기본값이 3초로 들어가있는데 필요한만큼 늘리면 된다.




참고
https://dev.to/kumo/dont-miss-on-the-cloud-revolution-learn-serverless-on-aws-the-right-way-1kac
https://docs.aws.amazon.com/lambda/latest/dg/lambda-typescript.html
https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_lambda_code_examples.html

0개의 댓글