Power Platform から VNet を使用して Azure OpenAI へ通信する


# はじめに

これまで、Power Platform と Azure OpenAI を連携する方法についていくつか記事を書いてきました。

https://qiita.com/Takashi_Masumori/items/8a07fb6d1869967ce1f9

https://qiita.com/Takashi_Masumori/items/12095390a633b8789522

ローコードのため、かなり早く作成できますし、ちょっとしたカスタマイズ、修正もすぐに出来るのがメリットです。

しかし、以下のような構成の場合、すぐに作成できますが、Power Automate から Azure OpenAI への通信周りについて、パブリックな通信になってしまう点が気になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/2154b60d-b25a-7b4a-1d5f-4bc37db8f80f.png)

対して、以下のような構成の場合、Azure APIM への通信については、パブリックな通信となってしまいますが、Azure AD で認証認可周りが強化されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/8e44cbdb-9e48-0976-2565-64e54f19e91f.png)

しかし、こちらの構成については、色々柔軟性はあるものの、実装のハードルが高くなってしまいます。

そのため、今回は、以下の機能を利用して、Power Platform から VNet を使用して Azure OpenAI へ通信する方法について試してみた結果を共有しようと思います。

https://learn.microsoft.com/en-us/data-integration/vnet/sql-server-and-custom-connectors#power-automate-custom-connectors

https://learn.microsoft.com/ja-jp/data-integration/vnet/data-gateway-power-platform-dataflows

:::note warn
マイクロソフトサポートチームの以下のブログ記事より、こちらの機能のプレビューが取り下げられたようです。。内部的には、機能自体は削除されていないようですが、残念ながら本機能は現状サポートされていないようです。Power Platform から Azure OpenAI の生成 AI を利用するという意味では、その他の記事で紹介している通り、AI Builder を利用する方法がございます。しかし、利用するモデル、機能等の要件により、直接 Azure OpenAI と連携したいというケースも多くあると思います。結果的に、生成 AI 技術を民主化 (誰でも利用できるようにする) という意味でも、もちろん、マイクロソフトのビジネスにとってもメリットがあると思うので、Power Platform と Azure OpenAI のネットワークセキュリティ強化の観点でその他代替案が出てくることを期待したいです。

:::

https://jpdynamicscrm.github.io/blog/powerplatform/vnetgateway-support-status/


:::note
※2024 年 6 月追記
今後はこちらの手段が代替案になると考えます。
:::

https://qiita.com/Takashi_Masumori/items/4b2da664481faed84cfc


以下、今回の記事の構成イメージになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/5392d05e-4abd-63f1-d999-3be07c7718c4.png)

# 仮想ネットワーク データ ゲートウェイの作成

サブスクリプションで、Microsoft.PowerPlatform プロバイダーを選択し、登録を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/4bd5ebde-f5f0-3086-f68e-0bc10a17ceb7.png)

仮想ネットワークを作成し、[サブネットの委任]ドロップダウン リストから [Microsoft.PowerPlatform/vnetaccesslinks] を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/6901d3c7-a8ef-572f-5d06-5b593fcd67ea.png)

ネットワーク共同作成者を付与しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/da55e8ec-0b49-4803-c4c1-73a7228da541.png)

Power Platform 側で、VNet データ ゲートウェイを作成します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/cf101fa8-9aab-39a1-0db4-ba1558b51998.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a8084a29-2b30-7e71-caab-41701ade7f85.png)

:::note warn
権限が不足していると、以下のようなエラーが出ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/8f198ecd-da34-8e3b-415e-213263b49b29.png)

:::

# Azure OpenAI の設定変更

Azure OpenAI 側では、以下のように、選択したネットワークから接続を受け付けるようにして、作成した仮想ネットワークを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/e2bfb124-2211-e7c9-afb8-dd0e9278dffd.png)

# カスタムコネクタ―の設定

まず、カスタムコネクタベースで、Azure OpenAI の ChatGPT と連携させる際のアプローチは以下のような感じです。

## Power Apps 側

Power Apps 側で送信ボタンを押した際の処理は以下のような感じです。colChat コレクションに Power Automate からの戻り値を格納していきます。他の記事で書いたように、トークンが増えてきた際は少し加工してもいいかもです。

```
Set(
    gblChatGPTCustomConnectorResponse,
    ChatGPTAzureOpenAICustomConnector.Run(
        JSON(
            Collect(
                colChat,
                {
                    role: "user",
                    content: txtRequestDetail.Text
                }
            )
        )
    )
);
Collect(
    colChat,
    {
        role: gblChatGPTCustomConnectorResponse.role,
        content: gblChatGPTCustomConnectorResponse.content
    }
);
```

## Power Automate 側

Power Autoamte 側は非常にシンプルです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/399cc2f2-a8b9-8f1c-cb41-717cea9efdab.png)

Power Apps から受け取った値を以下のようにしてカスタムコネクタに渡します。

```
JSON(triggerBody()['text'])
```

カスタムコネクタの戻り値を以下のようにして Power Apps に返します。

```
first(outputs('callChatGPT')?['body/choices'])?['message']?['content']

first(outputs('callChatGPT')?['body/choices'])?['message']?['role']
```

## 仮想ネットワークゲートウェイ経由で利用する

カスタムコネクタ―側では、以下の設定をオンにし、接続作成時にゲートウェイを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/60c02928-35b6-8095-0f58-5c5d6a02d7c9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/db8cc5f6-510a-32fd-abc0-e3a14bb97521.png)

# 動作確認

まず、HTTP コネクタで Azure OpenAI に接続しようとすると、以下の通りエラーになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/726175ea-4020-380b-4254-167f060434d4.png)

エラーメッセージより、正しく動作しているようです。

```
{
  "error": {
    "code": "AccessDenied",
    "message": "A Virtual Network is configured for this resource. Please use the correct endpoint for making requests. Check https://aka.ms/cogsvc-vnet for more details."
  },
  "debugInfo": "clientRequestId: bc9b949f-e76b-429b-990e-9592fb206f3f"
}

```

プレイグラウンドでも以下の通りエラーになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/ea849f9d-e9a7-d327-319f-0ed09b6cde22.png)


次に、カスタムコネクタで接続してみます。無事に結果を取得できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/ad05c427-99c9-335c-3e53-8ccc0c257cf2.png)

# まとめ

今回、仮想ネットワーク データ ゲートウェイを使用して、Power Platform から Azure OpenAI への接続をセキュアにする方法について説明しました。

既にカスタムコネクタで実装をしている場合は、少し変更をするだけで実現できる方法のため、Power Platform と Azure OpenAI を連携させる一つのソリューションとして参考にしていただけると幸いです。