Check! Azure でもロールを使った権限管理で快適に！

こんにちは、 @dz_ こと大平かづみです。

この記事は、[Microsoft Azure Advent Calendar 2017](https://qiita.com/advent-calendar/2017/azure) の18日目の記事です。

Prologue - はじめに
====

AWS では、 CLI や API を使うとき、最小限の権限に絞ったIAMのクレデンシャルを使って安全に運用すると思います。

Azure でもできるんです 🙌

Azure でのアクセス管理
====

Azure Active Directory では、様々な単位で権限を与えることができます。以下は `az` コマンドの Azure Active Directory サブコマンドの例です。

```bash
az ad --help

Group
    az ad: Synchronize on-premises directories and manage Azure Active Directory resources.

Subgroups:
    app  : Manage Azure Active Directory applications.
    group: Manage Azure Active Directory groups.
    sp   : Manage Azure Active Directory service principals for automation authentication.
    user : Manage Azure Active Directory users and user authentication.
```

このうち、CLI や SDK などプログラマブルにAzureリソースを利用する場合は、 **サービスプリンシパル**  (**service principal**) を発行して使います。

サービスプリンシパルは、Azure Active Directory の「アプリケーション」に紐づきます。これらの関係は少しややこしいので、気になる方はこちらをご参考ください。

- [Azure Active Directory のアプリケーションおよびサービス プリンシパル オブジェクト | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/active-directory/develop/active-directory-application-objects)

ロールベースのアクセス制御
====

そして、Azure Active Directory では、 **Role-Based Access Control** (**RBAC**) として、**ロール**（**役割**）を割り当てることで必要なリソースへのアクセス許可/制限を行います。

ロールは、 Azure Active Directory に登録されたユーザー、グループ、およびアプリケーション（サービスプリンシパル含む）に割り当てることができます。

- [RBAC を使用したアクセスとアクセス許可の管理 - Azure RBAC | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-control-what-is "RBAC を使用したアクセスとアクセス許可の管理 - Azure RBAC | Microsoft Docs")

主要なロールはすでに用意されていて 60 個ほどあります。また、新しいロールも作成できます。(後述）

- [Actions と NotActions - Azure ロールベースのアクセス制御 (RBAC) | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-built-in-roles)

```bash
# ロール定義一覧を表示する
az role definition list -o table

Name            Type         Description
--------------  -----------  ------------------------------------------------------------
...
Contributor     BuiltInRole  Lets you manage everything except access to resources.
...
Owner           BuiltInRole  Lets you manage everything, including access to resources.
Reader          BuiltInRole  Lets you view everything, but not make any changes.
...
```

ロールを割り当てる
----

ロールの割り当ては、ポータルでも、[CLI](https://docs.microsoft.com/ja-jp/cli/azure/overview?view=azure-cli-latest "Azure CLI 2.0 | Microsoft Docs") でも作業できます。

- [Azure Portal におけるロールベースのアクセス制御 | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-control-configure)
- [Azure CLI を使用したロールベースの Access Control (RBAC) の管理 | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-control-manage-access-azure-cli)

```bash
# ロールを割り当てる
az role assignment create --assignee <user, group, or service principal> --role <role name or id>

# ロールの割り当て一覧を表示する
az role assignment list 
```

カスタムロールを作成する
----

カスタムロールを作成するには、JSON で定義を作り、それを指定します。

```bash
# カスタムロールを作成する
az role definition create --role-definition @ad-role.json

# カスタムロールを更新する
az role definition update --role-definition @ad-role.json
```

### ロールの定義
ロールの定義はこのようなフォーマットです。

```json:ad-role.json
{
    "Name": "Custom Role",
    "Description": "This is a custom role",
    "Actions": [
      "Microsoft.Compute/virtualMachines/*"
    ],
    "NotActions": [
    ],
    "AssignableScopes": ["/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]
}
```

| 項目 | 説明 |
| --- | --- |
| `Name` | ロールの名前。 |
| `Description` | ロールの説明。 |
| `Actions` | ロールに対して許可するアクションを指定する（後述） |
| `NotActions` | ロールに対して、禁止するアクションを指定する。 |
| `AssignableScopes` | ロールのスコープを指定する（後述） |

#### Actions

`Actions` には、 `Microsoft.Compute/virtualMachines/read` などのアクションを指定します。ARM (Azure Resource Manager) テンプレートを書く人にはおなじみですね。 `*` も使えます。

アクション一覧については、下記ドキュメントに掲載されている他、CLI でも取得することができます。

- [ロールのアクセス許可 - Actions と NotActions - Azure ロールベースのアクセス制御 (RBAC) | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-built-in-roles#role-permissions)

```bash
# プロバイダのネームスペース一覧を表示する
az provider list --query "[].namespace" -o tsv

# アクション一覧の取得例（Microsoft.Compute に該当するアクション）
az provider operation show -n "Microsoft.Compute" --query "resourceTypes[].operations[].name"
```

#### AssignableScopes
`AssignableScopes` には、ロールの対象範囲を指定します。サブスクリプション全体だったり、特定のリソースを指定することもできます。

参考までに、 `az` コマンドでサインイン中のアカウントのサブスクリプションIDを取得する方法を載せておきます。

```bash
# サインイン中のアカウントのサブスクリプションIDを取得する
az account show --query "id" -o tsv

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```


ロールを割り当てたサービスプリンシパルを作成する
----
SDK や CLI で使えるように、実際にロールを割り当てたサービスプリンシパルを作成するには、以下のコマンドで行えます。ロールの指定を省略すると `Contributor` が割り当てられます。

```bash
# ロールを割り当ててサービスプリンシパルを作成する
az ad sp create-for-rbac -n <service principal name> --role "<Role name>" -p <password>
```

また、 `--sdk-auth` を付けるとクレデンシャル情報を JSON 形式で出力してくれます。ファイルとして出力し、環境変数 `AZURE_AUTH_LOCATION` に登録しておくと、SDKで使いやすいのでお勧めです。詳細は下記ドキュメント（python）などをご参照ください。

- [ファイル ベースの認証 - Python 用 Azure 管理ライブラリを使用した認証 | Microsoft Docs](https://docs.microsoft.com/ja-jp/python/azure/python-sdk-azure-authenticate?view=azure-python#mgmt-auth-file)

```bash
# ロール割り当て済みのサービスプリンシパルを SDK 用に書き出す
az ad sp create-for-rbac --sdk-auth > azure_credentials.json

# 環境変数に登録する
export AZURE_AUTH_LOCATION=<path to your azure credentials JSON>
```

```python:AZURE_AUTH_LOCATIONのクレデンシャル情報を利用する例
from azure.common.client_factory import get_client_from_auth_file
from azure.mgmt.compute import ComputeManagementClient

client = get_client_from_auth_file(ComputeManagementClient)
```

Epilogue - おわりに
====
便利なロールベースの権限管理について、改めてまとめてみました！

ご参考になれば幸いです 🙌