Search code examples
amazon-web-servicesaws-api-gatewayaws-step-functions

How to invoke an AWS Step Function using API Gateway


How do I invoke an AWS Step Function using an API Gateway POST request, and the request's JSON payload to the Step Function ?


Solution

  • 1. Create your step function

    Quite obvious. I guess that if you're reading this you know how to do it.

    Otherwise, you can go have a look at the documentation here: What is AWS Step Functions?.


    2. Create the IAM Role for your API

    It can be for either all Step Functions, or only this one. We'll only cover the first case, as explained in an Amazon tutorial: Creating an API Using API Gateway.

    To create the IAM role

    • Log in to the AWS Identity and Access Management console.

    • On the Roles page, choose Create New Role.

    • On the Set Role Name page, type APIGatewayToStepFunctions for Role Name, and then choose Next Step.

    • On the Select Role Type page, under Select Role Type, select Amazon API Gateway.

    • On the Attach Policy page, choose Next Step.

    • On the Review page, note the Role ARN, for example:

    • arn:aws:iam::123456789012:role/APIGatewayToStepFunctions

    • Choose Create Role.

    To attach a policy to the IAM role

    • On the Roles page, search for your role by name (APIGatewayToStepFunctions) and then choose the role.
    • On the Permissions tab, choose Attach Policy.
    • On the Attach Policy page, search for AWSStepFunctionsFullAccess, choose the policy, and then choose Attach Policy.

    3. Setup

    3.a If you don't have a JSON payload

    As explained by Ka Hou Ieong in How can i call AWS Step Functions by API Gateway?, you can create an AWS Service integration via API Gateway Console, like this:

    • Integration Type: AWS Service
    • AWS Service: Step Functions
    • HTTP method: POST
    • Action Type: Use action name
    • Action: StartExecution
    • Execution role: role to start the execution (the one we just created. Just paste it's ARN)
    • Headers:

      X-Amz-Target -> 'AWSStepFunctions.StartExecution'
      Content-Type -> 'application/x-amz-json-1.0'

    • Body Mapping Templates/Request payload:

      {
          "input": "string" (optional),
          "name": "string" (optional),
          "stateMachineArn": "string"
      }
      

    3.b If you do have JSON payload to pass as an input

    Everything is the same as in 2.a, except for the body mapping template. You have to do is make it into a string. Using $util.escapeJavascript(), like this for example. It will pass your whole request's body as an input to your Step Function

        #set($data = $util.escapeJavaScript($input.json('$')))
        {
            "input": "$data",
            "name": "string" (optional),
            "stateMachineArn": "string" (required)
        }
    

    Notes

    • stateMachineArn: If you do not want to have to pass the stateMachineArn as part of your requests to API Gateway, you can simply hard-code it inside your Body Mapping Template (see AWS API Gateway with Step Function)
    • name: Omitting the name property will have API Gateway generate a different one for you at each execution.

    Now, this is my first "Answer your own question", so maybe this is not how it's done, but I did spend quite a few hours trying to understand what was wrong with my Mapping Template. Hope this will help save other people's hair and time.