Are you trying to build a serverless web application with AWS lambda?
This guide will help you.
You can build a serverless web application by using several AWS services together. Each service is fully managed and does not require you to provision or manage servers.
You only need to configure them together and upload your application code to AWS Lambda, a serverless compute service.
Here at Ibmi Media, as part of our Server Management Services, we regularly help our Customers to perform AWS related queries.
In this context, we shall look into how to create a simple serverless web application that enables users to request unicorn rides from the Wild Rydes fleet.
The application architecture uses AWS Lambda, Amazon API Gateway, Amazon DynamoDB, Amazon Cognito, and AWS Amplify Console.
This workshop comprises five modules.
They are:
i. Static Web Hosting
ii. User Management
iii. Serverless Backend
iv. RESTful APIs
v. Resource Termination and Next Steps
Here, we shall configure AWS Amplify to host the static resources to the web application with continuous deployment built-in.
All of the static web content including HTML, CSS, JavaScript, images, and other files is managed by AWS Amplify Console.
Now let's take a look at how our Support Experts implement this.
We can deploy the web application in any AWS region that supports all the services used in this application, which include AWS Amplify, AWS CodeCommit, Amazon Cognito, AWS Lambda, Amazon API Gateway, and Amazon DynamoDB.
We select the region from the dropdown in the upper right corner of the AWS Management Console.
We can either manage the source code through AWS CodeCommit or GitHub. Here we are using CodeCommit to store our application code.
Below are the steps that we follow:
i. First, we open the AWS CodeCommit console
ii. Next, we select Create Repository
iii. Here we set the Repository name* to “wildrydes-site”
iv. Then we select Create
v. Now that we have created the repository, we set up an IAM user with Git credentials in the IAM console.
vi. Then back in the CodeCommit console, From the Clone URL, drop down, we select Clone HTTPS
vii. From a terminal window, we run git clone and the HTTPS URL of the repository:
$ git clone https://git-codecommit.us-east1.ibmimedia.com/v1/repos/wildrydes-site Cloning into 'wildrydes-site'... Username for 'https://git-codecommit.us-east-1.ibmimedia.com':XXXXXXXXXX Password for 'USERID': XXXXXXXXXXXX warning: You appear to have cloned an empty repository.
Now we've created our git repository and cloned it locally.
Now we need to copy the website content from an existing publicly accessible S3 bucket and add the content to your repository.
a. We change the directory into the repository and copy the static files from S3:
cd wildrydes-site/
aws s3 cp s3://wildrydes-us-east-1/WebApplication/1_StaticWebHosting/website ./ --recursive
b. Then we commit the files to the Git service
$ git add .
$ git commit -m 'new'
$ git push
Now we shall use the AWS Amplify Console to deploy the website that we just committed to git.
The Amplify Console takes care of the work of setting up a place to store the static web application code.
i. First, we launch the Amplify Console console page
ii. Next, we click Get Started under Deploy with Amplify Console
iii. Here we select the Repository service provider used today and select Next
iv. Then from the dropdown, we select the Repository and Branch just created
v. On the “Configure build settings” page, we leave all the defaults and select Next.
vi. On the “Review” page, we select Save and deploy
vii. The process takes a couple of minutes for Amplify Console to create the necessary resources and to deploy the code.
viii. After it completes, we click on the site image to launch the Wild Rydes site.
The AWS Amplify Console will rebuild and redeploy the app when it detects changes to the connected repository.
We can make a change to the main page to test out this process.
a. First, we open the `index.html` page and modify the title line so that it says: <title>Wild Rydes – Rydes of Future!</title>
b. Then we save the file and commit to the git repository again. Once, the Amplify Console notices the update to the repository, it will begin to build the site again. It will happen pretty quickly.
We then head back to the Amplify Console console page to watch the process.
$ git add index.html
$ git commit -m "updated title"
[master dfec2e5] updated title
1 file changed, 1 insertion(+), 1 deletion(-)
$ git push
Counting objects: 3, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 315 bytes | 315.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: processing
To https://git-codecommit.us-east-1.ibmimedia.com/v1/repos/wildrydes-site
2e9f540..dfec2e5 master -> master
c. Once completed, we re-open the Wild Rydes site and notice the title change.
In this module, we shall create an Amazon Cognito user pool to manage the user's accounts.
Here we will deploy pages that enable customers to register as a new user, verify their email address, and sign into the site.
Here are the steps to implement it.
There are two different mechanisms for authenticating users that Amazon Cognito provides.
We can either use Cognito User Pools to add sign-up and sign-in functionality to the application.
Or we can use Cognito Identity Pools to authenticate users through social identity providers such as Facebook, Twitter, or Amazon, with SAML identity solutions, or by using our own identity system.
Here we shall use a user pool as the backend for the provided registration and sign-in pages.
i. From the AWS Console, we click Services then select Cognito under Mobile Services.
ii. Next, we choose to Manage your User Pools.
iii. Then we choose to Create a User Pool
iv. Here, we provide a name for the user pool such as WildRydes, then select Review Defaults
v. On the review page, we click Create pool.
vi. We note the Pool Id on the Pool details page of your newly created user pool.
From the Amazon Cognito console, we select the user pool and then select the App clients section.
We add a new app client and make sure the Generate client secret option is deselected.
i. From the Pool Details page for the user pool, we select App clients from the left General Settings section in the navigation bar.
ii. Next, we choose to Add an app client.
iii. We give the app client a name such as WildRydesWebApp.
iv. Then we uncheck the Generate client secret option. Client secrets aren’t currently supported for use with browser-based applications.
v. We choose to Create app client.
vi. We note the App client id for the newly created application.
The settings for the user pool ID, app client ID, and Region are present in /js/config.js file.
We update this file with the settings from the user pool and app we created in the previous steps and upload the file back to the bucket.
i. From our local machine, we open `wild-ryde-site/js/config.js` in a text editor.
ii. Then we update the cognito section with the correct values for the user pool and app we just created.
iii. The updated config.js file should look as below. Note that the actual values for your file will be different:
window._config = {
cognito: {
userPoolId: 'us-west-2_uXboG5pAb', // e.g. us-east-2_uXboG5pAb
userPoolClientId: '25ddkmj4v6hfsfvruhpfi7n4hv', // e.g. 25ddkmj4v6hfsfvruhpfi7n4hv
region: 'us-west-2' // e.g. us-east-2
},
api: {
invokeUrl: '' // e.g. https://rc7nyt4tql.execute-api.us-west-2.amazonaws.com/prod',
}
};
iv. We then save the modified file and push it to your Git repository to have it automatically deploy to Amplify Console.
$ git push
i. First, we visit /register.html under the website domain.
ii. Now, we complete the registration form and choose Let’s Ryde. We enter an email. If you wish you can use a dummy email as well. Then we enter the password which we need to remember for later use. We see an alert that confirms that our user has been created.
iii. We then confirm our new user using one of the two following methods.
a. If you used an email address you control, you can complete the account verification process by visiting /verify.html under your website domain and entering the verification code that is emailed to you. Please note, the verification email may end up in your spam folder. For real deployments, we recommend configuring your user pool to use Amazon Simple Email Service to send emails from a domain you own.
b. If you used a dummy email address, you must confirm the user manually through the Cognito console.
iv. From the AWS console, we click Services then select Cognito under Security, Identity & Compliance.
v. Then we choose Manage your User Pools
vi. We select the WildRydes user pool and click Users and groups in the left navigation bar.
vii. Here we see a user corresponding to the email address that we submitted through the registration page. We choose that username to view the user detail page.
viii. Then we choose Confirm user to finalize the account creation process.
ix. After confirming the new user using either the /verify.html page or the Cognito console, we visit /signin.html and log in using the email address and password we entered during the registration step.
x. If successful we should be redirected to /ride.html. We can see a notification that the API is not configured.
In this module, we shall use AWS Lambda and Amazon DynamoDB to build a backend process for handling requests for the web application.
The browser application that we deployed in the first module allows users to request that a unicorn be sent to a location of their choice.
In order to fulfill those requests, the JavaScript running in the browser will need to invoke a service running in the cloud.
Here are the steps to implement it:
We make use of Amazon DynamoDB console to create a new DynamoDB table.
i. From the AWS Management Console, choose Services then select DynamoDB under Databases.
ii. Choose Create table.
iii. Enter Rides for the Table name. This field is case sensitive.
iv. Enter RideId for the Partition key and select String for the key type. This field is case sensitive.
v. Check the Use default settings box and choose Create.
vi. Scroll to the bottom of the Overview section of your new table and note the ARN. You will use this in the next section.
i. From the AWS Management Console, we click on Services and then select IAM in the Security, Identity & Compliance section.
ii. Next, we select Roles in the left navigation bar and then choose Create New Role.
iii. Then we select Lambda for the role type from the AWS service group, then click Next: Permissions.
iv. We begin typing AWSLambdaBasicExecutionRole in the Filter text box and check the box next to that role.
v. Then we choose Next Step.
vi. We enter WildRydesLambda for the Role Name and choose Create Role.
vii. Then we type WildRydesLambda into the filter box on the Roles page and choose the role we just created.
viii. On the Permissions tab, we choose the Add inline policy link in the lower right corner to create a new inline policy.
ix. Then we select Choose a service.
x. We begin typing DynamoDB into the search box labeled Find a service and select DynamoDB when it appears and choose Select actions.
xi. We begin typing PutItem into the search box labeled Filter actions and check the box next to PutItem when it appears and select the Resources section.
xii. With the Specific option selected, we choose the Add ARN link in the table section.
xiii. We then paste the ARN of the table you created in the previous section in the Specify ARN for table field, and choose Add.
xiv. After that, we choose Review Policy.
xv. Finally, we enter DynamoDBWriteAccess for the policy name and choose Create policy.
AWS Lambda will run the code in response to events such as an HTTP request.
In this step we'll build the core function that will process API requests from the web application to dispatch a unicorn.
i. First, we choose Services then select Lambda in the Compute section.
ii. Next, we click Create function.
iii. We keep the default Author from scratch card selected.
iv. Then we enter RequestUnicorn in the Name field.
v. Select Node.js 6.10 for the Runtime.
vi. We ensure Choose an existing role is selected from the Role dropdown.
vii. Select WildRydesLambda from the Existing Role dropdown and click on Create function.
viii. After that, we scroll down to the Function code section and replace the exiting code in the index.js code editor with the contents of requestUnicorn.js.
ix. Finally, we click “Save” in the upper right corner of the page.
i. From the main edit screen for the function, we select Configure test event from the the Select a test event… dropdown.
ii. We keep Create new test event selected.
iii. Then we enter TestRequestEvent in the Event name field
iv. After that, we copy and paste the following test event into the editor:
{
"path": "/ride",
"httpMethod": "POST",
"headers": {
"Accept": "*/*",
"Authorization": "eyJraWQiOiJLTzRVMWZs",
"content-type": "application/json; charset=UTF-8"
},
"queryStringParameters": null,
"pathParameters": null,
"requestContext": {
"authorizer": {
"claims": {
"cognito:username": "the_username"
}
}
},
"body": "{\"PickupLocation\":{\"Latitude\":47.6174755835663,\"Longitude\":-122.28837066650185}}"
}
v. Then we click Create.
vi. On the main function, we edit screen click Test with TestRequestEvent selected in the dropdown.
vii. We then scroll to the top of the page and expand the Details section of the Execution result section.
viii. We verify that the execution succeeded and that the function result looks like the following:
{
"statusCode": 201,
"body": "{\"RideId\":\"SvLnijIAtg6inAFUBRT+Fg==\",\"Unicorn\":{\"Name\":\"Rocinante\",\"Color\":\"Yellow\",\"Gender\":\"Female\"},\"Eta\":\"30 seconds\"}",
"headers": {
"Access-Control-Allow-Origin": "*"
}
}
In this module, we shall use Amazon API Gateway to expose the Lambda function we built in the previous module as a RESTful API.
Now, let's take a look at the implementation.
i. First, in the AWS Management Console, we click Services then select API Gateway under Application Services.
ii. Next, we choose Create API.
iii. Then we select New API and enter WildRydes for the API Name.
iv. We keep Edge optimized selected in the Endpoint Type dropdown.
v. Finally, we choose Create API
i. Under our newly created API, we choose Authorizers.
ii. Then we choose Create New Authorizer.
iii. After that, we enter WildRydes for the Authorizer name.
iv. Then we select Cognito for the type.
v. In the Region drop-down under Cognito User Pool, we select the Region where we created our Cognito user pool in module 2 (by default the current region should be selected).
vi. Here we enter WildRydes in the Cognito User Pool input.
vii. Then we enter Authorization for the Token Source and choose Create.
viii. We verify our authorizer configuration
ix. Then we open a new browser tab and visit /ride.html under our website’s domain.
x. If we are redirected to the sign-in page, we sign in with the user we created in the last module. We will be redirected back to /ride.html.
xi. We copy the auth token from the notification on the /ride.html,
xii. Then we go back to the previous tab where we just finished creating the Authorizer
xiii. After that, we click Test at the bottom of the card for the authorizer.
xiv. Here we paste the auth token into the Authorization Token field in the popup dialog.
xv. Finally, we click the Test button and verify that the response code is 200 and that we see the claims for our user displayed.
Now we shall create a new resource called /ride within our API.
i. In the left navigation, we click on Resources under our WildRydes API.
ii. From the Actions dropdown, we select Create Resource.
iii. Then we enter ride as the Resource Name.
iv. We ensure the Resource Path is set to ride.
v. Then we select Enable API Gateway CORS for the resource and then we click Create Resource.
vi. With the newly created /ride resource selected, from the Action dropdown, we select Create Method.
vii. After that, we select POST from the new dropdown that appears, then we click the checkmark.
viii. We then select Lambda Function for the integration type.
ix. Next, we check the box for Use Lambda Proxy integration.
x. After that, we select the Region we are using for Lambda Region.
xi. We enter the name of the function we created in the previous module, RequestUnicorn, for Lambda Function.
xii. Then we choose Save.
xiii. When prompted to give Amazon API Gateway permission to invoke our function, we choose OK.
xiv. We choose on the Method Request card and choose the pencil icon next to Authorization.
xv. Finally, we select the WildRydes Cognito user pool authorizer from the drop-down list and click the checkmark icon.
i. From the Amazon API Gateway console, we choose Actions, Deploy API. We'll be prompted to create a new stage.
We use prod for the stage name.
ii. In the Actions drop-down list, we select Deploy API.
iii. Then we select [New Stage] in the Deployment stage drop-down list.
iv. After that, we enter prod for the Stage Name and choose Deploy.
v. We note the Invoke URL. We will use it in the next section.
Now we update the /js/config.js file in the website deployment to include the invoke URL of the stage we just created.
i. We open the config.js file in a text editor.
ii. Next, we update the invokeUrl setting under the api key in the config.js file.
We then set the value to the Invoke URL for the deployment stage we created in the previous section.
An example of a complete config.js file is included below.
However, the actual values in the file will be different.
window._config = {
cognito: {
userPoolId: ‘us-west-2_uXboG5pAb’, // e.g. us-east-2_uXboG5pAb
userPoolClientId: ’25ddkmj4v6hfsfvruhpfi7n4hv’, // e.g. 25ddkmj4v6hfsfvruhpfi7n4hv
region: ‘us-west-2’ // e.g. us-east-2
},
api: {
invokeUrl: ‘https://rc7nyt4tql.execute-api.us-west-2.amazonaws.com/prod’ // e.g. https://rc7nyt4tql.execute-api.us-west-2.amazonaws.com/prod,
}
};
iii. Finally, we save the modified file and push it to the Git repository to have it automatically deploy to Amplify Console.
$ git push
i. First, we visit /ride.html under your website domain.
ii. If we are redirected to the sign in page, we sign in with the user we created in the previous module.
iii. After the map has loaded, we click anywhere on the map to set a pickup location.
iv. We choose Request Unicorn. We see a notification in the right sidebar that a unicorn is on its way and then we see a unicorn icon fly to our pickup location.
It is possible to terminate the AWS Amplify app, an Amazon Cognito User Pool, an AWS Lambda function, an IAM role, a DynamoDB table, a REST API, and a CloudWatch Log. It is a best practice to delete resources that we no longer use to avoid unwanted charges.
This article will guide you on how to build serverless Web Application AWS #Lambda.
1. The application architecture uses #AWS Lambda, Amazon API Gateway, Amazon DynamoDB, Amazon Cognito, and AWS Amplify Console.
2. Amplify Console provides continuous deployment and hosting of the static web resources including HTML, CSS, JavaScript, and image files which are loaded in the user's browser.
3. JavaScript executed in the browser sends and receives data from a public backend API built using Lambda and API Gateway.
4. Amazon Cognito provides user management and authentication functions to secure the backend API.
5. Finally, #DynamoDB provides a persistence layer where data can be stored by the API's Lambda function.