Skip to content

Latest commit

 

History

History
147 lines (96 loc) · 8.48 KB

README.md

File metadata and controls

147 lines (96 loc) · 8.48 KB

Coffee Store Web Basic - Deploying a website on AWS

There are many ways of hosting websites. If you want to host on AWS it's not as easy as it could be, but this example will get you started.

Introduction

Deploying a "static" website on AWS is surprisingly tricky - it requires managing S3, CloudFront, the security between them, Route 53, and more. This example project helps you get started using AWS CDK to deploy a website.

If you are looking to do this with "vanilla" CloudFormation, see the older version of this project in the CloudFormation branch.

This example is part of a collection of CDK examples - others are as follows:

  • CDK bare-bones app for TypeScript - Base project for any TypeScript app using CDK for deployment to AWS. Try this first if you are getting started with CDK.
  • Coffee Store Web Full - An extension of this project that is a real working demo of a production-ready website, including TLS certificates, DNS, Github Actions Workflows, multiple CDK environments (prod vs test vs dev). Head straight to this project if you already familiar with CDK and deploying websites to AWS.
  • Coffee Store V2 - Includes a Lambda Function resource; source code + build for the Lambda Function; unit + in-cloud integration tests

How this example works

This example deploys an S3 Bucket to hold your website content, and a CloudFront Distribution to handle web requests. CloudFront is actually a Content Delivery Network (CDN) and so also provides a location-oriented cache.

The example deploys these two resources as a CDK App, which in turn uses AWS CloudFormation under the covers, to provide an automated infrastructure-as-code process.

During the deployment process your site's content is also uploaded, courtesy of CDK's BucketDeployment Construct. If you want to use your own upload mechanism then remove the BucketDeployment from the code.

This example does not include setting up a custom hostname for the site - it uses the default provided by cloudfront. To use a custom hostname see my Coffee Store Web Full example project instead.

Mostly this example uses the default configuration for S3 and CloudFront provided by CDK or the services themselves - including "good practice" security. A few small tweaks related to CloudFront are:

  • Redirect http requests to https (NB: this is good for web sites but not always a great idea for web APIs - see this link for why)
  • Enable http version 2 and version 3
  • Set the default root object (for requests to /) as index.html

Prerequistes

Please see the prerequisites of the cdk-bare-bones project - they are the same as for this one.

Deployment

After cloning this project to your local machine, run the following, which uses the default CloudFormation stack name of coffee-store-web:

$ npm install && npm run deploy

Alternatively if you want to use a custom stack name then specify the stackName CDK context property e.g. as follows:

$ npm install && npm run deploy -- --context stackName=my-website-stack

This will normally take 5 - 15 minutes the first time you deploy, mostly because of how long it takes AWS to provision a new CloudFront distribution.

If successful, the end result will look something like this:

coffee-store-web: creating CloudFormation changeset...

 ✅  CoffeeStoreWeb (coffee-store-web)

✨  Deployment time: 610.9s

Outputs:
CoffeeStoreWeb.CloudFrontUrl = dcurepuzhyubr.cloudfront.net
Stack ARN:
arn:aws:cloudformation:us-east-1:123456789012:stack/coffee-store-web/d92ffbc0-18d3-11ed-b23b-12285e0da875

✨  Total time: 613s

Assuming deployment is successful then go to the CoffeeStoreWeb.CloudFrontUrl value (the one ending in cloudfront.net) from your version of the output in a browser - you should the see a message saying "Hello Coffee World!"

Once you've run npm install once in the directory you won't need to again

Teardown

To teardown the stack either (a) delete the stack from the CloudFormation console or (b) run the following. IMPORTANT - if you haven't made any changes to the project this will delete the default stack (coffee-store-web) in your Account + Region.

$ npm run cdk-destroy
...
Are you sure you want to delete: CoffeeStoreWeb (y/n)? y
CoffeeStoreWeb (coffee-store-web): destroying...

 ✅  CoffeeStoreWeb (coffee-store-web): destroyed

If you want to teardown a stack with name that's not the default, you can add a stackName property, e.g. -- --context stackName=my-app-stack, the same as with deploy.

Once teardown is completed you'll need to manually delete the contents of the S3 bucket and the bucket itself.

For other commands see the Usage section of the bare-bones project README.

Next steps

The most immediate thing you'll want to do next is deploy some actually interesting content. By default this project uploads everything from src/site to your site, so you can just change the contents of that directory. Alternatively if your site has a build process you may want to run that first, and change the sources property under the BucketDeployment instance in app.ts to point to your build output folder.

Other next steps including custom domain names, setting up multiple environments, using Github Actions, and more, can be found in the larger Coffee Store Web Full project.

CDK Style

My style of using CDK is a little different from the default templates provided by AWS. For more details, and reasoning, see the Motivation section of the bare-bones project Readme.

Scaling and Cost

All of the primary resources in this example are serverless - in other words they automatically scale according to actual load, and their costs are tied to this load. Your biggest cost will likely be CloudFront - see the CloudFront pricing page here.

Note that if you are deploying frequently - e.g. in a development environment - you'll likely want to turn off CloudFront cache invalidation for non-production environments. See the comment for the distribution property in the BucketDeployment instance in app.ts

Questions / Feedback / etc.

If you have questions related to this example please add a Github issue, or drop me a line at [email protected] . I'm also on Mastodon at http://hachyderm.io/@mikebroberts and BlueSky at https://bsky.app/profile/mikebroberts.com .

Changelog

2025.1

  • Switch to Node 22 from 16
  • Update package-lock to use latest versions of specified dependencies
  • Use TypeScript 5
  • Inline cdk-website custom construct into project, and include following changes:
    • Change to Origin Access Control from Origin Identity Control for CloudFront to S3 access
    • Specify custom logger on BucketDeployment so that we can specify log retention
    • Remove specifying various S3 bucket properties which are now default
  • Switched to tsx from ts-node in CDK configuration
    • And so run tsc manually during deploy to perform pre-deploy typechecking
  • Removed no-longer used "import 'source-map-support/register'" from CDK

2022.1

  • Move cdk.json to src/cdk directory. This is for a couple of reasons:
    • One fewer file in project root, which I think is A Good Thing
    • Makes it easier to have repos with multiple, separate, CDK apps
  • Modify app.ts to point to new (relative) location of site content
  • Move output and requireApproval CDK settings from package.json to cdk.json
    • I hadn't read the docs enough to know they could be in cdk.json. Oops. This way is cleaner
  • Add package-lock.json - these are specific dependency versions I've tested with