Azure 環境の RAG システム構築　ローカル開発手順～デプロイ②

:::note info
ローカルでの開発手順（前記事）はこちら
（この記事の解説は、前記事でサービス等作成済みな事を前提としています）

Azure 環境の RAG システム構築　ローカル開発手順～デプロイ①
https://qiita.com/KUROMAGOORO/items/f79b6f4c43756f97f02d
:::

# 概要

- Azure 環境でのアプリ開発～デプロイの流れをまとめました（②ではウェブアプリのデプロイについて）
- 各サービスと接続する事を優先したので「①情報取得」でデータをいろいろな所から集めたり、「③生成結果保存」が複数発生します
- 実施には偉い権限（所有者以上）が必要です
- **Azure環境での接続例**
    - AISearch, AzureDatabaseMySQLServer は（多分）仮想ネットワークに属させる事が出来ないので、AppService（Webアプリ）と接続するために PrivateEndpoint を作成してあげる必要があります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/c66a4f36-48bb-04e5-803e-9b1a21c95d6b.png)

# 追加サービスのデプロイ（Webアプリ関連）

- ①から追加で以下のサービスをデプロイします

## AppServiceプラン

- B1 プランを選択します
- 現在 Japan East が人気でエラーが出たため、Japan West にしました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/615814ee-4584-2074-4f88-479c4b6e8937.png)

## 仮想ネットワーク

- Japan West で追加します
:::note warn
AppServiceプランが Japan East に作成出来なかったので追加で作成しましたが、既に「AppService プラン」と「仮想ネットワーク」のリージョンが揃っていたら不要です
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/677432f3-488e-d016-8070-27a5c7eb3969.png)
- 「Azure OpenAI」「ストレージアカウント」の各ネットワーク設定から、Japan West の仮想ネットワークに属させます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/c350e343-e45c-a117-fad3-bf23c7ba25fa.png)

- 「委任先」があるサブネットにはプライベートエンドを作成出来ないため、プライベートエンド用に新しくサブネットを作成します
名前だけ入力して他はデフォルトです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/d368a00d-b9cc-655e-f077-95b39aa9bf0e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/c54fc3a6-df00-e437-a5b0-2932bda50ea2.png)

## Webアプリ

- タグを追加します
- 「基本認証」を有効にします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/4478c74b-5558-b6b6-eb1a-c31b70d179d4.png)

### ネットワーク設定

- 仮想ネットワーク統合で仮想ネットワークを選択します
    - 同じリージョンでないと駄目だったので、Japan West にしています
    - 作成する際は AppServiceプラン を最初に作成してエラーが出ないか確認しておくと、後々リージョン揃える必要無くて良いかもしれません
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/c5c45603-ad10-9e47-3c60-82cd8af88b8a.png)

- 自身の IP アドレスを許可します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/4f635a9d-4fae-cccd-a731-0302af562d2c.png)

### ローカル git 設定

- ローカル git を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/6313e73f-692a-7d81-451a-d6cfa33e743d.png)

- ユーザ情報を入力します
- この情報は開発者が各々設定しておく必要があります（他人のものが上書きはされない）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/921f3871-e7a4-4534-c5a4-16e092a2ea8a.png)

### システムマネージド ID 設定

- 今回 `DefaultAzureCredential()` を使用しているので、Web アプリサービスに権限を付与しておく必要があります
- この認証方法を使用した場合「キー」を必要とせず、IAM の認証によってアクセス出来る事が利点かと思います
- ローカル確認時には動作確認前に az login をして、実行ユーザのアカウントで認証を行っていました
<https://qiita.com/KUROMAGOORO/items/f79b6f4c43756f97f02d#%E3%82%A2%E3%83%97%E3%83%AA%E6%A7%8B%E7%AF%89>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/1fa17a72-0dff-8ed0-8d37-7ac49aa870f7.png)
- 「ストレージBLOBデータ共同作成者」「Cognitive Services OpenAI User」を付与します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/390e99a4-06ee-a184-b735-98d4fe311ca0.png)
- それぞれのサービスで web アプリにロールが付与されている事を確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/20f08ec3-210f-01d6-1fe4-503b9285dc53.png)

# プライベートエンドポイントの作成

- 仮想ネットワーク内に「プライベートエンドポイント」を作成して、仮想ネットワークに属す事が出来ないサービスへの接続を可能な状態にします

## AISerach

- プライベートエンドポイントを作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/58e51646-1372-9b86-33a2-4fde7f6f80d2.png)

## Azure Database for MySQL Flexible Server

- プライベートエンドポイントを作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/90ee5c0e-f229-cb7e-b797-b0296c6f5c76.png)

# 資材の作成

:::note info
流れは以下の記事と同じです
https://qiita.com/KUROMAGOORO/items/376f090adb529aef0bd9#%E6%89%8B%E9%A0%862-azure-web-apps-%E3%81%AB%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB-git%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%81%A6%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%81%AB-clone
:::

## ローカル git から clone

- 作成された git URL をコピーして clone します
- clone する際に先ほど作成したユーザ情報を聞かれるので、入力します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/3c172d26-b7cb-751d-cd4f-0beb3de7a961.png)

- 空のフォルダが作成されるので、「webapp」フォルダを作成します
- ローカルで動かしていたアプリを上記フォルダにコピーします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/5b086050-12fe-ff93-03ce-a293436c77e0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/50ea8d31-fdc6-953c-a108-b8581a8fd505.png)

## azd init による初期化

- azd init で初期化をします
    - 「Use code in the current directory」を選択します
    - 「Confirm and continue initializing my app」を選択します
    - 任意の「environment name」を入力します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/265a08bb-2728-1eb8-6ed3-91582e7f735c.png)

- 新規ファイルが作成されています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/0af1fb71-6749-5c83-29a8-35f6b6473db8.png)

## azd init のテンプレートファイルを更新

- azure.yaml を編集します
    - webアプリ作成時の「タグ」名に合わせて「webapp-rrr3」にします
    - コンテナアプリではないので「appservice」にします

```diff_yaml:azure.yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json

name: webapp-rrr3
metadata:
    template: azd-init@1.9.3
services:
-   webapp:
+   webapp-rrr3:
        project: webapp
-       host: containerapp
+       host: appservice
        language: python
```

- インフラは新規構築しないので infra/main.bicep は全てコメントアウトします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/47b15ef2-2936-ab31-5380-2dad54924884.png)

- 任意の実施で大丈夫ですが .gitignore は既存のものはコメントアウトして、ルートフォルダの方に venv __pycache__ を追加しています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/6ae6a4dc-5222-f091-00e5-e611f1eef325.png)

## アプリをwebアプリ向けに更新

- webapp/start.sh の作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/4dafc801-5d56-1e7f-21df-47de2e88e1e6.png)

```sh:start.sh
#!/bin/sh
# TZ の変更
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtaime
echo '仮想環境の作成'
python -m venv venv
echo 'ライブラリのインストール'
./venv/bin/python -m pip install -r requirements.txt
echo 'アプリの実行'
./venv/bin/python app.py
```

- webapp/app.py を更新
    - `demo.launch(server_port=8000, server_name='0.0.0.0')` に更新する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/9a86de82-0131-8258-3a06-c31751f9b068.png)

## webアプリサービス の更新

- 「構成」→「全般設定」の「スタートアップコマンド」に以下のコマンドを登録する
`start.sh`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/be683843-cb09-d526-9a3e-0bf43ee7a972.png)

# デプロイ

- azd auth login を実行します
- azd provision を実行します
    - provision はインフラ構築用ですが実行すると .azure 内の .env を更新してくれます
    - main.bicep をコメントアウトしているので、インフラの変更はありません
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/df7892d4-0637-b262-7ccd-dd8fa0cc9f08.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/551d433e-b813-b304-970b-d42db61776a8.png)

- azd deploy を実行します
    - 完了まで時間がかかります

# アプリの起動

- 既定のドメインからアクセスしてアプリを確認します
    - アプリの立ち上げは時間かかる場合があります（初回は30分～1時間ぐらいかかることもあるかも）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/8b0b5d56-1017-acdd-84c5-bdf8ccacb63e.png)
    - ログを見ながら気長に待ちます
（ログでエラーが出ても、時間が経過すると動き出したりという事もあるので油断出来ないですが）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/3f3e8a40-8138-2fd1-fee7-bf0162fc0d84.png)
- しばらくすると確認出来ました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/f25f09b8-5de8-a1e3-d5a3-c44209ce14de.png)

# アプリの動作確認

- メッセージを送信してレスポンスを確認出来ます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/d3ffa1b3-e06b-918f-3dbb-19a803071009.png)
- Blob, MySQL にデータが登録されている事を確認出来ます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424166/c2a39c40-2c64-da1d-adbd-c32897d7a0b4.png)