Simply put a nested workflow is a workflow within a workflow… workflow-ception! It is a feature requested of AWS Step Functions for a long time now and it was recently released (read the blog post: here). The core problem users were finding with Step Functions was they had no way of re-using workflows, if you had two workflows A and B and B needed to do everything A did and a little more it would make sense for B to use A and then do it’s little bit afterwards, right? Well that wasn’t possible (without a lot of scrappy workarounds) until now.
In this article I am going to dive in to the new nested workflows feature.This article assumes you are reasonably comfortable with AWS Step Functions and know the foundations of how to use it. Calling nested workflows is done using an AWS Step Functions integration state that specifies the StateMachineArn of the state machine to execute.
If you want a quick refresher on AWS Step Functions then I recommend the video below. After you watch this video you should have the basic knowledge required for this article.
I also highly recommend reading the AWS Step Functions developer guide which can be found here.
If you don’t wait to wait for a nested workflow to finish before continuing your own then you can call a nested workflow asynchronously and proceed with the rest of the parent workflow.
This is perfect for any workflows that you want to run in the background while another parents workflow runs, for example you could have a parent workflow for uploading images and a child workflow for resizing the image and storing it in different formats.
An example state that starts a state machine and immediately move on is given below.
If you need to wait for a nested state machine to finish executing before proceeding with the parent state machine then you need to start the nested state machine synchronously. There are two ways of doing this, right now we will cover the first.
The call is essentially completely the same as the asynchronous call except we add in .sync to the end of the Resource value. This indicates to Step Functions to pause the current execution of the parent workflow until the child workflow either succeeds or fails.
The .sync method is also the only method where the output of the child state machine execution is automatically returned to the parent state machine.
This is the second, more in-depth, way of performing a synchronous nested workflow call. It uses an already established pattern within AWS Step Functions known as the callback service integration pattern. In short this pattern allows you to issue a task token to a service you are calling and then pauses the execution of the calling state machine until a call to SendTaskSuccess or SendTaskFailure is made using the task token by the child service.
There are two main advantages to this pattern over the previous .sync method:
- Heartbeats: You can use the task token to call SendTaskHeartbeat allowing your child workflow to indicate to the parent workflow it is still running. This allows you to ensure your parent workflow is never halted on a stuck child workflow by setting a HeartbeatSeconds timeout value. For example if HeartbeatSeconds is 30 then you expect a heartbeat call from the child workflow every 30 seconds or else you declare the execution a failure.
- You don’t have to wait for the whole child: Any state in the child workflow can call SendTaskSuccess or SendTaskFailure, meaning if for example you only need to reach state 3 out of 5 in the child workflow before restarting the parent workflow you can do exactly that. Alternatively your last step can make the call, effectively emulating the .sync method.
You can see below the special task token value being passed as input to the child workflow as part of the context object (specified by $$). See here for how to access the context object.
Step Functions has added a new special parameter to allow you to track what workflow started the execution of another workflow, this parameter is called AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID.
This special parameter can be accessed in the child workflow that gets started by accessing the special context object that Step Functions exposes.