GithubHelp home page GithubHelp logo

nikhil-shrestha / backend Goto Github PK

View Code? Open in Web Editor NEW

This project forked from mfogel/real-backend

0.0 1.0 0.0 11.66 MB

License: GNU General Public License v3.0

Shell 0.27% JavaScript 35.31% Python 64.43%

backend's Introduction

REAL Backend

Overview

serverless is used to manage this project.

The backend is organized as a series of cloudformation stacks to speed up the standard deploy and to help protect stateful resources. The stacks so far are:

  • real-main
  • real-auth
  • real-cloudfront
  • real-lambda-layers

Getting started

Installed on your system you will need nodejs12, yarn, python3.8, poetry, docker.

In each of the stack root directories, run yarn install to install serverless and required plugins.

To lint python files you will need black and flake8 installed globally.

Deployment

To deploy each serverless stack, run yarn deploy in that stack's root directory.

AWS Credentials

By default, serverless will use aws credentials stored in the profile with name real-{stage} (ie: real-dev, real-staging, or real-production). This behavior can be overridden by using the --aws-profile option.

Serverless expects the AWS credentials to have AdministratorAccess policy attached.

First-time deployment manual steps

CloudWatch

Once per AWS Account, must be done before first deployment

  • Create a LogGroup with name sns/<aws-region>/<aws-account-id>/DirectPublishToPhoneNumber/Failure. This log group will be referenced by all deployments in the account, and used by SNS to log SMS delivery failures.

IAM

Once per AWS Account

  • Google needs to be configured as an IAM OIDC Provider before real-main can be deployed. Step-by-step instructions are available here.

Pinpoint

Once per deployment

Pinpoint must be manually configured to send Apple Push notifications. After first deployment, from the Pinpoint console

  • navigate REAL Pinpoint Project -> Settings -> Push notifications -> Edit -> Apple Push Notification Service
  • Enable APNS and choose 'Key credentials' as authentication type
    • Our 'Bundle identifier' is app.real.mobile and our 'Team identifier' is YA5Y244F5C
    • A 'Key ID' corresponding 'Authentication key (.p8 file)' are available from the frontend iOS team

SecretsManager

Once per deployment

  • A CloudFront Key Pair must be generated and added. To do so, one must login to the AWS Console using the account's root credentials. See Setting up CloudFront Signed URLs for details.
  • Credentials to access the post verification API must be added. Reference the environment variable in serverless.yml for required format. Talk to the backend team lead to get a set of credentials.
  • Google OAuth Client Ids must be added. These are available from our google app's profile on the google app console and have format {"ios": "***", "web": "***", ...}. Reference the environment variable in serverless.yml for the proper naming.

SES

Once per AWS Account

To allow SES to send transactional emails from Cognito:

  • Add and verify the domain real.app. To do this you will need to be able to add a code to a TXT record on the real.app domain.
  • Configure the MAIL FROM domain of mail.real.app
  • If this is a production account, you will also want to configure DKIM for real.app in the SES interface.

You must also confirm, using the SES interface, the email address you wish to send email from (even if you've already confirmed the domain). By default [email protected] will be used. You can either:

  • confirm that email address. You would want to do this for a brand-new production deployment, and possibly for a new staging or pre-production deployment.
  • alternatively, you can set the environment variable SES_SENDER_ADDRESS in a .env file in the real-main directory to an email address you control, and then confirm that email address in SES.

SNS

Once per AWS Account

  • Use this guide to enable CloudWatch Logs for all SMS messages

Other stacks outside this repo

The stacks in the following repos will need to be deployed before these

  • themes

The themes stack will create an S3 bucket, within which there is a subdirectory placeholder-photos. The integration tests in this repo expect that subdirectory to be empty.

First-time stack deployment order

Resource dependencies between the stacks make initial deployment tricky. Stacks should be deployed in this order:

  • real-lambda-layers
  • real-main, with the following commented out from serverless.yml
    • the AWS::S3::BucketPolicy resource that depends on real-cloudfront
    • the AWS::Logs::MetricFilters and AWS::CloudWatch::Alarm that depend on a AppSync GraphQL LogGroup
  • real-cloudfront
  • real-main again, with nothing commented out
  • real-auth

Updates to an existing deployment

In general, only stacks that have been changed since the last deployment need to be redeployed.

However, if a stack changed naming or versioning of a resource that another stack depends on, then the dependent stack needs to be redeployed as well. For example:

  • when the real-lambda-layers stack is redeployed with new python packages, its lambda layer version number is incremented
  • old versions of the real-lambda-layers are retained to allow rolling back a deployment of a dependent stack (ie: real-main) if necessary. Old versions of the layer should be deleted manually via the AWS Console once all stacks using the layer have been upgraded to use the new version.
  • in order for the real-main lambda handlers to the latest version of that lambda layer, real-main must be redeployed as well

External-facing API's, resources

AppSync graphql endpoint

  • Browse the graphql schema.
  • Endpoint url is provided by CloudFormation output real-<stage>-main.GraphQlApiUrl

Cognito User Pool

  • Allows authentication of new and existing users with email/phone and password
  • User pool client id is provided by CloudFormation output real-<stage>-main.CognitoFrontendUserPoolClientId
  • If SES is still in sandbox mode for the AWS Account (it is if you haven't moved it out of the sandbox) then Cognito will only be able to send emails to addresses that have been verified either in IAM or in SES.

Running the tests

Integration tets

Please see the Integation Testing README

Unit tests

The unit tests of the python lambda handlers in the primary stack use pytest. To run them:

cd real-main
poetry shell
pytest --cov=app app_tests/

Development

The serverless stacks

real-main

This is the primary stack, it holds everything not explicitly relegated to one of the other stacks.

Most development takes place here. To initialize the development environment, run poetry install in the stack root directory.

real-auth

Holds:

  • Api endpoints to asist in sign up / sign in process
  • Planned: Cognito resources will be moved in here (they are still in real-main at the moment)

Please see the real-auth README for further details.

real-cloudfront

Holds:

  • CloudFront CDN for the main 'uploads' bucket
  • Lambda@Edge handlers for that CloudFront instance

The Lambda@Edge handlers need to be broken into a separate stack because:

  • they are included in every deploy regardless of whether they have changed or not
  • re-deploying them takes ~20 minutes

CloudFront is included because:

  • changes to the CloudFront config, while somewhat uncommon, also trigger a ~20 minute deploy
  • separating the CloudFront config and the Lambda@Edge handlers into separate stacks isn't supported by the cloudfront-lambda-edge serverless plugin

real-lambda-layers

Holds the lambda layers. The python packages which the lambda handlers in the primary stack depend on are stored in a layer. This reduces the size of the deployment package of the primary stack from several megabytes to several kilobytes, making deploys of the primary stack much faster.

Adding new python dependencies

Note that new python packages dependencies for the lambda handlers in the primary real-main stack should be installed in two places:

  • in the primary real-main stack as a dev dependency: poetry add --dev <package name>
  • in the real-main-lambda-layers stack as a runtime dependency: poetry add <package name>

After adding a new dependency, the real-main-lambda-layers stack should be re-deployed first, followed by the real-main stack.

Setting up CloudFront Signed URLs

After a deploy to a new account, a CloudFront key pair needs to be manually generated and stored in the AWS secrets manager.

  • a new CloudFront key pair can be generated in the your security credentials section of IAM in the AMZ console. This is only available when logging in using AWS account's root credentials.

  • the public and private parts of the generated key should be stored in an entry in the AWS Secrets Manager

    • the name of the secret must match the value in the environment variable SECRETSMANAGER_CLOUDFRONT_KEY_PAIR_NAME as defined in the environment section of serverless.yml

    • the publicKey and privateKey values in the secret must not contain the header and footer lines (ie the ----- BEGIN/END RSA PRIVATE KEY ----- lines)

    • the format of the secret should be

      {
        "keyId": "<access key id>",
        "publicKey": "<cat public-key.pem | sed '1d;$d'>",
        "privateKey": "<cat private-key.pem | sed '1d;$d'>"
      }

Internal stateful services

DynamoDB

Table Schema

Please see the SCHEMA.md document.

Data Migrations

The order of operations to implement a data migration is:

  • deploy code that can read from both old and new schemaVersion, and uses new schemaVersion when creating new items
  • run data migration transforming all items with old schemaVersion to new schemaVersion
  • deploy code that only reads and writes new schemaVersion

S3

The following objects are stored with the given path structures:

  • Image posts:
    • {userId}/post/{postId}/image/***.jpg
  • Video posts:
    • {userId}/post/{postId}/video/video-original.mov.
    • {userId}/post/{postId}/video/video-hls/*
    • {userId}/post/{postId}/image/***.jpg
  • User profile photo: {userId}/profile-photo/{photoPostId}/***.jpg
  • Album art: {userId}/album/{albumId}/{artHash}/***.jpg

backend's People

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.