Open8

PrismaからAzure Database for MySQLにアクセスしたい

kage1020kage1020

Vercel+Prisma+PlanetScaleでとても簡単にwebアプリをローンチできるが,デプロイ先をVercelからAzureにしたいとき,ちょっと困ったことになっている.

kage1020kage1020

データベースとしてMySQLを使う場合,Azure Database for MySQLが候補にあがる.
インスタンスを作成し,Prismaのドキュメントに従ってURLを指定して,いざ!
というところでSSL証明書が必要.

kage1020kage1020

github上でも議論されているが,解決していなかったりハック的なものがあるだけで根本の解決はできていない.

https://github.com/prisma/prisma/issues/4324

https://github.com/prisma/prisma/issues/1673

今のところtmpフォルダを生成し,環境変数から取り出したprivate keyを.pemに書き込んでそれを認証URLのパラメータに渡すという強引な方法が有力な手法か

import { PrismaClient } from '@prisma/client'
import { tmpdir } from 'os'
import fs from 'fs'
import crypto from 'crypto'
// nextjs dev server reloads files on page navigation, so new Prisma Clients were being spawned everytime
let prisma

if (!global.prisma) {
  if (process.env.NODE_ENV !== 'development') {
    fs.writeFile(
      `${tmpdir()}/server-ca.pem`,
      process.env.CLIENT_CERTIFICATE,
      err => {
        if (err) return console.log(err)
      }
    )

    const algorithm = 'aes-128-cbc'
    const decipher = crypto.createDecipheriv(
      algorithm,
      process.env.CLIENT_IDENTITY_KEY,
      process.env.CLIENT_IDENTITY_IV
    )

    const getDecryptedSecret = () => {
      let decrypted = decipher.update(
        process.env.ENCRYPTED_CLIENT_IDENTITY,
        'base64',
        'utf8'
      )
      decrypted += decipher.final('utf8')
      return decrypted
    }

    fs.writeFile(
      `${tmpdir()}/client-identity.p12`,
      getDecryptedSecret(),
      'base64',
      err => {
        if (err) return console.log(err)
      }
    )
  }
  global.prisma = new PrismaClient({})
}

prisma = global.prisma

export default prisma
kage1020kage1020

クラウドとインフラ周りの知識がなさ過ぎてこれ以上手を付けられない.
Static Web App経由だったら証明書いらないとかないのかな.
最悪証明書なしで...