Azure Lighthouseを使ってAzureADのサインインログを集約する

## はじめに

Azureを使っていると、用途に応じてAzureADテナントやサブスクリプションを分けることがありますが、共通的な情報（例えばサインインログや監査ログ）は一つにまとめて、そこで統合的に保管したり、監視基盤に繋げたり、ということをしたくなります。

例えばこんなイメージです。
![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/22b77f2e-2c12-5591-4405-f975705c36a6.png)

こんな時は、Azure Lighthouseを使うと簡単に実現できます。

本来Azure Lighthouseはサービスプロバイダがマルチテナント管理を行うことを目的としたサービスです。例えば、複数の顧客のAzureテナントに対して自社のマネージドサービスを適用する際に、各テナントからサービスの稼働に必要な一定の権限を委任してもらうことで、サービス側としてはテナントの余計な権限を持つこと無く、安全にマネージドサービスを提供することができます。

![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/26648c9a-0eb6-5261-977f-b8533712ed25.png)

その他にも、冒頭で書いたように社内でマルチテナント化しているAzure環境に対して必要な統制を取るために、Azure Lighthouseを適用することもできます。今回は、Azure Lighthouseを使って、AzureADのサインインログを自テナントに保管するのではなく、共通環境のAzure Storageに転送する方法について紹介いたします。

![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/de276775-a3b0-55ff-d663-3ef8bc6e8380.png)

## 準備

まず、ログ転送元テナントの方で下記を取得・作成しておきましょう。

　1. AzureADテナント名
　2. AzureADテナントID
　3. 管理を委任するグループ名
　4. 管理を委任するグループのObjectID
　※このグループに所属しているユーザは、ログ転送先テナントのサブスクリプションに一定の権限を持ってアクセスできるようになります。

ログ転送先テナントでは、ログ保管用のストレージアカウントを作成しておきます。

次に、ログ転送先テナントにて、リソースプロバイダー[Microsoft.ManagedServices]を有効化します。
[サブスクリプション]→[リソースプロバイダー]と進み、”Microsoft.ManagedServices”が NotRegisterd となっていた場合は、[登録]ボタンを押下し、Registerd にしておきましょう。

## Azure Lighthouse 設定

Azure Resource Manager テンプレートを用意し、Azureの委任されたリソース管理にログ転送元テナントをオンボードします。
手順詳細は下記サイトを参考にしています。

https://docs.microsoft.com/ja-jp/azure/lighthouse/how-to/onboard-customer#create-an-azure-resource-manager-template

この設定はPowerShellで行います。まず「subscription.parameters.json」というJsonファイルを作成しましょう。Valueに準備しておいたパラメータを埋めていきます。authorizationsのところで転送先テナントに何の権限を付与するか設定することができます。ロールIDを指定する点に注意してください。


```subscription.parameters.json
{
    "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "mspOfferName": {
            "value": "ログ転送先テナント名など任意の値" 
        },
        "mspOfferDescription": {
            "value": "ログ転送先テナントの説明など任意の値" 
        },
        "managedByTenantId": {
            "value": "ログ転送元のテナントID"
        },
        "authorizations": {
            "value": [
                {
                    "principalId": "管理を委任するグループのObjectID(ログ転送元のグループ)",
                    "roleDefinitionId": "委任したいロールのID。共同作成者の場合はb24988ac-6180-42a0-ab88-20f7382dd24c", 
                    "principalIdDisplayName": "管理を委任するグループ名"
                }
            ]
        }
    }
}
```

続いて「subscription.json」というJsonファイルを作成します。こちらについてはパラメータの変更は不要です。
```subscription.json
{
    "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "mspOfferName": {
            "type": "string",
            "metadata": {
                "description": "Specify a unique name for your offer"
            }
        },
        "mspOfferDescription": {
            "type": "string",
            "metadata": {
                "description": "Name of the Managed Service Provider offering"
            }
        },
        "managedByTenantId": {
            "type": "string",
            "metadata": {
                "description": "Specify the tenant id of the Managed Service Provider"
            }
        },
        "authorizations": {
            "type": "array",
            "metadata": {
                "description": "Specify an array of objects, containing tuples of Azure Active Directory principalId, a Azure roleDefinitionId, and an optional principalIdDisplayName. The roleDefinition specified is granted to the principalId in the provider's Active Directory and the principalIdDisplayName is visible to customers."
            }
        }              
    },
    "variables": {
        "mspRegistrationName": "[guid(parameters('mspOfferName'))]",
        "mspAssignmentName": "[guid(parameters('mspOfferName'))]"
    },
    "resources": [
        {
            "type": "Microsoft.ManagedServices/registrationDefinitions",
            "apiVersion": "2019-09-01",
            "name": "[variables('mspRegistrationName')]",
            "properties": {
                "registrationDefinitionName": "[parameters('mspOfferName')]",
                "description": "[parameters('mspOfferDescription')]",
                "managedByTenantId": "[parameters('managedByTenantId')]",
                "authorizations": "[parameters('authorizations')]"
            }
        },
        {
            "type": "Microsoft.ManagedServices/registrationAssignments",
            "apiVersion": "2019-09-01",
            "name": "[variables('mspAssignmentName')]",
            "dependsOn": [
                "[resourceId('Microsoft.ManagedServices/registrationDefinitions/', variables('mspRegistrationName'))]"
            ],
            "properties": {
                "registrationDefinitionId": "[resourceId('Microsoft.ManagedServices/registrationDefinitions/', variables('mspRegistrationName'))]"
            }
        }
    ],
    "outputs": {
        "mspOfferName": {
            "type": "string",
            "value": "[concat('Managed by', ' ', parameters('mspOfferName'))]"
        },
        "authorizations": {
            "type": "array",
            "value": "[parameters('authorizations')]"
        }
    }
}
```

2つのJsonファイルの準備が整ったら、PowerShellコンソールからAzureにログオンします。ログオン先は「ログ転送先」テナントの方です。さらに、保管用のストレージアカウントがあるサブスクリプションに移動しておきます。

```powershell
Connect-AzAccount
Select-AzSubscription -Subscription <Subscription ID>
```

次に下記コマンド実行します。-Name の値(signinlog_transfer)は任意の名前で構いません。

```powershell
New-AzSubscriptionDeployment -Name signinlog_transfer `
                -Location JapanEast `
                 -TemplateFile .\subscription.json `
                 -TemplateParameterFile .\subscription.parameters.json `
                -Verbose
```
コマンドが成功すると、こんなメッセージが出力されます。(一部マスクしています)
ここで「ProvisioningState       : Succeeded 」となっていることを確認しましょう。
```
詳細: 
詳細: 23:07:18 - Template is valid.
詳細: 23:07:24 - Create template deployment 'signinlog_transfer'
詳細: 23:07:24 - Checking deployment status in 5 seconds
詳細: 23:07:30 - Resource Microsoft.ManagedServices/registrationDefinitions 'e2f60cfd-a214-5133-bfaa-50c1cc9f1eed' provisioning status is succeeded
詳細: 23:07:31 - Checking deployment status in 16 seconds
詳細: 23:07:48 - Resource Microsoft.ManagedServices/registrationAssignments 'e2f60cfd-a214-5133-bfaa-50c1cc9f1eed' provisioning status is running
詳細: 23:07:55 - Checking deployment status in 8 seconds


Id                      : /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/providers/Microsoft.Resources/deployments/signinlog_transfer
DeploymentName          : signinlog_transfer
Location                : japaneast
ProvisioningState       : Succeeded
Timestamp               : 2022/xx/xx xx:xx:xx
Mode                    : Incremental
TemplateLink            : 
Parameters              : 
                          Name                   Type                       Value     
                          =====================  =========================  ==========
                          mspOfferName           String                     xxxxxxxxxx
                          mspOfferDescription    String                     xxxxxxxxxxxxxxxxxxxx
                          managedByTenantId      String                     xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
                          authorizations         Array                      [
                            {
                              "principalId": "e945fd5f-b02a-445b-940e-1082e87d457c",
                              "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c",
                              "principalIdDisplayName": "Lighthouse group"
                            }
                          ]
                          
Outputs                 : 
                          Name              Type                       Value     
                          ================  =========================  ==========
                          mspOfferName      String                     Managed by xxxxxxx
                          authorizations    Array                      [
                            {
                              "principalId": "e945fd5f-b02a-445b-940e-1082e87d457c",
                              "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c",
                              "principalIdDisplayName": "Lighthouse group"
                            }
                          ]
                          
DeploymentDebugLogLevel : 
```

これで設定完了です。

ログ転送元テナントの方でAzureさポータル右上にある歯車マークから「ポータルの設定｜ディレクトリとサブスクリプション」に進み、”現在のサブスクリプションフィルター”に委任したサブスクリプションが含まれていることを確認し、追加のチェックをつけてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/37133c34-2ef4-1f3a-93e4-76f692c0eb93.png)

その後、[Azure Active Directory] → [診断設定] に進み、診断設定から各種ログ保存するストレージアカウントを選択するところで「サブスクリプション」を見ると、自サブスクリプションの他に委任したサブスクリプションが出てきて、さらに「ストレージアカウント」では委任先の環境のストレージアカウントを選択することができるようになります。

## おわりに
今回はAzure Lighthouseを用いて他テナントにAuzreADサインインログを保存するまでの方法について紹介しました。PowerShellを使うあたり少々手間ではありますが、慣れてしまえば簡単に設定できてしまいますので、ぜひチャレンジしてみてください。

それでは！