State Machine

Create an initial AWS Step Functions state machine

After the riders upload their photo, the first thing we need do in our processing pipeline is to run a face detection algorithm on it to verify that it has a recognizable face in the photo (zero or multiple faces in the photo doesn’t help unicorns recognize the rider) and the face is not wearing sunglasses (makes it harder to identify the rider). If these validations fail, notify the user and end the workflow.

The AWS Lambda function that implements this check by leveraging the Amazon Rekognition deep-learning based image analysis API is already deployed by AWS CloudFormation in the previous step. Look in the Outputs section for FaceDetectionFunctionArn for the ARN of the Lambda function.

The AWS Lambda function to be called when the validations fail is the NotificationPlaceholderFunction deployed by AWS CloudFormation. The intent behind this step is to notify the user the photo validation failed and the error reason, so they can try upload a different photo. It’s currently a stub implementation that just prepares the message instead of actually sending the message.

Now you can create an AWS Step Functions state machine with the initial face detection step.

initial state machine diagram
  1. AWS Step Functions state machine flows are defined by a JSON document. We will first create our state machine definition JSON file in our Cloud9 IDE.

  2. From within the Cloud9 editor, right-click the top-level image-processing-development folder and select New file

    New JSON definition creation - Step 1
  3. Next, name the flle rider-photo-state-machine.json and hit enter to save the file name.

    New JSON definition creation - Step 2
  4. Finally, double click the newly created rider-photo-state-machine.json file to open the Cloud9 text editor.

  5. Copy and paste the following into your JSON file:

    {
    	"Comment": "Rider photo processing workflow",
    	"StartAt": "FaceDetection",
    	"States": {
    		"FaceDetection": {
    			"Type": "Task",
    			"Resource": "REPLACE_WITH_FaceDetectionFunctionArn",
    			"ResultPath": "$.detectedFaceDetails",
    			"End": true,
    			"Catch": [
    				{
    					"ErrorEquals": [
    						"PhotoDoesNotMeetRequirementError"
    					],
    					"ResultPath": "$.errorInfo",
    					"Next": "PhotoDoesNotMeetRequirement"
    				}
    			]
    		},
    		"PhotoDoesNotMeetRequirement": {
    			"Type": "Task",
    			"Resource": "REPLACE_WITH_NotificationPlaceholderFunctionArn",
    			"End": true
    		}
    	}
    }	

    The above JSON defines a state machine using the Amazon States Language. Take a moment to understand its structure.

    When this state machine is launched, the AWS Step Functions interpreter begins execution by identifying the Start State. It executes that state, and then checks to see if the state is marked as an End State. If it is, the machine terminates and returns a result. If the state is not an End State, the interpreter looks for a “Next” field to determine what state to run next; it repeats this process until it reaches a Terminal State (Succeed, Fail, or an End State) or a runtime error occurs.

    The ResultPath parameter in the FaceDetection state causes the output of the state to be the union of the original input passed to the state and an additional detectedFaceDetails field that holds the output from the AWS Lambda function.

    The Catch parameter in the FaceDetection state can match custom error types thrown by the AWS Lambda function and change the flow of the execution based on the error type caught.

  6. Replace the REPLACE_WITH_FaceDetectionFunctionArn in the JSON with the ARN of the face detection AWS Lambda function.

    To find the ARN of the face detection AWS Lambda function, in the AWS CloudFormation Console, go to the wildrydes-step-module-resources stack, look in the Outputs section for FaceDetectionFunctionArn)

  7. Replace the REPLACE_WITH_NotificationPlaceholderFunctionArn in the JSON with the ARN of the AWS Lambda function that mocks sending user notifications.

    To find the ARN of the mock notification AWS Lambda function, in the AWS CloudFormation Console, go to the wildrydes-step-module-resources stack, look in the Outputs section for NotificationPlaceholderFunctionArn)

  8. From the AWS Management Console, choose Services then select Step Functions.

  9. You might see the following Get Started page if you have not used AWS Step Functions before. If that’s the case, click on the three horizontal lines in the top-left corner.

    Create Initial State Machine - Step 2
  10. Next, click State Machines.

    Create Initial State Machine - Step 3
  11. Next, click Create State Macine.

    Create Initial State Machine - Step 4
  12. Select Author with Code Snippets if it’s not already selected.

  13. Leave default setting of a “Standard” type.

    Create Initial State Machine - Step 5
  14. Highlight and replace all of the existing sample state machine definition JSON by pasting your custom state machine JSON definition from your rider-photo-state-machine.json file from Cloud9 into the Code editor portion.

  15. You can click on the ↺ sign in the preview panel to visualize the workflow:

    Create initial state machine
  16. Click Next.

  17. Type RiderPhotoProcessing for the state machine name.

  18. For IAM role for executions, pick Choose an existing role, and select the IAM role created by the CloudFormation in the previous step.

    The name of the IAM role should have the prefix wildrydes-step-modules-resources (the name of the CloudFormation stack) To verify the IAM role’s full name, you can open a new tab for the CloudFormation console and check the Output section of the stack you just created, and look for StateMachineRole.

    Select IAM role
  19. Click Create State Machine to create the state machine.

  20. Click the Start execution button to start a new execution.

  21. Here you specify the input data passed into the AWS Step Functions state machine to process.

    Each execution of a Step Functions state machine has an unique ID. You can either specify one when starting the execution, or have the service generate one for you. In the text field that says “enter your execution id here”, you can specify an execution ID, or leave it blank.

    For the input data, type in the follow JSON. Make sure to substitute the s3Bucket field with your own values.

    For s3Bucket field, look in the Outputs section of the wildrydes-step-module-resources stack for RiderPhotoS3Bucket.

    The userId field is needed because in later processing steps, the userId is used to record which user the profile picture is associated with.

    {
    	"userId": "user_a", 
    	"s3Bucket": "REPLACE_WITH_YOUR_BUCKET_NAME",
    	"s3Key": "1_happy_face.jpg"
    }	

    this tells the image processing workflow the userId that uploaded the picture and the Amazon S3 bucket and keys the photo is at.

    Test new execution
  22. You can now see the state machine execution in action. Explore the different tabs in the Console to see what information is available to you for this execution:

    First execution result
  23. Create another execution by passing in the s3 key of a photo that wears sunglasses. Notice how the execution differs:

    {
    	"userId": "user_b",
    	"s3Bucket": "REPLACE_WITH_YOUR_BUCKET_NAME",
    	"s3Key": "2_sunglass_face.jpg"
    }	
Sunglasses execution result