본문 바로가기

Application Service/Step Functions

AWS Step Functions 이해

AWS Step Functions은 AWS Lambda 및 Amazon ECS의 워크플로우를 연결하여 Serverless 서비스의 설계를 명확하고 유연하게 만들어준다.

 

특히 많은 데이터들을 Lambda를 통해 처리할 때 Lambda의 제한 시간 900초는 부족하다...

Lambda의 Invoke를 사용해서 분산 API를 구성할 수 있지만 유지보수가 힘들어지고, Invoke의 Timeout도 고려해야 한다. (https://aws.amazon.com/ko/premiumsupport/knowledge-center/lambda-function-retry-timeout-sdk/)

 

그럴 때 Step Function을 고려해 볼만하다.

- AWS Step Functions을 사용하면 Serverless의 가시성이 확보되어 서비스를 빠르게 빌드하고 업데이트 할 수 있다. 

- Lambda Function들을 유기적으로 연결하여 오류와 예외처리를 쉽게 할 수 있다.

- 각 단위 Function들의 결합으로 코드를 간결하게 개발할 수 있다.

 

그럼 오늘은 간단한 샘플을 통해 Step Functions의 튜토리얼을 진행한다.

Step Functions

위 그림과 같이 AWS Step Functions을 이용하여 간단한 구매, 환불 스크립트를 샘플로 진행한다.

샘플은 아래 링크를 참고했다.

 

djg07’s gists

GitHub Gist: star and fork djg07's gists by creating an account on GitHub.

gist.github.com

 

 

1. Lambda Function 생성

 

이제 AWS Web Console에서 Lambda를 선택하고 Function을 생성해준다.

Lambda Functions 생성

Author from scratch: 사용자가 직접 개발

Use a blueprint: AWS의 샘플 예제

Browse serverless app repository: 사용자들이 만든 다양한 소스가 있는 repository

Role의 경우 Create a new role with basic Lambda permissions을 사용하여 생성할 수 있다. 나같은 경우 이미 Lambda Role이 생성되어 있기 때문에 Use an existing role을 선택했다.

 

Lambda 코드의 경우 1. ZIP 파일을 직접 업로드, 2. S3에 저장된 파일 사용, 3. 직접 Lambda IDE에서 코딩할 수 있다.

Handler의 경우 '파일명'.'메인Function명' (e.g lambda_function.process_purchase) 형식으로 기입한다.

샘플 스크립트는 아래와 같다.

from __future__ import print_function
import json
import urllib
import boto3
import datetime

print('Loading function...')

def process_purchase(message, context):
    # Input Example
    # {'TransactionType': 'PURCHASE'}
    # 1. Log input message
    print("Received message from Step Functions: ")
    print(message)
    
    #2. Construct response object
    response = {}
    response['TransactionType'] = message['TransactionType']
    response['Timestamp'] = datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S")
    response['Message'] = 'Hello from lambda land inside the ProcessPurchase function'
    
    return response

message를 받아서 message에 따라 response 값을 정해주는 간단한 예제이다. context의 경우 Function의 상태 값을 알 수 있다.

 

아래 그림과 같이 다양한 파라미터가 있는데, 파라미터의 정의를 알아보자.

Environment variables: 환경변수 설정이다. 기존 env 값이라고 생각하면 된다.

Tags: 그냥 태그..

Basic settings: Lambda의 Memory와 Timeout 설정(Maxium 3GiB, 15분)

Network: VPC 내에 Lambda를 넣어 Private 한 환경에서 사용할 수 있다.

AWS X-Ray: Lambda의 성능을 측정할 수 있다. (processing time 등 확인)

Concurrency: Lambda의 동시 실행 개수를 정의할 수 있다. (기본은 1,000 소프트리밋임!)

 

그럼 샘플코드를 입력하고 Save 한다.

 

구매(purchase)에 대한 샘플코드를 만들었으니, 이제 환불(refund)에 대한 샘플코드를 입력한다.

from __future__ import print_function

import json
import urllib
import boto3
import datetime

print('Loading message function...')

def process_refund(message, context):

    #1. Log input message
    print('Received message from Step Function:')
    print(message)
    
    #2. Construct response
    response = {}
    response['TransactionType'] = message['TransactionType']
    response['Timestamp'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    response['Message'] = 'Hello from Refund Processor!'
    
    #3. Return response
    print(response)
    
    return (response)

 

그리고 각 Function에 대한 ARN 값을 저장한다. ARN은 Amazon Resource Name의 약자로 이름 그대로 각 AWS의 리소스에 대한 이름을 정의한다.

ARN

 

2. Step Functions

Step Functions을 생성하기 앞서 IAM Role을 생성한다. IAM -> Role -> Create 

Step Functions Role 생성

IAM Role의 경우 AWS의 Resource에 권한을 주는 것이다. 가령, Step Functions이 Lambda를 제어해야 한다면 위와 같이 Step Functions을 선택하고, Policy에 AWSLambdaRole 권한을 추가한다. 디폴트(Deafult)로 Lambda Policy가 입력된다.

 

그럼 이제 Step Functions을 생성한다.

 

Step Functions을 기존 생성한 Lambda을 제어하기 위해 아래와 같이 States라는 json 값을 넣어준다. Resource 값은 여러분이 생성한 Lambda Functoins의 ARN 값을 넣는다.

{
  "Comment": "A simple AWS Step Functions state machine that automates a call center support session.",
  "StartAt": "ProcessTransaction",
  "States": {
    "ProcessTransaction": {
        "Type" : "Choice",
        "Choices": [ 
          {
            "Variable": "$.TransactionType",
            "StringEquals": "PURCHASE",
            "Next": "ProcessPurchase"
          },
          {
            "Variable": "$.TransactionType",
            "StringEquals": "REFUND",
            "Next": "ProcessRefund"
          }
      ]
    },
     "ProcessRefund": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-2:557652101750:function:ProcessRefund",
      "End": true
    },
    "ProcessPurchase": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-2:557652101750:function:ProcessPurchase",
      "End": true
    }
  }
}

참고: Step Functions States 관련

 

Amazon States 언어 - AWS Step Functions

Amazon States 언어 Amazon States 언어은 작업을 수행할 수 있는 상태 시스템(상태 모음)을 정의하거나(Task 상태), 다음으로 전환할 상태를 결정하거나(Choice 상태), 오류를 표시하며 실행을 중지하는 등(Fail 상태)의 작업을 정의하는 데 사용되는 JSON 기반의 구조화된 언어입니다. 자세한 내용은 Amazon States Language Specification 및 Statelint(Amazon States Language

docs.aws.amazon.com

Type에는 Pass, Choice, Wait, Succeed, Fail, Parallel, Map 과 같은 조건을 줄 수 있다.

Variable의 경우 Input의 값을 넣어준다. (e.g $.TransactionType)

Varialbe에 따라 Next Process를 정의한다. 

 

위 JSON 값을 Step Functions 생성 시 넣어준다.

Step Functions States json

그럼 위 그림과 같이 가시적으로 Step Functions의 구조를 볼 수 있다.

 

Next를 진행한다. 그리고 Configure settings에서는 기존에 생성한 IAM Role을 입력하고 Step Functions을 생성한다.

 

그 뒤에 Start execution에서 아래와 같은 JSON을 입력한다.

{
	"TransactionType": "PURCHASE"
}

Lambda의 Test 와 같이 INPUT 값을 지정해주는 것이다.

 

그럼 아래와 같이 Test에 대한 결과 값을 볼 수 있다.

Step Functions Result

Input "TransactionType": "PURCHASE" 의 경우 왼쪽 다이어그램과 같이 ProcessPurchase에 전달되고 실제 Lambda의 결과 Output 값을 확인할 수 있다.

 

그럼 Input은 어떻게 줄 수 있을까? 이것은 Lambda와 동일하다. Lambda의 경우 Input을 CloudWatch Event, S3 Trigger Event 그리고 API Gateway로 받을 수 있는데, Step Functions의 경우 S3를 제외하고 CloudWatch Event, API G/W로Input에 대한 Trigger를 구성할 수 있다.

 

Step Functions의 경우 AWS Document에 잘 정리되어 있다. 내용이 많기 때문에 간단한 샘플을 구성한 뒤에 필요한 워크플로우에 따라 아래 링크를 참고해서 구성하자.

https://docs.aws.amazon.com/ko_kr/step-functions/latest/dg/step-functions-dg.pdf

 

3. 결론

Step Functions을 이용하여 Serverless를 통한 간단한 모듈을 구현해봤다. 최근 AWS의 오픈소스들은 대부분 Serverless 환경으로 배포되고 있다. Serverless 환경의 파워풀한 강점은 리소스 유지/보수가 필요 없는 것이다.

 

Step Functions을 통해 Serverless 환경으로 거의 모든 로직을 구현할 수 있는데, 그러기 위해서는 Step Functions의 States 문법을 익혀야 한다. 실제 프로젝트를 진행하며 필요한 부분을 습득하고 구현하는 것을 권장한다.

 

또한 Step Functions도 API Gateway 와 연동되긴 하나, 몇 시간을 구글링 해도 참고할만한 자료가 존재하지 않는다. 

 

그나마 외국 블로거가 API Gateway -> Lambda -> Step Functions과 같은 기이한(?) 형태를 추천해주는데, 자료도 부족한 API Gateway -> Step Functions을 삽질하는 것보단 나은 선택이 될 수도 있을 것 같다.

 

AWS Step Functions Tutorial

What are step functions?

foobar123.com

 

 

아 물론 나도 해보진 않았다.