AWS Step Functions은 시각적 워크플로우를 사용해 분산 애플리케이션 및 마이크로서비스의 구성 요소를 손쉽게 조정하도록 해주는 웹 서비스입니다. 각각 기능 또는 작업을 수행하는 개별 구성 요소를 사용하여 애플리케이션을 구축하면 애플리케이션을 빠르게 확장하거나 변경할 수 있습니다.
AWS에 있는 여러 컴퓨팅 자원들을 일련의 단계(Step)으로 시각화할 수 있는 AWS 서비스. 알아듣기 쉽게 설명하자면, AWS에 있는 여러 컴퓨팅 자원 등의 수행되는 순서를 설정할 수 있다고 보면 된다.
간단한 예제를 통해 이 서비스가 왜 필요하고, 어떻게 사용되는 지를 이해해보자.
우리가 간단한 결제 시스템을 만들어야 한다고 하자. 이 시스템의 요구 사항은 다음과 같다.
당신이 AWS와 마이크로서비스(MSA)에 익숙하다면, 금방 구조를 떠올릴 수 있을 것이다.
하지만 여기서 새로운 요구사항이 들어온다고 가정한다.
Step Functions를 쓰지 않는다면, 1번 요구사항을 해결하려면 결제 요청을 검증하는 Lambda 함수가 실제 결제를 실행하는 람다를 호출해야 한다.
2번 요구 사항은 1번 요구 사항에 비해 간단해 보인다. 결제 Lambda에 "borrow" 등의 새로운 명령에 대응하는 로직을 추가하는 것으로 해결할 수 있으니까. 하지만 추가되는 명령이 한 개가 아니라 여러 개라면 어떨까? 또는, 새로 추가되는 명령들이 각각 다른 라이브러리를 요구하고 그 라이브러리들을 모두 한 람다 함수에 담을 수 없다면 어떨까? (AWS Lambda의 용량 제한이 발목을 잡는다면 AWS Fargate라는 것을 사용해서 해결할 수 있지만 여기서는 논외로 한다)
이런 경우에 AWS Step Functions를 통해 문제를 해결할 수 있다. 람다 함수가 2개(람다 A, 람다 B)가 있고, A가 실행된 후에 B가 실행되도록 워크플로우를 설정할 수 있다면, 1번 문제를 해결 할 수 있다. 2번 문제의 경우에도 간단히 해결할 수 있다. 새 명령은, 그 명령만 해결하는 람다 함수를 새롭게 만들면 된다.
실제 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은 그 자체로는 새로운 서비스가 아니다. 서비스와 서비스 사이의 관계를 설정해 워크플로우를 만드는 서비스다. 유식하게 말하자면,
AWS Step Functions는 각 단계가 이전 단계의 출력으로 입력되는 단계로 구성된 워크 플로우를 설계하고 실행할 수 있도록 함으로써, 작업을 보다 쉽게 조정할 수 있게 하는 완전 관리형 서비스다.
간단하게 말하자면, 각 단계를 정점으로 생각하고 그 정점간의 관계를 그래프로 그려 표현한 것을 수행할 수 있는 서비스라고 보면 되겠다.
각 단계는 State라 불리는데, 이들은 각자의 Type 등으로 자신의 어떤 명령을 수행하는지를 나타낸다. 그 외에도 State는 여러가지 값을 가진다.
State Type는 여러 종류가 있다.
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" 이외에도 여러가지 값을 지정해 다른 동작을 일으킬 수 있다.
TheTake의 워크플로우를 살펴보자.
이 워크플로우는 Start에서 하나의 Input을 받아, 그 Input에 따라 VendorA, VendorB, VendorC, ScreenScrapeState 중 어느 작업을 수행할 것인지 판단해 수행한 후, UpdateProduct를 수행하고 종료하는 워크플로우를 나타낸다.
위는 ChoiceState를 코드로 나타낸 것이다. 이 JSON이 가지고 있는 속성들에 대해서 하나하나 살펴보자.
실제로 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"}를 반환받아야 한다. 실제로 실행해보자.
실행 세부 정보에서 입력과 출력 탭을 클릭해서 값이 제대로 나오는지 검증해보자.
성공이다!