Host a Website on Amazon S3

Deploy a static portfolio site to AWS S3 using the AWS CLI.

Introduction

30 Second Summary

Every website needs a home on the internet. Cloud platforms like AWS let you host sites that are fast, reliable, and accessible to anyone in the world.

In this project, you will deploy a static website to Amazon S3 using the AWS CLI. You'll create a portfolio landing page, configure cloud storage for web hosting, and make your site live at a public URL.

What You'll Build

A personal portfolio landing page deployed to Amazon S3 and accessible to anyone on the internet via a public URL.

By the end of this project, you'll have:

  • A simple HTML/CSS landing page built from scratch and previewed locally.
  • An S3 bucket configured for static website hosting with public access permissions.
  • A live website URL you can share with anyone, deployed entirely from your command line.
  • Secret Mission: Add a custom 404 error page and practice incremental deployments with aws s3 sync.

Are there any prerequisites?

None. This project includes full setup instructions for every tool you need, including your AWS account and the AWS CLI. No prior cloud experience is required.

Set Up Your AWS Account and CLI

Before you can deploy anything to the cloud, you need an AWS account and a way to talk to AWS from your computer.

In this step, you will create an AWS account, install the AWS CLI (Command Line Interface), and configure it with your credentials. This gives your computer permission to create and manage AWS resources on your behalf.

In this step, get ready to:
  • Create an AWS account (or sign in to your existing one).
  • Install AWS CLI v2 on Windows.
  • Create an IAM user and configure the CLI with your credentials.
Create an AWS account

AWS offers a Free plan for new accounts that includes up to $200 in credits. A small HTML website on Amazon S3 will stay well within these credits.

  • Open your browser and go to https://aws.amazon.com/free/.
  • Click Create a Free Account (or sign in if you already have an account).
  • Follow the prompts to enter your email, set a password, and provide payment information.
  • Choose the Free plan when prompted.
  • Wait for your account to activate. This usually takes a few minutes but can take up to 24 hours.

What is AWS Free Tier?

New AWS customers receive up to $200 in Free Tier credits ($100 upon sign-up, plus up to $100 more). The Free plan is available for 6 months, and credits expire 12 months from account creation.

A few HTML files on S3 cost fractions of a cent to store, so this project will not use any meaningful portion of your credits.

✔️ I already have an AWS account

Great. Sign in to the AWS Management Console at https://console.aws.amazon.com and continue to the next substep.

ⓧ I just created my account

Once your account is active, sign in to the AWS Management Console at https://console.aws.amazon.com. You should see the Console Home dashboard.

Install AWS CLI v2 on Windows

The AWS CLI lets you run commands in your terminal to manage AWS resources. Instead of clicking through the console for every action, you type a single command.

  • Download the AWS CLI v2 installer for Windows from this link: https://awscli.amazonaws.com/AWSCLIV2.msi.
  • Run the downloaded AWSCLIV2.msi file and follow the installer prompts (accept the defaults).
  • Once the installer finishes, open a new Command Prompt window. Press the Windows key, type cmd, and press Enter.
  • Verify the installation by running:
aws --version

You should see output similar to aws-cli/2.x.x Python/3.x.x Windows/10 exe/AMD64.

✔️ I see aws-cli/2.x.x

Your AWS CLI is installed and ready. Continue to the next substep.

ⓧ I see aws-cli/1.x.x

You have an older version installed. Download and run the latest installer from https://awscli.amazonaws.com/AWSCLIV2.msi to upgrade to v2. After the installer finishes, close your Command Prompt and open a new one, then run aws --version again.

ⓧ Command not found

The CLI is not installed yet, or the Command Prompt was opened before the installation finished.

The new window is important because your system PATH only updates for new terminal sessions.

Create an IAM user and configure the CLI

The AWS CLI needs credentials to prove it has permission to manage your resources. You will create a dedicated IAM user (instead of using your root account) and generate an access key for it.

Why not use the root account?

Your root account has unlimited access to everything. Creating a separate IAM user with only the permissions you need is a security best practice. If credentials are ever compromised, the blast radius is limited.

First, create the IAM user in the AWS Console:

  • In the AWS Management Console, type IAM in the search bar at the top and select the IAM service.
  • In the left navigation pane, click Users.
  • Click Create user.
  • Enter a user name (for example, s3-deploy-user) and click Next.
  • On the Set permissions page, select Attach policies directly.
  • Search for AdministratorAccess and check the box next to it.
  • Click Next, then click Create user.

Now generate an access key for this user:

  • Click on the user name you just created to open the user details.
  • Select the Security credentials tab.
  • In the Access keys section, click Create access key.
  • On the best practices page, select Other as your use case, then click Next.
  • Click Create access key.
  • Copy your Access key ID and Secret access key and save them somewhere safe (for example, a text file on your desktop). You will not be able to see the secret key again after closing this page.

Save your secret key now

The Secret access key is shown only once at creation time. If you close this page without copying it, you will need to delete the key and create a new one.

Finally, configure the AWS CLI with your new credentials. Switch back to your Command Prompt and run:

aws configure

The command will prompt you for four values. Enter them one at a time:

  • AWS Access Key ID: paste the Access Key ID you saved.
  • AWS Secret Access Key: paste the Secret Access Key you saved.
  • Default region name: enter us-east-1.
  • Default output format: enter json.

What does aws configure do?

This command stores your credentials and preferences in a local configuration file so you do not need to type them every time you run a command. The region us-east-1 tells the CLI which AWS data center to use by default.

Verify your CLI is configured correctly by running:

aws sts get-caller-identity

You should see JSON output containing your account ID, user ARN, and the username you created. This confirms the CLI can authenticate with AWS.

Seeing an error about credentials?

Make sure you pasted the Access Key ID and Secret Access Key without any extra spaces. Run aws configure again to re-enter your values.

If you see a message about an invalid key, go back to the IAM console and create a new access key for your user.

Help me fix my AWS CLI credentials error.

Your AWS account is active and your CLI is ready to go. Next up, you will create the HTML files for your website.

Create Your Website Files

Your AWS environment is configured and ready to deploy resources to the cloud.

Now you need a website to deploy. In this step, you'll build a simple portfolio landing page using HTML and CSS, then preview it locally before pushing it to Amazon S3.

In this step, get ready to:
  • Create a my-website folder on your desktop.
  • Write a portfolio landing page with HTML and inline CSS.
  • Preview your page in a browser to confirm it displays correctly.
Create your project folder and landing page

You need a dedicated folder to hold your website files. This keeps everything organized and makes deployment easier later.

  • In your Command Prompt, move to your Desktop by running this command:
cd %USERPROFILE%\Desktop
  • Create the my-website folder by running:
mkdir my-website
  • Confirm the folder exists by running:
dir

You should see my-website listed as a directory in the output.

Don't see the my-website folder?

Make sure you ran cd %USERPROFILE%\Desktop first. If you see an error saying the directory already exists, that means you already created it. Run dir to confirm.

Help me troubleshoot why my folder wasn't created on Windows.

Now you'll create the index.html file that will become your live website.

  • Open Notepad with your new file by running this command:
notepad my-website\index.html

Notepad will ask to create the file

Since index.html doesn't exist yet, Notepad displays a dialog asking "Do you want to create a new file?" Click Yes to continue.

  • Copy all of the HTML below and paste it into the empty Notepad window:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Portfolio</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #fff;
        }
        .container {
            text-align: center;
            padding: 2rem;
            max-width: 600px;
        }
        h1 {
            font-size: 3rem;
            margin-bottom: 1rem;
        }
        p {
            font-size: 1.25rem;
            opacity: 0.9;
            line-height: 1.6;
            margin-bottom: 2rem;
        }
        .badge {
            display: inline-block;
            background: rgba(255, 255, 255, 0.2);
            padding: 0.5rem 1rem;
            border-radius: 2rem;
            font-size: 0.9rem;
            backdrop-filter: blur(10px);
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Hello, World!</h1>
        <p>Welcome to my portfolio. This site is hosted on Amazon S3 and deployed using the AWS CLI.</p>
        <span class="badge">Powered by AWS S3</span>
    </div>
</body>
</html>

What does this code do?

This is a complete HTML page with styles included directly in the <style> tag. Here's what each section handles:

  • The * reset removes default browser margins and padding so your layout looks consistent.
  • The body styles create a purple gradient background and center everything vertically and horizontally using flexbox.
  • The .container holds your heading, paragraph text, and a badge with a frosted glass effect.
  • Press Ctrl+S to save the file.
  • Close Notepad.
  • Back in your Command Prompt, confirm the file was created by running:
dir my-website

You should see index.html listed inside the my-website folder.

Don't see index.html?

If the file shows as index.html.txt, Notepad added an extra extension. Delete it and try again. When Notepad asks to save, make sure the filename still says index.html and not index.html.txt.

If the folder appears empty, make sure you pressed Ctrl+S in Notepad before closing it.

Help me figure out why my index.html file wasn't saved correctly.

✔️ Awesome, I've got everything!

Great. Make sure you've saved and closed the file before moving on.

ⓧ I'd like to double check the full code

Here is the complete index.html file. Make sure yours matches exactly:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Portfolio</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #fff;
        }
        .container {
            text-align: center;
            padding: 2rem;
            max-width: 600px;
        }
        h1 {
            font-size: 3rem;
            margin-bottom: 1rem;
        }
        p {
            font-size: 1.25rem;
            opacity: 0.9;
            line-height: 1.6;
            margin-bottom: 2rem;
        }
        .badge {
            display: inline-block;
            background: rgba(255, 255, 255, 0.2);
            padding: 0.5rem 1rem;
            border-radius: 2rem;
            font-size: 0.9rem;
            backdrop-filter: blur(10px);
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Hello, World!</h1>
        <p>Welcome to my portfolio. This site is hosted on Amazon S3 and deployed using the AWS CLI.</p>
        <span class="badge">Powered by AWS S3</span>
    </div>
</body>
</html>
Preview your page in the browser

Before deploying to the cloud, you should confirm your page looks right locally. This saves you from uploading a broken file.

  • Open your page in the browser by running this command:
start my-website\index.html

Your default browser opens with a purple gradient background. You should see a large "Hello, World!" heading, a welcome paragraph, and a "Powered by AWS S3" badge at the bottom.

What is a static website?

A static website is made of fixed files (HTML, CSS, images) that display the same content for every visitor. There is no server-side code processing requests.

This makes static sites perfect for S3 hosting because S3 simply serves files. No application server needed.

Page doesn't look right?

If you see raw HTML code instead of a styled page, your file may have been saved with a .txt extension. Check that the file is named exactly index.html in your my-website folder.

If the page is blank, open the file in Notepad again and make sure you pasted all of the HTML including the opening <!DOCTYPE html> and the closing </html> tag.

Help me figure out why my HTML page isn't displaying correctly in the browser.

Your website files are ready to go. Next up, you'll create an S3 bucket in the cloud and configure it to host these files as a live website.

Create and Configure Your S3 Bucket

Your website files are ready. Now you need somewhere on the internet to put them.

In this step, you will create an Amazon S3 bucket, turn on its built-in static website hosting feature, and open it up so anyone on the internet can view your site.

In this step, get ready to:
  • Create an S3 bucket with a globally unique name.
  • Enable static website hosting on the bucket.
  • Disable Block Public Access so visitors can reach your site.
Create your S3 bucket

Every file you upload to S3 lives inside a container called a bucket. Bucket names must be globally unique across all AWS accounts, so you will include your name or a random string to make yours one-of-a-kind.

  • Create your S3 bucket by running this command in your Command Prompt:
aws s3 mb s3://[[BUCKET_NAME="your-unique-bucket-name"]] --region us-east-1

What does this command do?

  • aws s3 mb stands for "make bucket." It creates a new, empty S3 bucket in your AWS account.
  • --region us-east-1 tells AWS to create the bucket in the US East (N. Virginia) region.

What should my bucket name look like?

Bucket names must be 3-63 characters and can only contain lowercase letters, numbers, and hyphens. No periods, no uppercase. A good pattern is my-portfolio-yourname-2026 where you swap in your actual name.

  • You should see a message like make_bucket: your-unique-bucket-name confirming the bucket was created.

Seeing a BucketAlreadyExists error?

This means someone else in the world already owns that bucket name. Try a more unique name by adding extra numbers or your initials.

Help me fix my bucket name error.

Enable static website hosting

S3 buckets can store any type of file, but they do not serve files as a website by default. You need to turn on the static website hosting feature and tell S3 which file is your homepage.

  • Enable static website hosting on your bucket by running:
aws s3 website s3://[[BUCKET_NAME="your-unique-bucket-name"]]/ --index-document index.html --error-document error.html

What does this command do?

  • aws s3 website sets the website configuration for a bucket.
  • --index-document index.html tells S3 to serve index.html when someone visits the root URL of your site.
  • --error-document error.html tells S3 which page to show when a visitor requests a page that does not exist.
  • This command produces no output if it succeeds. No news is good news.

Seeing a NoSuchBucket error?

Double-check that the bucket name in this command matches exactly what you used in the aws s3 mb command. Bucket names are case-sensitive and must match character-for-character.

Help me fix my website hosting configuration.

Disable Block Public Access

By default, Amazon S3 blocks public access to your account and buckets. This is a safety feature that prevents accidental data exposure. For a public website, you need to explicitly disable these protections on this specific bucket.

  • Disable all four Block Public Access settings on your bucket by running:
aws s3api put-public-access-block --bucket [[BUCKET_NAME="your-unique-bucket-name"]] --public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"

What does this command do?

S3 has four separate Block Public Access settings that each protect a different aspect of public access. Setting all four to false disables the safety guards so you can attach a public policy in the next step.

  • BlockPublicAcls controls whether public ACLs can be applied.
  • IgnorePublicAcls controls whether existing public ACLs are ignored.
  • BlockPublicPolicy controls whether public bucket policies can be attached.
  • RestrictPublicBuckets controls whether access is restricted when a public policy exists.

Why disable all four settings?

In the next step, you will attach a bucket policy that grants everyone read access to your website files. If BlockPublicPolicy is still true, S3 will reject that policy. Disabling all four ensures nothing blocks your website from being publicly readable.

  • This command produces no output if it succeeds.
  • Verify the settings applied correctly by running:
aws s3api get-public-access-block --bucket [[BUCKET_NAME="your-unique-bucket-name"]]
  • You should see all four values set to false in the output.

Seeing an Access Denied error?

Your IAM user may not have the s3:PutBucketPublicAccessBlock permission. Go back to the IAM console and make sure your user has the AmazonS3FullAccess policy attached.

Help me fix my Access Denied error.

Your bucket is created, configured for hosting, and open for public access. Next up, you will set the bucket policy and deploy your website files.

Set Bucket Permissions and Deploy

In the previous step, you created your S3 bucket and configured it for static website hosting. Now it is time to make your website publicly accessible and deploy your files.

By default, Amazon S3 blocks all public access to your bucket. You already disabled Block Public Access, but the bucket still needs a policy that explicitly grants read permission to everyone on the internet.

In this step, get ready to:
  • Apply a public bucket policy that allows anyone to view your website files.
  • Upload your website files to S3 using the AWS CLI.
  • Visit your live website in a browser and confirm it works.
Apply a public read policy to your bucket

A bucket policy is a JSON document that defines who can access your bucket and what actions they can perform. You need a policy that grants the s3:GetObject permission to everyone (*) for all objects in your bucket.

  • In your Command Prompt, make sure you are on your Desktop (where your my-website folder lives) by running this command:
cd %USERPROFILE%\Desktop
  • Create a file called policy.json on your Desktop by running this command:
notepad policy.json
  • Notepad will ask if you want to create a new file. Click Yes.
  • Paste the following JSON into the file:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::[[BUCKET_NAME="your-unique-bucket-name"]]/*"
        }
    ]
}
  • Replace your-unique-bucket-name with the actual name of the bucket you created in the previous step.
  • Save the file in Notepad (Ctrl+S) and close it.

What does this policy do?

This policy has one statement that grants everyone ("Principal": "*") permission to read (s3:GetObject) any object in your bucket.

The Resource field uses your bucket's ARN followed by /* to target all objects inside it. Without this policy, visitors would get an Access Denied error when trying to view your site.

  • Apply the policy to your bucket by running this command:
aws s3api put-bucket-policy --bucket [[BUCKET_NAME="your-unique-bucket-name"]] --policy file://policy.json
  • If the command succeeds, it returns no output. That means the policy was applied.

What does this command do?

The aws s3api put-bucket-policy command attaches a JSON policy document to your bucket. The --policy file://policy.json flag tells the CLI to read the policy from your local file instead of passing it inline.

Seeing an Access Denied error?

Make sure you disabled all four Block Public Access settings in the previous step. If Block Public Access is still enabled, S3 rejects any policy that grants public access.

Also check that the bucket name in your policy.json matches the actual bucket name exactly. Bucket names are case-sensitive.

Help me troubleshoot my bucket policy error.

Upload your website files to S3

With permissions set, you can now deploy your website files to the bucket. The aws s3 sync command copies files from a local folder to your S3 bucket.

  • Upload your website by running this command:
aws s3 sync ./my-website s3://[[BUCKET_NAME="your-unique-bucket-name"]]
  • You should see output showing index.html being uploaded to your bucket.

What does aws s3 sync do?

The aws s3 sync command compares your local files to what is already in the bucket and only uploads new or changed files. This makes future deployments fast because unchanged files are skipped.

This is the same pattern used in real CI/CD pipelines for deploying static websites.

Upload failed or no files shown?

Make sure you are in your Desktop directory (where the my-website folder is). Run dir my-website to confirm index.html is listed inside.

Check that your bucket name is spelled correctly with no extra spaces.

Help me fix my aws s3 sync upload issue.

Visit your live website

Your website is now live on the internet. S3 static websites are served at a specific endpoint URL based on your bucket name and region.

  • Open your web browser.
  • Paste the following URL into your address bar (replace the bucket name with yours):
http://[[BUCKET_NAME="your-unique-bucket-name"]].s3-website-us-east-1.amazonaws.com
  • You should see your portfolio page with a purple gradient background, the heading "Hello, World!" in white text, and a "Powered by AWS S3" badge at the bottom.

Why HTTP and not HTTPS?

S3 static website endpoints only serve content over HTTP. For HTTPS, you would need to add Amazon CloudFront (a CDN) in front of your bucket. That is beyond the scope of this project, but good to know for production websites.

Seeing a 403 Forbidden or blank page?

A 403 error usually means your bucket policy was not applied correctly. Re-run the aws s3api put-bucket-policy command and check that the bucket name in policy.json matches exactly.

If you see a 404 error, confirm that index.html was uploaded by running:

aws s3 ls s3://[[BUCKET_NAME="your-unique-bucket-name"]]

Help me figure out why my S3 website is not loading.

Your static website is live on the internet. Anyone with the URL can now visit your page. Next up, you will take on a secret mission to add a custom 404 error page and practice incremental deployments.

Secret mission

Add a 404 Page and Redeploy

What happens when someone visits a page that doesn't exist on your site? Right now, they get an ugly default error. In this mission, you'll create a custom 404 page and learn how real deployments work with incremental sync.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

This project uses Amazon S3 storage, which costs virtually nothing for a few HTML files. New AWS accounts have up to $200 in Free Tier credits that cover this easily.

Resources you used:

  • One S3 bucket (your-unique-bucket-name) with static website hosting enabled, containing index.html and 404.html.
  • Local my-website folder on your Desktop.
  • AWS CLI v2 installed on your machine.

Keep everything running

No action needed. Choose this if you plan to keep experimenting with your site or building more AWS projects.

  • Your site stays live at its S3 website URL. A few HTML files cost fractions of a cent per month to store.
  • AWS CLI stays installed and configured for future AWS projects.
  • Your local my-website folder remains on your Desktop for future edits.

Pause - I'll come back to this later

S3 static websites have no running compute to pause. Your site is just files sitting in storage.

Your only options are to keep it live (essentially free) or delete it entirely. There is no in-between state for S3 static hosting.

Delete - I don't want to use this again

Remove all project resources and start fresh. Follow each step below.

  • Delete your S3 bucket and all its contents by running this command in your Command Prompt:
aws s3 rb s3://[[BUCKET_NAME="your-unique-bucket-name"]] --force

What does this command do?

The --force flag tells AWS to empty the bucket first (deleting all objects inside), then delete the bucket itself. This is permanent and cannot be undone.

  • Delete your local my-website folder. On Windows, run this in Command Prompt:
rmdir /s /q %USERPROFILE%\Desktop\my-website

On macOS or Linux, run:

rm -rf ~/Desktop/my-website
  • Uninstall AWS CLI v2. On Windows, open Apps & features in Windows Settings, find AWS Command Line Interface in the list, and select Uninstall.
  • Remove your stored AWS credentials by deleting the .aws folder in your user profile directory:
rmdir /s /q %USERPROFILE%\.aws

What is the .aws folder?

When you ran aws configure, your Access Key ID and Secret Access Key were saved in this folder. Deleting it removes those credentials from your machine.

That's a Wrap!

That's a Wrap!

Nice work! You just deployed your first website to the cloud using Amazon S3 and the AWS CLI.

You've learned how to:

  • Created and configured an S3 bucket for static website hosting, including permissions and public access settings.
  • Set up the AWS CLI and used it to create buckets, configure hosting, apply policies, and deploy files from your command line.
  • Deployed a live website accessible to anyone on the internet via a public S3 website endpoint.
  • Added a custom 404 error page and practiced incremental deployments with aws s3 sync.

Ready to quiz yourself?