sst / ion

❍ — a new engine for SST
https://ion.sst.dev
MIT License
1.11k stars 131 forks source link

Please provide required params for Postgres driver #623

Open zhifez opened 4 days ago

zhifez commented 4 days ago

I was setting up Postgres with Drizzle while following this tutorial.

It able to generate migration file just fine, but when it tries to run the migration (npm run db migrate), an error is thrown: "Please provide required params for Postgres driver":

Screenshot_2024-07-01_at_12_38_07 PM

I have no idea where am I supposed to get the host from (it's not found in Resource.MyPostgres), meanwhile the tutorial only required database, secretArn, and resourceArn values in config.

import { Resource } from "sst";
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  driver: "aws-data-api",
  dialect: "postgresql",
  dbCredentials: {
    database: Resource.MyPostgres.database,
    secretArn: Resource.MyPostgres.secretArn,
    resourceArn: Resource.MyPostgres.clusterArn,
  },
  // Pick up all our schema files
  schema: ["./src/**/*.sql.ts"],
  out: "./migrations",
});

I've tried removing .sst and node_modules folders and rebuilt everything, but to no avail.

zhifez commented 4 days ago

Thanks to ChatGPT, I managed to figure out how to get host (and other values):

const rds = new RDSClient();
const secretsManager = new SecretsManager(Resource.MyPostgres.secretArn);

const getDbCredentials = async (secretArn: string) => {
  const secretValue = await secretsManager.getSecretValue({ SecretId: secretArn });
  if (!secretValue || !secretValue.SecretString) {
    throw new Error('Secret value not found');
  }
  return JSON.parse(secretValue.SecretString);
};

const getRdsDetails = async (clusterArn: string) => {
  const clusterIdentifier = clusterArn.split(':').pop();
  const params = {
    DBClusterIdentifier: clusterIdentifier
  };
  const command = new DescribeDBClustersCommand(params);

  const rdsData = await rds.send(command);
  const cluster = rdsData.DBClusters[0];
  return {
    host: cluster.Endpoint,
    port: cluster.Port,
  };
}

const main = async () => {
  const dbCredentials = await getDbCredentials(Resource.MyPostgres.secretArn);
  const rdsDetails = await getRdsDetails(Resource.MyPostgres.clusterArn);

  return defineConfig({
    dialect: 'postgresql',
    schema: ["./src/**/*.sql.ts"],
    out: "./migrations",
    dbCredentials: {
      host: rdsDetails.host,
      port: rdsDetails.port,
      user: dbCredentials.user,
      password: dbCredentials.password,
      database: Resource.MyPostgres.database,
      secretArn: Resource.MyPostgres.secretArn,
      resourceArn: Resource.MyPostgres.clusterArn,
    },
  });
};

export default main();

However, I still can't complete the migration without it constantly throwing ETIMEDOUT. I'm guessing it's because I'm not supposed to be able to connect to the Postgres DB on local?

jayair commented 1 day ago

Which version are you using?

When I wrote this tutorial, we were using a pretty early version. Maybe it's been updated since: https://github.com/sst/ion/blob/dev/examples/aws-drizzle/package.json#L11