# Hosting  a Serverless Web Application in AWS - Part II

*This is the second article in this series about hosting a serverless web application in AWS.*

In the [previous article](https://blog.cloudbuff.in/serverless-web-app-p1), we set up a static website using AWS S3. However, there are some problems with this - we had to enable public access on our bucket and the website does not use SSL/TLS. In this article, we will enable [CloudFront](https://aws.amazon.com/cloudfront/) distribution for this website and avoid these problems.

### Amazon CloudFront

Amazon CloudFront is a Content Delivery Network (CDN) that distributes our content globally to various edge locations. When a user requests our content, they are served from the edge location nearest to them, reducing latency. CloudFront caches our files at edge locations. This means that repeated requests for the same content are served from the cache, which is much faster. Also, serving content from the cache reduces the number of requests to our S3 bucket, which can reduce our S3 costs.

### Create a CloudFront Distribution

Navigate to the CloudFront page from the AWS console.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699114949045/f7dfd9f0-8eb9-4e92-b411-10e022b6483c.png align="center")

Click `Create a CloudFront distribution` .

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699114986751/70e0e7d6-111a-4f90-bb83-9f3eae4da319.png align="center")

We will choose our S3 bucket in the `Origin domain` dropdown list. For `Origin access`, lets' select the `Origin access control settings` option as we do not want our bucket to be publicly accessible.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699115039274/f5a40e7f-2cfc-401f-a720-c3476e0a232b.png align="center")

Next, we will create a new control settings.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699115199067/f6aee078-de88-4112-824d-be43699cdeee.png align="center")

We'll keep the default values in the `Create control setting` windows that pop-ups. Click the `Create` button to create the control setting.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699115227471/2c31c799-de1c-4024-bf64-196a8b60b908.png align="center")

Note that we will need to manually update the bucket policy to grant permissions to our CloudFront distribution.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699116505024/62a1d9cb-3633-4f51-8d82-98544e1df2f1.png align="center")

As this is just a sample application, choose `Do not enable security protections` in the `Web Application Firewall` section. For production applications, we should consider enabling security protections.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699116581112/27ab8582-8822-4bd6-9ff7-463118fda76f.png align="center")

Let's assume that a majority of our users will be from North America and Europe and choose the appropriate `Price class`. This means that our website content will only be served by edge locations in these regions. This also means that users in other regions may see higher latency.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699116724678/da9d3c32-270f-47e1-8ddc-4047584acb58.png align="center")

Since `index.html` is the home page of our website, we will set that as the `Default root object`. This is the content that will be returned when the user requests the root URL.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699116965143/5cb8bd0a-b30e-4488-8a8a-4967987508af.png align="center")

We will keep the remaining options as default and click `Create distribution` button at the bottom to create our distribution. We should see a confirmation that the new distribution was created successfully.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699117189422/dcdcfdd4-8a6f-457d-af4e-b2ec956a8a62.png align="center")

Make a note of the Distribution domain name as we will use it to access our website. There should be a `Copy policy` button on the top left corner. Click the copy icon to copy the S3 bucket policy. Now, let's navigate to the S3 bucket and update the bucket policy.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699117386440/eb4129af-2dac-4366-9121-3ba46ae614a4.png align="center")

Replace the policy we created earlier with the policy that was copied above. Since we have created a CloudFront distribution to serve our website, we no longer require our bucket to be publicly accessible.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699117477415/7e840868-6f70-4ae4-8f36-230bb477e767.png align="center")

We will navigate back to `Edit Block public access` for our bucket and check `Block all public access` box and save changes. Checking this box will result in a confirmation pop-up.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699117724124/14a13714-e2b5-4f0f-816d-2b1efc20e927.png align="center")

Type `confirm` in the field to confirm the settings and click `Confirm`.

### Accessing our website

Our website will now be accessible using the Distribution domain name.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699118072231/e9f2ab94-8321-4ac5-b738-8fd67c77ce3d.png align="center")

This is great but there is still one issue. The link for our website is cryptic and not ideal. So, now let us associate our domain with this CloudFront distribution so we can use a friendlier URL for our website.

### Use our domain for our website

Note: If you don't have a domain, you can register one for a reasonably economical price or even free (with some restrictions). You can do a web search for this.

We already have a domain, `cloudbuff.in` , registered, so we will use [tic-tac-toe.cloudbuff.in](http://tic-tac-toe.cloudbuff.in) for our website.

### Request a certificate

Since we want our website to be secure and support SSL/TLS, we will request a new certificate for this domain from [AWS Certificate Manager](https://aws.amazon.com/certificate-manager/).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699121561050/ce26911f-9031-42cb-b20b-f7c4ca6c1ba4.png align="center")

On `AWS Certificate Manager` screen, click the `Request` button to request this new certificate.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699121673532/46c821f9-90f3-4f13-a936-b999f9e509f4.png align="center")

We will request a public certificate.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699121773295/00b52ada-0283-49d7-9490-9d2446d91f67.png align="center")

We will put in the desired domain for our website as the `Fully qualified domain name` and choose `DNS validation` as the method to validate domain ownership. Click the `Request` button at the bottom of the page to continue.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699121834170/0f07a70b-6d6c-4590-ba79-c7996360fd8f.png align="center")

We should see a message that the certificate has been successfully requested. the status is `Pending validation`. We need to take some additional steps before the certificate is approved.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699121989806/c321c8b4-05f9-48e2-9c80-805e629691f7.png align="center")

Click on the Certificate ID link and navigate to the `Domains` section.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699122125128/22e5e833-a218-4e06-b98a-717b91c946de.png align="center")

The status is `Pending validation` and there are two columns of interest `CNAME name` and `CNAME value`. We need to add a DNS record of type CNAME through the domain registration website. Our domain is registered with GoDaddy, so we will go that site and add a DNS record there.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699122344196/461459d7-4b6a-41bd-84b9-5327e799b987.png align="center")

Make sure that the type is `CNAME` and copy the Name and Value from the AWS Certificate Manager screen. Save your changes. This will allow AWS Certificate Manager to confirm that we own this domain.

Note: DNS validation can sometimes take hours depending how DNS changes are propagated and become visible to AWS Certificate Manager.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699161400975/5d746a8a-2e74-4509-8f3d-12ae395e5b14.png align="center")

### Update DNS

Once the validation is complete, we can add a new `CNAME` record to our DNS. This is to point subdomain `tic-tac-toe` to our CloudFront distribution domain.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699122442121/c8fc2f74-3e86-400a-9d72-d4be122d1b76.png align="center")

### Update domain for distribution

Now, we will associate this domain with our CloudFront distribution. For this, we need to edit the distribution settings.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699161563715/00d77f22-7ae2-4e37-9ab5-973359abcb47.png align="center")

We need to specify our custom domain in the `Alternate domain name (CNAME)` field. We also need to select the certificate we created earlier in the `Custom SSL certificate` dropdown.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699161603360/6e75c049-ce8b-4b59-a0e6-58e3c0b7d373.png align="center")

Click the `Save changes` button at the bottom to save. Now we should see our changes being deployed. This can take some time.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699161766174/ed75d013-723e-4811-a4ef-bc2d44c44336.png align="center")

Once the changes are successfully deployed, we should see the date and time in the `Last modified` column.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699161929360/7983c8af-30b8-43c2-9664-0adb3932b3cb.png align="center")

Now we should be able to access our website using our custom domain [https://tic-tac-toe.cloudbuff.in/](https://tic-tac-toe.cloudbuff.in/). Note that the website is secure and uses SSL/TLS.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1699162242975/f15fc387-ff20-4e3e-bd11-a8d45bacd09e.png align="center")

### Conclusion

In this article, we saw how we can use CloudFront as the CDN for our website. We also associated our custom domain with our static website hosted using S3. In subsequent articles, we will build further on this and see how we can deploy a dynamic web application in AWS without setting up any servers.
