AWS Lambda: 가볍게 시작하기

최근에 AWS Lambda를 좀 써볼만한 일이 생겨서 이래저래 삽질을 했다. 막상 시작하려니 내가 잘 모르는 분야라 부담스럽기도 해서 시도를 주저하고 있었는데, 해보고 나니 생각보다 어려운 편은 아니었다. 그 삽질의 결과를 공유해보고자 글을 남긴다.

준비물

AWS Lambda를 쓰기 위해서는 당연히 AWS 계정이 필요하다. 또한, 모든 예제는 Node.js로 진행되기 때문에 Node.js에 대한 기본적인 이해가 필요하다.

새로운 Lambda 함수 만들기

아래와 같은 절차를 밟아 새로운 Lambda 함수를 만들어 볼 수 있다.

1) AWS Lambda 콘솔에 들어간다.

Lambda Console Screenshot

2) Get Started Now 버튼을 클릭해 새로운 Lambda 함수를 만든다. 이미 Lambda 함수가 있는 경우 Create a Lambda function이라는 버튼을 통해서 만들 수 있다.

Lambda Blueprint Screenshot

3) Blueprint는 미리 준비된 Lambda 함수의 환경 같은 것인데, 여기서는 Blank Function을 선택한다. 이 글에서 다루고 있는 예제는 그리 복잡하지 않으므로 Blank Function으로 충분하다.

Lambda Trigger Screenshot

4) Trigger는 아래에서 다시 다룰 것이다. 여기서는 선택하지 않은 채로 Next 버튼을 눌러 넘어간다.

Configure Function Screenshot

5) Configure Function > Name에 적절한 이름을 입력한다.

Lambda Role Screenshot

6) 아래로 내려 Lambda function handler and role > Role에서 Create new role from template(s)를 선택한 뒤, Role name에 적절한 이름을 입력하고 Next 버튼을 눌러 넘어간다.

7) 마지막으로 Create Function 버튼을 눌러 함수를 만든다.

이렇게 해서 만들어진 Lambda 함수는 Test 버튼을 클릭하여 테스트 할 수 있다.

이제 입력으로 숫자를 하나 받아 그 숫자를 두 배로 곱해주는 함수를 만들어 보자. 코드는 아래와 같다.

함수 내부를 들여다보면 우리가 일반적으로 사용하는 함수와는 조금 다른 방식으로 함수를 사용하는 것을 볼 수 있다. 먼저, 입력 데이터는 함수의 매개변수가 아니라 event라는 매개변수의 프로퍼티로 전달된다. 즉, event의 프로퍼티가 실질적으로 기존 함수들의 매개변수 역할을 대신하는 것이다. 마찬가지로, return문이 아니라 매개변수로 넘어온 callback이라는 함수를 실행시킴으로서 결과 값을 출력한다. 물론 return문도 여전히 사용할 수 있지만 함수를 중간에 중단시키는 것 이외의 다른 역할은 하지 않는다.

context는 Lambda 함수의 시스템에 관련된 정보를 속성으로 담고 있는 변수다. context의 프로퍼티 리스트는 이 링크에서 확인할 수 있다. 이 글에서는 context 변수를 다루지 않는다.

이제 만들어진 함수를 테스트할 차례다. Actions > Configure test event를 누르면 event의 프로퍼티로 전달될 값을 편집할 수 있다.

여기서는 event.num이라는 값을 사용하므로 key로 "num"이라는 값을 가지는 JSON을 입력한뒤 Save and test 버튼을 누른다.

그럼 Execution result: Succeeded 라는 말과 함께 결과 값을 확인할 수 있을 것이다.

API Gateway 연동하기

이렇게 해서 만든 Lambda 함수는 현재로서는 별 가치가 없다. 내가 Test 버튼을 누를 때에만 동작하는 함수기 때문이다. Trigger를 지정해줘야만 제대로 된 Lambda 함수로서 기능할 수 있다. 설정할 수 있는 Trigger로는 다양한 종류가 있지만 가장 흔히 사용되는 것이 API Gateway 이므로 API Gateway와 연동하는 법을 소개한다.

먼저, 아래의 절차를 따라 API를 만들 수 있다.

API Gateway Console Screenshot

1) AWS API Gateway 콘솔로 진입해 Get Started 버튼을 누른다.

API Gateway Create Screenshot

2) Create new API > New API를 선택하고, API name에 적당한 이름을 넣고 Create API 버튼을 눌러 API를 만든다.

API는 만들어졌지만 아직 Lambda와 연동되지는 않았다. Lambda와 연동하는 부분은 각 API의 Method이므로 새로운 메소드를 만들어 Lambda와 연동해야한다.

API Gateway New Method Screenshot

1) Actions > Create method 버튼을 클릭하고 나온 Select Box에서 POST 메소드를 선택하고 체크를 눌러 메소드를 새로 만든다.

API Gateway Method Setup Screenshot

2) Intergration type > Lambda Function을 선택하고 Lambda Region을 아까 Lambda 함수를 만들었던 Region을 선택한다.

3) Lambda Function이라는 새로운 입력칸이 나오는데, 여기에서 아까 만들었던 Lambda 함수 이름을 입력한 뒤, Save 버튼을 누른다.

4) 그러면 API Gateway에 Lambda 함수를 호출할 수 있는 권한을 준다는 모달이 나오는데, 당연히 줘야 하므로 OK를 눌러 진행한다.

이제 만들어진 API를 테스트해보자. 왼쪽 위의 번개모양 Test 버튼을 누르면 테스트를 진행할 수 있다. Request Body에 아까 Lambda 함수를 테스트할 때 넣었던 값을 다시 입력한 뒤 Test 버튼을 누르면 동일한 값이 출력되는 것을 볼 수 있다.

다만, 아직까지는 HTTP Request를 통해 이 Lambda 함수를 실행시키지 못한다. HTTP Request를 통해 이 함수를 실행시키려면 API를 배포해야한다. 아래와 같은 절차를 따라 API를 배포한다.

API Gateway Deploy API Screenshot

1) Actions > Deploy API 버튼을 클릭한다.

API Gateway Stage Screenshot

2) Deployment Stage[New Stage]를 선택하고, Stage name을 적당히 입력한다.

3) Deploy 버튼을 눌러 Deploy 한다.

이제 상단에 Invoke URL이 표시되는 것을 볼 수 있다. 적당한 HTTP Request용 툴을 사용해서 해당 주소로 요청을 해보자.

Postman Screenshot

여기서는 Postman을 사용했다. 정상적으로 응답이 도착했다면 API Gateway와의 연동이 끝난 것이다.

이 글에서는 API Gateway에 대해서 여기까지만 다루지만, 이외에도 API Gateway는 유용한 기능이 많다.

npm 모듈 사용하기

AWS 콘솔에서도 직접 코드를 수정하거나 만들어 낼 수도 있지만, 이렇게 해서는 npm 모듈을 사용할 수도 없고 파일을 분할해서 관리할 수도 없다. Lambda는 이 부분을 보완하기 위해서 ZIP 파일을 업로드하거나 S3에서 파일을 불러오는 선택지도 제시하고 있다. 이 글에서는 ZIP 파일을 업로드하는 부분에 대해서만 다룰 것이다.

방법은 간단하다. 필요한 파일을 모두 포함한 채로 ZIP 파일을 만들어 그걸 업로드하기만 하면 된다.

여기서는 Lambda 함수의 요구사항을 조금 바꿔, 숫자 하나를 입력받으면 그만큼의 길이의 자연수 배열을 만들어서 돌려주는 함수를 만들 것이다.

이 요구사항을 만족시키기 위해서 Lodash의 range함수를 사용한다. 따라서 먼저 Lodash를 인스톨한 뒤, index.js 파일에 아래와 같이 handler 함수를 작성하면 된다.

Lodash를 import 한다는 것을 제외하면 전에 작성했었던 함수와 구조적으로 크게 다르지 않다. 이제 설치된 node_modules와 함께 index.js 파일을 ZIP 파일로 묶어서 Lambda에 업로드 하기만 하면 모든 절차가 끝난다. ZIP 파일의 이름은 상관없으나, JavaScript 엔트리 파일은 이름이 index.js여야 한다.1

Lambda Upload ZIP Screenshot

AWS Lambda로 돌아가서 Code entry typeUpload a ZIP file로 변경하고 만들어진 ZIP 파일을 올린다. 그 뒤 Save and test 버튼을 클릭하여 테스트도 해보자. 실수가 없다면, 테스트 결과는 의도한대로 배열을 돌려줄 것이다.

S3 접근하기

Node.js에서 AWS에 접근하기 위해서는 aws-sdk 모듈을 사용해야 한다. AWS Lambda의 Node.js 런타임에는 이 모듈이 기본적으로 설치되어 있으므로 추가로 설치할 필요없이, 바로 사용할 수 있다.

여기서는 Lambda 함수에 파일 이름과 파일 내용을 포함해서 요청하면 그 내용대로 S3에 파일을 만드는 함수를 작성한다. 함수의 구현은 아래와 같다.

s3.putObject()라는 함수의 콜백에서 callback() 함수를 호출해서 에러를 전달하는 것을 볼 수 있을 것이다. 에러가 발생하는 경우 저렇게 callback() 함수의 첫 번째 인자로 에러 객체를 넘기면 에러가 출력된다.

여기서는 이미 버킷이 만들어져 있는 경우를 가정하고 있다. BUCKET_NAME이라는 상수를 각자의 버킷에 맞춰 수정한 뒤 다시 ZIP 파일을 업로드해 테스트해보자. 테스트를 실행하면 Access Denied 에러와 함께 실패할 것이다.

Lambda 함수는 기본적으로 S3에 접근할 권한이 주어져있지 않다. 그렇기 때문에 S3에 쓰기를 하니 에러가 나는 것이다. 이를 해결하기 위해서는 S3 쓰기 권한을 얻어야 하고, 권한을 얻기 위해서는 Role을 설정해야 한다.

Lambda에서 S3에 쓰기 권한을 주는 Role은 미리 템플릿으로 정의되어 있지 않으므로 직접 만들어야 한다. AWS IAM 콘솔에 들어간 뒤 아래와 같은 절차를 밟아서 Role을 만들면 된다.

IAM Create Role Screenshot

1) Roles > Create new role을 클릭한 뒤,

IAM Select Rolt Type Screenshot

2) Select role type > AWS Lambda를 선택한다.

IAM Attach Policy Screenshot

3) Policy NameAWSLambdaExecute인 정책을 찾아 선택한 후 다음 스텝으로 넘어간다.

4) 이름을 짓고 Create role 버튼을 클릭해 Role을 만든다.

Role을 만든 뒤에는 다시 Lambda 콘솔로 돌아와서 Configuration > Role에서 Choose an existing role을 선택한 뒤, Existing role에서 방금 만든 Role을 선택하고 저장하면 된다. 저장한 뒤, 알맞는 테스트 데이터를 입력해 테스트해보면 아까와 같은 권한 에러가 나지 않고 성공하는 것을 볼 수 있다. S3 버킷에서 실제로 파일이 작성되었는지도 확인해보자.

Next

코드를 수정하고, ZIP 파일을 올리는 과정을 몇 번 반복하다 보면 조금 귀찮아지고, 이런 것들을 좀 더 편하게 할 수 있는 방법을 찾게 된다. 물론 이미 Setup이나 Deploy를 돕는 툴이 나와있다. Node.js를 지원하는 것으로는 node-lambdaApex라는 툴이 있는데 node-lambda는 단일 함수만 관리할 경우 큰 불편없이 사용할 수 있지만, 여러개의 함수를 관리하기는 좀 버겁다. Apex는 여러 개의 함수를 관리하는 데 특화되어 있고, 사용자의 수도 훨씬 많다. 다음 글에서는 Apex의 기본적인 사용법과 더불어, TypeScript로 된 코드베이스에서 Deploy하는 법을 다룬다.

다음 글: AWS Lambda: Apex로 관리하기


  1. 1.Configuration > Handler 항목을 수정하면 바꿀 수 있다.