サービス プリンシパルに Azure へのアクセス権を付与する

完了

サービス プリンシパルは、それ自体では、Azure 環境で何も行うことができません。 これは、ユーザーが Azure リソースを操作することを承認されていなければ操作できないのと同じです。 このユニットでは、不要なアクセス許可の付与を回避しながら、サービス プリンシパルによる Azure リソースのデプロイおよび構成を承認する方法について説明します。

注意

このユニットのコマンドは、概念を説明するために示されています。 コマンドはまだ実行しないでください。 ここで学習した内容をすぐに練習します。

サービス プリンシパルの承認

ここまでは、サービス プリンシパルの概要と、それらを使用して、Microsoft Entra ID に対してパイプラインの身元を証明する方法に焦点を当ててきました。 これは、すべて "認証" に関するものです。

Microsoft Entra ID がサービス プリンシパルを認証した後、次の疑問として浮かぶのは、このサービス プリンシパルは何ができるのかということです。 これは "認可" の概念です。 これは、Azure のロールベースのアクセス制御 (RBAC) システム (場合により ID およびアクセス管理 (IAM) とも呼ばれる) の役割です。 Azure RBAC を使用すると、特定のリソース グループ、サブスクリプション、または管理グループへのアクセス権をサービス プリンシパルに付与できます。

Note

ここで行うのは、Azure RBAC システムを使用して、Azure リソース (ストレージ アカウント、App Service プラン、仮想ネットワークなど) を作成および管理するためのアクセス権を付与することのみです。 また、Microsoft Entra ID には、独自のロール システムもあります。これは、"ディレクトリ ロール" と呼ばれることもあります。 これらのロールを使用して、Microsoft Entra ID を管理するためのアクセス許可をサービス プリンシパルに付与します。 このモジュールでは、この件について詳しく説明しませんが、一部のドキュメントでは、両方の状況に対して "ロール" という用語が使用されている場合があるので注意してください。

パイプラインに適したロールの割り当てを選択する

ロールの割り当てには、ロールの割り当て対象者 ("担当者")、担当者が実行できる内容 ("ロール")、ロールの割り当てが適用される 1 つ以上のリソース ("スコープ") という 3 つの重要な構成要素があります。

担当者

サービス プリンシパルを使用する場合、そのサービス プリンシパルにロールを割り当てます。 サービス プリンシパルのアプリケーション ID を使用して、その担当者の適切なサービス プリンシパルを識別します。

ロール

割り当てるロールを判断するのに、多少労力が必要になる場合があります。 Azure には、一般的なロールがいくつかあります。

  • "閲覧者": 担当者は、リソースに関する情報を読み取ることができますが、それらを変更または削除することはできません。
  • "共同作成者": 担当者は、リソースの作成、既存のリソースの読み取りと変更を行うことができます。 ただし、共同作成者は、リソースへのアクセス権を他のプリンシパルに付与することはできません。
  • "所有者": 他のプリンシパルへのアクセス権の付与など、リソースを完全に制御できます。

注意事項

サービス プリンシパルには、ジョブを実行するために必要な最小限のアクセス許可のみを付与するべきです。 ほとんどの場合、所有者ロールは、デプロイ パイプラインに対しては制限が緩すぎます。

また、機能のサブセットのみへのアクセス権を提供する特定のロールも多数あります。 独自の "カスタム ロールの定義" を作成して、割り当てるアクセス許可の正確な一覧を指定することもできます。

Note

カスタム ロールの定義は、Azure リソースへのアクセス許可を付与するための強力な方法ですが、取り扱いが難しい場合があります。 カスタム ロールの定義にどのアクセス許可を追加する必要があるかを正確に判断するのは必ずしも簡単ではありません。また、ロールの定義に対して制限を誤って厳しくしすぎたり、緩くしすぎたりする可能性もあります。 どうすればよいかわからない場合は、代わりに、組み込みロールの定義のいずれかを使用することをお勧めします。 カスタム ロールの定義は、このモジュールの範囲を超えています。

Scope

ロールを割り当てる範囲を決定する必要があります。 この決定は、サービス プリンシパルが変更できるリソースの数に影響します。 一般的なスコープは次のとおりです。

  • 単一リソース: 特定のリソースのみへのアクセス権を付与できます。 通常、デプロイ パイプラインでは、このスコープは使用されません。これは、パイプラインで、まだ存在しないリソースを作成するため、または複数のリソースを再構成するためです。
  • リソース グループ: リソース グループ内のすべてのリソースへのアクセス権を付与できます。 共同作成者と所有者は、グループ内でリソースを作成することもできます。 これは、多くのデプロイ パイプラインに適したオプションです。
  • サブスクリプション: サブスクリプション内のすべてのリソースへのアクセス権を付与できます。 1 つのサブスクリプションに複数のアプリケーション、ワークロード、または環境がある場合、サブスクリプションのスコープへのアクセス許可を付与できます。 ただし、これは通常、デプロイ パイプラインに対しては制限が緩すぎます。 代わりに、ロールの割り当てのスコープをリソース グループに設定することを検討する必要があります (デプロイ ワークフロー自体でリソース グループを作成する必要がある場合を除きます)。

ロールの割り当ては継承されることに注意してください。 サブスクリプションでロールを割り当てると、担当者は、そのサブスクリプション内のすべてのリソース グループとリソースへのアクセス権を持つことになります。

適切なロールの割り当ての選択

ロールの割り当ての要素について理解したので、シナリオに適した値を決定できます。 ここでは、考慮する必要がある一般的なガイドラインを示します。

  • できるだけ制限が厳しいロールを使用します。 パイプラインで、基本的な Bicep テンプレートのデプロイのみ行い、ロールの割り当ては管理しない場合、所有者ロールは使用しないでください。
  • できるだけ狭いスコープを使用します。 ほとんどのパイプラインでは、リソース グループへのリソースのデプロイのみ必要です。したがって、これらに対しては、サブスクリプション スコープのロールの割り当ては付与しないでください。
  • 多くのパイプラインでは、ロールの割り当ての適切な既定のオプションは、リソース グループ スコープでの共同作成者ロールです。
  • パイプラインで実行するすべての処理と、今後実行する可能性のあるすべての処理について検討します。 たとえば、Web サイトのデプロイ パイプライン用のカスタム ロールの定義を作成することを検討し、App Service と Application Insights へのアクセス許可のみ付与するとします。 次の月に、Bicep ファイルに Azure Cosmos DB アカウントを追加することが必要になりましたが、このカスタム ロールでは Azure Cosmos DB リソースの作成はブロックされます。 ロールの定義を繰り返し変更せずにすむように、組み込みロール、または組み込みロールの組み合わせを代わりに使用することが多くの場合より適切です。 Azure Policy を使用して、許可されたサービス、SKU、場所のガバナンス要件を適用することを検討します。
  • パイプラインをテストして、ロールの割り当てが機能することを確認します。

ロールの割り当ての混在と一致

異なるスコープで異なるアクセス許可を提供する複数のロールの割り当てを作成できます。 たとえば、サブスクリプション全体のスコープを持つ閲覧者ロールをサービス プリンシパルに割り当て、その後、特定のリソース グループの共同作成者ロールを同じサービス プリンシパルに個別に割り当てることができます。 サービス プリンシパルがリソース グループを操作しようとしたとき、より制限の緩い割り当てが適用されます。

複数の環境の使用

多くの場合、アプリケーションの開発、テスト、運用環境など、複数の環境を使用します。 各環境のリソースは、異なるリソース グループまたはサブスクリプションにデプロイする必要があります。

環境ごとに個別のサービス プリンシパルを作成し、デプロイに必要な最小限のアクセス許可セットを各サービス プリンシパルに付与する必要があります。 運用環境へのデプロイのためのアクセス許可と、非運用環境へのデプロイのためのアクセス許可を混在させないように特に注意してください。

サービス プリンシパルのロールの割り当てを作成する

サービス プリンシパルのロールの割り当てを作成するには、az role assignment create コマンドを使用します。 担当者、ロール、スコープを指定する必要があります。

az role assignment create \
  --assignee b585b740-942d-44e9-9126-f1181c95d497 \
  --role Contributor \
  --scope "/subscriptions/f0750bbe-ea75-4ae5-b24d-a92ca601da2c/resourceGroups/ToyWebsite" \
  --description "The deployment pipeline for the company's website needs to be able to create resources within the resource group."

各引数を見てみましょう。

  • --assignee は、サービス プリンシパルを指定します。 あいまいさを避けるために、アプリケーション ID を使用することをお勧めします。
  • --role は、ロールを指定します。 組み込みのロールを使用する場合、名前でそれを指定できます。 カスタム ロールの定義を使用する場合、完全なロールの定義 ID を指定します。
  • --scope は、スコープを指定します。 これは通常、単一リソース、リソース グループ、またはサブスクリプションのリソース ID です。
  • --description は、人間が判読できるロールの割り当ての説明です。

サービス プリンシパルのロールの割り当てを作成するには、New-AzRoleAssignment コマンドレットを使用します。 担当者、ロール、スコープを指定する必要があります。

New-AzRoleAssignment `
  -ApplicationId b585b740-942d-44e9-9126-f1181c95d497 `
  -RoleDefinitionName Contributor `
  -Scope '/subscriptions/f0750bbe-ea75-4ae5-b24d-a92ca601da2c/resourceGroups/ToyWebsite' `
  -Description "The deployment pipeline for the company's website needs to be able to create resources within the resource group."

各引数を見てみましょう。

  • -ApplicationId は、サービス プリンシパルのアプリケーション登録 ID を指定します。
  • -RoleDefinitionName は、組み込みロールの名前を指定します。 カスタム ロールの定義を使用する場合、代わりに -RoleDefinitionId 引数を使用して完全なロールの定義 ID を指定します。
  • -Scope は、スコープを指定します。 これは通常、単一リソース、リソース グループ、またはサブスクリプションのリソース ID です。
  • -Description は、人間が判読できるロールの割り当ての説明です。

ヒント

説明を記入して、ロールの割り当ての理由を示すことをお勧めします。 説明により、後でそのロールの割り当てを確認するユーザーがその目的を理解でき、担当者、ロール、スコープをどのように決定したかを理解できます。

Note

ロールの割り当ては、アクティブになるまで数分かかることがあります。

1 回の操作でサービス プリンシパルとロールの割り当てを作成する

サービス プリンシパルを作成するときに、同時にロールの割り当ても作成できます。 コードは、前のユニットでサービス プリンシパルを作成するために使用したコマンドと似ていますが、追加の引数がいくつかあります。

az ad sp create-for-rbac \
  --name MyPipeline \
  --role Contributor \
  --scopes "/subscriptions/f0750bbe-ea75-4ae5-b24d-a92ca601da2c/resourceGroups/ToyWebsite"
$servicePrincipal = New-AzADServicePrincipal `
  -DisplayName MyPipeline `
  -Role Contributor `
  -Scope '/subscriptions/f0750bbe-ea75-4ae5-b24d-a92ca601da2c/resourceGroups/ToyWebsite'

Bicep を使用してアクセス権を付与する

ロールの割り当ては Azure リソースです。 これは、Bicep を使用してロールの割り当てを作成できることを意味します。 Bicep を使用してリソース グループを初期化し、その後、サービス プリンシパルを使用してリソース グループにリソースをデプロイする場合は、これを実行する場合があります。 上記のロールの割り当ての Bicep 定義の例を次に示します。

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2023-04-01-preview' = {
  name: guid(principalId, roleDefinitionId, resourceGroup().id)
  properties: {
    principalType: 'ServicePrincipal'
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId)
    principalId: principalId
    description: 'The deployment pipeline for the company\'s website needs to be able to create resources within the resource group.'
  }
}

各引数を見てみましょう。

  • name は、ロールの割り当ての一意の識別子です。 これは、グローバル一意識別子 (GUID) の形式である必要があります。 ロールの割り当てごとに一意の名前を確実に作成するために、Bicep の guid() 関数を使用して GUID を作成すること、およびこの関数のシード引数としてプリンシパル ID、ロールの定義 ID、スコープを使用することをお勧めします。
  • principalTypeServicePrincipal に設定する必要があります。
  • roleDefinitionId は、割り当てるロールの定義の完全修飾リソース ID です。 多くの場合、組み込みロールを使用し、Azure の組み込みロールのドキュメントでロールの定義 ID を確認します。 たとえば、"共同作成者" ロールのロールの定義 ID は b24988ac-6180-42a0-ab88-20f7382dd24c です。 Bicep ファイルでこれを指定する場合、/subscriptions/f0750bbe-ea75-4ae5-b24d-a92ca601da2c/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c などの完全修飾リソース ID を使用してこれを表現します。
  • principalId は、サービス プリンシパルのオブジェクト ID です。 アプリケーション ID またはアプリケーション登録のオブジェクト ID は使用しないでください。
  • description は、人間が判読できるロールの割り当ての説明です。