Azureのユーザ割り当てマネージドIDを使ってVMからサインインする

## 環境

* Azure Key Vault
* Azure ManagedIdentity
* Azure Virtual Machine - CentOS  8.2
* Azure Cli - 2.38.1

## 要約

* AzureのVMからazコマンドでKey Vaultの情報を取得しようとしたが失敗した
* ユーザ割り当てマネージドIDを作成してロールを割り当てたにもかかわらず、リソースが閲覧できないように見える
* システム割り当てマネージドIDが存在する状態で `az login` すると、デフォルトではそれが使用されることが分かった
* loginコマンドに `--username` オプションでユーザ割り当てマネージドIDを指定すればよい

## 構成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3018916/4eb98a1e-1b4a-9520-614e-b10502c62474.png)

## 問題が起きていた状態

VMからシークレットを取得してみるが、失敗。権限がないように見える。  

```bash
# azコマンドでサインイン
$ az login --identity
[
  {
    "environmentName": "AzureCloud",
    "homeTenantId": "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx",
    "id": "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx",
    "isDefault": true,
    "managedByTenants": [],
    "name": "xxxxxx",
    "state": "Enabled",
    "tenantId": "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx",
    "user": {
      "assignedIdentityInfo": "MSI",
      "name": "systemAssignedIdentity",
      "type": "servicePrincipal"
    }
  }
]

# Key Vaultのシークレットを取得に失敗
$ az keyvault secret list --vault-name mykey-sercret-0001
Caller is not authorized to perform action on resource.
If role assignments, deny assignments or role definitions were changed recently, please observe propagation time.
Caller: appid=xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx;iss=https://sts.windows.net/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx/
Action: 'Microsoft.KeyVault/vaults/secrets/readMetadata/action'
Resource: '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx/resourcegroups/tastylog-dev-rg/providers/microsoft.keyvault/vaults/mykey-sercret-0001'
Assignment: (not found)
DenyAssignmentId: null
DecisionReason: null 
Vault: mykey-sercret-0001;location=japaneast
```

#### VMにユーザ割り当てマネージドIDを設定できている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3018916/20fd5c09-6bb4-ef50-5d7e-f6830cecbe03.png)

#### Key Vaultにロールを割り当てできてる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3018916/bd08b911-517b-5c20-6b6f-9c9d5880a952.png)

## 原因

サインインしたときにシステム割り当てマネージドIDが表示されており、ユーザ割り当てのマネージドIDが使用されていないように見える。

```bash
# az login の出力結果を抜粋
    "user": {
      "assignedIdentityInfo": "MSI",
      "name": "systemAssignedIdentity",  # システム割り当てマネージドIDに見える
      "type": "servicePrincipal"
    }
```

Azure CLIのドキュメントを改めて読んでみたところ、サインインのオプション指定が必要であることが分かった。 

```text
リソースに複数のユーザー割り当てマネージド ID があり、システム割り当てIDがない場合は、
ログインで --username を使用してユーザー割り当てマネージドIDのクライアントID、オブジェクトID、
またはリソースIDを指定する必要があります。
```

[Microsoft Learn - Azure CLI でマネージド ID 使用したサインイン](https://learn.microsoft.com/ja-jp/cli/azure/authenticate-azure-cli-managed-identity)

## 解決法

ユーザ割り当てマネージドIDのクライアントIDを指定してサインインすればよい。  

### クライアントIDの取得

クライアントIDはポータルから確認できる。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3018916/9ac7cdd6-d782-d412-2347-f76f997f3b0a.png)

### VMからクライアントIDを指定してサインイン

`az login --identity --username <クライアントID>`

```bash
# ユーザ割り当てマネージドIDを指定してサインイン
$ az login --identity --username xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx
[
  {
    "environmentName": "AzureCloud",
    "homeTenantId": "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx",
    "id": "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx",
    "isDefault": true,
    "managedByTenants": [],
    "name": "xxxxxx",
    "state": "Enabled",
    "tenantId": "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx",
    "user": {
      "assignedIdentityInfo": "MSIClient-xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx",  # クライアントIDが設定されている
      "name": "userAssignedIdentity",   # ユーザ割り当てマネージドIDが使用されている
      "type": "servicePrincipal"
    }
  }
]

# 無事に取得できた
$ az keyvault secret list --vault-name mykey-sercret-0001
[
  {
    "attributes": {
      "created": "2024-03-16T06:33:18+00:00",
      "enabled": true,
      "expires": null,
      "notBefore": null,
      "recoveryLevel": "CustomizedRecoverable+Purgeable",
      "updated": "2024-03-16T06:33:18+00:00"
    },
    "contentType": null,
    "id": "https://xxxxxxxxxxxx.vault.azure.net/secrets/xxxxxx",
    "managed": null,
    "name": "xxxxxx",
    "tags": {}
  }
]
```

無事に取得ができた。