Dify を Azure Container Apps + Azure DB for PostgreSQL + Azure Cache for Redis でホストして動かす

# 今回の着想
Dify を Azure Portal からの操作だけで、Azure 仮想マシン上に立ち上げる方法は過去に記事を書いたことがありました。

https://qiita.com/tokawa-ms/items/160c40010151bfbb2549

でも、やっぱり Azure を使うからには、仮想マシン上にすべてのサービスをホストするのではなく、一つ一つのコンテナやデータベースを Azure の PaaS 上に乗せたい！そして、あわよくば Kubernetes 環境の管理をしたくないので、Azure Container Apps にホストしたいなぁ、と思ったのがきっかけ。

# 結論
Microsoft MVP の平林さんが公開してくださっている Bicep のコードで、かなり簡単に展開が可能でした！平林さんありがとうございます！！

https://github.com/himanago/dify-azure-bicep

今回はこの Bicep コードを Azure にデプロイするにあたって、ちょっとしたハマりどころの補足をいたします。

# 手順
## Azure のサブスクリプションの準備
今回の手順を進めるのに、Azure のサブスクリプションが必要です。

Azure のサブスクリプションをお持ちでない方は、以下のサイトの「Azure を無料で試す」のボタンから、Azure のサブスクリプションを新規にサインアップしてください。

https://azure.microsoft.com/ja-jp/pricing/purchase-options/azure-account/

## 事前準備
今回の Bicep コードを使って、Azure 環境にサービスをデプロイするには、以下のツールを自分の PC にインストールする必要があります。

### Azure CLI
Azure をコマンドラインから操作するための、CLI ツールです。Windows, Mac, Linux の環境で動くのですが、セットアップ方法はそれぞれの環境で異なるので、以下のドキュメントを参考に、インストールを済ませてください。

https://learn.microsoft.com/ja-jp/cli/azure/install-azure-cli

### PowerShell
インストール用のスクリプトの実行に必要です。Windows 環境の方はデフォルトでインストール済みのものも使えますが、Windows, Mac, Linux それぞれの環境での最新版のインストール方法も以下のドキュメントに記述があります。Mac, Linux の方は必須で、Windows の方はオプショナルで、以下ドキュメントを参考にして、最新の PowerShell をインストールしてください。

https://learn.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell?view=powershell-7.5

### Visual Studio Code（オプショナル）
ファイルの編集を行う際に、Visual Studio Code (VSCode) があると何かと便利です。以下の URL からダウンロードください。

https://azure.microsoft.com/ja-jp/products/visual-studio-code

## コードのダウンロード
GitHub のリポジトリからコードをダウンロードします。以下のスクリーンショットの "<>Code" という緑のボタンを押すと、"Download Zip" の選択肢が出てきますので、それが一番簡単なダウンロード手順となるかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/07cb4af4-f69e-45cd-9f89-fd71a23ab938.png)

Zip ファイルをダウンロードしたら、任意のフォルダに展開します。

## 変数の設定
Zip ファイルの展開ができたら、展開後のフォルダに入っている、parameters.json を適宜変更します。
VSCode や任意のテキストエディタで開いて、必要なところを書き換えましょう。

少なくとも、べた書きで書かれている PostgreSQL と ACA の証明書のパスワードはデフォルトのものから自分オリジナルのものに変えておいた方が安心なように思います。

## deploy.ps1 のテキストエンコーディングの変更
PowerShell のスクリプトで、日本語コメントが含まれている場合に UTF-8 with BOM エンコード以外のスクリプトは実行時に文字化けに起因するエラーが発生する場合があります。（当方手元の環境ではハマりました）

VSCode の場合 deploy.ps1 を開いて、画面下部のファイルのエンコードの表記（"UTF-8" や "UTF-8 with BOM" や "ShiftJIS" などと書かれている部分）が "UTF-8 with BOM" でなかった場合、ファイルのエンコードの名前の部分をクリックすると、コマンドパレットに「エンコード付きで保存」という選択肢が表示されますので、そこをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/2bcd6f6b-6703-47b3-9efd-46f680825dab.png)

すると、ファイルのエンコードを指定する選択肢が出てきますので、"UTF-8 with BOM" を選択しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/35180b9e-c92a-4496-8b09-99d28208a8d6.png)

## Azure へのログイン
ここは、Readme にも書いてある通りで、Azure CLI の機能を使ってログイン作業を行います。
CLI を使うために PowerShell ターミナルを起動する必要があります。

例えば、VSCode でしたら、アプリ上部の「ターミナル」というメニューから新しいターミナルを開くことも可能ですし、`Windows キー` + `R キー` を押して開いたウィンドウで、`powershell` と入力することでも PowerShell を開けます。
（Mac, Linux 環境の人は各々頑張ってください）

PowerShell が開けたら以下のコマンドをまずは実行し、Azure のアカウントにログインします。

```powershell
az login
```

複数個の契約をお持ちの方はここで選択肢が出てくると思いますので、利用する対象のサブスクリプションを選択する必要があります。

ここで利用するサブスクリプションを選ぶと、Subscription ID という、英数字で "8文字-4文字-4文字-4文字-12文字" の形式の文字列が表示されます。このすぐ後の手順で使いますので、この値をメモしましょう。

次に、利用する Azure サブスクリプションを明示的に設定するため、上でメモした値を使って、以下のコマンドを実行します。

```powershell
az account set --subscription ここにメモしたSubscriptionID
```

これで準備は完了です！

## デプロイ
以下のコマンドを、Azure ログイン済みの PowerShell のターミナルで実行します。

```powershell
./deploy.ps1
```

エラーが発生しなければ、約 30 分くらいかかりますが、待っているだけで Azure 上に必要なリソースがデプロイされて Dify が使えるようになります。

スクリプトの実行が完了すると、一番最後のメッセージに、Dify のポータルにアクセスするための URL が表示されますので、その URL はどこかにメモしておきましょう。

### （補足）PowerShell の実行ポリシーについて
お使いの環境の PowerShell に設定されている実行ポリシーによっては、以下のようなエラーがデプロイスクリプト実行時に発生する場合があります。

```powershell
.\deploy.ps1 : このシステムではスクリプトの実行が無効になっているため、ファイル path\to\deploy.ps1 
を読み込むことができません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170)   
を参照してください。
発生場所 行:1 文字:1
+ .\deploy.ps1
+ ~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
```

その場合、実行ポリシーを一時的に変更して、ダウンロードした PowerShell スクリプトを実行できるようにして、改めて実行してください。

```powershell
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
```
https://go.microsoft.com/fwlink/?LinkID=135170

## あとは楽しむ！
スクリプトの最後にあった Dify のポータルの URL にアクセスすると、まずは管理者ユーザーの作成を求められます。この設定まで済ませれば、あとは見慣れた Dify の画面で色々と試すことが可能です。

# まとめ
IaC の仕組みをうまく使うことで、あまりインフラ構築の手間を感じずに、よりクラウドらしい方法で Dify を Azure にホストすることができました！

Azure Container Apps で Dify のホストをしてみたいなーと思っていたところに、めちゃくちゃ便利な Bicep コードならびに PowerShell のデプロイスクリプトを用意してくださった、MVP 平林さんに大感謝です！

# 補足
## デプロイされる Azure リソース
この Bicep コードを公開してくださっている MVP の平林さんによるプレゼン資料にアーキテクチャ図が載っているので、そちらを参考にしてください。

https://www.docswell.com/s/4330282/ZXEDMR-dify-on-azure#p17

ざっくり説明すると、各種コンピューティングは Azure Container Apps でホストされており、データベースは Azure Database for PostgreSQL に、キャッシュは Azure Cache for Redis に、ストレージは Azure Storage に置かれています。

すべて、Azure の PaaS の機能を使って実装されており、管理者はサーバーの面倒を見なくてもいい構成になっているのがとても嬉しいポイントかなと思います。

## 利用している Azure リソースや周辺技術の解説
それぞれ、Azure のドキュメントへのリンクを掲載しましたのでご覧ください。

https://learn.microsoft.com/ja-jp/azure/container-apps/overview

https://learn.microsoft.com/ja-jp/azure/postgresql/

https://learn.microsoft.com/ja-jp/azure/azure-cache-for-redis/cache-overview

https://learn.microsoft.com/ja-jp/azure/storage/common/storage-introduction

https://learn.microsoft.com/ja-jp/azure/virtual-network/virtual-networks-overview

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/overview?tabs=bicep