Azure Resource Manager テンプレートを使用して Azure でのロールを割り当てる

Azure ロールベースのアクセス制御 (Azure RBAC) は、Azure のリソースに対するアクセスを管理するために使用する承認システムです。 アクセス権を付与するには、特定のスコープでユーザー、グループ、サービス プリンシパル、またはマネージド ID にロールを割り当てます。Azure PowerShell または Azure CLI を使う以外に、Azure Resource Manager テンプレートを使ってロールを割り当てることもできます。 リソースを一貫して繰り返しデプロイする場合は、テンプレートが便利です。 この記事では、テンプレートを使用してロールを割り当てる方法について説明します。

前提条件

Azure ロールを割り当てるには、以下が必要です。

オブジェクト ID を取得する

ロールを割り当てるには、ロールの割り当て先のユーザー、グループ、またはアプリケーションの ID を指定する必要があります。 ID の形式は 11111111-1111-1111-1111-111111111111 です。 この ID は、Azure portal、Azure PowerShell、または Azure CLI を使用して取得できます。

User

ユーザーの ID を取得するには、Get-AzADUser または az ad user show コマンドを使用します。

$objectid = (Get-AzADUser -DisplayName "{name}").id
objectid=$(az ad user show --id "{email}" --query objectId --output tsv)

グループ

グループの ID を取得するには、Get-AzADGroup または az ad group show コマンドを使用します。

$objectid = (Get-AzADGroup -DisplayName "{name}").id
objectid=$(az ad group show --group "{name}" --query objectId --output tsv)

マネージド ID

マネージド ID の ID を取得するには、Get-AzAdServiceprincipal コマンド、または az ad sp コマンドを使用できます。

$objectid = (Get-AzADServicePrincipal -DisplayName <Azure resource name>).id
objectid=$(az ad sp list --display-name <Azure resource name> --query [].objectId --output tsv)

Application

サービス プリンシパルの ID (アプリケーションによって使用される ID) を取得するには、Get-AzADServicePrincipal または az ad sp list コマンドを使用します。 サービス プリンシパルの場合は、アプリケーション ID ではなく、オブジェクト ID を使用します。

$objectid = (Get-AzADServicePrincipal -DisplayName "{name}").id
objectid=$(az ad sp list --display-name "{name}" --query [].objectId --output tsv)

Azure ロールを割り当てる

Azure RBAC でアクセス権を付与するには、ロールを割り当てます。

リソース グループのスコープ (パラメーターなし)

次のテンプレートは、ロールを割り当てる基本的な方法を示したものです。 一部の値は、テンプレート内で指定されます。 以下のテンプレートでは次のことを示します。

  • リソース グループのスコープでユーザー、グループ、またはアプリケーションに閲覧者ロールを割り当てる方法

テンプレートを使うには、以下を実行する必要があります。

  • 新しい JSON ファイルを作成してテンプレートをコピーする
  • <your-principal-id> を、ロールの割当先となるユーザー、グループ、マネージド ID、またはアプリケーションの ID に置き換える
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "resources": [
        {
            "type": "Microsoft.Authorization/roleAssignments",
            "apiVersion": "2018-09-01-preview",
            "name": "[guid(resourceGroup().id)]",
            "properties": {
                "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
                "principalId": "<your-principal-id>"
            }
        }
    ]
}

次に示すのは、New-AzResourceGroupDeployment および az deployment group create コマンドの例です。"ExampleGroup" という名前のリソース グループでデプロイを開始する方法を示しています。

New-AzResourceGroupDeployment -ResourceGroupName ExampleGroup -TemplateFile rbac-test.json
az deployment group create --resource-group ExampleGroup --template-file rbac-test.json

以下では、テンプレートをデプロイした後でユーザーにリソース グループの閲覧者ロールを割り当てる例を示します。

リソース グループをスコープとするロールの割り当て

リソース グループまたはサブスクリプションのスコープ

前述のテンプレートは、それほど柔軟性が高いものではありません。 次のテンプレートでは、パラメーターを使用して、異なるスコープで使用できます。 以下のテンプレートでは次のことを示します。

  • リソース グループまたはサブスクリプションのどちらかのスコープでユーザー、グループ、またはアプリケーションにロールを割り当てる方法
  • 所有者、共同作成者、閲覧者のロールをパラメーターとして指定する方法

テンプレートを使うには、次の入力を指定する必要があります。

  • ロールの割り当て先となるユーザー、グループ、マネージド ID、またはアプリケーションの ID
  • ロール割り当てに使用する一意の ID。または既定の ID を使用できます
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "principalId": {
            "type": "string",
            "metadata": {
                "description": "The principal to assign the role to"
            }
        },
        "builtInRoleType": {
            "type": "string",
            "allowedValues": [
                "Owner",
                "Contributor",
                "Reader"
            ],
            "metadata": {
                "description": "Built-in role to assign"
            }
        },
        "roleNameGuid": {
            "type": "string",
            "defaultValue": "[newGuid()]",
            "metadata": {
                "description": "A new GUID used to identify the role assignment"
            }
        }
    },
    "variables": {
        "Owner": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
        "Contributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
        "Reader": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]"
    },
    "resources": [
        {
            "type": "Microsoft.Authorization/roleAssignments",
            "apiVersion": "2018-09-01-preview",
            "name": "[parameters('roleNameGuid')]",
            "properties": {
                "roleDefinitionId": "[variables(parameters('builtInRoleType'))]",
                "principalId": "[parameters('principalId')]"
            }
        }
    ]
}

注意

テンプレートの各デプロイのパラメーターとして同じ roleNameGuid 値が指定されていない場合、このテンプレートはべき等ではありません。 roleNameGuid が指定されていない場合、既定では、デプロイごとに新しい GUID が生成され、後続のデプロイは Conflict: RoleAssignmentExists のエラーで失敗します。

ロール割り当てのスコープは、デプロイのレベルから特定できます。 次に示すのは、New-AzResourceGroupDeployment および az deployment group create コマンドの例です。リソース グループのスコープでデプロイを開始する方法を示しています。

New-AzResourceGroupDeployment -ResourceGroupName ExampleGroup -TemplateFile rbac-test.json -principalId $objectid -builtInRoleType Reader
az deployment group create --resource-group ExampleGroup --template-file rbac-test.json --parameters principalId=$objectid builtInRoleType=Reader

次に示すのは、New-AzDeployment および az deployment sub create コマンドの例です。サブスクリプションのスコープでデプロイを開始し、場所を指定する方法を示しています。

New-AzDeployment -Location centralus -TemplateFile rbac-test.json -principalId $objectid -builtInRoleType Reader
az deployment sub create --location centralus --template-file rbac-test.json --parameters principalId=$objectid builtInRoleType=Reader

リソースのスコープ

リソース レベルでロールを割り当てる必要がある場合は、ロールの割り当てで scope プロパティをリソースの名前に設定します。

以下のテンプレートでは次のことを示します。

  • 新しいストレージ アカウントの作成方法
  • ストレージ アカウントのスコープでユーザー、グループ、またはアプリケーションにロールを割り当てる方法
  • 所有者、共同作成者、閲覧者のロールをパラメーターとして指定する方法

テンプレートを使うには、次の入力を指定する必要があります。

  • ロールの割り当て先となるユーザー、グループ、マネージド ID、またはアプリケーションの ID
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "principalId": {
            "type": "string",
            "metadata": {
                "description": "The principal to assign the role to"
            }
        },
        "builtInRoleType": {
            "type": "string",
            "allowedValues": [
                "Owner",
                "Contributor",
                "Reader"
            ],
            "metadata": {
                "description": "Built-in role to assign"
            }
        },
        "roleNameGuid": {
            "type": "string",
            "defaultValue": "[newGuid()]",
            "metadata": {
                "description": "A new GUID used to identify the role assignment"
            }
        },
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]"
        }
    },
    "variables": {
        "Owner": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
        "Contributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
        "Reader": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
        "storageName": "[concat('storage', uniqueString(resourceGroup().id))]"
    },
    "resources": [
        {
            "apiVersion": "2019-04-01",
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageName')]",
            "location": "[parameters('location')]",
            "sku": {
                "name": "Standard_LRS"
            },
            "kind": "Storage",
            "properties": {}
        },
        {
            "type": "Microsoft.Authorization/roleAssignments",
            "apiVersion": "2020-04-01-preview",
            "name": "[parameters('roleNameGuid')]",
            "scope": "[concat('Microsoft.Storage/storageAccounts', '/', variables('storageName'))]",
            "dependsOn": [
                "[variables('storageName')]"
            ],
            "properties": {
                "roleDefinitionId": "[variables(parameters('builtInRoleType'))]",
                "principalId": "[parameters('principalId')]"
            }
        }
    ]
}

前述のテンプレートをデプロイするには、リソース グループのコマンドを使用します。 次に示すのは、New-AzResourceGroupDeployment および az deployment group create コマンドの例です。リソースのスコープでデプロイを開始する方法を示しています。

New-AzResourceGroupDeployment -ResourceGroupName ExampleGroup -TemplateFile rbac-test.json -principalId $objectid -builtInRoleType Contributor
az deployment group create --resource-group ExampleGroup --template-file rbac-test.json --parameters principalId=$objectid builtInRoleType=Contributor

以下では、テンプレートをデプロイした後でユーザーにストレージ アカウントの共同作成者ロールを割り当てる例を示します。

リソースをスコープとするロールの割り当て

新しいサービス プリンシパル

新しいサービス プリンシパルを作成し、そのサービス プリンシパルにロールをすぐに割り当てようとすると、場合によってはそのロールの割り当てが失敗することがあります。 たとえば、新しいマネージド ID を作成し、同じ Azure Resource Manager テンプレート内でそのサービス プリンシパルにロールを割り当てようとすると、ロールの割り当てが失敗する可能性があります。 このエラーの原因は、レプリケーションの遅延である可能性があります。 サービス プリンシパルは 1 つのリージョンに作成されます。ただし、ロールの割り当ては、サービス プリンシパルがまだレプリケートされていない別のリージョンで発生する可能性があります。

このシナリオに対処するには、ロールの割り当てを作成するときに、principalType プロパティを ServicePrincipal に設定する必要があります。 また、ロールの割り当ての apiVersion2018-09-01-preview 以降に設定する必要もあります。

以下のテンプレートでは次のことを示します。

  • 新しいマネージド ID サービス プリンシパルを作成する方法
  • principalType の指定方法
  • リソース グループのスコープで、そのサービス プリンシパルに共同作成者ロールを割り当てる方法

テンプレートを使うには、次の入力を指定する必要があります。

  • マネージド ID の基本名。既定の文字列を使用することもできます
{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "baseName": {
            "type": "string",
            "defaultValue": "msi-test"
        }
    },
    "variables": {
        "identityName": "[concat(parameters('baseName'), '-bootstrap')]",
        "bootstrapRoleAssignmentId": "[guid(concat(resourceGroup().id, 'contributor'))]",
        "contributorRoleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]"
    },
    "resources": [
        {
            "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
            "name": "[variables('identityName')]",
            "apiVersion": "2018-11-30",
            "location": "[resourceGroup().location]"
        },
        {
            "type": "Microsoft.Authorization/roleAssignments",
            "apiVersion": "2018-09-01-preview",
            "name": "[variables('bootstrapRoleAssignmentId')]",
            "dependsOn": [
                "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]"
            ],
            "properties": {
                "roleDefinitionId": "[variables('contributorRoleDefinitionId')]",
                "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName')), '2018-11-30').principalId]",
                "principalType": "ServicePrincipal"
            }
        }
    ]
}

次に示すのは、New-AzResourceGroupDeployment および az deployment group create コマンドの例です。リソース グループのスコープでデプロイを開始する方法を示しています。

New-AzResourceGroupDeployment -ResourceGroupName ExampleGroup2 -TemplateFile rbac-test.json
az deployment group create --resource-group ExampleGroup2 --template-file rbac-test.json

次に示すのは、テンプレートをデプロイした後で、新しいマネージド ID サービス プリンシパルに共同作成者ロールを割り当てる場合の例です。

新しいマネージド ID サービス プリンシパルに対するロールの割り当て

次のステップ