카테고리 없음

AWS SAM과 AWS SAR를 위한 Nested application

카니슈카 2020. 12. 29. 12:05

배경

서버리스 어플리케이션 아키텍처들은 커다란 프로젝트를 좀 더 작게, 그리고 더욱 관리하기 쉬운 서비스 형태로, 즉 재사용성이 높고 확장성과 보안이 뛰어난, 시간이 지날수록 진화가 용이한 형태로 만들어 준다. 서버리스 아키텍처의 성숙도가 커감에 따라, 공통적인 패턴들을 뽑아낼 수가 있었다. 

 

AWS에서는 새로운 서버리스 형태의 아키텍처를 좀 더 쉽게 개발할 수 있도록 만들어왔고, 그 예로 AWS SAM과 SAR를 통한 nested application에 대한 지원을 들 수 있다.

 

어떻게 동작하는가?

Nested application은 nested stack이라고 불리우는 CloudFormation의 개념으로부터 만들어졌다. nested application을 통해, 서버리스 어플리케이션들은 마치 stack처럼 혹은 리소스의 집합으로 배포된다. 이러한 nested template에서 생성된 리소스들을 상위(parent) 스택이나 다른 nested stack에 참조하여 이러한 리소스 컬렉션들을 보다 쉽게 관리할 수 있다.

 

위의 그림과 같이, nested application을 사용하면 서버리스 아키텍처를 좀 더 정교하게 만들 수 있다. 각각의 서비스가 독립적으로 유지 및 작성됨으로 인해 재활용이 쉽고, 더 나아가 AWS SAM과 SAR를 통해 보다 손 쉽게 작성이 가능해졌다. 이러한 어플리케이션들은 AWS SAR에서 공개 혹은 비공개로 사용될 수 있다. 나만의 서버리스 어플리케이션들은 생성한 다음에 추후 다른 nested application에서 재사용하는 게 굉장히 쉬워졌다. 개발자는 어플리케이션 코드에 접근할 수 있으며, nested application 템플릿을 통해 노출된 파라미터들을 설정하면서, 그러한 설정들을 지속적으로 관리할 수가 있다.

 

Nested application 작성하기

AWS Lambda와 API Gateway를 통해 서버리스 어플리케이션 기반 API를 제공한다고 가정해 보자. AWS SAM을 통해 람다 함수 생성, API Gateway 설정, 배포 및 관리를 할 수가 있다.

 

아래는 sam init 명령어를 통해 초기화하는 과정을 보여준다.

$ sam init -r python2.7
[+] Initializing project structure...
[SUCCESS] - Read sam-app/README.md for further instructions on how to proceed
[*] Project initialization is now complete

 

sam-app 디렉토리는 아래와 같이 서버리스 어플리케이션을 구축하는데 필요한 모든 것들을 담고 있다.

$ tree sam-app/
sam-app/
├── hello_world
│   ├── app.py
│   ├── app.pyc
│   ├── __init__.py
│   ├── __init__.pyc
│   └── requirements.txt
├── README.md
├── template.yaml
└── tests
    └── unit
        ├── __init__.py
        ├── __init__.pyc
        ├── test_handler.py
        └── test_handler.pyc
        
3 directories, 11 files

 

sam build 명령어를 통해 내가 만든 서버리스 어플리케이션을 빌드할 수가 있다.

$ cd sam-app/
$ sam build
2018-11-21 20:41:23 Building resource 'HelloWorldFunction'
2018-11-21 20:41:23 Running PythonPipBuilder:ResolveDependencies
2018-11-21 20:41:24 Running PythonPipBuilder:CopySource

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml
...

 

아래는 local에서 실행하는 방법을 보여준다.

$ cd .aws-sam/build/
$ sam local invoke --no-event
2018-11-21 20:43:52 Invoking app.lambda_handler (python2.7)

....trimmed output....

{"body": "{\"message\": \"hello world\", \"location\": \"34.239.158.3\"}", "statusCode": 200}

 

그 외에 sam local start-api, sam package, sam deploy 등과 같은 명령어를 통해서 내가 만든 어플리케이션을 조작할 수가 있다.

 

이렇게 만들어진 아주 기본적인 서버리스 어플리케이션에 보안 목적으로 인증 메카니즘을 넣는다고 가정해보자. API Gateway에서는 인증을 위한 몇 가지 방법들을 제공하고 있으며, 여기서는 HTTP Basic Auth 기본 형태를 사용하려고 한다. 만들어진 API에 대해 최고의 보안을 제공하는 게 아닐지라도, 여기서는 nested application에 대한 이해를 돕고자 위와 같은 인증 방법을 사용해서 진행하려고 한다.

 

시작하기에 앞서, 아래와 같이 AWS SAR에서 "http basic auth"를 검색해서 기존에 이미 존재하는 서버리스 어플리케이션이 있는 지 확인해보자.

보는 바와 같이 HTTP Basic Auth 어플리케이션이 존재한다.

 내용은 간단하다. HTTP Request의 authorization 헤더 안에 있는 내용을 가지고서, DynamoDB에 해당 username과 password가 존재하는 지 확인하는 절차를 통해서 인증 과정을 진행한다.

 

자, 그러면 내가 이전에 만든 API 어플리케이션과 HTTP Basic Auth을 인증하는 위 어플리케이션을 어떻게 합쳐서 하나의 서버리스 어플리케이션으로 구축할 수 있을까?

 

먼저, AWS::Serverless::Application 을 보면, 아래와 같이 표현할 수 있다.

application-alias-name:
  Type: AWS::Serverless::Application
  Properties:
    Location:
    Parameters:

여기서, Location부분을 아래와 같이 몇 가지 방식을 통해 넣을 수 있다. (SAR, S3 등)

Location:
  ApplicationId: arn:aws:serverlessrepo:region:account-id:applications/application-name
  SemanticVersion: 1.0.0
Location: https://s3.region.amazonaws.com/bucket-name/sam-template-object

Parameters는 nested application에서 필요로 하는 파라미터들을 넣을 수 있도록 설정이 가능하다.

위 HTTP Basic Auth는 파라미터가 없기 때문에, 현재로써는 필요가 없다.

 

아래는 전체적으로 구성된 SAM 템플릿을 나타낸다.

 

아래 SAR로 가서 Copy as SAM Resource를 클릭해보자.

버튼을 클릭하면, 위 어플리케이션을 nested 시킬 수 있도록, 아래와 같이 SAM Resource가 클립보드에 저장된다.

lambdaauthorizerbasicauth:
  Type: AWS::Serverless::Application
  Properties:
    Location:
      ApplicationId: arn:aws:serverlessrepo:us-east-1:560348900601:applications/lambda-authorizer-basic-auth
      SemanticVersion: 0.2.0

 

자, 그럼 위에 인증 방식을 API Gateway에 연동시켜보도록 하자!

아래 내용은 HTTP 요청에서 Authorization 헤더를 기준으로 HTTP Basic Auth 람다 함수를 동작시키도록 연결한 내용이다.

MyApi:
  Type: AWS::Serverless::Api
  Properties:
    StageName: Prod      
    Auth:
      DefaultAuthorizer: MyLambdaRequestAuthorizer
      Authorizers:
        MyLambdaRequestAuthorizer:
          FunctionPayloadType: REQUEST
          FunctionArn: !GetAtt lambdaauthorizerbasicauth.Outputs.LambdaAuthorizerBasicAuthFunction
          Identity:
            Headers:
              - Authorization

 

아래 내용은 내가 만든 API 람다 함수를 위에 작성한 API Gateway에 연결시키는 템플릿이다.

Events:
   HelloWorld:
      Type: Api
      Properties:
        Method: get
        Path: /hello
        RestApiId: !Ref MyApi
        Auth:
          Authorizers: MyLambdaRequestAuthorizer

 

sam deploy를 실행시키면 아래와 같이 2개의 어플리케이션을 볼 수 있다.

위 화면에서 보이는 2번째 어플리케이션 스택이 HTTP Basic Auth에 대한 처리를 진행하는 nested application이다. 여기서 중요하게 바라봐야할 점은 람다함수가 아니라 Application이 2개로 구성되어 있다는 점이다.

 

첫 번 째 SimpleAuthExample에 대한 내용을 좀 더 자세히 보기 위해 클릭해보자. 그러면, 아래와 같은 화면을 볼 수가 있다.

 

여기서 Logical ID 중, lambdaauthorizerbasicauth를 선택하면, 아래와 같은 화면을 볼 수 있다. 해당 리소스는 실제로 HTTP Basic Auth를 처리하는 람다함수와 username과 password를 포함하고 있는 DynamoDB Table로 구성되어 있는 것을 볼 수 있다.

 

결론

서버리스 어플리케이션을 사용하여 서비스를 구축하는 일이 많아지고, 서버리스 어플리케이션에 대한 방법 및 아키텍처 등도 함께 성장함에 따라, AWS에서는 개발자들이 서버리스 기반으로 서비스를 구축함에 있어, 공통적인 패턴들을 공유하고 재사용하려는 시도가 많아지고 있다. 그리고, 공통 패턴 기반 어플리케이션들은 다른 사람들과 공개적으로 공유하거나 프라이빗하게 개인만 사용 가능하도록 요구하는 부분이 생겨나고 있다.

 

그래서, AWS에서는 2018년 초에 Serverless Application Repository (SAR)을 통해서 사용자들의 이러한 요구 사항을 충족시켜주었으며, nested application은 개발자들이 어플리케이션을 작성할 때, 재사용 가능한 어플리케이션의 사용을 손 쉽게 제공해줄 수 있는 기능을 제공하고 있다. 

 

이 블로그를 통해서 AWS SAR에서 어플리케이션을 어떻게 찾는 지, 그리고 찾은 어플리케이션을 어떠한 방식으로 nested application으로 만들어서 내가 만든 기존 서버리스 어플리케이션에 통합하여 사용할 수 있는 지를 알 수 있다.