【第16回】Azureで社内システム再現（クラウド編）｜Key Vault のパスワードを Web App から使ってみた

## 概要

これまでの「オンプレ編」では、Azure の仮想マシン（IaaS）を使って、社員番号から名前を検索できるシンプルな社内システムを構築してきました。Active Directory、SQL Server、ADFS などを組み合わせ、オンプレミスの構成を仮想的に再現しています。

※全体構成の詳細は、[【第0回】Azureで社内システム再現（オンプレ編）｜構成図と動作の流れ](https://qiita.com/your-link-here) をご参照ください。

クラウド編では、これまでの構成をベースにしつつ、Azure のマネージドサービス（PaaS）を中心とした構成へ段階的に移行していきます。

※クラウド移行全体の設計方針については、[【第10.5回】Azureで社内システム再現（クラウド編）｜オンプレ構成をどうクラウドに移行するか？](https://qiita.com/saba_infra/items/4ff691131593e947d6cf) にまとめています。

---
## システム構成（今回の対象範囲）

今回のテーマは、**Azure Web App から Azure Key Vault に格納されたシークレット（SQLパスワード）を、マネージドIDと環境変数を使って安全に取得する構成を実現すること**です。

まず、下図は「クラウド編」の全体構成を示したものです。

![cloudのkey.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/4a544c7b-3473-426c-96da-171c959b2b97.png)

このうち、**赤枠で示している Azure Web App → Azure Key Vault の接続構成**が、今回の対象範囲です。

---

次に、下図がその**閉域構成の詳細図**です。

![cloudのkeype (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/b530fdab-899d-49e9-a4ac-acbb6d6cc7e8.png)


Azure Web App にマネージドIDを有効化し、Key Vault に対してアクセス権限を付与することで、  
**アプリケーションが Key Vault のシークレットを直接取得できる構成**を構築します。

また、App Service 側ではアプリケーション設定に Key Vault リファレンス構文を登録し、  
**環境変数経由でシークレットを取得・利用することで、コード上に認証情報を持たないセキュアな連携**を実現しています。

---

今回は以下の作業を行います。

- Key Vault を作成し、SQL パスワードをシークレットとして登録  
- Azure App Service にマネージドIDを有効化  
- Key Vault 側にマネージドIDへのアクセス権を付与  
- App Service に Key Vault リファレンス構文で環境変数を設定  
- PHP コード内で `getenv()` によりシークレット値を取得し、接続処理を実行  
- 動作確認


## Key Vault を作成し、シークレットを登録する

はじめに、Azure Web App から取得するパスワードを格納するための Key Vault（キーコンテナー）を作成します。

![スクリーンショット 2025-04-04 17.00.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/59d1e3fd-05f9-4821-a919-094a72f22e46.png)


リソースグループやリージョンは、他のサービスと同様に `rg-cloudinfra-sea` および `Southeast Asia` を選択しました。Key Vault 名は `kv-employeesearch` としています。

---

Key Vault の作成後、SQL のパスワードを格納するためのシークレットを新規作成します。

![スクリーンショット 2025-04-04 17.23.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/bf60574a-9d34-456b-b20a-0ef2eefbca90.png)


シークレット名は `SqlPassword`、値には実際のパスワードを指定しています。今回はシンプルに手動入力で登録しました。

---

## 補足：Key Vault のロールについて
![スクリーンショット 2025-04-04 17.14.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/4b96a7bd-8a55-4f2a-bc16-dce608f896de.png)

Key Vault では、Azure の他のリソースとは異なり、**中に格納されたデータ（シークレットやキーなど）へのアクセス権限が分離されている**点に注意が必要です。

たとえば、**「所有者（Owner）」ロールを持っていても、Vault の中身にはアクセスできません**。  
これは、Key Vault が「管理プレーン」と「データプレーン」に分かれており、Vault の作成や削除などは Owner ロールで可能でも、シークレットを作成・取得するには別途ロールが必要なためです。

今回は、Key Vault に対して「**キーコンテナー管理者（Key Vault Administrator）」ロール**を、シークレット作成を行うユーザーに割り当てています。

このロールを持つことで、Vault 内のキー・シークレット・証明書すべてに対する管理操作が可能となります。

---

## マネージドIDを有効化し、Key Vault にアクセスできるようにする

Azure Web App から Key Vault に保存されたパスワードを読み取るためには、アプリ側に「アクセスするためのIDと権限」を持たせる必要があります。

そこで今回は、**Azure App Service のマネージドIDを有効化**し、  
その ID に対して、Key Vault の中身を読み取るための権限を与える構成にします。

---

### マネージドIDとは？

マネージドIDは、Azure が自動で発行・管理してくれる「アプリ専用のID」です。  
アプリが Key Vault などのリソースにアクセスする際に、パスワードなどを使わずに安全に認証できるようになります。

アプリケーション側では、IDの管理や秘密情報の扱いを気にせず、安全に Azure のサービスへアクセスできます。

---

### マネージドIDを有効にする

まず、Azure App Service の「ID」設定から、**「システム割り当て」マネージドID**を有効にします。

![スクリーンショット 2025-04-04 17.32.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/2867177e-7db6-4ea4-bdb2-29d27c9fadf9.png)

有効化すると、この App Service 専用の ID が自動で作られます。

---

### Key Vault にアクセスできるようにする

続いて、Key Vault のアクセス制御（IAM）画面で、先ほど作成されたマネージドIDに対してロールを割り当てます。

![スクリーンショット 2025-04-04 17.34.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/c29ddcc9-6c4e-480d-9465-6d8632d631e1.png)

今回は、**「Key Vault Secrets User」ロール**を付与しました。  
このロールを付けることで、アプリケーションは Vault に登録されたシークレットを「読み取る」ことができるようになります。

---

## Key Vault のシークレットを環境変数として利用する

Azure Web App から SQL Server に接続する際、パスワードをコード内に直接書くのではなく、  
Azure Key Vault に登録されたシークレットを**環境変数経由で安全に取得**する構成とします。

---

### シークレット識別子の取得

まず、Key Vault に登録されたシークレット（今回は SQL パスワード）の識別子（URL）をコピーします。

![スクリーンショット 2025-04-04 17.27.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/51eca196-6ab2-4970-a947-de0cabbc1736.png)

この URL を、後ほど環境変数として利用します。

---

### Azure App Service に環境変数を設定

Azure App Service の「環境変数」から、以下のように環境変数を追加します。

- 名前：`SQL_PASSWORD`
- 値：`@Microsoft.KeyVault(SecretUri=https://kv-xxxx.vault.azure.net/secrets/SqlPassword/...)`

この書き方は **Key Vault リファレンス構文** と呼ばれ、App Service が自動的に Key Vault からシークレットの値を取得し、  
環境変数としてアプリに渡してくれる仕組みです。

![スクリーンショット 2025-04-05 12.59.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/5f809946-9e50-41ed-98f5-683db934bb21.png)

この処理には、**事前にマネージドIDを有効化し、Key Vault へのロールを割り当てている必要があります。**

---

### PHP アプリケーションから環境変数を利用する

アプリケーション側では、環境変数 `SQL_PASSWORD` にアクセスすることで、シークレットの値を取得できます。

今回は PHP を使用しており、以下のように `getenv()` 関数で環境変数の値を読み取るようにコードを変更しました。

![スクリーンショット 2025-04-04 17.31.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/d285de1f-cb7c-456d-8bff-c572dba2a071.png)

このようにすることで、**コード上にパスワードを直接記述せず、安全かつ柔軟に認証情報を管理することができます。**


---

## 動作確認

最後に、環境変数から Key Vault のシークレット値を正しく取得できているかを確認します。

まず、取得した値が正しく読み込まれているか確認するために、`getenv()` で取得したパスワードをログに出力してみました。

![スクリーンショット 2025-04-17 13.20.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/d24a318b-e0c6-44d2-b6c4-482fb1fc9540.png)


環境変数 `SQL_PASSWORD` に、Key Vault に登録したパスワードが正しく格納されていることを確認できました。

---

続いて、検索画面から実際に検索処理を行い、SQL 接続およびアプリの動作が正常であることを確認しました。


![スクリーンショット 2025-04-05 13.26.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037248/392d6d85-dc9b-41d3-9e08-34c45f475f8c.png)


Web App は、Key Vault に保存されたパスワードを通じて SQL Server に接続し、検索機能を問題なく実行できています。