AWS step function

DaeYoon Jin·2020년 3월 22일
2

AWS

목록 보기
1/1
post-thumbnail

AWS Step Functions

AWS Step Functions은 시각적 워크플로우를 사용해 분산 애플리케이션 및 마이크로서비스의 구성 요소를 손쉽게 조정하도록 해주는 웹 서비스입니다. 각각 기능 또는 작업을 수행하는 개별 구성 요소를 사용하여 애플리케이션을 구축하면 애플리케이션을 빠르게 확장하거나 변경할 수 있습니다.

AWS에 있는 여러 컴퓨팅 자원들을 일련의 단계(Step)으로 시각화할 수 있는 AWS 서비스. 알아듣기 쉽게 설명하자면, AWS에 있는 여러 컴퓨팅 자원 등의 수행되는 순서를 설정할 수 있다고 보면 된다.

간단한 예제를 통해 이 서비스가 왜 필요하고, 어떻게 사용되는 지를 이해해보자.

간단한 예제

우리가 간단한 결제 시스템을 만들어야 한다고 하자. 이 시스템의 요구 사항은 다음과 같다.

  • 결제 요청은 {"userid" : "yoonha", "command" : "buy", "item" : 1}의 JSON 형태로 들어온다. 편의상 결제 요청은 따로 웹 페이지를 거치지 않고, 클라이언트 앱 등으로 직접 들어온다고 가정한다.
  • userid는 유저를 나타내는 string이고, command는 "buy"(구매) 혹은 "sell"(판매)인 string이다. 예를 들어, 위의 결제 요청은 유저 "yoonha"가 1번 item을 구매한다는 것을 나타내는 JSON이다.
  • 올바르지 않은 결제 요청이 들어올 수 있다. 예를 들자면, DB에 존재하지 않는 item 혹은 userid가 들어올 수 있고, command에 "buy"나 "item" 이외의 string이 들어올 수 있다.

당신이 AWS와 마이크로서비스(MSA)에 익숙하다면, 금방 구조를 떠올릴 수 있을 것이다.

하지만 여기서 새로운 요구사항이 들어온다고 가정한다.

  1. 어떠한 이유로, 결제 요청이 올바른 결제 요청인지 검증하는 함수와 실제 결제를 실행하는 함수를 한 Lambda 함수 안에서 실행할 수 없다.
  2. "buy"나 "command" 이외에 새로운 명령이 추가될 수 있다. 예를 들면, 물건을 빌리는 명령인 "borrow"가 "buy"나 "sell" 외에 새로운 command로 들어올 수 있다.

Step Functions를 쓰지 않는다면, 1번 요구사항을 해결하려면 결제 요청을 검증하는 Lambda 함수가 실제 결제를 실행하는 람다를 호출해야 한다.

2번 요구 사항은 1번 요구 사항에 비해 간단해 보인다. 결제 Lambda에 "borrow" 등의 새로운 명령에 대응하는 로직을 추가하는 것으로 해결할 수 있으니까. 하지만 추가되는 명령이 한 개가 아니라 여러 개라면 어떨까? 또는, 새로 추가되는 명령들이 각각 다른 라이브러리를 요구하고 그 라이브러리들을 모두 한 람다 함수에 담을 수 없다면 어떨까? (AWS Lambda의 용량 제한이 발목을 잡는다면 AWS Fargate라는 것을 사용해서 해결할 수 있지만 여기서는 논외로 한다)

이런 경우에 AWS Step Functions를 통해 문제를 해결할 수 있다. 람다 함수가 2개(람다 A, 람다 B)가 있고, A가 실행된 후에 B가 실행되도록 워크플로우를 설정할 수 있다면, 1번 문제를 해결 할 수 있다. 2번 문제의 경우에도 간단히 해결할 수 있다. 새 명령은, 그 명령 해결하는 람다 함수를 새롭게 만들면 된다.

Step Functions의 실제 모습

실제 Step Functions은 아래의 형태로 나타내어진다.

{
  "Comment": "A Hello World example demonstrating various state types of the Amazon States Language",
  "StartAt": "Pass",
  "States": {
    "Pass": {
      "Comment": "A Pass state passes its input to its output, without performing work. Pass states are useful when constructing and debugging state machines.",
      "Type": "Pass",
      "Next": "Hello World example?"
    },
    ...
}

Step Function을 나타내는 형식에 대해서 자세히 알고 싶은 사람은 아마존 State 언어를 참조하자.

Step Functions의 구성 요소

Step Functions은 그 자체로는 새로운 서비스가 아니다. 서비스와 서비스 사이의 관계를 설정해 워크플로우를 만드는 서비스다. 유식하게 말하자면,

AWS Step Functions는 각 단계가 이전 단계의 출력으로 입력되는 단계로 구성된 워크 플로우를 설계하고 실행할 수 있도록 함으로써, 작업을 보다 쉽게 조정할 수 있게 하는 완전 관리형 서비스다.

간단하게 말하자면, 각 단계를 정점으로 생각하고 그 정점간의 관계를 그래프로 그려 표현한 것을 수행할 수 있는 서비스라고 보면 되겠다.

State

각 단계는 State라 불리는데, 이들은 각자의 Type 등으로 자신의 어떤 명령을 수행하는지를 나타낸다. 그 외에도 State는 여러가지 값을 가진다.

State Type는 여러 종류가 있다.

  • Task : 하나의 수행되는 작업을 의미한다. Lambda로 수행되는 작업일 수도 있고, Batch로 수행되는 작업일 수도 있다.
  • Choice : 다음에 어떤 State로 넘어갈 지 분기를 설정할 수 있다. Inputpath의 값에 따라 서로 다른 로직을 수행해야 할 때 사용된다.
  • Pararell : Branch들을 병렬적으로 실행할 때 사용된다. Branch에 두 State가 있다면, 이 State를 서로 독립적으로 병렬적으로 수행한다는 뜻이다.
  • Wait : "Seconds"에 지정된 초만큼 기다린다(딜레이된다).
  • Fail : 작업을 멈추고 이 작업을 실패로 표시한다.
  • Succeed : 작업을 멈추고 이 작업을 성공으로 표시한다.
  • Pass : 입력된 데이터를 그대로 출력한다.* Pass : 입력된 데이터를 그대로 출력한다.

Task의 설명

Task는 다음의 JSON 형태를 가진다.

{
   "FirstState":{
      "Type":"Task",
      "Resource":"arn:aws:lambda:xxx:function:crawling_slideshare",
      "Next":"NextState"
   }
}

위의 State는 "FirstSate"라는 이름을 가진 State로, "arn:aws:lambda:xxx:function:crawling_slideshare"의 리소스를 실행하고, 실행한 후에는 "NextState"라는 State를 실행한다는 뜻을 가진 State이다. 참고로 "Resource"와 "Next" 이외에도 여러가지 값을 지정해 다른 동작을 일으킬 수 있다.

Choice의 설명

TheTake의 워크플로우를 살펴보자.

이 워크플로우는 Start에서 하나의 Input을 받아, 그 Input에 따라 VendorA, VendorB, VendorC, ScreenScrapeState 중 어느 작업을 수행할 것인지 판단해 수행한 후, UpdateProduct를 수행하고 종료하는 워크플로우를 나타낸다.

위는 ChoiceState를 코드로 나타낸 것이다. 이 JSON이 가지고 있는 속성들에 대해서 하나하나 살펴보자.

  • Type : Choice, 이 State의 Type이 Choice라는 것을 나타낸다.
  • Choices : Array, 이 State가 여러 State 중 하나를 실행할 수 있다는 것을 나타낸다.
    • 각 State를 실행한 조건들을 JSON 하나로 나타낸다. {"Variable" : "$.productSource", "StringEquals" : "vendor-a", "Next" : "VendorA"}는 input["productSource"]이 "vendor-a"와 같은 경우에는 vendor-a라는 state를 실행하라는 것을 의미한다.
  • Defualt : Choices의 어느 조건에도 해당되지 않는 경우에는 Default에 지정된 State로 넘어가게 된다.

실제 사용

실제로 Step Functions를 사용해보자. 첫 번째로, 아래의 Lambda 함수를 만들고 배포하자.

import json

def lambda_handler(event, context): 
    if (event["name"] == "PSY"):
        return {"song" : "gangnam style"}

    else:
        return {"song" : "i dont know"}

이 함수를 배포해 이 함수의 ARN을 얻자.

그리고 또다른 람다 함수를 배포하고, ARN을 얻자.

import json

def lambda_handler(event, context):
    if (event["song"] == "gangnam style"):
        return {"lyrics" : "oh oh oh oh oh pan gangnam style"}
    else:
        return {"lyrics" : "i don't know"}

우리는 이 함수를 2개를 사용해 간단한 step function을 만들어 볼 것이다. step functions에서 다음 코드를 설정하자.

이 Step Functions에는 2개의 State("song"과 "lyrics")가 있다. "song"은 arn:aws:lambda-us-east-1:..." ARN이 나타내는 람다를 실행하고, 그 결과를 "lyrics"에게 반환하는 State다. "lyrics"는 마찬가지로 "arn:aws:lambda:us-east-1:..." ARN이 나타내는 람다를 실행하고, 종료하는 State다.

즉, 이 Step functions는 {"name" : "PSY"}면 {"lyrics" : "oh oh oh oh oh pan gangnam style"}을, {"name" : "PSY"} 이외의 "name"이면 {"lyrics" : "i don't know"}를 반환하는 Step functions라고 할 수 있다.

이 Step functions가 잘 동작하는지 확인하는 방법은 간단하다. {"name" : "PSY"}를 입력으로 주고 실행시켜, 올바른 값이 출력되는지 검증하면 된다. 실제로 이 Step functions에 입력을 주고 실행시켜보자.

{"name" : PSY}를 입력으로 주었으므로, 우리는 {"lyrics" : "oh oh oh oh oh-pan gangnam style"}를 반환받아야 한다. 실제로 실행해보자.

실행 세부 정보에서 입력과 출력 탭을 클릭해서 값이 제대로 나오는지 검증해보자.

성공이다!

요약

  • AWS Step Functions라는 것을 사용하면 여러 컴퓨팅 자원의 순서를 정해 순차적으로 실행할 수 있다. 원한다면, 병렬적으로도 할 수 있다.
  • Step Functions는 그래프를 통해 컴퓨팅 자원들의 구성을 볼 수 있어 편리하다.
    • 그래프에서 각 정점은 State라 불리고, Start에서 시작해 End에서 끝난다.
  • 각 State의 입력 출력은 JSON 형태로 관리되고, 입력 출력은 따로 정의할 필요 없이 JSON으로 처리한다고 생각하면 된다.

0개의 댓글