
誰もがすなるぶろぐといふものを、私もしてみむとてするなり。
はじめに
こんにちは。(おそらく)1年ぶりにブログを書きます。酒井です。
最近縁あってAzure Cognitive Services for Language(以下、Language)とAzure Cognitive Search(以下、Search)を触っております。
聡明な読者の皆様なら既にお気づきかと思います。そうです、QnA Maker(以下、QnA)の後継サービス(どちらかというと機能?)です。
残念ながら、QnAは2025/03/31を持って廃止されてしまいます。悲しいですね。ですが、同じような機能がLanguageのカスタム質問応答機能として提供されます。やったね。
こやつらは、デフォルトでパブリックアクセスが有効になっており、すべてのネットワークからアクセスできてしまいます。APIアクセスにはキーが必要なのですが、あんまりいい気はしないですよね?
はい、ではこちらを見てください。では。
と言いたいところですが、ほんのちょっっっっっとだけ分かりづらく、詰まってしまいがちな部分なので備忘録として残しておきます。
前提
予めLanguageのリソースを作成して、カスタム質問応答機能を有効にしておいてください。(カスタム質問応答を有効にするタイミングでSearchのリソースも一緒に作ることができます。)
このようになっていたらOKです。
(ここから先は動作確認用です。)
また、Language Studioで適当なナレッジベースを作成してデプロイしておいてください。
方法はこちらの記事が大変参考になると思います。
【第二回】Azure Cognitive Services for Language で簡単テキスト分析!~質問応答を使ってみる編~
それでも難しい場合は、千尋の谷に落とされたと思って這い上がってみましょう。


手順
0. 試しにAPIを叩いてみる
まずは、ちゃんとAPIが叩けるか確認してみましょう。
LanguageはQuestion Answering - Get Answersを。
Searchはインデックスの一覧表示 (Azure Cognitive Search REST API)を叩いてみましょう。
Languageはこのようなレスポンスが返ってきます。

Searchはこのようなレスポンスが返ってきます。

ちなみに、APIキーをヘッダーに入れ忘れると、このようになります。
Language

Search

確認できましたね。APIキーはAzure Portalで確認できるので、探してみてください。
それでは、設定していきましょう。
1. LanguageリソースにSearchリソースの「共同作成者」のロールを割り振る
まず、Languageに紐づいたSearchリソースのアクセス制御(IAM)を開きます。

[+ 追加] > ロールの割り当ての追加と進みます。

あとは流れで割り当ててください。




このようになっていたらOKです。次いきましょ。
2. Searchリソースのパブリックアクセスを無効化する
お次はそのままネットワークを開きます。

無効をクリックするとこのようなダイアログが出てくるのでOKを押してください。

ちゃんとしばらく時間がかかるので、しばらく待ちます。
(公式ドキュメントによると最大30分かかることがあるとかなんとか)

完了したらこのようになります。

これでSearchのパブリックアクセスが無効化できました。次いきましょ。
3. Languageリソースにアクセス制限を入れる
いよいよ大詰めです。1つ前の手順とは打って変わって、今度はLanguageのリソースを開きます。
ネットワークを開き、選択したネットワークとプライベートエンドポイントを選びます。

するとこのようになるので、お好きな仮想ネットワークを選ぶなりなんなりしてください。

Saveを押したらぼちぼち待ちます。

ちゃんと更新されたらOKです。

そうすると、あらびっくり。Searchリソースにプライベートエンドポイントが生えているではありませんか。良かったですね。

4. 制限がかかっていることを確認する
最後に動作確認してみましょう。一番最初と同じようにAPIを叩いてみます。
Languageは同じように叩けますね。

しかし、Searchはタイムアウトするようになりました。ちゃんと制限がかかってますね。すばらしい。

ちなみに、Languageを別のIPから叩くと、ちゃんとブロックしてくれます。すばらしい。

これでLanguageとSearchがプライベートに接続され、SearchはLanguageからのみアクセスできるようになりました。また、Languageも特定のIPからのみアクセスできるようになりました。
実際にアプリにLanguageを組み込む場合は、特定の仮想ネットワークからのアクセスを許可して使うことになると思います。
えーそれでは良い感じになったので、あとはよしなにやってください。では。