はじめに
masamoriです。今年はもうちょっと記事書きたいです。
Azure FunctionsからDBに接続したい場合(クエリを発行したい場合)、シークレットの扱いが面倒だったりします。Key Vault使うのか環境変数ファイル用意するか。
ファイルを用意するのは正直面倒なので、Functionsの構成にシークレットを埋め込んで、それを呼び出すのもアリです。
しかし、それも面倒だったりするので、特に外部のDBを使う必要がなければ、Azure でDBを立ててマネージドIDを使うとシークレットの呼び出しする必要ないので、手間が減ります。(ただし、マネージドIDについて理解するには時間がかかる。)
マネージドIDの説明はこちらが詳しいです。
Azure Functions とAzure PostgrSqlを接続することにしたので、マネージドIDを使うことにしました。
しかし、これが意外に上手くいかず少しハマりました。
なので、そのエラーと解決法の共有をします。
準備
まずは、FunctionsのマネージドIDをONにします。 そして、IAMでFunctionsに対して「共同作成者」のロールを付与しました。 次にコードを書きます。 参考にしたコード例は以下のサイトから得られたこちら learn.microsoft.com
import { DefaultAzureCredential, ClientSecretCredential } from "@azure/identity"; const { Client } = require('pg'); // Uncomment the following lines according to the authentication type. // For system-assigned identity. // const credential = new DefaultAzureCredential(); // For user-assigned identity. // const clientId = process.env.AZURE_POSTGRESQL_CLIENTID; // const credential = new DefaultAzureCredential({ // managedIdentityClientId: clientId // }); // Acquire the access token. var accessToken = await credential.getToken('https://ossrdbms-aad.database.windows.net/.default'); // Use the token and the connection information from the environment variables added by Service Connector to establish the connection. (async () => { const client = new Client({ host: process.env.AZURE_POSTGRESQL_HOST, user: process.env.AZURE_POSTGRESQL_USER, password: accesstoken.token, database: process.env.AZURE_POSTGRESQL_DATABASE, port: Number(process.env.AZURE_POSTGRESQL_PORT) , ssl: process.env.AZURE_POSTGRESQL_SSL }); await client.connect(); await client.end(); })();
こちらはApp Serviceのチュートリアルですが、Functionでも基本的には同じです。 マネージドIDを使用してDBに接続を試みる場合、上記の「AZURE_POSTGRESQL_USER」は最初にDBを作成した際に設定したユーザーじゃないです。マネージドIDのオブジェクト名にします。今回は、Functionsの名前です。
実行とエラー
さて、とりあえずローカルの環境で接続テストをしてみました。すると、以下のエラーが発生。
error: password authentication failed for user "<ユーザー名>" at Parser.parseErrorMessage
.
どうやら認証に失敗した様子。おかしいな。マネージドIDを設定したはずなのに、IAMのロール割り当てが間違っていたか?
ところが、「管理者」権限を割り当てても解決しません。
解決法
ということは、他の認証が必要ということですね。ググってみたら、解決に役立ちそうな記事がありました。 qiita.com
なるほど、この認証が必要なんですね。 そして、この画面下にある「Microsoft Entra 管理者の追加」でFunctinosのマネージドIDを設定したら、接続に成功しました。
まとめ
DBと接続したい場合は、「認証」をRBACとは別に設定する必要があります。ということは、この「認証」はDB特有の設定なのでしょうか?
ちなみに、「管理者」「共同作成者」を外してもDBに接続できました。この「認証」を次の記事あたりで深掘りしてみたいですね。
また、踏み台サーバーなどからDBに通常アクセスしたい場合は、最初に設定したユーザー名とパスワードでアクセスしましょう。