Project: Static website hosting on S3

·

9 min read

Project: Static website hosting on S3

Today, we will be creating a static website and host it in an S3 bucket.

Overview

We will use an S3 bucket to store our website files, CloudFront for content distribution & issue a certificate from AWS ACM for security. Finally, we will make updates in DNS records to access our static site with custom domain name.

Prerequisites

To complete this tutorial, we need a registered domain name. Amazon Route 53 (R53) provides domain registration and DNS management services, but we can choose separate providers like GoDaddy, Namecheap, or Google Domains for these services if desired.

I am expecting you already have your custom domain name before proceeding.


Task 1: Creating an S3 bucket

Search for S3 in the search box.

Click on Create bucket.

Your bucket name should match the domain name exactly. For example, I'll be using "sujanmagar.com.np" so my bucket name needs to be "sujanmagar.com.np".

Scroll down and deselect the setting for "Block all public access". This is usually not recommended, but since we're creating a static website hosting, it required to disable this setting.

Tick on the acknowledgment box.

Use the defaults for the rest of the bucket settings and then click on Create bucket.

Click on your bucket and on Properties tab, scroll down to Static website hosting section.

Click on Edit.

Enable the Static website hosting and input index.html in the Index document field. This specifies the default home page for our site.

Leaving all other configurations as default, click on Save changes.

When we created the bucket, we said we didn't want to block all public access. But even with that setting, the default behavior of S3 is to "deny" everything. So if we don't explicitly say that people can access the files in our bucket, they won't be able to so, we'll grant read permissions with a bucket policy.

On Permissions tab, on Bucket policy section, click on Edit.

Paste the following bucket policy in the Policy section.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::Bucket-Name/*"#make sure to add your bucket name
            ]
        }
    ]
}

Make sure to update the Bucket-Name with your own.

Click on Save changes.

Now, it's time to upload our files.

On Objects tab, click on Upload.

Click on Add files.

Select your files and click on Upload. You can create your static files that will make up your static website, or you can use mine.

My files for static website

Now it's time to test that our site loads. To do this, we'll need to get the S3 bucket website endpoint.

Head to the Properties tab of the bucket & scroll down to the Static website hosting section.

Click on the Bucket website endpoint link.

If everything worked, you should be able to load your static website.

We have hosted our site in S3 with public access. But as impressive as it is, it would be even more impressive if it were using a custom domain. Currently, it is using the S3 website URL, formatted as [bucketname].s3website[regionname].amazonaws.com.


Task 2: Creating a record to point to the S3 website

To create a DNS record, we need to be working within our DNS zone, which in my case is managed by Cloudflare. You might have your zone hosted with other providers like Amazon Route 53 (R53) or other DNS management services.

Click on Add record.

Copy the Bucket website endpoint and remove the protocol from the endpoint, & paste it in the Target field.

In Amazon Route 53, we have the alias option to point our domain to AWS resources. However, since I'm using Cloudflare, which doesn't have an alias option, I am using a CNAME record type to achieve the similar functionality. Cloudflare automatically enables CNAME flattening for the root domain, allowing it to point to another domain name. This is typically not allowed by DNS standards, but Cloudflare makes it possible.

Click on Save.

Now let's test! If everything worked, then when you type your domain name into a browser (like sujanmagar.com.np), DNS provider should direct you to the S3 website.

Alright, the last step is to set up a secure connection (HTTPS with a TLS/SSL certificate) to eliminate the "Not secure" message from our browser.


Task 3: Creating a Public TLS/SSL Certificate

Certificates

TLS/SSL Certificate Security
We need a public TLS/SSL certificate to secure our website. It encrypts data between users and our server, protecting sensitive information. It also verifies our website's authenticity, removing the "Not secure" warning in browsers, building user trust, and improving our site's credibility.

In AWS, certificates are handled through AWS Certificate Manager (ACM), where you can create and manage certificates. ACM also allows you to import certificates from another authority if you already have them.

In your AWS console, search for Certificate Manager in the search box.

For this section, you need to switch your region to us-east-1 (N. Virginia).

ACM Certificates: Regional vs. Global Usage with CloudFront
When you create a certificate in ACM, it is stored in the region where you created it. This means that if you create a certificate in the us-west-2 region, that certificate is only available for use within services in the us-west-2 region. However, CloudFront's integration with ACM allows it to use certificates from the us-east-1 region for distribution globally. This integration is a special case and does not follow the typical region-specific behavior of ACM certificates.
Click on Request a certificate. Click on Next. Enter your domain name & leave the rest of the options as defaults, then click on Request.
Validation methods
When setting up a new SSL certificate, you must prove ownership of the domain. This is done through two main methods: DNS validation, where you add a specific record to your domain's DNS settings, and Email validation, where a confirmation email is sent to a predefined email address associated with the domain.

For now, we choose the DNS validation method.

The request was successful, but it will have a "Pending validation" status until we validate DNS.

Click on View certificate.

While DNS validation is straightforward with Route 53, using Cloudflare as my DNS provider requires some manual steps to validate domain ownership when issuing an ACM certificate. With Cloudflare, I need to add a specific DNS record provided by ACM to my DNS settings to complete the validation process.

Copy the CNAME name and value, then add a new CNAME record in DNS provider's DNS records.

Click on Save.

We have a TLS/SSL certificate now and our website files are hosted in S3, but we can't use a certificate on an S3 bucket.

What we need instead is a CloudFront distribution that points to the S3 bucket. And then the certificate is applied to the CloudFront distribution.


Task 4: Create a CloudFront Distribution

Amazon's content delivery network (CDN), CloudFront, speeds up content delivery by caching it at various “Edge locations” globally. This setup is particularly effective for accelerating the load times of videos and images.

For a simple site with few files like ours, the performance boost might not be very noticeable. However, using CloudFront is essential for applying the TLS/SSL certificate that we created in the previous task.

Search for CloudFront in the search box.

Click on Create a CloudFront distribution.

The origin domain is where our website files are stored, which is in S3. If you filter by typing in S3, it will show our bucket.

However, we'll get a message about using the website endpoint instead of the bucket endpoint. Click on Use website endpoint and AWS will update the endpoint for us.

Scroll down to the Default cache behavior section, then under Viewer, select Redirect HTTP to HTTPS. This will help ensure that all traffic to our website is encrypted, enhancing security and protecting user data.

Scroll down to Web Application Firewall (WAF) and select Do not enable security protections.

In the next section, Settings, click on Add item.

Provide your domain name there and select your certificate in Custom SSL certificate.

Scroll to the bottom of the page.

For Default root object, enter index.html (our default home page) and then click on Create distribution.

It will take several minutes for the CloudFront distribution to finish deploying.

To test that everything is working with CloudFront and the TLS/SSL certificate, copy the Distribution domain name.

Open a new tab in the browser and navigate to that address.

Now, the last thing is to use our custom domain name to load the site instead of this lengthy CloudFront distribution domain name.


Task 5: Updating DNS Record

At the moment, the CNAME Record in Cloudflare is pointing to the S3 bucket.

Instead, we want Cloudflare to point to the CloudFront distribution, which then points to S3.

Navigate back to your DNS Records settings.

Instead of routing traffic to S3, update the DNS record to point to your CloudFront distribution.

Click on Save.


Task 6: The Final Show

Alright! Type your custom domain name in the new tab in your browser and hit the ENTER button.

If everything worked, we should be able to load our static website without our own custom domain name on a secure connection.

Aha! It worked.

The static files (coming from S3 via CloudFront) load on the custom domain name (from Cloudflare) over a secure connection using the TLS/SSL certificate (from Certificate Manager).


Conclusion

We utilized an S3 bucket for storing our website files & leveraged CloudFront for efficient content distribution. We secured our site with a certificate from AWS ACM, and updated DNS records to enable access through our custom domain, making a scalable, secure, and performant static website on AWS.

Here's what we've built:


Task 7: Clean Up

  1. Deleting CloudFront distribution.

    Before deleting our Distribution, we have to Disable it.

    It'll take a couple of minutes even after being disabled to be able to finally delete.

  2. Deleting records from DNS Records.

    Navigate to your DNS Records settings and delete the created records.

  3. Delete the certificate from Certificate Manager.

    Navigate to Certificate Manager. Select your certificate and then click on Delete.

  4. Deleting S3 bucket.

    Navigate to your bucket and then empty your bucket, deleting all the files contained.

    After you've deleted all the contents, select your bucket and click on Delete.

Now we have deleted all the resources that we used during the lab session.


Alright, that was it for this project.

See you in the next one!

Did you find this article valuable?

Support AWS X SUJAN by becoming a sponsor. Any amount is appreciated!