Azure Lighthouse を理解して Azure AD B2C の監視設定する

# はじめに

Azure AD B2C を管理するための説明とセットアップ方法は Microsoft公式の [Azure Monitor で Azure AD B2C を監視する](https://docs.microsoft.com/ja-jp/azure/active-directory-b2c/azure-monitor) にあります。

このドキュメントは正確な説明ではありますが、Azure Lighthouse という謎のリソースの話が突然出てきてチンプンカンプンになり、ARM テンプレートを使って一気にデプロイするやり方しか紹介されていないので何がどうなってしまうのかがわからない恐ろしさがあります。

ここでは Azure AD B2C の監視をする構成を１つずつ手作業で実施して、何が行われているのかを理解していきます。（理解してしまえば、更新も削除も怖くないですよね）

# Azure Lighthouse とは

Azure AD B2C の監視設定をするためには、まず Azure Lighthouse を理解しなければなりません。
一旦 Azure AD B2C のことは忘れて Azure Lighthouse を勉強しましょう。[Azure Lighthouse](https://docs.microsoft.com/ja-jp/azure/lighthouse/overview) とは、複数のAzure AD テナントの管理を一か所のテナントで行えるようにするものです。

Azure Lighthouseは [MSP(Managed Service Provider)](https://partner.microsoft.com/ja-jp/membership/azure-expert-msp) という資格を保持するような Azure のエキスパート企業が複数の顧客の Azure 環境を取り扱う場合に大変便利なリソース（機能）です。

応用として、自社の Azure AD テナントが事情によって複数存在してしまっている場合に一括管理するシナリオがあります。
https://docs.microsoft.com/ja-jp/azure/lighthouse/concepts/enterprise

## Lighthouse による委任のイメージ
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/7d02610b-2f02-84cd-e4a7-c192ac52bd43.png">


委任元：自分のリソースを差し出して（管理を委任して）管理をお願いする側です。
委任先：差し出された（委任された）リソースを管理していく側です。

サブスクリプション、またはリソースグループを、別の Azure AD テナントのグループ、ユーザー（またはサービスプリンシパル）に触っていいですよ、と委任するのが Azure Lighthouse です。

委任しても委任元はそれまで通り自分のリソースを管理することができますので、安心してください。
ちなみに docs や Azure Portal などでは委任先のことを**サービスプロバイダー**と表記している場合が多いので覚えておくと読みやすいです。

委任の構築を行う流れは次の二つです。

1. 委任の定義を作る
2. 範囲（サブスク or リソースグループ）を指定して委任する

## 委任の定義とは

委任の定義は、**委任元**で作成します。委任の定義には以下の情報をセットする必要があります。

| 委任元の情報 |
|:-:|
| 委任先へ付与するロール。共同管理者など | 

| 委任先の情報 |
|:-:|
| 委任先のテナントID |
| 委任されるユーザーやグループのID |

委任の定義の作成は限定的に Azure Portal で作成することができます。限定的というのは、Azure Portal で作成する時には Marketplace 上のサードパーティ製品のテナントしか委任先として選ぶことができないからです。
今回の Azure AD B2C のような Marketplace 上には存在しないテナントを指定したい場合は Azure CLI もしくは Azure PowerShell を使用しなければなりません。

## 範囲（サブスク or リソースグループ）を指定して委任する

委任の定義を作っただけではまだ委任したことにはなりません。委任の定義に対して、範囲を指定することで初めて委任したことになります。

範囲として指定できるのは委任元のサブスク、またはリソースグループです。そしてこの指定は**委任元**で行います。当たり前ですね、自分が相手に託す訳ですから。

# Azure AD B2C への委任

Azure AD B2C はとても特殊なリソースで、Azure AD に B2C 用の特殊なアプリケーションとインストールした特殊なテナントです。サブスクリプションを持っていないため、ログを保管する Azure Storage アカウントや Log Analytics などの Azure リソースを作成することは一切できません。

そこで Azure Lighthouse の出番です。別の Azure のサブスクリプションからリソース（Storage とか Log Analytics）をAzure AD B2C に委任することによって、Azure AD B2C の監視設定を別のテナント配下のサブスクリプション内に構築することできるようになります。間借りするイメージです。

つまり、Azure AD B2C が委任先（サービスプロバイダー）となります。委任元に指定するAzure AD、サブスクリプションに制限はありません。（課金用に紐づけたサブスクリプションでなくても構いません）
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/c0b8e856-42f1-25a2-790e-60a4f9003f1e.png">

## Microsoft.ManagedServices プロバイダーの登録

では1つずつ作業していきましょう。まずは委任元となるAzure AD テナントにログインしてください。まずは Microsoft.ManagedServices プロバイダーを使用できるようにします。

### 手順

1. Azure Portal のサブスクリプションリソースを開く
2. リソースプロバイダーを選択
3. 検索ボックスに Microsoft.Managed と入力
4. Microsoft.ManagedServices を選択し、登録ボタンをクリック

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/e6dd0b0b-3b57-29e0-7441-612d546178ad.png">

登録したら１，２分待ちます。更新ボタンを押しても更新されないことが多いので、画面をリロードしてください。状態が Registered になれば OK です。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/f53b1e3e-af56-6ec1-0ecc-22e15329b0e2.png">

## 委任の定義を作成するための情報の収集

委任の定義に必要な情報を収集します。まずは**委任先（Azure AD B2C側）**の情報を収集します。必要な情報は

- 委任先のテナントID
- 委任される「ユーザーかグループ」のID

です。

委任される ID ですが、ユーザーかグループ（またはサービスプリンシパル）の ID です。１つしか指定できませんので、お薦めは（セキュリティ）グループを指定する方法です。グループを指定しておけば、後でグループに人を追加・削除することで委任されたリソースを扱う人を簡単に増減できます。

### テナント ID の収集手順
1. Azure AD B2C テナントへログイン
2. Azure AD を表示

**3. 「テナント ID」をコピー**
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/15ef4d6e-0ff3-cd9a-1e23-0c8639b2d864.png">

### 委任する相手（グループ）の ID の収集手順

1. Azure AD B2C テナントへのログイン（既にログインしているはず）
2. Azure AD を表示

**3. 「グループ」をクリック。「新しいグループ」をクリック**
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/39449043-c26c-a595-f143-5a1af2f8a139.png">

**4. グループ名、グループの説明を入力し、メンバーを選択（少なくともログインしている自分をこのグループに入れておくこと）。作成ボタンをクリック**
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/df7138ed-6d46-3ea1-a971-ee9f1ad4aad9.png">

**5. 作成したグループをクリック**
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/26e7f26b-e2f2-9f6c-116a-5d0a63de5e16.png">

**6. オブジェクト ID をコピー**
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/32e5fd04-937a-110e-1eb2-5989e25f1a44.png">

次に**委任先へ付与するロール**の情報を収集します。カスタムロールを付与する場合はその ID をコピーしてください。共同作成者などの組み込みロールを使用する場合はその ID を収集します。以下の手順では共同作成者の ID を収集します。

1. 委任元の Azure AD テナントへログイン
2. Azure Cloud Shell を開く

**3. コマンドを叩いて ID を取得。コピーする**
コマンドの結果得られたリソース ID の一番最後に表示される GUID をコピーします。

```powershell
az role definition list --name "Contributor" --query '[0].{id:id}'

{
  "id": "/subscriptions/<subscriptionid>/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
}
```
もし共同作成者以外のロールが使用したい場合は、は次のコマンドを叩いてロール名の一覧を取得し、ロール名から リソース ID を取得してください。

```powershell
az role definition list --output table --query '[].{roleName:roleName, description:description}'
```

と、ここまで説明しておいて今更ですが、実は共同作成者などの組み込みロールの ID は全テナントで共通なので、いちいち取得する必要はありません。共同作成者ロールを割り当てる場合は次の ID を使用してください。

共同作成者ロールの ID
> b24988ac-6180-42a0-ab88-20f7382dd24c

## 委任の定義の作成

ではいよいよ、委任の定義を作成します。委任の定義の作成は**委任元**で行います。Azure AD B2C テナントではないので注意します。

1. 委任元の Azure AD テナントへログイン
2. Azure Cloud Shell を開く

**3. 現在のサブスクリプションが間違いないかを確認**

```powershell
az account show
```
現在のサブスクリプションが表示されます。もし変更したい場合は次のコマンドです。

```powershell
az account set --subscription <subscription id or name>
```

**4. 委任の定義を作成**

```powershell
az managedservices definition create --name <name> --tenant-id <tenanid> --principal-id <principalid> --role-definition-id <role-id>
```

| パラメータ名 | 内容 |
|:-:|:--|
| --name | 定義名称。わかりやすいものを。ex. Azure AD B2C Monitoring|
| --tenant-id | 委任先のテナント ID (Azure AD B2C のテナント ID) |
| --principal-id | 委任される(Azure AD B2C 側の)「ユーザーかグループ」の ID |
| --role-definition-id | 委任先へ付与するロールの ID 。ex.共同管理者の ID |

さきほど収集した情報を使ってコマンドを実行してください。コマンドの説明は[こちら](https://docs.microsoft.com/en-us/cli/azure/managedservices/definition?view=azure-cli-latest)です。

コマンドが正常に実行できない場合は大抵の場合権限が不足しています。所有者権限を付与してください。

正常に委任の定義が作成できると、Azure Portal で確認することができます。
画面上部のの検索ボックスにサービスプロバイダと入力し、「サービスプロバイダー」リソースを選択します。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/05e4b1ed-1b36-c717-8584-38cf1702bbd0.png">

「サービスプロバイダーのオファー」というメニューをクリックしてください。サービスプロバイダーのオファーとは委任の定義のことです。先ほど入力した名称で委任の定義が作成されていることを確認できるはずです。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/5a0a734a-586d-c77c-f699-c7c1127fcd30.png">

作成した委任の定義をクリックしてください。コマンドで入力した ID を適切にセットされていることがわかると思います。サービスプロバイダーの名前が Azure AD B2C のテナント名になっていることがわかります。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/8b27df5e-c60f-05b1-04e1-08daadf9efd4.png">


## 委任する

何を委任するのかを決めて設定します。サブスクリプション全てを委任するか、特定のリソースグループだけを委任するかを選択できます。この設定はAzure CLI でもできるし、Azure Portal でも可能です。

Azure AD B2C の監視設定を行うのが今回の目的なので、サブスクリプション全てを委任するのはやり過ぎです。特定のリソースグループだけを委任して、そのリソースグループには、ログを保管する Azure Storage や分析に使用する Log Analytics を作成することにしましょう。

なので、あらかじめリソースグループを作りましょう。好きな名前で良いのですが、ここではazure-ad-b2c-monitorという名前にした、とします。
ついでにログを保管する Azure Storage アカウントもそのリソースグループ内に作っておいてください。後で監視設定に使用します。（もし Log Analytics で分析するなら Log Analytics をこのリソースグループに作ります）

では、委任しましょう。Portal でのやり方が簡単なのでご紹介します。

**1. サービスプロバイダーのオファーにて、先ほど作った委任の定義の行の「委任なし」リンクをクリック**
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/08ff70c4-00d7-002f-833e-9e2ffbbc370a.png">

**2. リソース グループの委任をクリック**
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/110f6438-3bc5-1796-1a56-9ca998e29e2c.png">

**3. 作成したResourceグループを選択し、リソースの委任ボタンをクリック**
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/558cf46e-276a-a25d-3b8e-a468ff2639de.png">

**4. 注意事項を熟読の上、チェック ボックスをオン、デリゲートボタンをクリック**
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/d4564590-3591-0ea1-4917-0e4a4b79efa2.png">

しばらく待つと、委任が完了します。Portal で委任されたことを確認します。

左側の「委任」メニューをクリックすると、委任の一覧が表示されます。指定したリソースグループと委任の定義が関連付いていることがわかりますね。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/0cc5432f-5597-bb17-bff6-b716efb7dfa3.png">

## Azure AD B2C テナント側で監視設定をする

Azure Lighthouse による委任は終わりました。後は Azure AD B2C 側での作業です。
まずはAzure AD B2C のテナントにログインしましょう。（さきほどまでは委任元のテナントにログインしていたはず）

そして監視設定を行うのですが、その前やらなければならないことがあります。
それは、 Portal で委任されたサブスクリプションを扱えるようにすることです。

**1. 画面上部の「ディレクトリ＋サブスクリプション」アイコンをクリック。現在のディレクトリ＋委任されたディレクトリの下のドロップボックスをクリック**
この時点ではまだサブスクリプションが0個です。（Azure AD B2C テナントだから）
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/f1c6ecfe-a74c-0975-1a5c-9cfc194f7502.png">

**2. 委任されたテナントを選択**
この画像では全部墨でつぶしているのでわかりにくくて申し訳ないのですが委任されたテナントが表示されているはずです。選択してください。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/1f550228-9fd6-f7c5-53ba-48f4850aae73.png">

**3. サブスクリプションを選択**
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/3016f822-754c-261e-1864-6101f7cd4092.png">

これで監視設定ができるようになりました。Azure AD B2C の監視設定を行いましょう。

**1. Azure AD を開いて診断設定を選択し、「診断設定を追加する」をクリック**
Azure AD B2C ではありません。診断設定は Azure AD から行います（Azure AD B2C は Azure AD を特殊なアプリケーションでラップしたようなリソースです）
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/c31ea997-ddb6-69aa-4cfe-7e0da1a74cc9.png">

**2. 診断設定の名前、保存したいログ（ここでは AuditLogs, SignInLogs）、ストレージ アカウントへのアーカイブをチェックしてストレージアカウントを選択。最後に保存ボタンをクリック**
委任元のリソースグループであらかじめ作っておいたストレージアカウントを選択します。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/e7e0e847-e1f4-db5a-f2c1-fbd7d216df1e.png">

これで監視設定は終了です。お疲れ様でした。

# 最後に
今回は Azure AD B2C のログを Azure Storage に保存するだけでしたが、Log Analytics を設定すると、ログ分析も可能です。

Azure AD B2C でログ保管、監視分析などを行うにはどうしても Azure Lighthouse による委任を行う必要がありますが、本来の Azure Lighthouse の役割はクロス（マルチ）テナント管理です。このクロス（マルチ）テナント管理ですが、 Azure Lighthouse で委任するか、もしくは Azure AD B2Bで個別に招待してもらうかのどちらかで行うことになります。

どちらにもメリット・デメリットがありますので、よく検討が必要です。