Configure a static Next.js website on Amazon S3
Tags: aws, nextjs, tutorial, beginners
Published: 2022-08-05 19:22:00

This is the start of a multi-blog series as I make my way through the Cloud Resume Challenge. As advertised, the [Cloud Resume Challenge](https://cloudresumechallenge.dev/) is a popular 16-step project that takes you from certified to hired in cloud. 

I already have a job and have passed two AWS exams. Still, a couple of months ago, I ventured off to see what's out there, and oh boy, the number of cloud questions I could not answer at the interviews made me really think, "I don't know my stuff. I owe it to the people involved to do a really good job here". The worst part is I didn't blindly send out resumes and hope these companies would call me; I reached out to my connections and asked them to put my name out there. Some of which returned to me with opportunities that have not been made public yet. I underperformed in these interviews, but I now know what these companies are looking for.

Anyway, I don't want to ramble on about how I replayed these interviews in my head because this is about what I'm going to do moving forward to make myself a better candidate, so whenever I decide to venture off again, I'll be prepared!

## Chunk 1: Building the frontend
The minimum requirement for this part of Chunk 1 is to have an HTML page with some CSS and serve the files in an Amazon S3 bucket.

It sounds simple enough, but since I love frontend development, so I decided to add the **Developer Mod**. I'll build my website using a JavaScript framework instead of just HTML and CSS.

Stack:
- Next.js
- Amazon S3

### Getting Started with Next.js
I made a GitHub repo [here](https://github.com/cindyledev/cloud-resume-challenge) if you wanna see what I have so far. For this part of Chunk 1, you really just need to have a Next.js app, then `build` and `export` it.

1. Create a new Next.js app using `create-next-app`. We have been using [`pnpm`](https://pnpm.io/) on [Telescope](https://github.com/Seneca-CDOT/telescope), and I simply cannot go back to `npm`.

```bash
pnpm create next-app
```

2. Run `pnpm run dev` to start the development server on `http://localhost:3000` and view your initial Next.js application.

3. Update the `build` script in the `package.json` file.

```diff
  "scripts": {
    ...
-    "build": "next build",
+    "build": "next build && next export",
    ...
  },
```

4. Run `pnpm run build` will generate an `out` directory with everything you need for your static website.

```diff
cloud-resume-challenge
  ├── .next
  ├── node_modules
+ ├── out
+ │   ├── _next
+ │   ├── favicon.ico
+ │   ├── index.html
+ │   └── vercel.svg
  ├── pages
  ├── public
  ├── styles
  ├── .eslintrc.json
  ├── .gitignore
  ├── next.config.js
  ├── package.json
  ├── pnpm-lock.yaml
  └── README.md
```

### Host the Next.js website on Amazon S3

I mostly followed [Tutorial: Configuring a static website on Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/HostingWebsiteOnS3Setup.html) for this part. However, to proceed with the CloudFront Distribution in a later blog post, you will need to **Block all public access** for the S3 bucket.

1. In the [Amazon S3 console](https://console.aws.amazon.com/s3/), choose **Create bucket** and enter the following:
  - Bucket name: **cindy-crc**
  - AWS Region: **US East (N. Virginia) us-east-1**
  - Uncheck **Block _all_ public access**
  - Bucket Versioning: **Enable**
2. Click on **Create**
3. Once the bucket as been created, upload everything from your `out` folder into the bucket
4. Click on your newly created bucket from the list and go to the **Properties** tab
5. Go all the way to the bottom, under **Static website hosting** and Enable Static website hosting
6. Specify the **Index document** as `index.html`
7. Save your changes, and you should be able to see a **Bucket website endpoint** like [http://cindy-crc.s3-website-us-east-1.amazonaws.com/](http://cindy-crc.s3-website-us-east-1.amazonaws.com/)
8. In the **Permissions** tab of your bucket, add a new Bucket policy and save the changes

```diff
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
-                "arn:aws:s3:::Bucket-Name/*"
+                "arn:aws:s3:::cindy-crc/*"
            ]
        }
    ]
}
```

9. Test your website endpoint by visiting [http://cindy-crc.s3-website-us-east-1.amazonaws.com/](http://cindy-crc.s3-website-us-east-1.amazonaws.com/)

10. You can stop here if you're satisfied with having a static website on Amazon S3, but for the purpose of the Cloud Resume Challenge, which will move on to using CloudFront, you need to remove the Bucket policy and Block all public access again.