diff --git a/README.md b/README.md index 59e8ce6..f815b00 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,25 @@ -# Coffee Store Web Demo - real example of a deployed website on AWS +# Coffee Store Web Full - real example of a deployed website on AWS -_"Production-ready websites on AWS with slightly less faff"_ +_"Production-ready websites on AWS made slightly easier"_ -This is a "real" instance of the Coffee Store Web repo (NB - https://github.com/symphoniacloud/coffee-store-web is currently still an old version - it will be updated soon.) +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 set you up for a real production website, along with development and test environments. -This repository is deployed using the included Github Actions workflows to https://www.coffeestorewebdemo.symphonia.io/ . +## Introduction -This demo shows various techniques: +Deploying a "static" website on AWS is surprisingly tricky - it requires managing S3, CloudFront, the security between them, Route 53, and more. This example helps you wrangle all of these things, by way of using [**AWS CDK**](https://docs.aws.amazon.com/cdk/v2/guide/home.html). -* Deploying a website on AWS with CDK using Symphonia's [`cdk-website`](https://github.com/symphoniacloud/cdk-website) construct +This project is an extension of my [CDK bare-bones app for TypeScript](https://github.com/symphoniacloud/cdk-bare-bones) project. I recommend that you **try this first if you are getting started with CDK.** + +It's also an extension of my [_Coffee Store Web Basic_](https://github.com/symphoniacloud/coffee-store-web-basic) project - adding custom domain names, setting up multiple environments, using Github Actions, and more. **If you're new to hosting websites on AWS you may want to start with the _Basic_ version first.** + +To show this isn't all made up this repository is **really deployed** using the included Github Actions workflows to https://www.coffeestorewebfull.symphonia.io/ ! + +## How this project works + +This example deploys a CDK _App_ that uses S3 and CloudFront to host a website. It shows various techniques: + +* Deploying a website on AWS with CDK using my [`cdk-website`](https://github.com/symphoniacloud/cdk-website) construct * Use multiple custom domain names in production (apex domain, and `www.` domain), and single custom domains elsewhere. * Use caching behavior and invalidations in production; use a pass-through cache without invalidations in development and test. * Use a CloudFront Function for URL manipulation and redirects @@ -17,16 +28,26 @@ This demo shows various techniques: * Use Github OIDC for AWS access * Use a custom action for shared behavior between workflows -## How to use +## Prerequisites -This is a somewhat advanced example. Prerequisites are as follows: +Please see the [prerequisites of the cdk-bare-bones](https://github.com/symphoniacloud/cdk-bare-bones#prerequisites) project - all of the prerequisites in that project also apply to this one. + +Further: -* You should already be able to deploy CDK stacks to AWS. For more details on how to do this, see my ["bare bones CDK" example](https://github.com/symphoniacloud/cdk-bare-bones). * You should understand the basics of deploying websites, certificates, and DNS. +* If you are going to deploy this with a custom domain name you will need a valid certificate deployed to AWS Certificate Manager in your target account, and optionally you will need the correct Route 53 hosted zone in your target account. + +## Deployment + +**NB- Don't try deploying until you've updated the environment configuration** in [_envProps.ts_](src/cdk/envProps.ts) for your own AWS account, domain name settins etc. - see the next section. + +Once you've changed those you can use the included _deploy.sh_ script, or run `npm run deploy`. + +## How to use Overall I recommend you review the entire contents of this repo. Particularly relevant files are: -* [src/cdk/*](src/cdk) - The CDK definition files for the application +* [src/cdk/*](src/cdk) - The CDK definition files for the application, including environment properties. * [src/cloudfront/preProcessFunction.js](src/cloudfront/preProcessFunction.js) - A CloudFront Function that will be run for every request * [src/site/*](src/site) - Sample site content - you will want to replace this with your own, or generate content at build time * [.github/*](.github) - Github Actions configuration for PR (test) and production deployment @@ -34,17 +55,27 @@ Overall I recommend you review the entire contents of this repo. Particularly re Many of the specific elements in this repo are custom, since it is an actual deployed site. Elements that you will likely want to change if you are copying it are: * The [per-environment properties](src/cdk/envProps.ts) will change. - * Note the main `CoffeeStoreWebDemoStackPropsPerEnv` constant in that file is keyed by account ID, so these will have to change. + * Note the main `CoffeeStoreWebFullStackPropsPerEnv` constant in that file **is keyed by account ID**, so these will have to change. * Also you'll want to change custom domain names, certificate ARN import details, and hosted zone names (assuming you want to automatically update DNS) * For more on this, see the [documentation for the `cdk-website` construct](https://github.com/symphoniacloud/cdk-website) -* You will want to change `DEFAULT_STACK_NAME` in [App.ts](src/cdk/App.ts) . You may also want to be able to change the stack name outside of that file, but that's beyond the scope of this demo +* You will want to change `DEFAULT_STACK_NAME` in [app.ts](src/cdk/app.ts) . You may also want to be able to change the stack name outside of that file - see comment in [_deploy.sh_](deploy.sh) * If you are generating any content before deployment you will either want to update [deploy.sh](deploy.sh), or update the [custom Github Actions action](.github/actions/deploy/action.yaml) to also build and not just deploy. - * You'll probably also want to change `content` -> `path` in [App.ts](src/cdk/App.ts) + * You'll probably also want to change `content` -> `path` in [app.ts](src/cdk/app.ts) * If you are just using static content in the repo, then change the contents of [src/site](src/site) * Consider the ["pre process" CloudFront function](src/cloudfront/preProcessFunction.js): - * Either delete it, and remove the `preProcessFunctionCode` property in [App.ts](src/cdk/App.ts) ... + * Either delete it, and remove the `preProcessFunctionCode` property in [app.ts](src/cdk/app.ts) ... * ... or update the `manualRedirects` value in [preProcessFunction.js](src/cloudfront/preProcessFunction.js) * If you want to use the Github Actions workflows: * You'll need to deploy the Github OIDC resources if you haven't done so already. See [here](https://github.com/symphoniacloud/coffee-store-v2/tree/main/github-actions-prereqs) for an example. * You'll also want to save the relevant role ARNs as secrets in Github Actions, and change `OPENSOURCE_ACTIONS_ROLE_ARN` in [deploy-to-prod.yaml](.github/workflows/deploy-to-prod.yaml) and `TEST_ACTIONS_ROLE_ARN` in [deploy-pr-to-test.yaml](.github/workflows/deploy-pr-to-test.yaml) -* If you don't want to use Github Actions, then delete the [.github](.github) directory. \ No newline at end of file +* If you don't want to use Github Actions, then delete the [.github](.github) directory. + +## 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](https://github.com/symphoniacloud/cdk-bare-bones#design-decisions--motivation). + +## Questions / Feedback / etc. + +If you have questions related to this example please add a Github issue, or drop me a line +at [mike@symphonia.io](mailto:mike@symphonia.io) . I'm also on Twitter +at [@mikebroberts](https://twitter.com/mikebroberts) . diff --git a/cdk.json b/cdk.json index a384a08..11a8556 100644 --- a/cdk.json +++ b/cdk.json @@ -1,3 +1,3 @@ { - "app": "npx ts-node --prefer-ts-exts src/cdk/App.ts" + "app": "npx ts-node --prefer-ts-exts src/cdk/app.ts" } diff --git a/package-lock.json b/package-lock.json index 79dd852..aa78ebb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,13 @@ { - "name": "cdk-website-basic-example", - "version": "2022.1.0", + "name": "coffee-store-web-full", + "version": "2022.1.1", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "cdk-website-basic-example", - "version": "2022.1.0", + "name": "coffee-store-web-full", + "version": "2022.1.1", + "license": "MIT", "devDependencies": { "@symphoniacloud/cdk-website": "0.0.6", "@tsconfig/node16": "1.x", diff --git a/package.json b/package.json index 550b93a..3328440 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "coffee-store-web-demo", + "name": "coffee-store-web-full", "version": "2022.1.1", - "homepage": "https://github.com/symphoniacloud/coffee-store-web-demo", + "homepage": "https://github.com/symphoniacloud/coffee-store-web-full", "license": "MIT", "author": { "email": "mike@symphonia.io", diff --git a/src/cdk/App.ts b/src/cdk/app.ts similarity index 75% rename from src/cdk/App.ts rename to src/cdk/app.ts index 128bf02..b3f2b63 100644 --- a/src/cdk/App.ts +++ b/src/cdk/app.ts @@ -3,12 +3,12 @@ import 'source-map-support/register'; import {App, Stack} from 'aws-cdk-lib'; import {Construct} from 'constructs'; import {Website} from "@symphoniacloud/cdk-website"; -import {CoffeeStoreWebDemoStackProps, createCoffeeStoreWebDemoStackProps} from "./envProps"; +import {CoffeeStoreWebFullStackProps, createCoffeeStoreWebFullStackProps} from "./envProps"; -const DEFAULT_STACK_NAME = 'coffee-store-web-demo' +const DEFAULT_STACK_NAME = 'coffee-store-web-full' -class CoffeeStoreWebDemo extends Stack { - constructor(scope: Construct, id: string, props: CoffeeStoreWebDemoStackProps) { +class CoffeeStoreWebFull extends Stack { + constructor(scope: Construct, id: string, props: CoffeeStoreWebFullStackProps) { super(scope, id, props); new Website(this, 'Website', { @@ -25,4 +25,4 @@ class CoffeeStoreWebDemo extends Stack { } const app = new App(); -new CoffeeStoreWebDemo(app, 'CoffeeStoreWebDemo', createCoffeeStoreWebDemoStackProps(app, DEFAULT_STACK_NAME)); \ No newline at end of file +new CoffeeStoreWebFull(app, 'CoffeeStoreWebFull', createCoffeeStoreWebFullStackProps(app, DEFAULT_STACK_NAME)); \ No newline at end of file diff --git a/src/cdk/envProps.ts b/src/cdk/envProps.ts index f4e21c9..faf6053 100644 --- a/src/cdk/envProps.ts +++ b/src/cdk/envProps.ts @@ -3,14 +3,14 @@ import {BehaviorOptions, CachePolicy} from "aws-cdk-lib/aws-cloudfront"; import {WebsiteCustomDomain} from "@symphoniacloud/cdk-website"; import {createStackProps} from "./initSupport"; -export interface CoffeeStoreWebDemoStackProps extends StackProps { +export interface CoffeeStoreWebFullStackProps extends StackProps { customDomain: WebsiteCustomDomain performCacheInvalidation?: boolean additionalDefaultBehaviorOptions?: Omit; } -const CoffeeStoreWebDemoStackPropsPerEnv: Record = { - // Opensource account - this is this demo's "prod" account +const CoffeeStoreWebFullStackPropsPerEnv: Record = { + // This is this demo's "prod" account '073101298092': { customDomain: { // For this demo we want to serve in production on both the "apex" domain, and "www." @@ -54,10 +54,10 @@ const CoffeeStoreWebDemoStackPropsPerEnv: Record