Open8
PrismaからAzure Database for MySQLにアクセスしたい
Vercel+Prisma+PlanetScaleでとても簡単にwebアプリをローンチできるが,デプロイ先をVercelからAzureにしたいとき,ちょっと困ったことになっている.
まず,Next.jsをどこで動かすか.
Azure Static Appsで動かせるらしい?
静的アプリ(ハイブリット)と言いながら下の方にAPIルートを追加するという項目があり,未検証ではあるができそう.
データベースとしてMySQLを使う場合,Azure Database for MySQLが候補にあがる.
インスタンスを作成し,Prismaのドキュメントに従ってURLを指定して,いざ!
というところでSSL証明書が必要.
ローカルであれば証明書をダウンロードしてきて直接指定すればできる.
しかし,証明書をアップロードするのはセキュリティ的にだめっぽい
Prismaの公式ドキュメントにはAzure functions使えばええやろって書いてあっても自分のインフラ知識のキャパオーバーで追いきれない.
github上でも議論されているが,解決していなかったりハック的なものがあるだけで根本の解決はできていない.
今のところ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
クラウドとインフラ周りの知識がなさ過ぎてこれ以上手を付けられない.
Static Web App経由だったら証明書いらないとかないのかな.
最悪証明書なしで...