Amazon Web Services 한국 블로그

AWS Serverless Application Model(SAM) 명령줄 인터페이스 – 서버리스 앱 로컬 구축, 테스트 및 디버깅

오늘은 AWS Serverless Application Model(SAM) 신규 명령줄 인터페이스에 대해 설명을 드리고자 합니다. 설명을 드리면서 여러분도 AWS Lambda를 사용하여 뭔가를 만들 수 있는 자신감을 가질 수 있다면 좋겠군요. 먼저 용어를 정리해 보겠습니다.

AWS SAM은 Serverless Application Model의 약어로서, AWS에서 서버리스 애플리케이션을 구축할 때 사용할 수 있는 오픈 소스 프레임워크입니다. AWS SAM은 간단한 YAML 템플릿을 사용하여 애플리케이션(Lambda 함수, API 엔드포인트, DynamoDB 테이블 및 기타 리소스)을 설명하는 데 사용할 수 있는 단축 구문을 제공합니다. 배포 과정에 SAM은 단축 SAM 구문을 AWS CloudFormation 템플릿으로 변환 및 확장합니다. 그런 다음 CloudFormation이 신뢰적이고 반복 가능한 방식으로 리소스를 프로비저닝합니다.

이전에 SAM Local이라는 이름으로 알려졌던 AWS SAM CLI는 SAM 기반 애플리케이션의 구축을 지원하는 명령줄 인터페이스입니다. 로컬 개발 및 테스팅을 지원하는 AWS SAM CLI는 현재 진행 중인 오픈 소스 프로젝트이기도 합니다. Python, Node, Java, Go, .NET 중에서 선택할 수 있는 이 CLI는 시작하는 데 도움이 되는 광범위한 템플릿 컬렉션을 포함하고 있습니다.

SAM CLI의 sam local 명령은 Lambda와 유사한 실행 환경에서 함수 코드를 로컬로 실행하면서 Lambda 함수 및 SAM 기반 애플리케이션의 로컬 호출과 테스트에 대한 지원을 제공합니다. 또한 sam local 명령을 사용하여 샘플 페이로드를 로컬로 생성하고, API를 테스트하기 위해 로컬 엔드포인트를 시작하고, Lambda 함수의 테스트를 자동화할 수 있습니다.

설치 및 설정
SAM CLI를 사용하는 방법을 보여드리려면 먼저 패키지를 몇 가지 설치해야 합니다. sam local이 제공하는 함수는 Docker를 활용하므로 이번에는 모처럼 비가상화 환경에서 작업해야 합니다! 설정 절차의 개요는 다음과 같습니다.

DockerDocker for Windows의 커뮤니티 에디션(512MB 다운로드)을 설치하고 docker ps를 실행하여 정상적으로 작동하는지 확인합니다.

PythonPython 3.6을 설치하고 Windows PATH에 설치되었는지 확인합니다.

Visual Studio CodeVS Code 및 관련 Python 확장을 설치합니다.

AWS CLI – AWS CLI를 설치합니다.

그리고 자격 증명을 구성합니다.

SAMpip를 사용하여 AWS SAM CLI를 설치합니다.

이제 필요한 요소를 모두 설치했으므로 SAM을 본격적으로 살펴보겠습니다.

SAM CLI 사용
내 프로젝트를 위한 디렉토리(sam_apps)를 생성한 다음 sam init를 실행하여 첫 프로젝트를 생성합니다.

이 명령은 모든 필수 소스 및 구성 파일이 포함된 하위 디렉토리(sam-app)를 생성합니다.

hello_world 안에 build 디렉토리를 생성한 다음 requirements에 정의된 패키지를 설치합니다. build 디렉토리는 SAM Local에 의해 로드된 소스 코드 및 Python 패키지를 포함합니다.

그리고 마지막 단계로, 배포를 위해 소스 파일을 build 디렉토리에 복사해야 합니다.

앱(app.py 및 비어있는 __init__.py)이 준비되었으므로 로컬 엔드포인트를 시작합니다.

이 시점에서 엔드포인트는 포트 3000에서 HTTP 연결을 수신하며, 연결이 설정되면 Docker 컨테이너가 시작됩니다. build 디렉토리를 컨테이너에서 사용할 수 있으므로 Python 패키지를 로드하고 app.py의 코드를 실행할 수 있습니다.

브라우저에서 http://127.0.0.1:3000/hello를 열면, 필요한 컨테이너 이미지가 다운로드되고 코드가 실행되며 브라우저에 출력이 표시됩니다.

다음은 배경에서 어떤 작업이 실행되는지를 보여줍니다. 여기에서 코드 호출, 이미지 다운로드, build 디렉토리 마운팅 및 요청 로깅을 비롯한 주요 단계를 모두 볼 수 있습니다.

코드를 수정한 경우 브라우저 탭을 새로 고치면 새 버전을 실행할 수 있습니다.

편집/배포/테스트 주기는 놀랄만큼 빠르므로 그 어느 때보다 생산성이 높아집니다!

여기서 명심해야 할 매우 중요한 사항이 하나 있습니다. 최초의 app.py 파일은 hello_world 디렉토리에 생성되었으며 이 파일은 몇 단계 앞에서 build 디렉토리에 복사해 두었습니다. 이 배포 단계를 매번 반복하거나 build 디렉토리에 있는 코드를 원본으로 간주하고 이를 직접 편집할 수도 있습니다. 이 때 선택하는 옵션은 코드를 빌드하고 버전 지정하는 소스 코드 제어 계획에 영향을 미칩니다.

작동 구조
이제 샘플 코드가 실행되므로 SAM 템플릿(상상력을 발휘해 template.yaml이라고 부르겠습니다)을 살펴보겠습니다. 공간 절약을 위해 Resources 섹션으로 바로 건너뛰겠습니다.

Resources:

    HelloWorldFunction:
        Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
        Properties:
            CodeUri: hello_world/build/
            Handler: app.lambda_handler
            Runtime: python3.6
            Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
                Variables:
                    PARAM1: VALUE
            Events:
                HelloWorld:
                    Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
                    Properties:
                        Path: /hello
                        Method: get

이 섹션은 HelloWorldFunction을 정의하고, 이 함수를 찾을 수 있는 위치(hello_world/build/)와 실행 방법(python3.6)을 지정하고 환경 변수를 정의 및 설정합니다. 그런 다음 이 함수가 GET에 의해 지정 경로(/hello)에 생성된 HelloWorld 이벤트를 처리할 수 있음을 나타냅니다.

이 템플릿은 자동으로 재로딩되지 않습니다. 템플릿을 변경한 경우에는 SAM Local을 재시작해야 합니다. 여기에서 신중하게 이름과 경로를 변경하면서 어떤 오류가 발생하는지 관찰하는 것이 좋습니다. 이렇게 하면 배경에서 이루어지는 작업에 대한 이해를 높일 수 있으며 추후 생산성을 개선하는 데 도움이 됩니다.

템플릿의 나머지 부분은 템플릿의 출력(API 게이트웨이 엔드포인트, 함수의 ARN 및 함수의 IAM 역할)을 설명합니다. 이러한 값은 로컬 실행에 영향을 미치지 않지만 성공적인 배포를 위해 중요합니다.

Outputs:

    HelloWorldApi:
      Description: "API Gateway endpoint URL for Prod stage for Hello World function"
      Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"

    HelloWorldFunction:
      Description: "Hello World Lambda Function ARN"
      Value: !GetAtt HelloWorldFunction.Arn

    HelloWorldFunctionIamRole:
      Description: "Implicit IAM Role created for Hello World function"
      Value: !GetAtt HelloWorldFunctionRole.Arn

이 모든 값은 작동 구조를 충분히 이해할 때까지 그대로 두어도 됩니다.

SAM CLI 및 VS Code를 사용한 디버깅
이제 상호 작용 방식의 디버깅을 준비해 보겠습니다! 이 부분을 이해하는 데 시간이 좀 걸렸습니다. 제 경험이 여러분에게 도움이 될 수 있기를 바랍니다. 첫 번째 단계는 ptvsd 패키지를 설치하는 것입니다.

그런 다음 requirements.txt를 편집하여 앱에 ptvsd가 필요하다고 지정합니다(버전 번호는 위의 패키지 이름에서 복사했습니다).

requests==2.18.4
ptvsd==4.1.4

다음에는 pip를 다시 실행하여 이 새로운 요구 사항을 build 디렉토리에 설치합니다.

이제 디버깅을 할 수 있도록 코드를 수정해야 합니다. 이 코드는 기존의 import 뒤에 추가합니다.

import ptvsd
ptvsd.enable_attach(address=('0.0.0.0', 5858), redirect_output=True)
ptvsd.wait_for_attach()

첫 번째 명령문은 디버거가 포트 5858에 연결될 것을 앱에 알리고 두 번째 명령문은 디버거가 연결될 때까지 코드를 일시 중지합니다(이 명령에는 조건을 설정할 수 있습니다).

다음에는 VS Code를 시작하고 애플리케이션의 루트 폴더를 선택합니다.

이제 디버깅을 위해 VS Code를 구성해야 합니다. 디버그 아이콘을 선택하고 DEBUG 옆의 흰색 삼각형을 클릭한 다음 구성 추가를 선택합니다.

Python 구성을 추가하고 파일(launch.json) 내용 전부를 다음 텍스트로 대체하고 파일을 저장합니다(파일:저장).

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [

        {
            "name": "Debug with SAM CLI (Remote Debug)",
            "type": "python",
            "request": "attach",
            "port": 5858,
            "host":  "localhost",
            "pathMappings": [
                {
                "localRoot": "${workspaceFolder}/hello_world/build",
                "remoteRoot" : "/var/task"
                }
            ]
        }
    ]
}

이제 DEBUG 메뉴에서 이 디버그 구성을 선택합니다.

지금까지 잘 따라오셨나요? 이제 거의 끝났습니다!

SAM Local을 다시 시작하고 디버그 포트를 수신하도록 지정합니다.

VS Code로 돌아가 코드에 중단점을 설정합니다(추억의 F9).

build 디렉토리에 있는 app.py를 열고 여기에 중단점을 설정할 것을 명심하십시오.

이제 웹 브라우저로 돌아가 로컬 주소(http://127.0.0.1:3000/hello)로 다시 이동합니다. 컨테이너가 요청 처리를 시작하고 app.py를 실행합니다. 코드는 wait_for_attach 호출에 도달할 때까지 실행됩니다. 이제 VS Code에서 F5를 눌러 디버깅을 시작합니다.

중단점에 도달하면 requests.get 호출을 단계별로 진행하여 ip 변수를 검사합니다.

그런 다음 F5를 눌러 진행하면 웹 요청이 완료됩니다. 여기서 볼 수 있듯이 VS Code 디버거의 전체 기능을 사용하여 Lambda 함수를 구축하고 디버깅할 수 있습니다. 지금까지 설명드린 내용은 시작에 불과합니다. 여기서 그치지 말고 계속해서 다양한 기능을 확인하시기 바랍니다. 자세한 내용은 Test Your Serverless Applications Locally Using SAM CLI를 참조하십시오.

클라우드 배포
SAM CLI는 완성된 코드를 패키징하여 S3에 업로드하고 실행하는 데에도 도움이 됩니다. S3 버킷(jbarr-sam)을 시작하고 sam package를 실행합니다. 이는 배포 패키지를 생성하여 S3에 업로드합니다.

이 작업에는 몇 초 정도가 소요됩니다. 그런 다음 sam deploy를 실행하여 CloudFormation 스택을 생성합니다.

스택이 이미 존재하는 경우, SAM CLI는 Change Set를 생성하여 스택을 업데이트하는 데 사용합니다. 스택은 1~2분 내에 준비되고 Lambda 함수, API 게이트웨이 및 모든 지원 리소스를 포함합니다.

API 게이트웨이 엔드포인트는 스택 출력에서 찾을 수 있습니다.

그리고 코드를 로컬로 실행했을 때와 같이 브라우저에서 액세스할 수 있습니다.

sam logs를 사용하여 스택 및 함수에 대한 CloudWatch Logs도 액세스할 수 있습니다.

SAM 앱은 이제 Lambda 콘솔에서 볼 수 있습니다(이는 상당히 최근에 추가된 기능입니다).

한 눈에 템플릿과 앱의 리소스를 볼 수 있습니다.

그리고 리소스 간의 관계를 볼 수 있습니다.

모니터링 대시보드도 있습니다.

Amazon CloudWatch 대시보드를 템플릿에 추가하여 대시보드를 사용자 지정할 수 있습니다(자세한 내용은 Managing Applications in the AWS Lambda Console을 참조하십시오).

이것이 전부가 아닙니다
믿기지 않겠지만 지금까지 설명드린 것은 SAM, SAM CLI 및sam local 명령으로 할 수 있는 수많은 기능 중 아주 일부에 불과합니다. 다음은 알아두어야 할 몇 가지 멋진 기능입니다.

로컬 함수 호출 – Lambda 함수를 직접 호출할 수 있습니다.

샘플 이벤트 소스 생성 – 다른 AWS 서비스의 트리거(S3 PUT 등)에 응답하는 Lambda 함수를 작성하는 경우, 샘플 이벤트를 생성하여 함수를 호출하는 데 사용할 수 있습니다.

실제 상황에서는 출력을 파일로 리디렉션하고, 필요한 경우 추가적인 사용자 지정을 수행한 다음 이를 사용하여 함수를 호출할 것입니다.

Cookiecutter 템플릿 – SAM CLI는 Cookiecutter 템플릿을 사용하여 프로젝트를 생성할 수 있으며 시작을 돕기 위한 몇 가지 예제가 작성되어 있습니다. 자세한 내용은 Cookiecutter AWS Sam S3 Rekognition Dynamodb PythonAWS SAM and .NET용 Cookiecutter를 참조하십시오.

CloudFormation 확장 – AWS SAM은 CloudFormation을 확장하고 코드로서의 인프라가 제공하는 이점을 활용할 수 있도록 해 줍니다. 신뢰적이고 반복 가능한 배포를 구현할 수 있으며 CloudFormation 리소스 유형, 내장 함수 및 기타 템플릿 기능을 모두 사용할 수 있습니다.

기본 제공 모범 사례 – 코드로서의 인프라 모델이 제공하는 이점 외에도, 코드 검토, AWS CodePipeline을 통한 안전한 배포 및 AWS X-Ray를 사용한 추적을 포함하는 모범 사례를 쉽게 활용할 수 있습니다.

개발 도구와의 긴밀한 통합 – AWS SAM을 일련의 AWS 도구와 함께 사용하여 서버리스 애플리케이션을 구축할 수 있습니다. 새로운 애플리케이션은 AWS Serverless Application Repository에서 확인할 수 있습니다. SAM 기반 서버리스 애플리케이션의 작성, 테스트 및 디버깅을 위해서는 AWS Cloud9 IDE를 사용할 수 있습니다. 서버리스 애플리케이션을 위한 배포 파이프라인을 구축하려면 AWS CodeBuild, AWS CodeDeployAWS CodePipeline을 사용할 수 있습니다. 또한 AWS CodeStar를 사용하면 자동으로 구성된 프로젝트 구조, 코드 리포지토리 및 CI/CD 파이프라인을 사용할 수 있습니다. 서버리스 애플리케이션을 배포하려면 AWS SAM Jenkins 플러그인을 사용할 수 있으며 Stackery.io의 툴킷을 사용하여 프로덕션을 위한 애플리케이션을 구축할 수 있습니다.

Jeff;