Slide 1

Slide 1 text

Deploy web frontend apps with AWS CDK Masashi Tomooka Prototyping Engineer 2023-09-29

Slide 2

Slide 2 text

About me Masashi Tomooka Prototyping Engineer @AWS Japan • Currently on parental leave 👶 Hobby contributor to CDK: • Improve CDK hotswap feature • AWS CDK Translator 2 GitHub/𝕏 : @tmokmss

Slide 3

Slide 3 text

AWS CDK Translator TypeScript CDK code to Python/Java/etc. Completely run in your web browser powered by jsii-rosetta and WebContainer API 3 https://tmokmss.github.io/cdk-translator/ Disclaimer: it is my private project; I do not guarantee anything.

Slide 4

Slide 4 text

Popularity of AWS CDK in Japan Monthly meetup with > 150 attendees on average Topics: Sharing best practices, deep dive into CDK internals, and lessons learned from production use cases 4 Archives: https://www.youtube.com/results?search_query=jawsug_cdk Photo credit: @nikuyoshi

Slide 5

Slide 5 text

Agenda • What to consider when deploying web frontend with CDK • Several patterns to deploy web frontend with CDK • Demo 5

Slide 6

Slide 6 text

Problem - Deploy static frontend app • Focus on static (CSR) frontend, not SSR • Serve static files from S3 via CloudFront • Frontend client calls AWS resources directly for authentication etc. 6 API Gateway backend Cognito UserPool S3 Bucket CloudFront HTML / CSS JavaScript UserPool ID Client ID API Gateway URL Frontend static assets Problem: How to build and deploy these frontend static assets?

Slide 7

Slide 7 text

Deploy-time values • Values only available on deployment time, not on synthesis time • e.g. most values accessed via construct’s properties • Not usable directly when you build a frontend app (constraint) 7

Slide 8

Slide 8 text

Using AWS resources from client • Need to pass AWS resource attributes to frontend clients • e.g. Cognito user pool ID • Usually the attributes are injected during frontend build process • but they are now deploy-time values… 8 Example: Frontend JavaScript code (w/ Amplify Libraries) Problem: How to make these values available to your frontend client?

Slide 9

Slide 9 text

Possible solutions 1. Deploy backend first, then build frontend locally 2. Fetch variables on runtime 3. Build frontend on deploy time 9

Slide 10

Slide 10 text

1. Build frontend assets locally 10 Build frontend assets NEXT_PUBLIC_AWS_REGION=us-east-1 \ NEXT_PUBLIC_USER_POOL_ID =xxxx \ … npm run build CDK synth/deploy npx cdk deploy CloudFormation deployment Assets deployed to S3 bucket (e.g. BucketDeployment) Deploy backend first, and build frontend locally with environment variables get those values from the deployed backend or create a .env file

Slide 11

Slide 11 text

1. Build frontend assets locally • Most straightforward approach • Lower cognitive load • Deployment needs multiple steps • Sometimes human-error prone • Manage env vars outside of CDK • using .env file / some shell script • Burden on setting up new env 11 $ npx cdk deploy BackendStack $ cd /frontend $ npm run build # inject env vars from the stack $ cd - $ npx cdk deploy FrontendStack 🟢 Pros 🔴 Cons Deploy backend first, and build frontend locally with env vars

Slide 12

Slide 12 text

Possible solutions 1. Deploy backend first, then build frontend locally 2. Fetch variables on runtime 3. Build frontend on deploy time 12

Slide 13

Slide 13 text

2. Inject env vars on runtime 13 Build frontend assets without environment variables npm run build CDK synth/deploy npx cdk deploy CloudFormation deployment Create runtime-config.json using deploy-time values Assets deployed to S3 bucket runtime-config.json runtime-config.json will be fetched from client on runtime

Slide 14

Slide 14 text

2. Inject env vars on runtime • Can deploy the entire system in a single step • Need to fetch variables on runtime • More code to manage • Slower initial page load 14 🟢 Pros 🔴 Cons Deploy a json containing deploy-time values, using BucketDeployment

Slide 15

Slide 15 text

3. Build frontend on deploy time 15 CDK synth/deploy npx cdk deploy CloudFormation deployment Assets deployed to S3 bucket (e.g. BucketDeployment) Build frontend assets NEXT_PUBLIC_AWS_REGION=us-east-1 \ NEXT_PUBLIC_USER_POOL_ID =xxxx \ … npm run build Frontend is now built on deploy time

Slide 16

Slide 16 text

3. Build frontend on deploy time • Build and deploy completes in a single CDK deployment • Build failure results in CFn rollback • More complexity on infrastructure 16 🟢 Pros 🔴 Cons Build frontend during deployment running a CodeBuild job https://github.com/tmokmss/deploy-time-build

Slide 17

Slide 17 text

Summarized trade-offs 🟢 Pros 🔴 Cons #1. Build locally Simple and straightforward, easy to implement and understand Deployment requires two steps (Backend deploy -> Frontend build/deploy) #2. Runtime config Deploy completes in a single step Easy to build and deploy Requires specific logic in frontend Not ideal for runtime performance #3. Deploy-time build Deploy completes in a single step More complexity in infrastructure Build failure results in CFn rollback 17 * Other possible options: Use Amplify Hosting (fronend deployment managed outside of CDK) Build locally and deploy-time injection of environment variables (SST way)

Slide 18

Slide 18 text

Key takeaways • Even for a simple static frontend deployment, there are several possible patterns to consider • Optimal path may vary with your use cases; evaluate the trade-offs • Understanding CDK-specific concepts like deploy-time value will help to use CDK more effectively 18 The code shown in demo is available here: https://github.com/tmokmss/deploy-static-web-frontend-with-cdk

Slide 19

Slide 19 text

Thank you! Masashi Tomooka GitHub/𝕏: @tmokmss 19

Slide 20

Slide 20 text

Appendix 20

Slide 21

Slide 21 text

Deploy-time-build architecture 21