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

AWS Lambda landing page #5293

Merged
merged 21 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8b84ee9
one aws lambda page to rule them all
jharrell Sep 8, 2023
5f2e965
Apply suggestions from code review
jharrell Sep 12, 2023
298cfb2
Merge branch 'main' into jharrell/issue5157
jharrell Sep 12, 2023
1218625
Update content/300-guides/200-deployment/201-serverless/400-deploy-to…
jharrell Sep 12, 2023
e3e1376
Apply suggestions from code review
jharrell Sep 12, 2023
8fbf99b
Update content/300-guides/200-deployment/201-serverless/400-deploy-to…
jharrell Sep 12, 2023
e1b77f3
Update content/300-guides/200-deployment/201-serverless/400-deploy-to…
jharrell Sep 12, 2023
1530475
Apply suggestions from code review
jharrell Sep 14, 2023
b943fab
Apply suggestions from code review
jharrell Sep 14, 2023
3887b2c
Merge branch 'main' into jharrell/issue5157
jharrell Sep 15, 2023
3b7ec47
remove references to other sections
jharrell Sep 15, 2023
12f3447
appease cSpell
jharrell Sep 15, 2023
2af282f
Merge branch 'main' into jharrell/issue5157
jharrell Sep 19, 2023
90d710f
Apply suggestions from code review
jharrell Sep 19, 2023
992ae1f
Update content/300-guides/200-deployment/201-serverless/400-deploy-to…
ruheni Sep 19, 2023
d262985
Update content/300-guides/200-deployment/201-serverless/400-deploy-to…
jharrell Sep 19, 2023
09e0167
Merge branch 'main' into jharrell/issue5157
jharrell Sep 19, 2023
14df6aa
Merge branch 'main' into jharrell/issue5157
jharrell Sep 20, 2023
7669054
Update content/300-guides/200-deployment/201-serverless/400-deploy-to…
nikolasburk Sep 22, 2023
8f542bd
Merge branch 'main' into jharrell/issue5157
jharrell Sep 22, 2023
aa3f96e
Merge branch 'main' into jharrell/issue5157
jharrell Sep 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,33 +1,41 @@
---
title: 'Deploy to AWS Lambda with Serverless Framework'
metaTitle: 'Deploy your Serverless Framework project with Prisma'
metaDescription: 'Learn how to deploy your Prisma-backed applications to AWS Lambda with Serverless Framework'
title: 'Deploy to AWS Lambda'
metaTitle: 'Deploy your application using Prisma to AWS Lambda'
metaDescription: 'Learn how to deploy your Prisma-backed applications to AWS Lambda with AWS SAM, Serverless Framework, or SST'
tocDepth: 3
---

<TopBlock>

This guide explains how to avoid common issues when deploying a project using Prisma with [Serverless Framework](https://www.serverless.com/framework/).
This guide explains how to avoid common issues when deploying a project using Prisma to [AWS Lambda](https://aws.amazon.com/lambda/).

The Serverless Framework simplifies deployment to AWS Lambda. It provides a CLI that helps with workflow automation and AWS resource provisioning. While Prisma works well with the Serverless Framework "out of the box", there are a few improvements that can be made within your project to ensure a smooth deployment and performance. There is also additional configuration that is needed if you are using the [`serverless-webpack`](https://www.npmjs.com/package/serverless-webpack) or [`serverless-bundle`](https://www.npmjs.com/package/serverless-bundle) libraries.
While a deployment framework is not required to deploy to AWS Lambda, this guide covers deploying with:

- [AWS Serverless Application Model (SAM)](https://aws.amazon.com/serverless/sam/) is an open-source framework from AWS that can be used in the creation of serverless applications. AWS SAM includes the [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-reference.html#serverless-sam-cli), which you can use to build, test, and deploy your application.
ruheni marked this conversation as resolved.
Show resolved Hide resolved
- [Serverless Framework](https://www.serverless.com/framework/) provides a CLI that helps with workflow automation and AWS resource provisioning. While Prisma works well with the Serverless Framework "out of the box", there are a few improvements that can be made within your project to ensure a smooth deployment and performance. There is also additional configuration that is needed if you are using the [`serverless-webpack`](https://www.npmjs.com/package/serverless-webpack) or [`serverless-bundle`](https://www.npmjs.com/package/serverless-bundle) libraries.
- [SST](https://sst.dev/) provides tools that make it easy for developers to define, test, debug, and deploy their applications. Prisma works well with SST but must be configured so that your schema is correctly packaged by SST.

</TopBlock>

## Prerequisites
## General considerations when deploying to AWS Lambda

This section covers changes you will need to make to your application, regardless of framework. After following these steps, follow the steps for your framework.

This guide assumes you have an existing project using both Serverless Framework and Prisma. For a guide on how to get started with Serverless Framework, we recommend [Setting Up Serverless Framework With AWS](https://www.serverless.com/framework/docs/getting-started).
- [Deploying with AWS SAM](#deploying-with-aws-sam)
- [Deploying with the Serverless Framework](#deploying-with-the-serverless-framework)
- [Deploying with SST](#deploying-with-sst)

## Binary targets in <inlinecode>schema.prisma</inlinecode>
### Define binary targets in Prisma Schema

The Prisma schema should contain the following in the `generator` block:

```prisma
binaryTargets = ["native", "rhel-openssl-1.0.x"]
```

This is necessary because the runtime used in the development and when your application is deployed differ. Add the [`binaryTarget`](/reference/api-reference/prisma-schema-reference#binarytargets-options) to make the compatible Prisma engine file available.
This is necessary because the runtimes used in development and deployment differ. Add the [`binaryTarget`](/reference/api-reference/prisma-schema-reference#binarytargets-options) to make the compatible Prisma engine file available.

### Lambda functions with arm64 architectures
#### Lambda functions with arm64 architectures

Lambda functions that use [arm64 architectures (AWS Graviton2 processor)](https://docs.aws.amazon.com/lambda/latest/dg/foundation-arch.html#foundation-arch-adv) must use an `arm64` precompiled engine file.
jharrell marked this conversation as resolved.
Show resolved Hide resolved

Expand All @@ -37,7 +45,61 @@ In the `generator` block of your `schema.prisma` file, add the following:
binaryTargets = ["native", "linux-arm64-openssl-1.0.x"]
```

## Loading environment variables via a <inlinecode>.env</inlinecode> file
### Prisma CLI binary targets

While we do not recommend running migrations within AWS Lambda, some applications will require it. In these cases, you can use the [PRISMA_CLI_BINARY_TARGETS](/reference/api-reference/environment-variables-reference#prisma_cli_binary_targets) environment variable to make sure that Prisma CLI commands, including `prisma migrate`, have access to the correct schema engine.

In the case of AWS lambda, you will have to add the following environment variable:

```env file=.env
PRISMA_CLI_BINARY_TARGETS=native,rhel-openssl-1.0.x
```

<Admonition>

`prisma migrate` is a command in the `prisma` package. Normally, this package is installed as a dev dependency. Depending on your setup, you may need to install this package as a dependency instead so that it is included in the bundle or archive that is uploaded to Lambda and executed.

</Admonition>

### Connection pooling

Generally, when you use a Function as a Service (FaaS) environment to interact with a database, every function invocation can result in a new connection to the database. This is not a problem with a constantly running Node.js server. Therefore, it is beneficial to pool database connections to get better performance. You can use [Accelerate](/data-platform/accelerate) to solve this issue. For other solutions, see the [connection management guide for serverless environments](/guides/performance-and-optimization/connection-management#serverless-environments-faas).

## Deploying with AWS SAM

### Loading environment variables

AWS SAM does not directly support loading values from a `.env` file. You will have to use one of AWS's services to store and retrieve these parameters. [This guide](https://medium.com/bip-xtech/a-practical-guide-to-surviving-aws-sam-d8ab141b3d25) provides a great overview of your options and how to store and retrieve values in Parameters, SSM, Secrets Manager, and more.

### Loading required files

AWS SAM uses [esbuild](https://esbuild.github.io/) to bundle your TypeScript code. However, the full esbuild API is not exposed and esbuild plugins are not supported. This leads to problems when using Prisma in your application as certain files (like `schema.prisma`) must be available at runtime.

To get around this, we will directly reference needed files in our code to bundle them correctly. In your application, you could add the following lines to your application where Prisma is instantiated.
nikolasburk marked this conversation as resolved.
Show resolved Hide resolved

```ts file=app.ts
import schema from './prisma/schema.prisma'
import x from './node_modules/.prisma/client/libquery_engine-rhel-openssl-1.0.x.so.node'

if (process.env.NODE_ENV !== 'production') {
console.debug(schema, x)
}
jharrell marked this conversation as resolved.
Show resolved Hide resolved
```

You will also need to define how to bundle these files with esbuild by adding the following lines to `Metadata.BuildProperties` in your `template.yaml`:

```yaml file=template.yaml
Loader:
- .prisma=file
- .so.node=file
AssetNames: '[name]'
jharrell marked this conversation as resolved.
Show resolved Hide resolved
```

This will make sure that files needed by Prisma will be included in the AWS SAM build.

## Deploying with the Serverless Framework

### Loading environment variables via a <inlinecode>.env</inlinecode> file

Your functions will need the `DATABASE_URL` environment variable to access the database. The `serverless-dotenv-plugin` will allow you to use your `.env` file in your deployments.

Expand Down Expand Up @@ -80,11 +142,7 @@ Packaging deployment-example-sls for stage dev (us-east-1)
</cmdResult>
</CodeWithResult>

## Connection pooling

Generally, when you use a FaaS (Function as a Service) environment to interact with a database, every function invocation can result in a new connection to the database. This is not a problem with a constantly running Node.js server. Therefore, it is beneficial to pool DB connections to get better performance. You can use [Accelerate](/data-platform/accelerate) to solve this issue. For other solutions, see the [connection management guide for serverless environments](/guides/performance-and-optimization/connection-management#serverless-environments-faas).

## Deploy only the required files
### Deploy only the required files

To reduce your deployment footprint, you can update your deployment process to only upload the files your application needs. The Serverless configuration file, `serverless.yml`, below shows a `package` pattern that includes only the Prisma engine file relevant to the Lambda runtime and excludes the others. This means that when Serverless Framework packages your app for upload, it includes only one engine file. This ensures the packaged archive is as small as possible.

Expand All @@ -110,23 +168,23 @@ package:

If you use `serverless-webpack`, see [Deployment with serverless webpack](#deployment-with-serverless-webpack) below.

## Deployment with <inlinecode>serverless-webpack</inlinecode>
### Deployment with <inlinecode>serverless-webpack</inlinecode>

If you use `serverless-webpack`, you will need additional configuration so that your `schema.prisma` is properly bundled. You will need to:

1. Copy your `schema.prisma` with [`copy-webpack-plugin`](https://www.npmjs.com/package/copy-webpack-plugin).
2. Run `prisma generate` via `custom > webpack > packagerOptions > scripts` in your `serverless.yml`.
3. Only package the correct Prisma engine file to save more than 40mb of capacity.

### 1. Install webpack specific dependencies
#### 1. Install webpack specific dependencies

First, ensure the following webpack dependencies are installed:

```terminal
npm install --save-dev webpack webpack-node-externals copy-webpack-plugin serverless-webpack
```

### 2. Update <inlinecode>webpack.config.js</inlinecode>
#### 2. Update <inlinecode>webpack.config.js</inlinecode>

In your `webpack.config.js`, make sure that you set `externals` to `nodeExternals()` like the following:

Expand Down Expand Up @@ -170,7 +228,7 @@ Depending on how your application is bundled, you may need to copy the schema fi

Refer to the [Serverless Webpack documentation](https://www.serverless.com/plugins/serverless-webpack) for additional configuration.

### 3. Update <inlinecode>serverless.yml</inlinecode>
#### 3. Update <inlinecode>serverless.yml</inlinecode>

In your `serverless.yml` file, make sure that the `custom > webpack` block has `prisma generate` under `packagerOptions > scripts` as follows:

Expand Down Expand Up @@ -206,7 +264,7 @@ custom:
-- find . -name "libquery_engine-*" -not -name "libquery_engine-arm64-openssl-*" | xargs rm
```

### 4. Wrapping up
#### 4. Wrapping up

You can now re-package and re-deploy your application. To do so, run `serverless deploy`. Webpack output will show the schema file being moved with `copy-webpack-plugin`:

Expand Down Expand Up @@ -241,6 +299,27 @@ Packing external modules: @prisma/client@^5.1.1
</cmdResult>
</CodeWithResult>

## Summary
## Deploying with SST

### Working with environment variables

While SST supports `.env` files, [it is not recommended](https://docs.sst.dev/config#should-i-use-configsecret-or-env-for-secrets). SST recommends using `Config` to access these environment variables in a secure way.

The SST guide [available here](https://docs.sst.dev/config#overview) is a step-by-step guide to get started with Config. Assuming you have created a new secret called `DATABASE_URL` and have [bound that secret to your app](https://docs.sst.dev/config#bind-the-config) you can set up `PrismaClient` with the following:
jharrell marked this conversation as resolved.
Show resolved Hide resolved

```ts file=prisma.ts
import { PrismaClient } from '@prisma/client'
import { Config } from 'sst/node/config'

You have successfully deployed a Prisma-backed Serverless Framework application. Congratulations!
const globalForPrisma = global as unknown as { prisma: PrismaClient }

export const prisma =
globalForPrisma.prisma ||
new PrismaClient({
datasourceUrl: Config.DATABASE_URL,
})

if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma

export default prisma
```
2 changes: 1 addition & 1 deletion content/800-data-platform/100-accelerate/600-faq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ The freshness of the data served by the cache depends on the cache strategy defi

## When should I not use Accelerate's caching features?

Accelerate is a global data cache and connection pool that allows you to optimize data access in code at the query level. While caching with Accelerate can greatly boost the performance of your app, it may not always the best choice for your usecase.
Accelerate is a global data cache and connection pool that allows you to optimize data access in code at the query level. While caching with Accelerate can greatly boost the performance of your app, it may not always the best choice for your use case.

Accelerate's global cache feature may not be a good fit for your app if:

Expand Down