Skip to main content

Creating Your Own Serverless Reminder on AWS with Step Functions, API Gateway, Lambda, and S3

Hands-On Lab

 

Photo of Julie  Elkins

Julie Elkins

AWS Training Architect I in Content

Length

01:45:00

Difficulty

Intermediate

In this hands-on lab, you will interact with several AWS services (including AWS Step Functions, API Gateway, AWS Lambda, and S3) to create a reminder serverless application using a static website hosted on S3. You will also integrate the SNS and SES services into your code (but don't worry — we will walk through it all together). By the end of this lab, you should feel comfortable developing applications that rely on multiple AWS services. This also provides you with an opportunity to prove your knowledge and skills integrating multiple AWS services.

What are Hands-On Labs?

Hands-On Labs are scenario-based learning environments where learners can practice without consequences. Don't compromise a system or waste money on expensive downloads. Practice real-world skills without the real-world risk, no assembly required.

Creating Your Own Serverless Reminder on AWS with Step Functions, API Gateway, Lambda, and S3

Introduction

In this hands-on lab, you will interact with several AWS services (including AWS Step Functions, API Gateway, AWS Lambda, and S3) to create a reminder serverless application using a static website hosted on S3. You will also integrate the SNS and SES services into your code (but don't worry — we will walk through it all together). By the end of this lab, you should feel comfortable developing applications that rely on multiple AWS services. This also provides you with an opportunity to prove your knowledge and skills integrating multiple AWS services.

Make sure you are in us-east-1 when you work in this environment.

You can find all the code used in this learning activity here:

https://github.com/julielkinsfembotit/LALabs

Note: Instead of creating state machines from scratch, you can use the hello world template as a place holder.

Logging In

Use the credentials provided on the hands-on lab overview page, and log in as cloud_user to the AWS console. It's a good idea to have the GitHub link opened up in a second browser window or tab.

Create Three Lambda Functions

Create the email Lambda Function

  • Navigate to the Lambda portion of the AWS console.
  • Click Create function.
  • Leave Author from scratch selected.
  • Set Function name to email.
  • Set Runtime to Python 3.7.
  • Click Choose or create an execution role.
  • Select Use an existing role, and click on the LambdaRuntimeRole that appears.
  • Click Create function.
  • In the next window, scroll down to the Function code section.
  • Get into the GitHub repository, and open up email_reminder.py. Click the Raw button, then copy the code we see displayed. Back over in the AWS console, replace the code that's in the Function code section with the code from email_reminder.py.
  • Open up a new browser tab, and navigate to Simple Email Service in the AWS console.
  • Click on Email Addresses in the left-hand menu, then click Verify a New Email Address on the next screen.
  • In the window that pops up, type in your own email address, then click Verify This Email Address.
  • Check that email address (in a client or a new browser tab) and click on the URL that AWS sent. That should lead to a Congratulations! page confirming the email address verification.
  • Back in the Lambda console (where we pasted that email function code), change the VERIFIED_EMAIL to the address you just used. Something like this:
    VERIFIED_EMAIL = 'youremail@yourdomain.com'
  • Click Save.

Create the sms Lambda Function

Scroll all the way up to the top of the window, and click Functions (to take us back to the main Lambda > Functions page). Now we'll make the sms function:

  • Click Create function.
  • Leave Author from scratch selected.
  • Set Function name to sms.
  • Set Runtime to Python 3.7.
  • Click Choose or create an execution role.
  • Select Use an existing role, and click on the LambdaRuntimeRole that appears.
  • Click Create function.
  • Get back into the GitHub repository, and open up sms_reminder.py. Click the Raw button, then copy the code we see displayed. Back over in the AWS console, replace the code that's in the Function code section with the code from sms_reminder.py.
  • Click Save.

Create the api_handler Lambda Function

Scroll up again to the top of the screen, and click Functions to take us back to the main Lambda > Functions page. We're going to create the api_handler function:

  • Click Create function.
  • Leave Author from scratch selected.
  • Set Function name to api_handler.
  • Set Runtime to Python 3.7.
  • Click Choose or create an execution role.
  • Select Use an existing role, and click on the LambdaRuntimeRole that appears.
  • Click Create function.
  • Get back into the GitHub repository, and open up api_handler.py. Click the Raw button, then copy the code we see displayed. Back over in the AWS console, replace the code that's in the Function code section with the code from api_handler.py.
  • Click Save.

Create a State Machine

In the AWS console, navigate to Step Functions, and click Get started. Click the word here near the top, where it says You can also skip and access more functionality here.

  • Leave Author with code snippets selected, and Standard below that, then delete the code that's down in the Definition section.
  • Flip back over to the GitHub repository, and open up step-function-template.json. Click the Raw button, then copy the code we see displayed. Back over in the AWS console, paste that code into the Definition section we just deleted code from.
  • In another AWS console window (we should still have a few open) navigate to Lambda, and click on our email function. Copy the ARN sitting in the upper right of the screen. It starts with arn:aws and ends with :function:email.
  • Back over in the Definition section of the step function we're creating, we've got to paste that ARN in two spots. There is a BothReminders section, and an EmailReminder section. They both have lines that read: "Resource": "EMAIL_REMINDER_ARN". Between the quotes on each of them, in place of the "EMAIL_REMINDER_ARN", is where we need to paste. They should both look something like this afterward (note that there are several periods here taking the place of actual characters in the ARN):
    • "Resource": "arn:aws......:function:email"
  • Navigate back to Lambda, and open up our sms function. Copy that ARN, and paste it like we did in the BothReminders and EmailReminder sections, but this time we're aiming for the "Resource": "TEXT_REMINDER_ARN" line in the TextReminder section. Replace TEXT_REMINDER_ARN with the actual ARN we copied from our sms function. Then scroll down and paste the ARN in the "Resource": "TEXT_REMINDER_ARN" line of the TextReminderPar section as well.
  • Click the Refresh button (at the top of the pane that's to the right of where we've been pasting the ARNs). The diagram should update.
  • Click the Next button.
  • Leave the State machine name set to MyStateMachine.
  • In the Permissions section, select Use an existing role, and click on the RoleForStepFunction that appears.
  • Click Create state machine.
  • On the next screen, click on our state machine, and then copy the ARN. Not the IAM role ARN, but the regular ARN.
  • Back in Lambda, open up the api_handler function so we can paste that ARN in. Replace 'STEP_FUNCTION_ARN' in the SFN_ARN = 'STEP_FUNCTION_ARN' line with our actual ARN, and make sure it's between the single quotes.
  • Click Save.

Create an API Gateway

In the State Machine dashboard, once we've got the State machine successfully created message, navigate to Services > API Gateway. Click Get Started. Click OK to get through the welcome message.

  • Make sure REST is selected.
  • Select New API.
  • Set *API name to reminders**.
  • Give it a Description of reminders.
  • Leave Endpoint Type set to Regional.
  • Click Create API.
  • On the next screen, click the Actions button, and select Create Resource.
  • In the form that appears, set *Resource Name to reminders* (Resource Path should populate automatically) and check the Enable API Gateway CORS box, then click Create Resource**.
  • Make sure /reminders is highlighted, then click the Actions button again and choose Create Method from the dropdown.
  • An OPTIONS dropdown box will show up beneath /reminders. Choose POST from it, and click the checkmark icon.
  • In the form that appears to the right, set Integration type to Lambda Function, check the Use Lambda Proxy integration box, make sure Lambda Region is set to us-east-1, and choose api_handler in the Lambda Function field.
  • Now we can click Save, and when a window pops up about adding permission to Lambda Function, click OK.
  • Click on the Actions button again, and choose Deploy API. A window will pop up with a form. Use these settings:
    • Deployment stage: [New Stage]
    • Stage name*: prod
    • Stage description: prod
    • Deployment description: We can leave this blank
  • Click Deploy, and ignore any warnings about permissions for Web Application Firewall.
  • Remember where to find this Invoke URL shown near the top of the window. We'll need it later.

Create a Static Website Hosted in S3

Navigate to S3 in the AWS console, and click Create bucket. Give it a Bucket name (this may take a couple of tries, as they need to be unique), click Next, Next again, and on the following screen uncheck the Block all public access box. Acknowledge the warning that pops up. Then click Next, and on the following screen click Create bucket.

Click on that bucket once it's created, then the Upload button. If you haven't done it yet, download the GitHub repository. Once you've got it, Click Add files in the AWS window we've got open. Upload error.html, formlogic.js, index.html, and main.css from wherever the GitHub repository got downloaded to.

In the next window, down under Manage public permissions, choose Grant public read access to this object(s), then click Next, then Next again, and finally on the last screen click Upload.

Now click + Create folder. Name it images and click Save. Navigate into images, and click Upload. Click Add files, and select IMG_0991.jpg. Just like with the last upload, we've got to set some permissions. In the next window, down under Manage public permissions, choose Grant public read access to this object(s), then click Next, Next, and finally (again) on the last screen click Upload.

Get back to this bucket's main screen, and click on the Properties tab, then select Static website hosting. Choose Use this bucket to host a website in the Static website hosting area of the screen we land on.

Set Index document to index.html, and Error document to error.html, then scroll down and click Save. Open up Static website hosting again, and copy the Endpoint. In another browser tab, paste that into the URL bar, and we should land on a Pet Reminders page.

Testing

On this page, we're going to run a test. In the Seconds to wait..., enter 1. Enter Hello in the Message field, and put your email in the next field down. Click the email button.

We'll get an error. Remember that Invoke URL, back when we set up the API gateway? To get it, navigate back to (or switch back to the browser tab if it's still open) our /reminders API, and copy that Invoke URL near the top of the page.

Get a text editor fired up, and open formlogic.js. That file is in the GitHub repository we downloaded, in the static_website directory. This line (which should be line 5) needs to be changed:

var API_ENDPOINT = 'UPDATETOYOURINVOKEURLENDPOINT/reminders';

Replace UPDATETOYOURINVOKEURLENDPOINT with the Invoke URL that you copied. Save the changes, and now we've got to upload the new file. Do it the same way we did before (navigating to our S3 bucket, click Upload files, choose this file, etc.)

Let's try the website again. Put the same things in the web form that we did before, and click email. We should see a {"Status":"Success"} message.

Now check your email to see if a reminder showed up.

Conclusion

The email should arrive shortly. This means our work is finished. We can navigate back into Step Functions > State Machines and get into our MyStateMachine. Down in the Executions section, we can select the event that just occurred. On the next screen we can look at the Visual workflow diagram to see exactly what happened. We're done though. Congratulations!