Host Your Portfolio on Amazon S3

Publish your HTML, CSS, and JavaScript portfolio with Amazon S3 static hosting.

Introduction

30 Second Summary

When someone asks to see your work, files stored only on your computer give them nothing to open. That friction can end the conversation before your projects get seen.

In this project, you will publish your existing portfolio as a public static website with Amazon Simple Storage Service (Amazon S3). You will test the live site from a visitor's perspective.

What You'll Build

Picture sending one link to a live page that displays your own design, text, projects, images, and interactive features.

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

  • A live portfolio at your S3 website endpoint that anyone can open in a browser.
  • A working visitor experience where your CSS, images, navigation links, downloadable files, external project links, and client-side JavaScript behave as they do locally.
  • Clear deployment evidence showing 403 (Access Denied) while the objects are private. The same endpoint serves your portfolio once a public-read bucket policy grants access. A nonexistent path returns 404 (Not Found).
  • Secret Mission: Replace one live image at the same object key. Prove the replacement is served. Restore the original from your local backup.

Are there any prerequisites?

This project requires a Windows computer, an AWS account with permission to manage Amazon S3 public access, and an existing HTML, CSS, and JavaScript portfolio whose home page can be named index.html.

The folder you publish contains only files intended for public viewing. Credentials, environment files, private documents, unpublished assets, and source maps containing secrets stay elsewhere.

Before We Start

This step sets a clear publishing boundary for your Amazon S3 portfolio. Only public static files belong online, while credentials, private documents, environment files, secret-bearing source maps, and unpublished assets stay on your computer. The S3 website endpoint uses HTTP. Custom-domain HTTPS belongs in a later CloudFront project.

Check Your Portfolio and AWS Access

Your portfolio’s folder structure controls how its file paths resolve after upload. If index.html sits inside an extra nested folder, Amazon S3 cannot use it as the home page from the bucket root.

You will inspect the approved folder in File Explorer. You will test the local site in Microsoft Edge.

You will finish by signing in to the AWS Management Console. The Amazon S3 bucket list confirms that the cloud side is ready.

In this step, get ready to:
  • Confirm index.html sits at the portfolio folder root with every asset path intact.
  • Test the portfolio locally in Microsoft Edge.
  • Reach the Amazon S3 General purpose buckets page.
Check the portfolio folder structure

Visible extensions let you verify the home page’s full filename. Correct folder placement keeps every relative asset path pointing to the intended file.

  • Open File Explorer by pressing Windows logo key + E.
  • Use the left navigation pane to select the approved portfolio folder.
  • Select View in the File Explorer toolbar.
  • Select Show.
  • Select File name extensions.
  • Confirm index.html appears directly inside the selected portfolio folder.
  • Confirm each referenced CSS, JavaScript, image, download, navigation target, or other public asset remains at its intended relative path.

You should now see the full extension on every file. The home page should appear as index.html at the top level of the selected folder.

Can’t See the Right Folder Structure?

  • Use the inner folder as your portfolio folder if it contains index.html plus every referenced asset.
  • Repeat the File name extensions selection if the suffixes remain hidden.

Help me check why my portfolio folder does not show index.html at its root.

Test the portfolio locally

A local browser test reveals broken paths before the files reach Amazon S3. It also confirms that the version you plan to upload is the version visitors should see.

  • Press the Windows key to open the search bar.
  • Type Microsoft Edge into the search bar.
  • Press Enter to open Microsoft Edge.
  • Return to File Explorer from earlier.
  • Drag index.html from the portfolio folder into the Microsoft Edge window.

You should see your portfolio load from a local file address in Microsoft Edge.

  • Inspect the page layout for missing styling.
  • Open every image or downloadable file linked from the page.
  • Follow every navigation link or project link.
  • Use every client-side JavaScript interaction.

Every visible asset should load from its intended relative path. Each local interaction should respond as designed.

Missing Styles or Assets?

  • Compare the missing asset’s path in index.html with its location in File Explorer.
  • Match the capitalization of every referenced folder name.
  • Restore any missing public asset from your approved local portfolio source.

Help me troubleshoot a local portfolio asset that does not load in Microsoft Edge.

Confirm access to Amazon S3

The General purpose buckets page is the starting point for the bucket you create next. Reaching it proves that your AWS account can access Amazon S3.

Your AWS credentials stay inside the AWS sign-in page throughout this step.

Before you load the console, consider which S3 page you expect the direct URL to open.

  • Return to Microsoft Edge from earlier.
  • Click the address bar.
  • Enter https://console.aws.amazon.com/s3/.
  • Press Enter.
  • Complete the AWS account sign-in flow if prompted.
  • Confirm the page heading shows General purpose buckets.

You should see the Amazon S3 General purpose buckets page. This confirms that your account can reach the bucket list.

Can’t Reach the Bucket List?

  • Reload https://console.aws.amazon.com/s3/ after completing the AWS sign-in flow.
  • Ask your AWS administrator for permission to manage S3 public access if the account cannot display the bucket list.

Help me troubleshoot access to the Amazon S3 General purpose buckets page.

Strong start. Your local portfolio works from its approved folder while your AWS account can reach Amazon S3.

Next, you’ll place the verified portfolio in its Amazon S3 bucket. You’ll also generate its website endpoint.

Upload a Private Portfolio

Your portfolio already works from its local folder. Now Amazon S3 needs an online copy that preserves the same paths.

Website hosting controls the endpoint. Object permissions control who can read each file.

In this step, get ready to:
  • Create a general purpose bucket with private access settings.
  • Upload your portfolio while preserving its folder structure.
  • Enable static website hosting to observe the planned private-access result.
Create your private S3 bucket

An S3 bucket is a container for your portfolio objects. Each bucket lives in one AWS Region.

Bucket names use 3 to 63 lowercase letters, numbers, periods, or hyphens. The name must begin with a letter or number.

Know What Can Cost Money

Creating this bucket starts persistent AWS usage. Amazon S3 has no minimum charge.

Storage, requests, data retrieval, or data transfer can incur charges. Your final cost depends on usage.

  • Click Create bucket on the General purpose buckets page.
  • Choose an AWS Region close to you from the AWS Region menu.
  • Enter {{BucketName}} in the Bucket name field.

The creation form now shows your chosen Region plus your globally unique bucket name.

  • Keep Bucket owner enforced selected under Object Ownership.
  • Keep Block all public access selected under Block Public Access settings for this bucket.

Why Keep These Defaults?

  • Bucket owner enforced disables ACLs.
  • Bucket policies define access to the bucket objects.
  • Block all public access keeps every uploaded object private during this step.
  • Keep Bucket Versioning set to Disabled.
  • Click Create bucket.
  • Click {{BucketName}} in the bucket list.

You should see {{BucketName}} at the top of the bucket page. Your private storage container is ready for the portfolio.

Upload your portfolio files

Each uploaded file becomes an S3 object. Its object key preserves the relative path that your HTML uses to find each asset.

  • Click Upload on the open bucket page.
  • Click Add files.
  • Select index.html plus every other root-level file approved for public viewing.
  • Click Open in the file picker.

The upload list should now show index.html without an extra portfolio folder in front of it.

  • Click Add folder.
  • Choose one public asset folder from your local portfolio folder.
  • Confirm the folder selection.
  • Repeat the folder upload for every remaining public asset folder.

The staged upload now shows each asset folder under the same relative path used by your local portfolio.

  • Click Upload to store the staged files.

You should see a success message after the upload completes.

That is the storage layer in place. Your portfolio now exists as private S3 objects with its browser paths intact.

  • Return to the bucket's object list.
  • Confirm that index.html appears at the bucket root.
  • Open each asset folder prefix to check its uploaded files.

You should see your CSS, JavaScript, images, downloads, navigation targets, plus other public assets at paths matching the local folder structure.

Do the Uploaded Paths Look Wrong?

An extra folder above index.html means the portfolio folder itself was uploaded. The website needs the contents of that folder at the bucket root.

Upload the root-level files through Add files. Upload each asset directory through Add folder.

Help me correct my S3 object paths before I enable static website hosting.

Enable static website hosting

Static website hosting tells S3 which object to serve for the root URL. The index document must match the uploaded filename exactly.

  • Click the Properties tab in your open bucket.
  • Scroll to Static website hosting.
  • Click Edit.
  • Select Use this bucket to host a website.
  • Select Enable.

The website configuration now displays the field that defines the root page.

  • Enter index.html in the Index document field.
  • Click Save changes.

The bucket properties now contain a generated HTTP website endpoint.

  • Return to the Static website hosting section.
  • Record the generated Endpoint here: your S3 website endpoint.

Before you open the endpoint, do you think the private bucket returns your portfolio or blocks the request?

  • Open your S3 website endpoint in a new Microsoft Edge tab.

Microsoft Edge reaches Amazon S3 but shows 403 (Access Denied).

That result is intentional. Static website hosting is active.

Anonymous visitors still cannot read the private objects. You have now separated hosting from access in a result you can see.

Not Seeing 403?

  • Confirm that index.html sits at the bucket root if you see 404 (Not Found).
  • Match the Index document value to index.html with the same letter case.

Help me diagnose why my private S3 website endpoint does not show the expected 403 response.

Your private website endpoint is working exactly as planned. Next, you will turn that blocked response into a publicly readable portfolio.

Publish the Portfolio with a Bucket Policy

The 403 (Access Denied) response from earlier proved that the website endpoint reaches your uploaded files. Amazon S3 still refuses anonymous reads because the bucket remains private.

This step opens the public-access gate for the bucket. A narrowly scoped bucket policy grants visitors permission to read portfolio objects without enabling legacy ACLs.

In this step, get ready to:
  • Confirm that the bucket contains only public portfolio assets.
  • Allow a public-read bucket policy to take effect.
  • Refresh the website endpoint to prove the portfolio is public.
Review what becomes public

Amazon S3's Block Public Access settings prevent public policies from exposing bucket content. Disabling the bucket-level setting lets your public policy take effect.

  • Switch back to the Amazon S3 bucket {{BucketName}} from earlier.
  • Select the Objects tab.
  • Confirm that every listed object is intended for public viewing.

Public Access Changes the Audience

Anyone on the internet can read objects covered by the policy you add next. Your bucket should contain only assets you have chosen to publish.

The policy grants only s3:GetObject access. It does not grant permission to upload or delete objects.

  • Select the Permissions tab.
  • Choose Edit under Block public access (bucket settings).
  • Clear Block all public access.

The settings form now shows the bucket-level public access blocks cleared. The change is ready to save.

  • Choose Save changes.

The Permissions page now shows that bucket-level Block all public access is disabled.

Account Rules Override Bucket Rules

An account-level Block Public Access setting overrides the bucket-level setting. Changing the account setting affects every S3 bucket in your AWS account.

  • Choose the tab that matches the account-level status shown in the S3 console.

✔️ No account-level override

The bucket-level change can apply to {{BucketName}}.

ⓧ Account-level access is blocked

This account-wide change is easy to overapply. Check its effect on your other buckets before changing it.

  • Confirm that no other bucket in your AWS account depends on the account-level block.
  • Select Account and organization settings in the S3 console.
  • Choose Edit under Block Public Access settings for this account.
  • Clear Block all public access.

The account settings form now shows the public access blocks cleared. The change is ready for confirmation.

  • Choose Save changes.

AWS opens a confirmation prompt for the account-level change.

  • Enter confirm.
  • Choose Confirm.

The account-level setting now permits the bucket's public policy to apply.

Add the public-read bucket policy

A bucket policy is a JSON document that defines access to the bucket. This policy grants anonymous visitors one action on the objects inside {{BucketName}}.

  • Return to the Permissions tab for {{BucketName}}.
  • Choose Edit under Bucket policy.
  • Paste the public-read policy into the policy editor by copying the JSON below:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::{{BucketName}}/*"
            ]
        }
    ]
}

What Does This Policy Allow?

  • The 2012-10-17 value identifies the policy language version.
  • The * principal represents everyone on the internet.
  • The s3:GetObject action permits visitors to read objects.
  • The arn:aws:s3:::{{BucketName}}/* resource limits that permission to objects inside this bucket.
  • Replace {{BucketName}} with the exact name of your S3 bucket.
  • Choose Save changes.

The saved policy now grants anonymous read access only to objects inside your portfolio bucket.

Seeing a Policy Resource Error?

  • Check whether the message says Policy has invalid resource.
  • Confirm that the bucket name in arn:aws:s3:::{{BucketName}}/* exactly matches the bucket name shown in Amazon S3.
  • Check that the resource ends with /* so the policy covers objects inside the bucket.

Help me fix my S3 public-read bucket policy.

✔️ Awesome, I've got everything!

Your saved bucket policy grants public read access to the portfolio objects.

ⓧ I'd like to double check the full code

Compare the complete bucket policy below with the policy saved for {{BucketName}}.

{"Version":"2012-10-17","Statement":[{"Sid":"PublicReadGetObject","Effect":"Allow","Principal":"*","Action":["s3:GetObject"],"Resource":["arn:aws:s3:::{{BucketName}}/*"]}]}
Refresh the website endpoint

Your HTTP website endpoint already points to the uploaded portfolio. The new permission now lets an anonymous browser read those objects.

  • Select the Properties tab for {{BucketName}}.
  • Find the Static website hosting section.

Before you open the endpoint, which result do you expect to see? Hold that prediction for the next click.

  • Choose the same Bucket website endpoint link you used earlier.

You'll see your portfolio in Microsoft Edge instead of 403 (Access Denied). You have cleared the permission barrier for anonymous visitors.

Still Seeing 403 Access Denied?

  • Confirm that bucket-level Block all public access remains disabled.
  • Confirm that the policy resource contains the exact bucket name.
  • Check whether an account-level Block Public Access setting overrides the bucket setting.
  • Refresh the same website endpoint after correcting the blocked setting.

Help me diagnose why my S3 website endpoint still returns 403 after I added the public-read policy.

Your portfolio is now public through its S3 website endpoint. Next, you'll test the live site from an anonymous visitor's perspective.

Test the Live Portfolio

Your Amazon S3 portfolio now loads from its public website endpoint. The next goal is to test that site in a separate Microsoft Edge window.

A visible home page can still hide broken assets or dead links. An anonymous test reveals what visitors actually receive.

In this step, get ready to:
  • Confirm the live portfolio loads in a separate browser window.
  • Test every visible portfolio feature.
  • Verify a missing object produces 404 (Not Found).
Confirm anonymous access

An S3 website endpoint serves publicly readable content. Opening it away from the console tab tests the same path an anonymous visitor uses.

  • Switch back to the Microsoft Edge window showing your live portfolio.
  • Copy the endpoint URL from the address bar.
  • Select the browser menu in the top-right corner.
  • Choose the option that creates a new window.
  • Paste the copied endpoint into the new address bar.
  • Press Enter to load the endpoint.

Your portfolio should load in the separate window without any interaction with the AWS console. This proves anonymous visitors can read the published objects.

Still Seeing 403 (Access Denied)?

  • Confirm the copied URL is the same Bucket website endpoint that loaded earlier.
  • Switch back to the S3 console tab from earlier to confirm the public-read policy remains saved.
  • Confirm Block all public access remains cleared so the s3:GetObject policy can apply.

Help me diagnose why my S3 website endpoint still shows 403 (Access Denied).

Test every visible feature

A static website can load index.html even when a related object key is wrong. Each feature test checks one browser request against the folder structure you uploaded.

  • Inspect the current page layout at the window's full width.
  • Resize the browser window to a narrow width.
  • Inspect each responsive section at the narrow width.
  • Return the browser window to a wide view.
  • Check every visible image for its expected appearance.
  • Use each navigation link.

The layout should remain readable at both widths. Every image should load.

Each navigation link should reach its intended section or page.

The remaining checks cover content that opens or runs.

  • Activate each download link.
  • Open each external project link in a separate browser tab.
  • Trigger every client-side JavaScript behavior.

Each download should begin or open the expected file. Every external project link should reach its intended destination.

Your client-side JavaScript should respond as it did in the local portfolio.

Something Broken on the Live Site?

  • Compare the failing asset's browser URL with its corresponding object key in the bucket.
  • Confirm the uploaded object exists at the expected folder path.
  • Check that the portfolio source references the same capitalization and relative path.

Help me trace a broken asset or link in my live S3 portfolio.

Check missing-object behavior

HTTP status codes make browser failures observable. This final test sends the endpoint a path that your bucket does not contain.

Before you load the missing path, what response do you think the website endpoint will return?

  • Select the address bar in the separate Microsoft Edge window.
  • Add missing-object.html after the endpoint's final /.
  • Press Enter to request the nonexistent object.

You should see 404 (Not Found). The endpoint is reachable, but no object exists at that key.

What Does 404 Prove?

The 404 (Not Found) response shows that S3 received your request for an object key with no matching object. The status makes a missing deployment asset visible during testing.

  • Select the address bar again.
  • Remove missing-object.html from the URL.
  • Press Enter to load the root endpoint.

Your portfolio should load again.

Strong finish. Your root endpoint still serves the portfolio after the missing-object test.

Not Seeing Both Results?

  • Confirm the address bar contains missing-object.html when you run the missing-path check.
  • Remove everything after the endpoint's final / before retesting the portfolio root.

Help me verify the missing-object path and restore my S3 portfolio root endpoint.

Secret mission

Replace and Roll Back a Live Asset

Update one image on your live portfolio while keeping its existing object key. You will prove that the replacement is live. Then you will restore the original from your local backup.

Clean Up Your Resources

Clean Up Your Resources

Your live portfolio uses persistent Amazon S3 resources that can incur usage-based charges. Decide whether to keep your website live, pause public access, or delete the project resources entirely.

Cost warning

S3 has no minimum charge. Storage, requests, data retrieval, and data transfer can still generate charges.

Keeping the website live or pausing only public access can leave billable storage in place.

Resources you used:

  • Cloud resource: The general purpose S3 bucket {{BucketName}}.
  • Cloud data: The uploaded portfolio objects in {{BucketName}}, including index.html and the restored object at {{imageObjectKey}}.
  • Cloud configuration: Static website hosting with index.html as the index document.
  • Cloud permission: The public-read bucket policy granting s3:GetObject access.
  • Local file: The backup copy of the original image at {{imageObjectKey}}.

Keep everything running

No action is needed. Choose this if you want your portfolio to remain available from its S3 website endpoint.

  • Leave bucket {{BucketName}} with its objects, website configuration, and public-read policy in place.
  • Retain the local backup of {{imageObjectKey}} for future updates.

Your portfolio stays publicly available. S3 usage charges can continue.

Pause - I'll come back to this later

Shut down public delivery while keeping your portfolio objects for a later project. Stored objects can continue to incur charges.

  • Return to bucket {{BucketName}} in the S3 console from earlier.
  • Select Permissions.
  • Remove the existing public-read policy under Bucket Policy.
  • Choose Edit under Block public access (bucket settings).
  • Select Block all public access.
  • Choose Save changes.

The objects are private again. The website configuration still remains enabled.

  • Select Properties.
  • Find Static website hosting.
  • Choose Edit.
  • Select Disabled.
  • Choose Save changes.

The S3 website endpoint no longer serves the portfolio.

The objects remain stored in the bucket. Storage charges can continue.

Delete - I don't want to use this again

This option removes every project-created cloud resource plus the Secret Mission backup. Bucket deletion is permanent.

Deleting a live site can feel drastic. Your verified local portfolio source folder stays untouched.

  • Return to General purpose buckets in the S3 console from earlier.
  • Select bucket {{BucketName}}.
  • Choose Empty.
  • Confirm the emptying by entering {{BucketName}}.

The bucket now contains no objects. It can now be deleted.

  • Return to General purpose buckets.
  • Select bucket {{BucketName}}.
  • Choose Delete.
  • Enter {{BucketName}} in the confirmation field.
  • Choose Delete bucket.
  • Refresh the bucket list to confirm that {{BucketName}} no longer appears.

The cloud cleanup is complete. Your portfolio is no longer stored or served by this bucket.

  • Return to the local backup of {{imageObjectKey}} in File Explorer.
  • Delete the backup copy created during the Secret Mission.

All project-created resources are now removed. Your original local portfolio remains available for future work.

Nice Work!

Nice Work!

Congratulations. Your portfolio is live at a public Amazon S3 website endpoint.

You learned how to:

  • Published your static portfolio from Amazon S3. Preserved its folder structure so browser paths resolve to the intended objects.
  • Turned the planned 403 (Access Denied) response into a working site. Applied a narrowly scoped bucket policy that grants s3:GetObject.
  • Completed an end-to-end anonymous test in Microsoft Edge. Confirmed each portfolio feature worked. Verified missing-object behavior through 404 (Not Found).
  • Secret Mission: Replaced the live image at {{imageObjectKey}}. Proved the overwrite reached the website. Restored the original from your local backup.

Ready to quiz yourself?