Build a static website using S3 & Route 53 with Terraform

I wrote an article in the past about hosting a static website in S3 using the AWS CDK. Now while I’m learning Terraform, I wanted to repeat the same process and connect that site to a custom domain on Route 53.

In this post, we’ll host a static site on S3 and add the appropriate route 53 records to provide access to this website when a user loads our custom domain in the browser.

https://www.pexels.com/photo /turned-on -computer-monitor-displaying-text-270360/

Site Creation

For this demo, we’ll create a simple index.html page that we could host on S3 in the following section:

Setting Up the Infrastructure

In this section, we’ll set up our local environment and start writing our infrastructure as code. Our infrastructure would be as follows:

Image description

When the user enters the URL in the browser, the request leaves the browser looking for the IP associated with the domain name: DNS will point to the zone hosted on Route 53 via its delegation system, then routes the request to the website hosted on the S3 bucket via from an A record (maps hostname to IPv4 address).

NOTE Route 53 offers hosting and registration services. If you have your domain registered with Route 53, you will have a hosted zone created automatically; deleting that hosted zone and creating a new one would cause problems. So I would recommend caution. If your domain is registered with an external service, you can still follow this post (for more information see: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/migrate-dns-domain-in-use .html)

Prerequisites

First, start installing Terraform if you don’t already have it installed: run brew tap hashicorp/tap and brew install hashicorp/ tap/terraform if you are on Macbook. For other operating systems, see the docs.

See Also:  How to Make a Chatbot for a Website in Minutes

Second, install the AWS CLI and set up your AWS credentials on your machine: https://docs.aws.amazon.com/cli/latest/userguide/cli – configure-files.html.

S3 bucket and website hosting

In this section, we’ll create an S3 bucket to host our website’s static files (in our case, that’s the index.html we created earlier). Note that for this to work, the bucket name in S3 must be exactly your domain name (for example, example.com or www.example.com).

Contrary to my previous post for programming Lambda with Terraform , where I listed all the resources in a single Terraform configuration file, I’ll try to make the Terraform files more structured in this post.

In an infrastructure-specific folder, create a provider.tf file to define the cloud provider we are working with, which is AWS in our case, and specifying the region (Sydney, feel free to change it to the AWS region where you would like to host your site):

Next, create a new variables.tf file where we declare the variables that we would use as part of our configuration:

Now, we need to configure the repository. To host a public static website in S3, we would need to have the following properties in the bucket:

  • Disable “Block all public access” – This is disabled by default in Terraform, so there is no nothing to do about it
  • Set “Static Website Hosting” enabled and provide an index document (eg index.html); could you also provide an error document
  • Attach a repository policy to allow read access
See Also:  Theater Resume Template (Guide & Example)

create an s3.tf file to configure our repository:

We have used the variables declared earlier in the variables.tf file to define the name of the repository.

Add the following resource to configure your repository as a static website:

Let’s move on to attaching a repository policy:

We’re loading the policy to a file called s3-policy.json – create this file and add the following content to it:

That’s mostly all what we need to do to get our website up and running. Now run the following commands to deploy your infrastructure:

  • terraform plan to see the resources to provision (or change)
  • terraform apply to deploy them

Navigate to the AWS console and verify that your bucket has been created and has:

  • Block all public access turned off in the Permissions tab
  • Correct bucket policy in the Permissions tab
  • Static website hosting enabled in the Properties tab

We still need to load the index.html. I’m used to using the AWS CLI from the CI/CD pipeline, but we could also do it using Terraform.Here’s how to do it:

Validate that index.html was created inside your bucket in the AWS console. Navigate to the bottom of the Properties tab and click the “Repository Website Endpoint” link. This will display the content of your index.html in a new page.

Note S3 assigns a binary/octet stream content type by default to any uploaded file . This means that the browser will download index.html when it requests your site instead of opening the file and displaying HTML. To fix this you can add: content_type=”text/html” to the block that loads the index.html file. Of course this is not sustainable with more files and types, but in that case you could create a JSON mapping file that would explain what each file type is (eg {“.html”: “text/html”}) and then iterate through each file to set the content type.

I found it easier to use the AWS CLI to upload your files instead of using Terraform.

Configure Route 53 to point to our newly created website

If you’ve registered your domain with AWS Route 53, you’ll find an automatically created hosted zone. Otherwise, if your domain is registered elsewhere, use the following settings to create a hosted zone:

See Also:  Netplay Guide

Create an A record to map your domain name to the S3 bucket:

If you skipped creating the hosted zone, you can retrieve it via the command line: aws route53 list-hosted-zones, then use the ID and domain in their corresponding fields in the above snippet.

NOTE I already had my domain registered so I had an existing hosted zone on route 53, got a new hosted zone created with the new terraform plan and ended up with 2 hosted zones for the same domain. I deleted the original hosted zone and that was a mistake because DNS resolvers usually cache the name from nameservers for 2 days which puts my domain offline for 2 days. If you had similar issues, this page is very helpful: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/troubleshooting-new-dns-settings-not-in-effect.html#troubleshooting-new -dns -settings-not-in-effect-updated-wrong-hosted-zone

I hope this was helpful. Please let me know your thoughts.

.

Leave a Reply

Your email address will not be published. Required fields are marked *