Hello everyone, Has anyone been able to perform a...
# orm-help
c
Hello everyone, Has anyone been able to perform a prisma migrate deploy from AWS Lambda, AWS Fargate or AWS ECS Container? I was following this thread on Github https://github.com/prisma/prisma/issues/4703 however there doesn't seem to be a conclusion. The main problem is that lambdas are read-only so you cannot execute prisma migrate deploy successfully as it requires to write a couple of things. I don't really need to execute this on NodeJS, I just need to be able to instruct prisma to perform a deploy with a specific Connection URL to create new customer tenants in Postgresql (Each tenant is a schema) and await for it to confirm that the schema was created. This process should not take more than 5 seconds as the database is pretty small. I don't use EC2 instance, so I appreciate if any recommendation doesn't include virtual machines or EC2 instances.
1
d
Yes I just did this, I'll share below for Lambda
Copy code
import { execFile } from 'child_process';
import path from 'path';

const SCHEMA_PATH = process.env.SERVICE_SCHEMA_PATH;

export interface MigrationsResponse {
  body: string;
  statusCode: number;
}

export const coreDeploy = async (): Promise<MigrationsResponse> => {
  const command = 'deploy';
  const options: string[] = [`--schema=./${SCHEMA_PATH}`];
  const exitCode = await new Promise(resolve => {
    execFile(
      path.resolve('./node_modules/prisma/build/index.js'),
      ['migrate', command].concat(options),
      (error, stdout, stderr) => {
        console.log('STDOUT: ---------');
        console.log(stdout);
        console.log('STDOUT END ---------');
        console.log('STDERR: ---------');
        console.log(stderr);
        console.log('STDERR END ---------');
        if (error != null) {
          console.log(
            `prisma migrate ${command} exited with error ${error.message}`,
          );
          resolve(error.code ?? 1);
        } else {
          resolve(0);
        }
      },
    );
  });
  if (exitCode != 0) {
    throw Error(`command ${command} failed with exit code ${exitCode}`);
  }
  const response = {
    body: JSON.stringify('Migrations successfully applied.'),
    statusCode: 200,
  };

  console.log('Response: ' + JSON.stringify(response));
  return response;
};
That's the actual lambda code
Here is a serverless.yml with some things blacked out, the important part here is the package patterns that are ignored, and then added back in. You want to only deploy the prisma engines you need otherwise the lambda is too large
Copy code
org: dborstelmann
app: TODO
service:
  name: TODO
provider:
  stage: dev
  region: us-east-2
  name: aws
  runtime: nodejs14.x
  timeout: 10
  vpc: TODO
  environment:
    SERVICE_DATABASE_URL: TODO?schema=public&connection_limit=1
    SERVICE_SCHEMA_PATH: TODO/src/schema.prisma
functions:
  deployMigrations:
    handler: TODO/dist/migrations.coreDeploy
    events:
      - http:
          path: /migrate
          method: post
          cors: true
    package:
      patterns:
        - node_modules/@prisma/engines/migration-engine-rhel-*
        - node_modules/@prisma/engines/libquery_engine-rhel-*
        - node_modules/prisma/libquery_engine-rhel*
package:
  individually: true
  patterns:
    - '!node_modules/typescript'
    - '!node_modules/.bin/prisma*'
    - '!node_modules/.prisma/client/libquery_engine-*'
    - '!node_modules/@prisma/client/generator-build'
    - '!node_modules/@prisma/engines/introspection-engine-*'
    - '!node_modules/@prisma/engines/libquery_engine-*'
    - '!node_modules/@prisma/engines/migration-engine-*'
    - '!node_modules/@prisma/engines/prisma-fmt-*'
    - '!node_modules/prisma/libquery_engine-*'
Then I actually run this from CI/CD using this script
Copy code
import axios from "axios";

process.on('unhandledRejection', (error) => {
  console.log(`Failed to migrate database at: ${process.argv[2]}`);
  console.log(error);
  process.exit(1);
});

const migrate = async () => {
    const response = await <http://axios.post|axios.post>(process.argv[2], {
      headers: {
        'Content-Type': 'application/json'
      },
    });
    if (response.status !== 200) {
      throw new Error(response);
    }

    console.log(`Successfully migrated database at: ${process.argv[2]}`);
};

migrate();
The last thing is that you need to make sure you have the correct deps for the lambda, including prisma as a prod dependency
Copy code
{
  "dependencies": {
    "@prisma/client": "^3.4.1",
    "prisma": "^3.4.0"
  }
}
Feel free to ask me any questions on this thread or in a DM because this was a painful process for me too!
c
Thanks Dan, one last questions, did you have any problem in lambda because it was read-only? In my case I was trying to do something similar to your approach but keep getting errors. If not, I will definitely try your approach, thank you so much.
d
I did not because you upload all the node_modules through serverless and if you are just running deploy rather than dev you should be fine. I have this running in production righ tnow. oh before you run npm install in CI/CD (or from wherever you deploy) make sure to run with this env variable:
PRISMA_CLI_BINARY_TARGETS=rhel-openssl-1.0.x
this is what tells it to install the engines for AWS
Here is the doc for that
🙌 1
c
Thank you so much Dan, I appreciate it
👌 1
I tested a few minutes ago and the new schema was created successfully, thanks for your help. This saved me a lot of time as I was struggling thinking it was related to read-only permissions in Lambda.
d
I’m glad to hear it, I’m sure you’ll solve my next issue