Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AWS for Frontend Engineers

AWS for Frontend Engineers

Steve Kinney

August 14, 2018
Tweet

More Decks by Steve Kinney

Other Decks in Technology

Transcript

  1. This workshop covers some of the approaches we’ve taken (or

    are taking) at SendGrid for our large, client-side application.
  2. The Original State • Our client-side code was hosted out

    of our Rails app. • The Rails application was located in Chicago. • Users from around the world had to reach Chicago in order to get the application. • We had to deploy Rails every time we wanted to make a change to our React application.
  3. Before After Difference Denver 5.682s 1.419s 133.26% Frankfurt 11.026s 1.869s

    489.94% Mumbai 9.641s 1.373s 602.18% Sydney 12.31s 0.87s 1314.94%
  4. Noted • A hollowed out version of our production application.

    • Based on the webpack configuration we use. • Includes modern techniques like lazy-loading and client- side routing. • Notable differences: smaller, not TypeScript.
  5. What are we going to cover? • We’ll be looking

    at getting a single-page application: • Hosted on AWS. • Distributed globally. • Secured with SSL. • Automatically deployed with CI/CD. • Dynamically responding to requests.
  6. What are we not going to cover. • Servers. This

    course is focused on the high-performance distribution of your client-side, JavaScript application. • Serverless. Scott Moss has an amazing workshop that came out recently and you should totally go watch it—after this one, of course.
  7. Together • Let’s take a quick tour of the free

    tier. • We’ll also set up billing notification warning us if we blow past the free tier.
  8. Together • We’re going to turn on MFA for our

    root account. • We’re going to make a new user (e.g. not our root account). • We’re going to turn on MFA for that one too.
  9. A High Level • In our S3 account, you have

    your buckets. • You can put objects (read: files) in your buckets. • You can read from your buckets as well. • You can host web pages out of your buckets.
  10. A Slightly Lower, But Still High Level • Infinitely scalable.

    • Files can be as small as zero bytes or as large as 5 terabytes. • 99.9% availability (built for 99.99%). • 99.999999999% durability.
  11. Storage Tiers • Standard—this is what we’ll be using today.

    • Infrequently accessed. • Reduced redundancy. • Glacier—this technically isn’t S3, but whatever.
  12. Data Consistency Model • Putting new objects in S3 is

    immediate. You’ll get back a 200 response. • Updating and removing objects is eventually consistent. Users might get an old version. (This has literally never happened to me.)
  13. So, what’s this going to cost me? • Uploading to

    S3 is free. • You get charged for storage. • You get charged for requests. (We’ll learn how to mitigate this later.)
  14. Exercise • The is totally optional. If you don’t want

    to purchase a domain name, you’ll skip a few steps as we go along, but you’ll be able to come along. • We’re going to register a domain name now so that we know we have one that’s unique. • Also: registration takes some time, so—let’s get it started now.
  15. Exercise • This is totally optional. If you don’t want

    to purchase a domain name, you’ll skip a few steps as we go along, but you’ll be able to come along. • Register a domain name now so that we know we have one that’s unique. • Also: registration takes some time, so—let’s get it started now.
  16. { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*",

    "Action": "s3:GetObject", "Resource": "arn:aws:s3 :::YOUR_BUCKET_NAME_HERE /*" } ] }
  17. Policy Terms • Principal — who can do the thing?

    • Action — what can they do? • Resource — to which things?
  18. Together • We’re going to set up an S3 bucket.

    • We’re going to set a policy on the bucket. • We’re going to configure the S3 bucket for static website hosting. • We’re going to upload a simple React application via the command line.
  19. Areas of Improvement • The URL isn’t great. • Doing

    this manually can get tedious. • It’s hosted in Virginia. (No offense to Virginia.) • Routing is kind of breaking the web.
  20. Copying a Directory to S3 aws s3 cp dist/ s3:

    //mysuperfunwebsite.com/ --recursive
  21. Exercise • Create a second alias for your “www” bucket.

    • Same process as before, but this time you want to add a subdomain and point to the bucket that has the “www” prefix.
  22. Areas of Improvement • The URL isn’t great over HTTPS.

    • Doing this manually can get tedious. • It’s hosted in Virginia. (No offense to Virginia.) • Routing is still breaking the web.
  23. Together • We’re going to generate a free SSL certificate

    for our fancy new domain name. • This will allow us to support HTTPS when we set up CloudFront.
  24. Together • Let’s see where we can set up a

    better error page. • Let’s not even use that error page. • We’ll just act like nothing ever went wrong.
  25. Exercise • Make a new bucket called www.<your-original- bucket-name>. •

    Go to Static Web Hosting. • Set it up to redirect to your main bucket. • Verify that it works. • (We’ll do this together shortly.)
  26. Areas of Improvement • The URL isn’t great. (It’s great,

    just not secure.) • Doing this manually can get tedious. • It’s hosted in Virginia. (No offense to Virginia.) • Routing is still kind of breaking the web.
  27. We’re going to do this out of order. • As

    my co-worker, Steven, likes to say CloudFront puts the “eventual” in eventual consistency. • Everything in CloudFront takes a while, so we’re going to just set it up now and then we’ll talk about it while it’s cooking.
  28. Together • We’re going to create a new CloudFront distribution.

    • We’re going to point it to our static website on S3. • We’ll add our domain names. • We’ll set up gzipping for our assets. • We’ll set a default root object.
  29. We could try to figure out where most of our

    users are and then put it as close to them as possible.
  30. Exercise • We’ll visit our CloudFront distribution and verify that

    it’s up and running. • Make a change to application (e.g. make a background color something ridiculous). • Deploy the application.
  31. Strategies • Best when possible: Don’t do it. Use unique

    names. • Alternative: Bust the cache when needed.
  32. Areas of Improvement • The URL isn’t great or secure.

    • Doing this manually can get tedious. • It’s hosting in Virginia. (No offense to Virginia, but it’s no New Jersey.) • Yea, routing is still weird. ¯\_(ツ)_/¯
  33. Disclaimer • I opted to use Travis CI because it’s

    free for public repositories and easy to set up. • You can do this with any CI tool. (We used to do it with Jenkins at SendGrid, now we use Buildkite.)
  34. Together • We’ll add our repository to Travis CI. •

    We’ll create a configuration for Travis CI. • We’ll deploy our application and witness the magic and glory.
  35. Exercise • Make another obnoxious change to your application. •

    Merge it into master and push it up. • Behold the glory of your creation.
  36. Tasting Notes • You eventually need to bust the cache

    on CloudFront. • You can do this with a relatively low TTL on the cache header or you can do this with invalidations. • You get up 1,000 invalidations per month for free. • You can have your CI/CD tool take care of all of this when merging to master.
  37. Areas of Improvement • The URL isn’t great. • Doing

    this manually can get tedious. • It’s hosting in Virginia. (No offense to Virginia.) • Oh yea—routing.
  38. Viewer Request • Executed on every request before CloudFront’s cache

    is checked. • Modify the cache key (URL, cookies, headers, query string). • Perform authentication and authorization checks. • Make additional network calls. • Generate responses (uncached).
  39. Origin Request • Executed on a cache miss, before the

    request is forwarded to the origin. • You can make external network calls. • Dynamically set an origin based on the headers. • Re-write URLs (pretty URLs). • Cool for stuff like internationalization.
  40. Origin Response • Responses from the origin that haven’t been

    cached yet. • Executed on cache miss, after a response is received from the origin. • Make external network calls. • Modify response headers prior to caching.
  41. Viewer Response • Executed on all requests, after a response

    is received from the origin or cache. • Modify the response headers without caching the result. • Make external network calls.
  42. Together • Let’s fix routing: If the viewer is looking

    for a known client- side route (e.g. /notes/1), we’ll get them the index.html instead. • Let’s adjust CloudFront to go back to treating 404s as 404s.
  43. Exercise • We want to look at each Viewer Request.

    We’re going to add some more to our previous Lambda. • If the request.uri is /prince-1.jpg, we want to change it to /prince-2.jpg.
  44. Areas of Improvement • The URL isn’t great. • Doing

    this manually can get tedious. • It’s hosting in Virginia. (No offense to Virginia.) • Oh yea—routing.
  45. Additional Things • Implement A/B testing. • URL redirection (pretty

    URLs). • Header normalization. • Redirecting unauthenticated users to the login page.
  46. Conclusion • The needs of your particular application will probably

    differ slightly. • But, there is probably a solution using AWS. • Some of this grunt work can be further automated via tools like Terraform or CloudFormation, but there is a cost/ benefit analysis that needs to happen there.
  47. provider "aws" { access_key = "${var.aws_access_key}" secret_key = "${var.aws_secret_key}" region

    = "us-east-1" } # Create a web server resource "aws_instance" "web" { # ... }
  48. Advantages • Infrastructure as code means that infrastructure changes can

    go through code review. • It means they can be checked into Git. • It means it can be made reusable.