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

Deploy mljsapi, madliberationjs to a CloudFront distro with API Gateway and S3 #254

Closed
3 of 9 tasks
douglasnaphas opened this issue Nov 23, 2020 · 15 comments
Closed
3 of 9 tasks
Labels
cdk Use the AWS CDK for infra code and deployment

Comments

@douglasnaphas
Copy link
Owner

douglasnaphas commented Nov 23, 2020

TODO

  • Run the API locally with SAM, from madliberation/. We're actually going to run with straight node, because incorporating SAM into the Docker setup is too hard, because SAM itself starts up a container
  • Set up nginx config to reverse proxy from a port to another service
  • Access the API (running with SAM outside of Docker) via port that talks to nginx. This will involve running sam local start-api with the --docker-network option. Won't do. There's no way for the nginx conf file to reference the out-of-Docker running API, at least not without doing container networking that I don't know how to do. Running with node is close enough to how it will be run in prod
  • Run the API locally with SAM, Docker, and docker-compose.
  • Try to run the SAM CLI Docker container from docker-compose. Try something like mapping the volume from madliberation/mljsapi.
  • Add an S3 bucket.
  • (live site) Add a div to the frontend on the About page containing the config values that I will inject, if they are present.
  • (live site) Inject the values (api.passover.lol for the backend, and the redirect URI) that I need for the app to function normally, and confirm they are present in the attributes of the added div
  • Switch the frontend to using the injected values, with the current location as default. Validate by observing the (failing) call on the new frontend to /scripts.
@douglasnaphas douglasnaphas added the cdk Use the AWS CDK for infra code and deployment label Nov 23, 2020
douglasnaphas added a commit that referenced this issue Nov 23, 2020
#254

This is after clearing out the files in the repo and running

cdk init sample-app --language=typescript
douglasnaphas added a commit that referenced this issue Nov 23, 2020
#254

The new experimental deployment process will pull existing application
code in as git submodules.
@douglasnaphas
Copy link
Owner Author

douglasnaphas commented Nov 23, 2020

@douglasnaphas
Copy link
Owner Author

API Gateway might be better due to Lambda@Edge limitations

Lambda@Edge has some pretty concerning limitations:

  1. Looks like function memory footprint is limited to 128 MB for viewer requests (I think that's what I'd be using to serve an HTTP API using CloudFront), which is too small.
  2. Lambda@Edge functions have to live in US East 1, though of course they are replicated throughout the world. This is a problem because I might want to use different regions as a way to deploy to the same account with different configurations read from AWS Systems Manager Parameter Store.
  3. Looks like Lambda@Edge functions can't use Lambda function environment variables. I currently use these for the NODE_ENV, but I might want to use them for other things, like parameters read from Parameter Store.

Now I want to see if I can use API Gateway without a custom domain name (thus using the CloudFront distro's TLS certificate) to proxy based on the path and route to, for example, my S3 bucket for passover.lol/, but API Gateway for passover.lol/api.

douglasnaphas added a commit that referenced this issue Nov 24, 2020
#254

Invocation of my endpoint is failing, because it looks like node_modules
is missing from my Lambda's ZIP file.
douglasnaphas added a commit that referenced this issue Nov 24, 2020
#254

I got this error:

```
$ cdk synth > dev-template-01.yml
Cannot find module '@aws-cdk/aws-apigateway'
Require stack:
- /Users/dougnaphas/repos/madliberation/lib/madliberation-stack.js
- /Users/dougnaphas/repos/madliberation/bin/madliberation.ts
Subprocess exited with error 1
```

and running npm i, resulting in the present changes to
package-lock.json, fixed it.
@douglasnaphas
Copy link
Owner Author

The following are sufficient (as of acaa69b) to run the API locally from madliberation/, with the MLJSAPI code living in madliberation/mljsapi/.

$ cdk --profile=doug synth --no-staging > dev-template-02.yml

$ sam local start-api --template dev-template-02.yml --port 3535 --host localhost

Then I can:

$ curl http://localhost:3535/public-endpoint
{"Output":"this endpoint is public"}

@douglasnaphas douglasnaphas changed the title Deploy mljsapi to a CloudFront distro with Lambda@Edge Deploy mljsapi to a CloudFront distro with Lambda@Edge or API Gateway Nov 24, 2020
douglasnaphas added a commit to douglasnaphas/mljsapi that referenced this issue Nov 28, 2020
douglasnaphas/madliberation#254

With this change, the madliberation repo (which includes this repo
mljsapi as a submodule) will be able to run mljsapi with `docker-compose
up` (without AWS SAM).
douglasnaphas added a commit that referenced this issue Nov 28, 2020
#254

This includes submodule changes to mljsapi that add the ability for
mljsapi to run locally in a Docker container (not with SAM).
douglasnaphas added a commit that referenced this issue Nov 28, 2020
#254

I can now, from madliberation/:

    $ docker-compose build
    ...
    $ docker-compose up
    ...

and

    $ curl http://localhost:3800/public-endpoint
    {"Output":"this endpoint is public"}
@douglasnaphas douglasnaphas changed the title Deploy mljsapi to a CloudFront distro with Lambda@Edge or API Gateway Deploy mljsapi, madliberationjs to a CloudFront distro with API Gateway and S3 Nov 28, 2020
@douglasnaphas
Copy link
Owner Author

I'm widening the scope here to include the front-end madliberationjs, because it will be the default origin for the CloudFront distro.

douglasnaphas added a commit to secret-traitor/secret-traitor that referenced this issue Dec 6, 2020
douglasnaphas/madliberation#254

The function is timing out. It was only using 128 MB of memory, so I
increased it to 3008 MB.
douglasnaphas added a commit to secret-traitor/secret-traitor that referenced this issue Dec 6, 2020
douglasnaphas/madliberation#254

This is to try to isolate problems with Apollo and createServer from
problems with wiring the Express app up with Lambda.
douglasnaphas added a commit that referenced this issue Dec 13, 2020
douglasnaphas added a commit that referenced this issue Dec 16, 2020
gh-254

It's already been built, as well, so remove the build command.
douglasnaphas added a commit that referenced this issue Dec 16, 2020
@douglasnaphas
Copy link
Owner Author

I need to set index.html as the default object on the distro.

https://d2zor2cnxtxt2r.cloudfront.net/index.html#/

Screen Shot 2020-12-16 at 2 37 17 AM

douglasnaphas added a commit that referenced this issue Dec 17, 2020
gh-254

I'm still getting the error that the origin domaain must be a domain
name.
douglasnaphas added a commit that referenced this issue Dec 17, 2020
gh-254

Trying to guess why my stripping of /prod/ from the domain name isn't
working.
douglasnaphas added a commit that referenced this issue Dec 19, 2020
gh-254

This was inspired by looking at the output of `cdk synth`, which
includes:

```
  lambdaApiurl:
    Value:
      Fn::Join:
        - ""
        - - https://
          - Ref: EndpointEEF1FD8F
          - .execute-api.
          - Ref: AWS::Region
          - "."
          - Ref: AWS::URLSuffix
          - /
          - Ref: EndpointDeploymentStageprodB78BEEA0
          - /
  lambdaApiurltransformed:
    Value:
      Fn::Join:
        - ""
        - - Ref: EndpointEEF1FD8F
          - .execute-api.
          - Ref: AWS::Region
          - "."
          - Ref: AWS::URLSuffix
          - /
          - Ref: EndpointDeploymentStageprodB78BEEA0
          - /
```
@douglasnaphas
Copy link
Owner Author

Here's a nice piece of progress.

$ curl https://d2zor2cnxtxt2r.cloudfront.net/prod/
{"Output":"Hello World!! "}
$ curl https://d2zor2cnxtxt2r.cloudfront.net/prod/public-endpoint
{"Output":"this endpoint is public"}

Screen Shot 2020-12-19 at 1 09 19 PM

@douglasnaphas
Copy link
Owner Author

douglasnaphas commented Dec 20, 2020

New mode of interaction at https://d2zor2cnxtxt2r.cloudfront.net/#/. fetch("/prod/public-endpoint").then(r => r.json()).then(j => {console.log(j)}); works, so the frontend doesn't need to have a backend URL specified.

Screen Shot 2020-12-20 at 10 49 55 AM

@douglasnaphas
Copy link
Owner Author

I think I need to set up the existing prod env of passover.lol to have the routing-through-CloudFront approach, because of this in MLJS Configs:

  static apiUrl() {
    if (process && process.env && process.env.REACT_APP_MLJSAPI_URL) {
      return process.env.REACT_APP_MLJSAPI_URL;
    }
    return 'https://api.passover.lol/';
  }

@douglasnaphas
Copy link
Owner Author

More progress on the local setup. I can fetch to /api/public-endpoint from http://localhost:3800.

Screen Shot 2020-12-23 at 8 13 42 AM

douglasnaphas added a commit to douglasnaphas/mljsapi that referenced this issue Jan 25, 2021
douglasnaphas/madliberation#254

This is needed so that:
    1. The existing app will still work, and
    2. The new setup (CDK) can send the dynamic, environment-specific
table name as a variable.
@douglasnaphas
Copy link
Owner Author

Some things to deal with.

admin_douglas_naphas:~/environment/mljsapi (table-env-var) $ grep -rIn --exclude-dir=.git --exclude-dir=node_modules 'TableName.*seders' .                                             
./lib/createSession.test.js:29:          params.TableName != 'seders' ||
./lib/dbPlayGetScripts.js:19:    TableName: 'seders'
./lib/db.js:28:          TableName: 'seders',
./lib/db.js:47:          TableName: 'seders',
./lib/joinSeder.test.js:169:        params.TableName != 'seders' ||
./lib/createSession.js:34:      TableName: 'seders',
./lib/dbPlayGetParticipants.js:21:    TableName: 'seders'
./lib/room-code.js:36:        TableName: 'seders',
./lib/joinSeder.js:46:      TableName: 'seders',

The table name should be fully parameterized so that I can pass it in as an environment variable from the CDK project.

@douglasnaphas
Copy link
Owner Author

I need to get the tests passing now that the table name is not hard-coded as 'seders', but rather is passed in from the environment.

douglasnaphas added a commit to douglasnaphas/mljsapi that referenced this issue Jan 26, 2021
douglasnaphas/madliberation#254

This includes a fix to some failing tests in joinSeder.test.js, where
the env var TABLE_NAME had to be mocked before schema.js was required.
@douglasnaphas
Copy link
Owner Author

The changes I made on my branch table-env-var are causing /scripts to return a 500.

@douglasnaphas
Copy link
Owner Author

I should set SameSite: None when NODE_ENV is "development." It looks like Chrome isn't sending my cookie from localhost:4000 to api-dev.passover.lol.

douglasnaphas pushed a commit to douglasnaphas/mljsapi that referenced this issue Jan 28, 2021
douglasnaphas/madliberation#254

Seders are failing in Chrome in dev, because in dev the frontend and
backend currently run in different domains for samesite cookie purposes.
Chrome now uses samesite lax as the default.
douglasnaphas added a commit to douglasnaphas/mljsapi that referenced this issue Jan 28, 2021
douglasnaphas/madliberation#254

Requests to paths "early" in the server (so to speak), like /scripts, /,
and /public-endpoint are intermittently throwing errors.
douglasnaphas added a commit to douglasnaphas/mljsapi that referenced this issue Jan 28, 2021
@douglasnaphas
Copy link
Owner Author

Closing. The frontend and backend are deployed. I'll set up separate Issues for implementing stages of the workflow (sign-in, listing scripts, joining the seder, etc) in the turnkey env.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cdk Use the AWS CDK for infra code and deployment
Projects
None yet
Development

No branches or pull requests

1 participant