[AWS] Lambda 사용법 및 예제

[AWS] Lambda 사용법 및 예제

안녕하세요? 정리하는 개발자 wonizz 입니다. 금번 시간에는 severless하면 제일 먼저 떠오르는 lambda 서비스에 대해서 알아보는 시간을 갖도록 하겠습니다.

서버리스가 초기 도입된 이유는 무엇보다 개발적인 관점에서 코드에만 집중하고 인프라는 Managed에게 맡기자! 라는 생각으로 나왔습니다. 서버리스인 이름에서부터 느껴지듯이 실제 서버가 없는 것처럼 생각이 됩니다.

개발자는 코드에만 집중을 할 수 있지만 실제 배포를 하게 되면 뒷단에서는 VM장비가 올라갈것이고, 해당 소스를 배포해주는 작업이 이루어질 것입니다.

Lambda 서비스에 작성한 비즈니스 로직을 올려놓고 HTTP 요청이나 AWS 내의 이벤트가 발생하면 해당 코드가 실행되는 구조이다.
가격은 월별 1백만 회, 400,000GB-초의 컴퓨팅 시간까지는 무료이다.

1. lambda 생성해보기

AWS Console 에 접속하여 서비스 > Lambda로 접속합니다.

필자는 Seoul Region을 사용하기 때문에 위의 url로 접속을 합니다.

Create function을 클릭하면 위와 같이 type이 노출이 됩니다.

  • 새로작성 : 신규로 function 을 직접 작성한다.
  • 블루프린트 사용 : 샘플 예제 형식으로 customize하여 사용할 수 있다.
  • 리포지토리 사용 : 외부 repository를 가져와서 사용할 수 있다.

필자는 lambda와 sns를 연계하여 mailing 을 해주는 간단한 예제를 만들어보려고 합니다.

여기서는 새로 작성을 누르고 넘어갑니다.

람다의 기본 정보를 입력해주는 내용입니다.

  • 함수 이름 : Deploy_Notice_Mailing_Lambda
  • Runtime 정보 : Node.js 8.10
  • 역할 mapping : 기존 역할 사용(lamda-to-sns : 필자가 생성한 역할)

역할 같은 경우는 lamda가 갖을 수 있는 역할이라고 보시면 됩니다. 가령 내부적으로 S3에 접근을 한다면 역할안에 권한들이 있어야 호출이 가능하게 됩니다.

2. lamda 소스 작성

필자는 sns 를 연계해서 메일링을 해주는 함수를 작성하기 떄문에 내부에서 aws 에서 제공해주는 sns 메서드를 이용해서 사용합니다.

console.log("Loading function");
var AWS = require("aws-sdk");

exports.handler = function(event, context, callback) {
    //var eventText = JSON.stringify(event, null, 2);

    var subject;
    var msg;
    var module;
    var stage;
    var group;
    var arn;

    module = event.queryStringParameters.module;
    stage = event.queryStringParameters.stage;
    group = event.queryStringParameters.group;
    var response = {
        "statusCode": 200,
        "body": JSON.stringify(event),
        "isBase64Encoded": false,
        "headers": {
            "Access-Control-Allow-Origin": "*"
        }
    };
    //1. 모듈
    if('B2C,B2B,SEMI,LED,SUPPORT'.indexOf(module) ==-1){
        response.statusCode = 500;
        response.body.result = "fail!";
            callback(null, response);
            return 0;
    }

    //2. 타겟 그룹
    if(group == 'SEC') arn = "arn:aws:sns:ap-northeast-2:194506033013:Deploy-Notice-Mailing"
    else if(group == 'Ninefive') arn = "arn:aws:sns:ap-northeast-2:194506033013:Deploy-Notice-Mailing"
    else if(group == 'Pivot') arn = "arn:aws:sns:ap-northeast-2:194506033013:Deploy-Notice-Mailing"
    else {
        response.statusCode = 500;
        response.body.result = "fail!";
        callback(null, response);
        return 0;
    }

    subject = 'AEM '+module+' '+stage+' 배포완료';
    msg = 'AEM '+module+' '+stage+' 배포완료 되었습니다';

    var sns = new AWS.SNS();
    sns.publish(
            {TopicArn:"arn:aws:sns:ap-northeast-2:240462130582:Deploy-Notice-Mailing", Message:msg, Subject:subject}
            , function(err,data){
            if (err){
                    console.log("Error sending a message "+err);
            }else{
                    console.log("Sending Email succeeded");
            }
    });


    response.body.evresult = "success!";
    callback(null, response);
};

그럼 소스를 하나씩 분석해보도록 하겠습니다.

  1. aws-sdk 삽입
var AWS = require("aws-sdk");

아마존에서 제공해주는 sns 메서드를 사용하기 위해서 sdk를 include 해줍니다.
만약 node.js 의 다른 npm 모듈이 필요하다면, 직접 s3같은 곳에 넣고 참조 해주어야 합니다. 람다는 기본적으로 인라인 편집 기능 말고도 zip 파일 업로드와 s3 버킷을 통한 파일 업로드를 지원한다.

  1. 이벤트 핸들러
exports.handler = function(event, context, callback) 

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

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

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

​ event 같은 경우, 파라미터 정보를 담고 있다.

    module = event.queryStringParameters.module;
    stage = event.queryStringParameters.stage;
    group = event.queryStringParameters.group;

​ context 같은 경우, 람다 시스템 정보를 담고 있다.

​ callback 같은 경우, return 문과 동일하게 사용된다.

callback(null, response);

3. API Gateway 연동하기

람다 함수를 만들었으니, 외부에서 호출을 할 수 있도록, Api Gateway연동을 해야 합니다.
Api Gateway같은 경우, 손쉽게 api 시스템을 구축할 수 있도록 도와주는 역할을 합니다.

중간에서 모든 처리를 담아서 URI기준으로 각 서비스(람다, EC2 ..) 로 연결을 해줍니다.

api gateway역시 아마존 콘솔에서 서비스 > api gateway로 손쉽게 접속 할 수 있습니다. 필자 같은 경우는 lamda함수 앞에 Deploy_Notice_Mailing으로 시작하는 Api gateway를 생성해두었습니다.

기본적인 설정에 대해서 정리해보겠습니다.

보시는것처럼 작업 > 메서드 생성 을 클릭하여 한가지 메서드를 생성해줍니다.

뒤쪽에는 Lambda를 연결해야 하므로 아래의 작업을 수행해줍니다.

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

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

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

  • Resource : uri 를 지정합니다.
  • Method: 하위로 어떠한 method를 사용할지 지정합니다.

여기까지 되었으면, 이제 api 승인을 위해 키를 셋팅합니다.

API KEY를 생성한 뒤, lambda의 method 요청에서 key를 필수로 지정합니다.

이제 API gateway를 배포해야합니다. 위의작업까지는 셋팅을 해줬고 실질적으로 운영환경에서 사용할 수 있도록 배포를 해주어야 합니다.

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

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

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

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

드디어!, api gateway – lamda가 정상적으로 연결이 되었습니다.

4. Client 에서 호출

api gateway를 통해서 클라이언트에서 api를 호출하여 동작하는 것을 보도록 하겠습니다.

 var titletext = $('.current-project').text();
    // 1. 정기 배포, 핫픽스 인경우만 진행 
    if(titletext.indexOf("정기") != -1){
                var selectedOption = $('#issue_status_id option:selected').text(); // Deployed
                var selectedTarget = $('.value').eq(6).text(); // LED
                var selectedGroup  = $('.value').eq(9).text(); // Pivot
                // 2. 현재값 취득해서 Deployed로 변경되는 경우만, 메일 발송 
                $('#issue_status_id').change(function(){
                    selectedOption = $('#issue_status_id option:selected').text(); // Deployed
                    console.log(selectedOption)
                })
            $('input[type=submit').eq(1).click(function(){
                if(selectedOption.indexOf("Deployed") !=-1) {
                    //3. 값이 모두 맞다면, 1) 배포대상 2) 상태 3) 타겟 잡아서 sns api 호출 
                    module=B2C&target=author&group=SEC
                    var parameter = "module="+ selectedTarget + "&stage="+selectedOption.split('- ')[1] + "&group=" + selectedGroup;
                    $.ajax({
                        type:"GET",
                        url : "https://jxkgpkgnui.execute-api.ap-northeast-2.amazonaws.com/prod/Deploy_Notice_Mailing_Lambda/sendmail?module=B2C&target=author&group=SEC",
                        beforeSend : function(xhr){
                            xhr.setRequestHeader("x-api-key", "AJiRKQYL7G8zZBYvh1PBM9d6DfrcrSwN1ApeFle7")            
                        },
                        success: function(data){
                            console.log(data);
                        },
                        error: function(xhr, status, error) {
                            console.log(error);
                        }  
                    });
                }
            })
    }

위의 전체 내용중 실질적으로는 아래의 2가지 내용이 중요합니다.

  • API 호출
https://jxkgpkgnui.execute-api.ap-northeast-2.amazonaws.com/prod/Deploy_Notice_Mailing_Lambda/sendmail
  • header에 키값 셋팅
beforeSend : function(xhr){
xhr.setRequestHeader("x-api-key", "AJiRKQYL7G8zZBYvh1PBM9d6DfrcrSwN1ApeFle7") 
}

위의 2가지를 통해서,

client 동작 -> api gateway -> lambda -> sns 호출 -> 메일링 의 동작을 수행합니다.

필자가 속한 프로젝트에서는 레드마인 동작(client)를 통해서 work flow가 진행될때 마다 메일링 연계를 통해서 배포 현황을 제 3자에게 공유를 하고 있습니다.

5.마치며..

이번시간에는 람다API Gateway에 대해서 알아봤습니다. 아마존의 서비스들을 사용하면서 느끼는 점은 정말 간단하게 서비스들을 만들고 여러가지 아마존의 서비스 끼리의 연계가 잘되어있어, 편리하게 구성할 수 있다는 점에 놀랐습니다. 람다를 통해서 비지니스 로직을 넣어 어플리케이션의 동작도 수행할 수 있고 그 외에 간단한 웹서비스도 가능하기에 정말 편리한 것 같습니다.

다음 이시간에는 아마존의 RDS 서비스에 대해서 알아보는 시간을 갖도록 하겠습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다