Microsoft Azure からリソースにアクセスする

このドキュメントでは、ID 連携を使用して Microsoft Azure から Google Cloud リソースにアクセスする方法について説明します。

従来、Google Cloud の外部で実行されているアプリケーションは、サービス アカウント キーを使用して Google Cloud リソースにアクセスしていました。ID 連携を使用すると、Azure リソースのマネージド ID でサービス アカウントになり代わることができます。これにより、ワークロードは短期間だけ有効なアクセス トークンを使用して Google Cloud リソースに直接アクセスでき、サービス アカウント キーに関連するメンテナンスとセキュリティの負担が軽減されます。

始める前に

  1. Workload Identity プール管理者ロール(roles/iam.workloadIdentityPoolAdmin)があることを確認します。

    IAM の基本ロールであるオーナー(roles/owner)と編集者(roles/editor)のロールでも、ID 連携を構成する権限が付与されます。それでも、Workload Identity プール管理者ロールを使用して、Google Cloud リソースへの不要なアクセス権の付与を避けることをおすすめします。

  2. Google Cloud サービス アカウントを作成します。

  3. サービス アカウントにアクセス権を付与して、ワークロードに必要な Google Cloud APIs を呼び出します。

Workload Identity プールの作成

Workload Identity プールは、外部 ID のコレクション用のコンテナです。Workload Identity プールは相互に分離されていますが、1 つのプールは任意の数のサービス アカウントになり代わることができます。一般に、開発、ステージング、本番環境など、環境ごとに新しいプールを作成することをおすすめします。

新しい Workload Identity プールを作成するには、ID を指定する必要があります。オプションの説明と表示名を指定することもできます。

gcloud コマンド

gcloud beta iam workload-identity-pools create コマンドを実行して Workload Identity プールを作成します。

gcloud beta iam workload-identity-pools create pool-id \
    --location="global" \
    --description="description" \
    --display-name="display-name"

REST API

projects.locations.workloadIdentityPools.create メソッドにより、Workload Identity プールが作成されます。

HTTP メソッドと URL:

POST https://iam.googleapis.com/v1beta/projects/project-id/locations/global/workloadIdentityPools?workloadIdentityPoolId=pool-id

JSON 本文のリクエスト:

{
  "description": "description",
  "display-name": "display-name"
}

リクエストを送信するには、次のいずれかのオプションを展開します。

 

ID 連携用に Azure を構成する

ID 連携に対応する Azure テナントを準備するには:

  1. Azure AD アプリケーションとサービス プリンシパルを作成し、アプリケーション ID URI を次に設定します。

    https://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id
    
  2. マネージド ID を作成し、そのオブジェクト ID をメモします。

  3. Google Cloud リソースへのアクセス権を付与する仮想マシンにマネージド ID を割り当てます

ID プロバイダとして Azure を追加する

Azure を Workload Identity プールの ID プロバイダとして構成するには、少なくとも次の情報を指定します。

  • プロバイダの ID。

  • このドキュメントの前のセクションの Workload Identity プール ID。

  • Azure テナント ID

次の複数のオプション パラメータを指定することもできます。

  • 表示名と説明。

  • Azure トークンのクレームを Google トークンの属性にマッピングする属性のマッピングのリスト。assertion を使用して Azure 認証情報を参照します。Google 属性の場合は google、カスタム属性の場合は attribute を使用します。

    Google 属性には google.subjectgoogle.groups の 2 つがあります。これらの属性は IAM バインディングで参照できます。google.subject も Cloud Logging のログエントリに表示されます。

    通常は、マネージド ID のオブジェクト ID を含む assertion.subgoogle.subject にマッピングすることをおすすめします。これにより、IAM バインディングで使用するための固定 ID が提供されます。マッピングは次のようになります。

    google.subject=assertion.sub
    

    より複雑なアサーションの場合は、Common Expression Language を使用できます。たとえば、Workload Identity プールに複数の ID プロバイダが含まれている場合は、それらの ID を明確化するために接頭辞を追加できます。

    google.subject="azure::" + assertion.tid + "::" + assertion.sub
    

    google.subject フィールドは 127 文字以下で指定してください。

    カスタム属性を指定することもできます。たとえば、以下では assertion.tidattribute.tid にマッピングします。

    attribute.tid=assertion.tid
    

    次の例では、assertion.oid の値に基づいて表示名を割り当てます。

    attribute.managed_identity_name={
    "8bb39bdb-1cc5-4447-b7db-a19e920eb111":"workload1",
    "55d36609-9bcf-48e0-a366-a3cf19027d2a":"workload2"
    }[assertion.oid]
    

    参照できるクレームの完全なリストを取得するには、ワークロード内の Azure VM のアクセス トークンを取得します。リクエストで、resource パラメータを Workload Identity プールの完全なリソース名に置き換えます。例:

    curl -s
      'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id' \
      -H Metadata:true -H "Cache-Control: no-cache"
    

    これにより、Azure VM のアクセス トークンが返されます。これをデコードし、使用可能なクレームを表示できます。

    式で使用されているクレームの特定の部分を参照するには、CEL の extract() 関数を使用します。この関数は、指定したテンプレートに基づいてクレームから値を抽出します。extract() の詳細については、リソース名からの値の抽出をご覧ください。

    認証情報にクレームが含まれているかどうかを確認するには、has() 関数を使用します。

  • プリンシパルが提示する必要がある属性を指定する属性条件。この条件は、Azure 認証情報に関するクレーム、または Google 認証情報の属性に適用できます。条件を満たしていないリクエストは拒否されます。

    属性条件は、ブール値を返す CEL 式の形式になります。たとえば以下では、特定のグループのメンバーではない ID からのリクエストは拒否されます。

    "e968c2ef-047c-498d-8d79-16ca1b61e77e" in assertion.groups
    

    属性条件の一般的なユースケースの詳細については、Workload Identity 連携の概要をご覧ください。

次の例では、Azure を ID プロバイダとして追加する方法を説明します。

gcloud コマンド

gcloud beta iam workload-identity-pools providers create-oidc コマンドを実行して、Azure を ID プロバイダとして追加します。

gcloud beta iam workload-identity-pools providers create-oidc provider-id \
    --workload-identity-pool="pool-id" \
    --issuer-uri="https://sts.windows.net/azure-tenant-id" \
    --location="global"

REST API

projects.locations.workloadIdentityPools.providers.create メソッドにより、Azure がプロバイダとして追加されます。

HTTP メソッドと URL:

POST https://iam.googleapis.com/v1beta/projects/project-id/locations/global/workloadIdentityPools/pool-id/providers?workloadIdentityPoolProviderId=provider-id

JSON 本文のリクエスト:

{
  "issuerUrl": "https://sts.windows.net/azure-tenant-id"
}

リクエストを送信するには、次のいずれかのオプションを展開します。

 

サービス アカウントになり代わる

Workload Identity プールとプロバイダから連携された ID に、IAM を使用してリソースのロールを付与できます。Workload Identity ユーザーのロール(roles/iam.workloadIdentityUser)により、サービス アカウントになり代わる権限が付与されます。これにより、外部 ID で Google Cloud リソースにアクセスできるようになります。

特定のマネージド ID にこのバインディングを追加するには:

gcloud iam service-accounts add-iam-policy-binding service-account-email \
  --role roles/iam.workloadIdentityUser \
  --member "principal://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/subject/managed-identity-object-id"

プール内のすべての ID にこのバインディングを追加するには:

gcloud iam service-accounts add-iam-policy-binding service-account-email \
    --role roles/iam.workloadIdentityUser \
    --member "principalSet://iam.googleapis.com/project/project-number/workloadIdentityPools/pool-id/groups/azure-tenant-id"

カスタム属性に基づいてアクセス権を付与することもできます。例:

gcloud iam service-accounts add-iam-policy-binding service-account-email \
  --role="roles/iam.workloadIdentityUser" \
  --member="principalSet://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/attribute.custom-attribute-name/custom-attribute-value"

アクセス権を取り消すには、add-iam-policy-bindingremove-iam-policy-binding に置き換えます。

REST API またはクライアント ライブラリを使用して、バインディングの追加または削除を行うこともできます。詳細については、リソースへのアクセス権の付与、変更、取り消しをご覧ください。

Azure トークンを Google トークンと交換する

Azure が管理する ID でサービス アカウントになり代わることができる状態であれば、その認証情報を Google 認証情報と交換できます。

認証情報を交換するには、次のようにします。

  1. Azure Instance Metadata Service(IMDS)を使用して Azure アクセス トークンを取得します

  2. Azure アクセス トークンをセキュリティ トークン サービス token() メソッドに渡して、連携アクセス トークンを取得します。

    REST API

    token メソッドにより、サードパーティ トークンが Google トークンに交換されます。

    後述のリクエストのデータを使用する前に、次のように置き換えます。

    • project-id: Google Cloud プロジェクト ID
    • pool-id: このチュートリアルで前に作成した Workload Identity プールの ID。
    • provider-id: このチュートリアルで前に構成した ID プロバイダの ID。

    HTTP メソッドと URL:

    POST https://sts.googleapis.com/v1beta/token

    JSON 本文のリクエスト:

    {
      "audience": "https://iam.googleapis.com/projects/project-id/locations/global/workloadIdentityPools/pool-id/providers/provider-id",
      "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
      "requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
      "scope": "https://www.googleapis.com/auth/cloud-platform",
      "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
      "subject_token": "azure-id-token"
    }
    

    リクエストを送信するには、次のいずれかのオプションを展開します。

     

    このメソッドは連携トークンを返します。

  3. generateAccessToken() を呼び出して、連携トークンを OAuth 2.0 アクセス トークンと交換します。

    REST API

    curl -X POST -H "Authorization: Bearer federated-token \
      https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/service-account-email:generateAccessToken
    

サービス アカウントのアクセス トークンを取得したら、リクエストの Authorization ヘッダーにトークンを含めることで、Google Cloud APIs の呼び出しに使用できます。

Authorization: Bearer service-account-access-token

リクエストはサービス アカウントとして承認されます。

次のステップ