ottokruse / s3-spa-upload

Upload a single page application to S3 with the right content-type and cache-control meta-data
20 stars 3 forks source link

Current best practice for uploading an SPA? #11

Open CsehAbel opened 2 months ago

CsehAbel commented 2 months ago

Hi,

I have been looking at cloudfront-authorization-at-edge repo and at the JWT workshop, and i was wondering if this s3-spa-upload method is still relevant or if another method would be the best practice when uploading SPAs. I am trying to do IaC for uploading the SPA with Content-Type, Cache-Content and CORS Rules, while fronting the S3 bucket with CloudFront and having access to the the distribution in the deployment code ( to add callback URL for the hosted ui, other origins like for apigw, cloudwatch alert for the distribution).

I just wanted a general advice for the skeleton of such an IaC project from a pro for uploading SPAs, and i might not be asking the right questions.

How would you go about implementing also CORS Rules? Do you recommend Amplify hosting to upload the SPA from a CodeCommit or GitHub repo? Would there be a way of customizing that CloudFront distribution via IaC like Price Class, access metrics via distribution.metricRequest() to create CloudWatch alarms in the same Stack while using this Amplify SPA upload? Is this s3-spa-upload method is still recommended? Would connecting CodeCommit with a cdk.aws_s3_deployment.BucketDeployment be a viable option?

ottokruse commented 2 months ago

Hi mate. Quick reply first. Did you read this blog yet by any chance? https://aws.amazon.com/blogs/networking-and-content-delivery/host-single-page-applications-spa-with-tiered-ttls-on-cloudfront-and-s3/

Tl;dr this lib here still makes sense.

I would add it as a separate step in your deployment pipeline.

Wil try to reply more elaborately soon

CsehAbel commented 2 months ago

Hi, I didn't know you have a blog post about it, oh wow :D, i will make sure to read it, thanks :).

CsehAbel commented 1 month ago

Okay, so i started implementing the CodePipeline with a CodeBuild Project as an action for the "deploy" stage.

[Container] 2024/05/13 14:06:52.505622 Running command s3-spa-upload --bucket ######## --source .
/usr/local/lib/node_modules/s3-spa-upload/src/index.js:73
    _s3client ??= new client_s3_1.S3Client({
               ^
SyntaxError: Unexpected token ?

It is pointing at the nullish coalescing assignment operator. I have nodejs:"latest" as the buildSpec's runtime version.

Should i fork the repo and rewrite it as:

if (!_s3client) { _s3client = new S3Client({ credentials: awsCredentials, }); }

And then add these commands in to my buildSpec?

Oh, wait, actually it works with only "npm install -g s3-spa-upload" in the "install" phase of buildSpec if i change the CodeBuild Project's environment from EC2 to Lambda. I was provisioning the CodePipeline and the CodeBuild Project via CDK and it seems like it defaults to EC2.

I had to add another Statement to the S3 bucket to allow the CodeBuild Projects service role and also a permission for the service role to access the S3 bucket.

I hope to be able to make the CDK code work to provision a Lambda environment for the CodeBuild Project and add the permissions in both, then its good to go. (Also the CDK Source Action doesn't support the newer Github authentication method it seems)

ottokruse commented 1 month ago

How's it going mate?

nullish coalescing assignment operator is pretty standard by now, and is supported I think from Node.js v15 onwards. What version of Node.js are you using?

CsehAbel commented 1 month ago

Hi, i am doing fine, making progress, fighting with the SDK to resolve some of the cyclic references in my CDK code.

I don't know anymore which Node.js version it was, it was the standard EC2 environment that CodeBuildAction Construct creates by default, anyway i added this to my CodeBuildAction, and the nullish coalescing assignment operator was gone:

environment: { computeType: cdk.aws_codebuild.ComputeType.LAMBDA_2GB, //aws/codebuild/amazonlinux-aarch64-lambda-standard:nodejs20 buildImage: cdk.aws_codebuild.LinuxArmLambdaBuildImage.AMAZON_LINUX_2023_NODE_20, }