Building Serverless Websites in AWS

Researching on RESTful APIs, I found the use case of AWS services to build Serverless websites very appealing. This can help small to mid-size organizations to reduce their operational overhead while delivering highly scalable and reliable services to customers. In this blog post, I will document steps to develop such a serverless website in AWS.

We will be using the unique public url for AWS S3 bucket as our web front-end. The S3 bucket would be simply used to host static content for the website like HTML files, image files, CSS files, etc.

  1. Login to AWS and select your preferred AWS region
  2. Create a bucket with default configurations using your preferred cloud region
  3. Upload the contents of your static website into the S3 bucket — CSS, Javascript, HTML, and images. Your S3 bucket should look like this after the procedure:
S3 bucket after content upload

4. Add a bucket policy to allow READs from the public. Below is the JSON that your bucket policy must have to allow Public READ access:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::[YOUR_BUCKET_NAME]/*"
}
]
}

Note: Depending on your bucket setting, you may or may not be able to do the above operation. If an error like ‘Access Denied’ comes up while granting updating bucket policy, please first update the Public Access Settings to remove the block on updating the bucket policy.

5. To enable users in the region of your S3 bucket to be able to see the contents of bucket as if they are coming from a website, you need to enable website hosting on your S3 bucket. This can be done from Properties of the bucket:

Enabling static website hosting on S3 bucket

6. Visit your S3 endpoint to see your implementation of static website at:

http://<bucket-name>.s3-website-<region-name>.amazonaws.com

Amazon offers a fully-managed SQL database through RDS and a fully-managed no-SQL database using DynamoDB. You can use either one for your serverless solution depending on your use case. For application level logic like getting or putting data from these databases, Amazon offers a very neat and powerful solution using AWS Lambda. In this section, we would create a new NoSQL table in DynamoDB and do a test to insert data into it through AWS Lambda

  1. Go to DynamoDB, select your Region, and create a table.
  2. Create an IAM role for AWS Lambda allowing it to be granted below policies:

a. AWS managed policy = AWSLambdaBasicExecutionRole

b. Inline policy with the below JSON, allowing PUT permission to the DynamoDB:

{
“Version”: “2012–10–17”,
“Statement”: [
{
“Sid”: “VisualEditor0”,
“Effect”: “Allow”,
“Action”: “dynamodb:PutItem”,
“Resource”: “<dynamoDB table ARN>”
}
]
}

3. Create a Lambda function at your preferred region, attaching the above-created role and selecting your preferred programming language.

4. Code your Lambda function to receive a POST-type request, capture necessary details in variables, and put these variables in the DynamoDB/RDS using AWS-offered SDKs.

5. In order to test this implementation, create a Test Event matching the details of the POST request. Test the Lambda function against the test event and see if values are populated in the back-end database.

The back-end process we created in Step 2 is a stand-alone process and is not connected to the front-end in Step 1. Before the birth of API Gateway, AWS Lambda was just a cloud event-driven coding platform. API Gateway has revolutionized the way in which Lambda can be used for delivering application logic outside of cloud events. In this blogpost, we would be using API Gateway to expose the functionality of the Lambda function we created in Step 2 as a RESTful API.

  1. Inside AWS console, click on API Gateway and create a new REST API
  2. Create a new resource inside the above created REST API, and assign it to the resource path desired.
  3. Create a new resource method inside the above resource to specify the type of REST API method — POST, GET,etc. Then select the Lambda function as the integration type which you have created as part of the previous step.
  4. Deploy your API and copy the Invoke URL created to be used as part of your website configuration files

For the purpose of this demonstration, we have taken authorization for this API as None. However, in most of the cases, you will need to authorize your APIs using JWT authorization or API keys or other methods as considered necessary.

Cloud Security Architect