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

Hosting SPA using AWS CloudFront and S3

Hosting SPA using AWS CloudFront and S3

A small introduction on how to host Single-page applications in AWS using CloudFront and S3.

Torsten Heinrich

April 03, 2018
Tweet

More Decks by Torsten Heinrich

Other Decks in Programming

Transcript

  1. 3 AWS S3 • Managed object storage for any amount

    of data • Data is organised as folders/objects inside buckets • Infinite amount of objects, single object up to 5TB • Guarantees 99.999999999% durability and 99.99% availability • Supports IAM policies, ACLs, bucket policies, query string authentication and VPC endpoints • Supports HTTPS and SSE at rest using AES 256-bit symmetric keys • Supports versioning • Accessible through AWS Console, REST API and various SDK
  2. 4 AWS S3 Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Join [

    "-", [ "spa-bucket", !Ref "AWS::Region" ]] AccessControl: PublicRead WebsiteConfiguration: IndexDocument: index.html ErrorDocument: index.html BucketPolicy: Type: AWS::S3::BucketPolicy DependsOn: Bucket Properties: Bucket: !Ref Bucket PolicyDocument: Statement: - Action: - s3:GetObject Effect: Allow Principal: "*" Resource: !Join [ "", [ !GetAtt Bucket.Arn, "/*" ]]
  3. 5 AWS CloudFront • Managed CDN to deliver static and

    dynamic web content • Network of edge locations, requests are routed to the one that provides the lowest latency • Supports caching based on query strings, cookies and request headers • Supports invalidations, custom error responses and compression • Supports HTTPS (internal/external) and CNAMEs • Supports Lambda@Edge to customise the content delivered • Accessible through AWS Console, REST API and various SDK
  4. 8 AWS CloudFront Distribution: Type: AWS::CloudFront::Distribution DependsOn: BucketPolicy Properties: DistributionConfig:

    Enabled: true DefaultCacheBehavior: AllowedMethods: - GET - HEAD Compress: true ForwardedValues: QueryString: true TargetOriginId: !Join [ ".", [ "static", !Ref HostedZoneName ]] ViewerProtocolPolicy: https-only DefaultRootObject: index.html Origins: - DomainName: !Select [ 1, !Split [ "://", !GetAtt Bucket.WebsiteURL ]] Id: !Join [ ".", [ "static", !Ref HostedZoneName ]] CustomOriginConfig: HTTPPort: 80 HTTPSPort: 443 OriginProtocolPolicy: http-only
  5. 10 Deployment # build docker build -t ${APPLICATION_NAME} . docker

    tag ${APPLICATION_NAME}:latest ${REPOSITORY_URI}:${TAG} # push docker push ${REPOSITORY_URI}:${TAG} # deploy docker run --name ${APPLICATION_NAME} ${REPOSITORY_URI}:${TAG} generate docker cp ${APPLICATION_NAME}:/home/node/app/dist . aws s3 sync --acl public-read --delete ./dist ${BUCKET} aws cloudfront create-invalidation --distribution-id ${DISTRIBUTION_ID} --paths /${APPLICATION_NAME}/*
  6. 11 Benefits • Deployment time reduced: 60s vs. 180s •

    Deployment simplified: 200 vs. 350 lines of logs • Runtime simplified: 100 vs. 350 LOC in CloudFormation templates • Costs reduced • 5GB data, 100 deployments, 1M requests in S3: ~$0.50 • 25GB data (125GB raw), 100 deployments in CloudFront: ~$3.00 • EC2 t2.medium instance running 24/7: ~$35.00