Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Static Site 403's for route based index pages (Cloudfront + s3 issue) #1332

Open
aisflat439 opened this issue Feb 4, 2022 · 15 comments

Comments

@aisflat439
Copy link
Contributor

I'm fully stumped on this issue.

I followed the suggested implementation for a gatsby site here. My gatsby site builds a few pages

index.html
404.html
blog/
  - index.html

// lots of JS files that re-hydrate the app and handle regular JS "stuff"

If you navigate to / then use a <Link /> tag (from gatsby) everything works correctly. Because the app is hydrated. However, if you /blog you get a 403. A gatsby site will reload though, becuase of the hydration. As an example, on my site you can see that on refresh we get a 403 for this file:

image

however, I can see it in s3 here:
image

Gatsby has a plugin for this https://gatsby-plugin-s3.jari.io/recipes/with-cloudfront/ that solves this issue. According to that plugin, in order to make an s3 bucket work, you need it to be public. That means you need to

In order for all the features of your site to work correctly, you must instead use your S3 bucket's Static Website Hosting Endpoint as the CloudFront origin

I looked at the aws docs and I see https://docs.aws.amazon.com/AmazonS3/latest/userguide/EnableWebsiteHosting.html which seems to say that you need to select Use This Bucket to enable static hosting. I don't see how to do that in SST or CDK.

image


perhaps the better solution I should try is https://docs.aws.amazon.com/cdk/api/v2/docs/aws-amplify-alpha-readme.html which side steps the issue I guess? I dunno. I've been messing with this for 2 weeks now. 😭 and am fully out of ideas.

@aisflat439
Copy link
Contributor Author

Doing some more work on this. I find:

https://github.com/aws-samples/aws-cdk-examples/blob/master/typescript/static-site/static-site.ts

Which looks like what sst.StaticSite extends. That seems right. It's still not obvious from the docs how to do the last part of teh static site deployment. new s3Deploy.bucketDeployment...

@aisflat439
Copy link
Contributor Author

I have a possible solution here. I'm going to try to play with this some this week. I'll update the thread with info if it works.

https://aws.amazon.com/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/

@fwang
Copy link
Contributor

fwang commented Feb 22, 2022

Hi @aisflat439, give this a try. This override the S3 bucket and the CloudFront distribution based on what you shared above:

    const site = new sst.StaticSite(this, "GatsbySite", {
      ...,
      s3Bucket: {
        websiteIndexDocument: "index.html",
        websiteErrorDocument: "404.html",
      },
      cfDistribution: {
        defaultBehavior: {
          origin: new cfOrigins.HttpOrigin(
            Lazy.stringValue({
              produce() {
                return site.s3Bucket.bucketWebsiteUrl;
              }
            })
          ),
        },
      },
    });

In short, pass in the s3Bucket props to enable S3 Bucket static hosting, so you can get the bucket's static website url. Then pass in the cfDistribution props to override the origin to point to the bucket's url.

Current, the StaticSite construct doesn't allow you to pass in websiteIndexDocument and websiteErrorDocument via the s3Bucket props, so you'd need to go into node_modules/@serverless-stack/resources/dist/StaticSite.js, search for websiteIndexDocument and websiteErrorDocument, and comment out the two blocks that looks like this:

    if (s3Bucket.websiteIndexDocument) {
      throw new Error(
        `Do not configure the "s3Bucket.websiteIndexDocument". Use the "indexPage" to configure the StaticSite index page.`
      );
    }

Give this a try, if it works for you, I will make a change to allow overriding s3Bucket.websiteIndexDocument.

@aisflat439
Copy link
Contributor Author

aisflat439 commented Feb 23, 2022

Sadly this does not work @fwang. There's a non zero chance this problem exists between keyboard and chair but, I think that what I'll need to do is a cloudfront + edge function as discussed on Slack. :(

I misunderstood this. There might be more I need to try here

@fwang fwang self-assigned this Feb 24, 2022
@aisflat439
Copy link
Contributor Author

@fwang I'm way unfamiliar with this but I think this line is the problem. I don't know how to test it though as the only way that I can test it is to deploy it and then I'm using the package that has the potential issue.

According to the note in this README the index document that SST is disallowing, handles this exact behavior. Does that seem possible to you?

@fwang
Copy link
Contributor

fwang commented Mar 1, 2022

@aisflat439 yeah, actually that's what I meant in the previous comment to comment out the two throw blocks.

Like I mentioned on Slack, if you can put together a sample repo with SST + Gastby that can reproduce this issue, I will give it a try on my end.

@aisflat439
Copy link
Contributor Author

aisflat439 commented Mar 2, 2022

Hey @fwang. Here's the example. I tried to keep it as minimal as possible. You have 2 urls in this case:

/
/example

if you run npx gatsby build you'll see the Pages tree in your console. You can then also go look at the generated Public folder. This is what Gatbsy builds for the S3 bucket. In there you should find

index.html      <---- root
/example        <--- folder
  index.html    <--- /example

which should be the document returned for the route /example but on deploy hitting /example will 403.

You can see a deployed example here:
full path
versus
normal link path

My understanding of StaticSite leads me to believe that this should apply to any website using the Static Site Construct.

I'm happy to help in any way I can and will provide more information if you need anything. I didn't bother actually deploying the example below since I'd guess you'll want to see it on your own. Please let me know if you have any luck or I'm just a bonehead 😄 .

https://github.com/aisflat439/gatsby-ex

@aisflat439
Copy link
Contributor Author

@fwang Is there anything else I can do to help you reproduce the issue at all?

@grenovales
Copy link

grenovales commented Jul 10, 2022

The websiteIndexDocument is needed to turn s3 into a webserver

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_deployment-readme.html
I had the same problem and had to remove the conditions mentioned by @fwang

@grenovales
Copy link

I think work around is to extend StaticSite and override createS3Bucket function

@fwang fwang removed their assignment Dec 14, 2022
@fjinkis
Copy link

fjinkis commented Feb 23, 2023

Has this issue any solution? Has anyone find any workaround? I'm using NextjsSite constructor and unfortunately it doesn't work either.

@aisflat439
Copy link
Contributor Author

aisflat439 commented Feb 23, 2023

Indeed @fjinkis! This is fixed in SST-2 with the new Static Site Construct.

Although I've left gatsby behind for astro

@fjinkis
Copy link

fjinkis commented Feb 23, 2023

@aisflat439 Do you think that I should migrate from NextjsSite constructor to StaticSite ?

@minizwergi
Copy link

Are there any news about this issue? I got the same error using sst 2 with RemixSite-Construct

@fjinkis
Copy link

fjinkis commented Apr 14, 2023

@minizwergi there is a bug fix in 2.5.1 version. Take a look at this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Pending Response
Development

No branches or pull requests

5 participants