Amazon Web Services 한국 블로그

AWS SAM Local (베타) – 로컬 기반 서버리스 앱 테스트 및 개발 도구

오늘 신규 서버리스(Serverless) 개발 도구 인 SAM Local 베타 버전을 발표했습니다.이 도구를  통해 로컬에서 쉽게 작성하고 테스트 할 수 있습니다. 이 글에서는 SAM local을 사용하여, 개발자들이 코드 개발 시, 탭 혹은 스페이스 선호도 투표 할 수 있는 빠른  애플리케이션을 빌드, 디버그 및 배포하는 예제를 소개해 드리고자 합니다. AWS는 작년에 Serverless Application Model (SAM)을 소개하고, 이를 통해 서버리스 애플리케이션을 쉽게 배포 할 수 있습니다.  SAM은 AWS CloudFormation을 기반으로 하는 강력한 오픈 소스 기반 인프라 코드 구현 모델 입니다. 로 유지하기가 쉽고 가장 멋진 마스코트를 갖추고 있습니다.

SAM Local은 SAM의 아래와 같은 장점을 로컬 시스템으로 가져와서 사용 가능합니다.

SAM Local을 설치하는 데에는 몇 가지 방법이 있지만 가장 쉬운 방법은 NPM을 사용하는 것입니다. npm install -g aws-sam-local 명령을 사용하거나, 최신 버전을 원하면 github.com/awslabs/aws-sam-local (aws-sam-local  바이너리)에서 설치 가능합니다..

개발자들이 코드 개발 시, 탭 혹은 스페이스 선호도 투표 할 수 있는 빠른  애플리케이션을 API Gateway 및 AWS Lambda를 통해 만든 후, 이를 DynomoDB에 저장합니다. https://SOMEURL/ -d '{"vote": "spaces"}' 같은 간단한 엔드포인트가 될 것이고, 아래와 같은 간단한 SAM 템플릿 파일로 정의할 수 있습니다.

YAML
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  VotesTable:
    Type: "AWS::Serverless::SimpleTable"
  VoteSpacesTabs:
    Type: "AWS::Serverless::Function"
    Properties:
      Runtime: python3.6
      Handler: lambda_function.lambda_handler
      Policies: AmazonDynamoDBFullAccess
      Environment:
        Variables:
          TABLE_NAME: !Ref VotesTable
      Events:
        Vote:
          Type: Api
          Properties:
            Path: /
            Method: post

그래서  TABLE_NAME이라는 환경 변수를 통해 Lambda 함수에 드러내는 [dynamo_i] 테이블을 생성합니다. 이 템플릿이 유효한지 테스트하기 위해 sam validate를 호출하여, Valid를 반환 받으면 됩니다.

아래는 우리가 사용할 Lambda 함수 코드입니다.

Python
import os
import os
import json
import boto3
votes_table = boto3.resource('dynamodb').Table(os.getenv('TABLE_NAME'))

def lambda_handler(event, context):
    print(event)
    if event['httpMethod'] == 'GET':
        resp = votes_table.scan()
        return {'body': json.dumps({item['id']: int(item['votes']) for item in resp['Items']})}
    elif event['httpMethod'] == 'POST':
        try:
            body = json.loads(event['body'])
        except:
            return {'statusCode': 400, 'body': 'malformed json input'}
        if 'vote' not in body:
            return {'statusCode': 400, 'body': 'missing vote in request body'}
        if body['vote'] not in ['spaces', 'tabs']:
            return {'statusCode': 400, 'body': 'vote value must be "spaces" or "tabs"'}

        resp = votes_table.update_item(
            Key={'id': body['vote']},
            UpdateExpression='ADD votes :incr',
            ExpressionAttributeValues={':incr': 1},
            ReturnValues='ALL_NEW'
        )
        return {'body': "{} now has {} votes".format(body['vote'], resp['Attributes']['votes'])}

이제 로컬에서 테스트 해 봅시다. 실제 DynamoDB 데이터베이스를 만들어야 하고 환경 변수 TABLE_NAME을 통해 해당 데이터베이스의 이름을 제공해야 합니다. env.json 파일을 사용하여 본 작업을 수행 할 수 있습니다. 또는, 명령 줄에서 호출해서 만들 수 있습니다.

$ echo '{"httpMethod": "POST", "body": "{\"vote\": \"spaces\"}"}' |\
TABLE_NAME="vote-spaces-tabs" sam local invoke "VoteSpacesTabs"

Lambda 함수를 테스트하기 위해, sam local generate-event api  API를 사용하여 샘플 이벤트를 생성하고 이를 로컬 호출에 전달할 수 있습니다.  sam local start-api 을 통해 로컬 엔드 포인트를 말아서 모든 것을 테스트 할 수 있습니다.

$ curl -d '{ "vote": "tabs"}'http://127.0.0.1:3000/

그러면 다음과 같이 “tabs now has 12 votes”을 반환합니다.  만약 DynamoDB에 대한 로컬 테스트를 원하시면, DynamoDB Local 을 다운로드하고, 아래와 같이 로컬에서 시작할 수 있습니다.

 java -Djava.library.path =. / DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb

이제 Lambda 함수가 AWS_SAM_LOCAL 환경 변수를 사용하여 어떻게 행동할지 결정할 수 있습니다. 우리 함수를 약간 수정 해 봅시다.

Python
import os
import json
import boto3
if os.getenv("AWS_SAM_LOCAL"):
    votes_table = boto3.resource(
        'dynamodb',
        endpoint_url="http://docker.for.mac.localhost:8000/"
    ).Table("spaces-tabs-votes")
else:
    votes_table = boto3.resource('dynamodb').Table(os.getenv('TABLE_NAME'))

이제는 로컬 엔드 포인트를 사용하여 로컬 데이터베이스에 연결하므로 무선 랜 없이도 쉽게 작업 할 수 있습니다.

SAM local은 대화형 디버깅을 지원합니다. Java 및 Node.js에서 -d 플래그와 포트를 전달하여 디버거를 즉시 사용할 수 있습니다. 파이썬의 경우 import epdb; 와 같은 라이브러리를 사용할 수 있습니다. epdb.serve() 를 호출하고, sam local invoke -d 8080 "VoteSpacesTabs" 를 통해 디버거를 단계별로 실행하게 됩니다.

이제 먼저 aws cloudformation package의 별칭인 sam package 명령을 호출 한 다음이 명령의 결과를 sam deploy에 사용합니다.

$ sam package --template-file template.yaml --s3-bucket MYAWESOMEBUCKET --output-template-file package.yaml
Uploading to 144e47a4a08f8338faae894afe7563c3  90570 / 90570.0  (100.00%)
Successfully packaged artifacts and wrote output template to file package.yaml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file package.yaml --stack-name 
$ sam deploy --template-file package.yaml --stack-name VoteForSpaces --capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - VoteForSpaces

이를 통해 API Gateway가 만들어집니다.

아래는 서비스가 라이브가 된 모습입니다. http://spaces-or-tabs.s3-website-us-east-1.amazonaws.com/

SAM Local 을 사용하면 서버리스 애플리케이션을 쉽게 테스트, 디버그 및 배포 할 수 있습니다. 본 소스 코드에 공헌하시려면, CONTRIBUTING.md 가이드 문서를 참고해 주시고, 좀 더 자세한 것은 기술 문서를 참고해 주시기 바랍니다.

Randall

이 글은 New – AWS SAM Local (Beta) – Build and Test Serverless Applications Locally의 한국어 번역 편집입니다.