[version_1.0]

© 2021 Amazon Web Services, Inc. or its affiliates. All rights reserved. This work may not be reproduced or redistributed, in whole or in part, without prior written permission from Amazon Web Services, Inc. Commercial copying, lending, or selling is prohibited. Corrections, feedback, or other questions? Contact us at https://support.aws.amazon.com/#/contacts/aws-training. All trademarks are the property of their owners.

Note

The exercises in this course will have an associated charge in your AWS account. In this exercise, you will create the following resource:

The final exercise includes instructions to delete all the resources created in the exercises.

Familiarize yourself with AWS Step Functions pricing and the AWS Free Tier.

Lab 5: AWS Step Functions

In this lab, you will complete the POST method of your application programming interface (API). You have already created the AddDragon, and ValidateDragon AWS Lambda functions. An AWS Step Functions state machine is created to build a workflow for the Lambda functions.

Task 1: Finding AWS Lambda ARNs

In this task, you find the Amazon Resource Names (ARNs) for the AddDragon and ValidateDragon AWS Lambda functions. ARNs are used to uniquely identify resources. They are used across all of AWS when you specify a resource, such as in an AWS Identity and Access Management (IAM) policy. For more information, see Amazon Resource Names.

  1. In a PowerShell window, list the ARNs by using the following AWS Command Line Interface (AWS CLI) command. The --query parameter uses JMESPath syntax to filter the output to only the ARNs.

    aws lambda list-functions --query 'Functions[].FunctionArn'

    Alternatively, you can list the same information with the PowerShell cmdlet.

    get-lmfunctionlist | select FunctionName,FunctionArn
  2. Note the ARNs of the AddDragon and ValidateDragon functions. They will look similar to this example: arn:aws:lambda:us-east-1:123456789012:function:AddDragon

Task 2: Creating the Step Functions workflow

  1. Log in to the AWS Management Console as the BuildingModernAppsUser IAM user.

  2. In the console, choose Services > Step Functions.

  3. Make sure that you are in the N. Virginia Region.

  4. If you don’t have any existing state machines, you will see a Get Started screen. You can ignore this option and choose the ☰ menu icon (on the top-left area of the window), then choose State machines.

  5. Choose Create state machine.

  6. Scroll down to the Definition. You will see a sample workflow in Amazon States Language.

    Replace the sample workflow with the following JavaScript Object Notation (JSON) code. Replace the REPLACE_WITH_ValidateDragon_ARN and REPLACE_WITH_AddDragon_ARN placeholders with the respective ARNs from the previous section.

    {
      "Comment": "Dragon will be validated. If validation fails, a failure message will be sent. If the dragon is valid, it will be added to the data and a success message will be sent.",
      "StartAt": "ValidateDragon",
      "States": {
        "ValidateDragon": {
          "Type": "Task",
          "Resource": "REPLACE_WITH_ValidateDragon_ARN",
          "Catch": [
            {
              "ErrorEquals": [
                "DragonValidationException"
              ],
              "Next": "AlertDragonValidationFailure",
              "ResultPath": null
            },
            {
              "ErrorEquals": [
                "States.ALL"
              ],
              "Next": "CatchAllFailure"
            }
          ],
          "Next": "AddDragon",
          "ResultPath": null
        },
        "AlertDragonValidationFailure": {
          "Type": "Task",
          "Resource": "arn:aws:states:::sns:publish",
          "Parameters": {
            "Message": "The dragon you reported failed validation and was not added.",
            "PhoneNumber.$": "$.reportingPhoneNumber"
          },
          "End": true
        },
        "CatchAllFailure": {
          "Type": "Fail",
          "Cause": "Something unknown went wrong."
        },
        "AddDragon": {
          "Type": "Task",
          "Resource": "REPLACE_WITH_AddDragon_ARN",
          "Next": "ConfirmationRequired",
          "ResultPath": null
        },
        "ConfirmationRequired": {
          "Type": "Choice",
          "Choices": [
            {
              "Variable": "$.confirmationRequired",
              "BooleanEquals": true,
              "Next": "AlertAddDragonSuccess"
            },
            {
              "Variable": "$.confirmationRequired",
              "BooleanEquals": false,
              "Next": "NoAlertAddDragonSuccess"
            }
          ],
          "Default": "CatchAllFailure"
        },
        "AlertAddDragonSuccess": {
          "Type": "Task",
          "Resource": "arn:aws:states:::sns:publish",
          "Parameters": {
            "Message": "The dragon you reported has been added!",
            "PhoneNumber.$": "$.reportingPhoneNumber"
          },
          "End": true
        },
        "NoAlertAddDragonSuccess": {
          "Type": "Succeed"
        }
      }
    }

    On the right side, a graph diagram of your workflow steps will appear.

    Workflow diagram
  7. Choose Next.

  8. For State machine name, enter: DragonsStateMachine

  9. For Permissions > Create new role, keep the default settings.

    The Step Functions console will create an AWS Identity and Access Management (IAM) role for you that allows publishing for AWS X-Ray and Amazon Simple Notification Service (Amazon SNS). The role also allows invoking Lambda for the two functions.

  10. Choose Create state machine.

  11. Note the ARN of the new state machine. It will look similar to this example: arn:aws:states:us-east-1:123456789012:stateMachine:DragonsStateMachine

Task 3: Creating a policy and a role in IAM

In this task, you will create a policy named dragons-apig-policy, attached to an API Gateway role named dragons-apig-role. The dragons-apig-policy policy uses the following policy JSON code.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "states:StartExecution",
            "Resource": "*"
        }
    ]
}

If you are familiar with IAM roles, you might want to try completing this section before you use the step-by-step instructions.

Expand for step-by-step instructions.
  1. In the navigation pane, choose Policies.

  2. Choose Create policy.

  3. Choose the JSON tab.

  4. In the editor text box, replace the sample policy with the following JSON code:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "states:StartExecution",
                "Resource": "*"
            }
        ]
    }
  5. Choose Next: Tags.

  6. Choose Next: Review.

  7. For Name, enter: dragons-apig-policy

  8. Choose Create policy.

  9. On the navigation pane, choose Roles.

  10. Choose Create role.

  11. For Select type of trusted entity, scroll and select API Gateway.

  12. Choose Next: Permissions.

  13. Choose Next: Tags.

  14. Choose Next: Review.

  15. For Role name, enter: dragons-apig-role

  16. Choose Create role.

  17. In the search box, enter dragons-apig-role and choose the search result.

  18. Copy the Role ARN to a file for future reference.

  19. In the Permissions tab, choose Attach policies.

  20. In the search box, enter: dragons-apig-policy

  21. Select dragons-apig-policy.

  22. Choose Attach policy.

Task 4: Updating the POST method of the REST API

In this task, you will update the POST method of the REST API so that it starts the execution of a Step Functions workflow. First, you will remove the mock integration that you are currently using in the POST method. You will then connect the method to the workflow for the Lambda functions.

  1. In the console, open the Amazon API Gateway dashboard by choosing Services > API Gateway.

  2. Choose the DragonsApp REST API.

  3. In the Resources navigation pane, select the /dragons resource POST method.

  4. Choose Integration Request.

  5. For Integration type, select AWS Service.

  6. For AWS Region, select us-east-1.

  7. For AWS Service, select Step Functions.

  8. For HTTP method, select POST.

  9. For Action Type, select Use action name.

  10. For Action, enter: StartExecution

  11. For Execution role, enter the role ARN for the dragons-apig-role that you created.

  12. Choose Save. When you are prompted with Are you sure you want to switch to a Lambda Proxy integration?, choose OK.

Task 5: Configuring the mapping template

In this task, you will set up a mapping template for the POST method of the REST API. The mapping template converts the POST body that you receive from the application to a body that the Step Functions StartExecution method understands.

This means updating the property names (such as changing dragonName to dragon_name_str), and including the state machine ARN as a parameter. The input parameter for StartExecution must be escaped so that it can be used in JavaScript Object Notation (JSON). For more information, see $util Variables.

  1. Expand the Mapping Templates section.

  2. For Request body passthrough, select When there are no templates defined.

  3. Choose Add mapping template.

  4. Under Content-Type, enter application/json and save the setting by choosing the check icon.

  5. Scroll down to the large text area and paste the following Apache Velocity Template Language (VTL) template. Replace REPLACE_WITH_STATE_MACHINE_ARN with the state machine ARN that you noted previously.

    #set($data = $input.path('$'))
    
    #set($input = " {
      ""dragon_name_str"" : ""$data.dragonName"",
      ""description_str"" : ""$data.description"",
      ""family_str"" : ""$data.family"",
      ""location_city_str"" : ""$data.city"",
      ""location_country_str"" : ""$data.country"",
      ""location_state_str"" : ""$data.state"",
      ""location_neighborhood_str"" : ""$data.neighborhood"",
      ""reportingPhoneNumber"" : ""$data.reportingPhoneNumber"",
      ""confirmationRequired"" : $data.confirmationRequired}")
    
    {
        "input": "$util.escapeJavaScript($input).replaceAll("\\'", "'")",
        "stateMachineArn": "REPLACE_WITH_STATE_MACHINE_ARN"
    }
  6. Choose Save.

Task 6: Re-enabling CORS and deploying the API

The changes to the POST method will remove the setting for Cross-Origin Resource Sharing (CORS) that you created previously. You will now follow the same instructions to apply CORS settings to your /dragons resource.

  1. In the Resources navigation pane, select your resource by choosing /dragons. Then, choose Actions > Enable CORS.

    You might need to scroll to the top of the window to find the Actions button.

  2. Choose Enable CORS and replace existing CORS headers.

  3. Confirm the action by choosing Yes, replace existing values.

  4. Choose the Actions button and select Deploy API.

  5. For Deployment stage, select prod.

  6. Choose Deploy.

Task 7: Testing in the web application

In this task, you will test the updated POST method from the web application. The POST method will start the execution of the Step Functions state machine. You can inspect the results of each execution in the Step Functions console.

  1. Visit the URL for your Dragons application. If you don’t have it bookmarked, the URL will be https://MYBUCKET.s3.amazonaws.com/dragonsapp/index.html. Make sure to replace MYBUCKET with the unique bucket that you created previously.

  2. The application remembers your Dragons Endpoint, Amazon Cognito domain, and Amazon Cognito Client ID. If these resources aren’t available, you can retrieve them from previous exercises.

  3. In the web application, choose Login. The login flow will update the Amazon Cognito ID token in your application.

  4. After you complete the login, choose Add. Enter the details for a new dragon, and choose POST /dragons. A successful POST operation will clear the form so that it is ready to enter another dragon. Now, use the POST method for an existing dragon name, such as Bahamethut.

  5. In the console, return to the Step Functions home, and choose Services > Step Functions.

  6. Choose the DragonsStateMachine state machine. You will see the two state machine executions for the calls to the POST method that were initiated from your web application.

  7. View both state machine executions and compare the graph diagrams for each one. Select the step in each diagram and observe the Details, Step input, and Step output tabs (where available).

    POST new dragon graph
    POST existing dragon graph
  8. Return to the web application, choose List, and then choose GET /dragons. You should see the newly added dragon in the results table.