Creating AWS serverless workflows using AWS SDK for JavaScript - AWS SDK for JavaScript

The AWS SDK for JavaScript V3 API Reference Guide describes in detail all the API operations for the AWS SDK for JavaScript version 3 (V3).

Creating AWS serverless workflows using AWS SDK for JavaScript

You can create an AWS serverless workflow by using Step Functions the AWS SDK for Java and AWS Step Functions. Each workflow step is implemented using an AWS Lambda function. Lambda is a compute service that enables you to run code without provisioning or managing servers. Step Functions is a serverless orchestration service that lets you combine Lambda functions and other AWS services to build business-critical applications.

Note

You can create Lambda functions in various programming languages. For this tutorial, Lambda functions implemented by using the Lambda Java API. For more information about Lambda, see What is Lambda.

In this tutorial, you create a workflow that creates support tickets for an organization. Each workflow step performs an operation on the ticket. This tutorial shows you how to use JavaScript to process workflow data. For example, you’ll learn how to read data that’s passed to the workflow, how to pass data between steps, and how to invoke AWS services from the workflow.

Cost to complete: The AWS services included in this document are included in the AWS Free Tier.

Note: Be sure to terminate all of the resources you create while going through this tutorial to ensure that you’re no longer charged.

Prerequisite tasks

To set up and run this example, you must first complete these tasks:

  • Set up the project environment to run these Node TypeScript examples, and install the required AWS SDK for JavaScript and third-party modules. Follow the instructions on GitHub.

  • Create a shared configurations file with your user credentials. For more information about providing a shared credentials file, see Shared config and credentials files in the AWS SDKs and Tools Reference Guide.

Create the AWS resources

This tutorial requires the following resources.

  • An Amazon DynamoDB table named Case with a key named Id.

  • An IAM role named lambda-support used to invoke Lambda functions. This role has policies that enable it to invoke the Amazon DynamoDB and Amazon Simple Email Service services from a Lambda function.

  • An IAM role named workflow-support used to invoke the workflow.

  • An Amazon S3 bucket to host the Lambda functions.

You can create these resources manually, but we recommend provisioning these resources using the AWS Cloud Development Kit (AWS CDK) (AWS CDK) as described in this tutorial.

Create the AWS resources using the AWS CloudFormation

AWS CloudFormation enables you to create and provision AWS infrastructure deployments predictably and repeatedly. For more information about AWS CloudFormation, see the AWS CloudFormation User Guide.

To create the AWS CloudFormation stack:

  1. Install and configure the AWS CLI following the instructions in the AWS CLI User Guide.

  2. Create a file named setup.yaml in the root directory of your project folder, and copy the content here on GitHub into it.

    Note

    The AWS CloudFormation template was generated using the AWS CDK available here on GitHub. For more information about the AWS CDK, see the AWS Cloud Development Kit (AWS CDK) Developer Guide.

  3. Run the following command from the command line, replacing STACK_NAME with a unique name for the stack.

    Important

    The stack name must be unique within an AWS Region and AWS account. You can specify up to 128 characters, and numbers and hyphens are allowed.

    aws cloudformation create-stack --stack-name STACK_NAME --template-body file://setup.yaml --capabilities CAPABILITY_IAM

    For more information on the create-stack command parameters, see the AWS CLI Command Reference guide, and the AWS CloudFormation User Guide.

Create the AWS resources using the Amazon Web Services Management Console;

To create resources for the app in the console, follow the instructions in the AWS CloudFormation User Guide. Use the template provided create a file named setup.yaml, and copy the content here on GitHub.

Important

The stack name must be unique within an AWS Region and AWS account. You can specify up to 128 characters, and numbers and hyphens are allowed.

View a list of the resources in the console by opening the stack on the AWS CloudFormation dashboard, and choosing the Resources tab. You require these for the tutorial.

Creating the workflow

The following figure shows the workflow you’ll create with this tutorial.

The following is what happens at each step in the workflow:

+ Start - Initiates the workflow.

+ Open Case – Handles a support ticket ID value by passing it to the workflow.

+ Assign Case – Assigns the support case to an employee and stores the data in a DynamoDB table.

+ Send Email – Sends the employee an email message by using the Amazon Simple Email Service (Amazon SES) to inform them there is a new ticket.

+ End - Stops the workflow.

Create a serverless workflow by using Step functions

You can create a workflow that processes support tickets. To define a workflow by using Step Functions, you create an Amazon States Language (JSON-based) document to define your state machine. An Amazon States Language document describes each step. After you define the document, Step functions provides a visual representation of the workflow. The following figure shows the Amazon States Language document and the visual representation of the workflow.

Workflows can pass data between steps. For example, the Open Case step processes a case ID value (passed to the workflow) and passes that value to the Assign Case step. Later in this tutorial, you’ll create application logic in the Lambda function to read and process the data values.

To create a workflow

  1. Open the Amazon Web Services Console.

  2. Choose Create State Machine.

  3. Choose Author with code snippets. In the Type area, choose Standard.

  4. Specify the Amazon States Language document by entering the following code.

    { "Comment": "A simple AWS Step Functions state machine that automates a call center support session.", "StartAt": "Open Case", "States": { "Open Case": { "Type": "Task", "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME", "Next": "Assign Case" }, "Assign Case": { "Type": "Task", "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME", "Next": "Send Email" }, "Send Email": { "Type": "Task", "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME", "End": true } } }
    Note

    Don’t worry about the errors related to the Lambda resource values. You’ll update these values later in this tutorial.

  5. Choose Next.

  6. In the name field, enter SupportStateMachine.

  7. In the Permission section, choose Choose an existing role.

  8. Choose workflow-support (the IAM role that you created).

  9. Choose Create state machine. A message appears that states the state machine was successfully created.

Create the Lambda functions

Use the Lambda runtime API to create the Lambda functions. In this example, there are three workflow steps that each correspond to each Lambda function.

Create these Lambda function, as described in the following sections:

  • getId Lambda function - Used as the first step in the workflow that processes the ticket ID value.

  • addItem Lambda class - Used as the second step in the workflow that assigns the ticket to an employee and stores the data in a DynamoDB database.

  • sendemail Lambda class - Used as the third step in the workflow that use the Amazon SES to send an email message to the employee to notify them about the ticket.

getId Lambda function

Create a Lambda function that returns the ticket ID value that is passed to the second step in the workflow.

exports.handler = async (event) => { // Create a support case using the input as the case ID, then return a confirmation message try{ const myCaseID = event.inputCaseID; var myMessage = "Case " + myCaseID + ": opened..."; var result = { Case: myCaseID, Message: myMessage }; } catch(err){ console.log('Error', err); } };

Enter the following in the command line to use webpack to bundle the file into a file named index.js.

webpack getid.js --mode development --target node --devtool false --output-library-target umd -o index.js

Then compress index.js into a ZIP file name getid.js.zip. Upload the ZIP file to the Amazon S3 bucket you created in the the topic of this example.

This code example is available here on GitHub.

addItem Lambda class

Create a Lambda function that selects an employee to assign the ticket, then stores the ticket data in a DynamoDB table named Case.

"use strict"; // Load the required clients and commands. const { PutItemCommand } = require ( "@aws-sdk/client-dynamodb" ); const { dynamoClient } = require ( "../libs/dynamoClient" ); exports.handler = async (event) => { try { // Helper function to send message using Amazon SNS. const val = event; //PersistCase adds an item to a DynamoDB table const tmp = Math.random() <= 0.5 ? 1 : 2; console.log(tmp); if (tmp == 1) { const params = { TableName: "Case", Item: { id: { N: val.Case }, empEmail: { S: "brmur@amazon.com" }, name: { S: "Tom Blue" }, }, }; console.log("adding item for tom"); try { const data = await dynamoClient.send(new PutItemCommand(params)); console.log(data); } catch (err) { console.error(err); } var result = { Email: params.Item.empEmail }; return result; } else { const params = { TableName: "Case", Item: { id: { N: val.Case }, empEmail: { S: "RECEIVER_EMAIL_ADDRESS" }, // Valid Amazon Simple Notification Services (Amazon SNS) email address. name: { S: "Sarah White" }, }, }; console.log("adding item for sarah"); try { const data = await dynamoClient.send(new PutItemCommand(params)); console.log(data); } catch (err) { console.error(err); } return params.Item.empEmail; var result = { Email: params.Item.empEmail }; } } catch (err) { console.log("Error", err); } };

Enter the following in the command line to use webpack to bundle the file into a file named index.js.

webpack additem.js --mode development --target node --devtool false --output-library-target umd -o index.js

Then compress index.js into a ZIP file name additem.js.zip. Upload the ZIP file to the Amazon S3 bucket you created in the the topic of this example.

This code example is available here on GitHub.

sendemail Lambda class

Create a Lambda function that sends an email to notify them about the new ticket. The email address that is passed from the second step is used.

// Load the required clients and commands. const { SendEmailCommand } = require ( "@aws-sdk/client-ses" ); const { sesClient } = require ( "../libs/sesClient" ); exports.handler = async (event) => { // Enter a sender email address. This address must be verified. const senderEmail = "SENDER_EMAIL" const sender = "Sender Name <" + senderEmail + ">"; // AWS Step Functions passes the employee's email to the event. // This address must be verified. const recepient = event.S; // The subject line for the email. const subject = "New case"; // The email body for recipients with non-HTML email clients. const body_text = "Hello,\r\n" + "Please check the database for new ticket assigned to you."; // The HTML body of the email. const body_html = `<html><head></head><body><h1>Hello!</h1><p>Please check the database for new ticket assigned to you.</p></body></html>`; // The character encoding for the email. const charset = "UTF-8"; var params = { Source: sender, Destination: { ToAddresses: [recepient], }, Message: { Subject: { Data: subject, Charset: charset, }, Body: { Text: { Data: body_text, Charset: charset, }, Html: { Data: body_html, Charset: charset, }, }, }, }; try { const data = await sesClient.send(new SendEmailCommand(params)); console.log(data); } catch (err) { console.error(err); } };

Enter the following in the command line to use webpack to bundle the file into a file named index.js.

webpack sendemail.js --mode development --target node --devtool false --output-library-target umd -o index.js

Then compress index.js into a ZIP file name sendemail.js.zip. Upload the ZIP file to the Amazon S3 bucket you created in the the topic of this example.

This code example is available here on GitHub.

Deploy the Lambda functions

To deploy the getid Lambda function:

  1. Open the Lambda console at Amazon Web Services Console.

  2. Choose Create Function.

  3. Choose Author from scratch.

  4. In the Basic information section, enter getid as the name.

  5. In the Runtime, choose Node.js 14x.

  6. Choose Use an existing role, and then choose lambda-support (the IAM role that you created in the ).

  7. Choose Create function.

  8. choose Upload from - Amazon S3 location.

  9. Choose Upload, choose Upload from - Amazon S3 location, and enter the Amazon S3 link URL.

  10. Choose Save.

  11. Repeat this procedure for the additem.js.zip and sendemail.js.zip to new Lambda functions. When you finish, you will have three Lambda functions that you can reference in the Amazon States Language document.

Add the Lambda functions to workflows

  1. Open the Lambda console. Notice that you can view the Lambda Amazon Resource Name (ARN) value in the upper-right corner.

  2. Copy the value and then paste it into step 1 of the Amazon States Language document, located in the Step Functions console.

  3. Update the Resource for the Assign Case and Send Email steps. This is how you hook in Lambda functions created by using the AWS SDK for Java into a workflow created by using Step Functions.

Execute your workflow by using the Step Functions console

You can invoke the workflow on the Step Functions console. An execution receives JSON input. For this example, you can pass the following JSON data to the workflow.

{ "inputCaseID": "001" }

To execute your workflow:

  1. On the Step Functions console, choose Start execution.

  2. In the Input section, pass the JSON data. View the workflow. As each step is completed, it turns green.

  3. If the step turns red, an error occurred. You can click the step and view the logs that are accessible from the right side.

    When the workflow is finished, you can view the data in the DynamoDB table.

Delete the AWS resources

Congratulations, you have created an AWS serverless workflow by using the AWS SDK for Java. As stated at the beginning of this tutorial, be sure to terminate all of the resources you create while going through this tutorial to ensure that you’re not charged. You can do this by deleting the AWS CloudFormation stack you created in the Create the AWS resources topic of this tutorial, as follows:

  1. Open the AWS CloudFormation in the AWS management console.

  2. Open the Stacks page, and select the stack.

  3. Choose Delete.