NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

Workload Identity連携でGoogle Cloudリソースへ直接アクセスする

本記事は  Google Cloudウィーク  2日目の記事です。
💻☁  1日目  ▶▶ 本記事 ▶▶  3日目  ☁💻

はじめに

先日、Google Cloudの認定試験を自宅で受けたのですが、何かと大変だったので次は大人しくテストセンターで受けようと思っています。

こんにちは、加藤です。

今回は、Google CloudのWorkload Identity連携について書きたいと思います。

Workload Identity連携

少し前に業務でAWSからGoogle Cloudへアクセスする必要がありWorkload Identity連携について調べました。

cloud.google.com

Workload Identity連携はAWSやAzure、GitHub等にGoogle Cloudリソースへのアクセス権限を付与することができる機能です。

導入することで、外部サービスとの連携において永続的な認証情報(サービスアカウントキー)の管理が不要となり、セキュリティリスク軽減や運用コスト削減が期待できます。

2種類のアクセス方式

Workload Identity連携のアクセス方式には「リソースへの直接アクセス」と「サービスアカウントの権限借用」の2つがあります。

リソースへの直接アクセス

サービスアカウントの権限借用

公式ドキュメントでは前者の「リソースへの直接アクセス」が推奨されています。ただし、「リソースへの直接アクセス」は一部のAPIにおいて制限があるため、利用したいAPIが制限に引っかかっている場合は後者の「サービスアカウントの権限借用」を選定すれば良いでしょう。

今回は「リソースへの直接アクセス」の具体的な手順を見ていこうと思います。

前提

  • 基本的に公式ドキュメントの手順に則ります。
  • AWSアカウントとGoogle Cloudプロジェクトは既に作成しているものとします。
  • AWSのEC2からGoogle CloudのGCSへアクセスするシンプルな構成で考えます。
    • EC2は事前にCloud9*1で構築しておきます。IAMロールは後で使用するので、デフォルトのIAMロールではなく新規で作成しておきEC2インスタンスに紐つけておきます。
    • GCSバケットもデフォルト設定で事前に作成しておきます。バケット名は t3-kato-test-bucket としています。
  • Google Cloudプロジェクトにて以下のAPIを有効化しておきます。
    • IAM
    • Resource Manager
    • Service Account Credentials
    • Security Token Service API

具体的な手順

では、具体的な手順を見ていきましょう。以下の段取りで進めます。

  1. IAMロールの確認
  2. Workload Identityのリソース作成
  3. GCSの権限設定
  4. 疎通確認

1. IAMロールの確認

Workload Identity連携では特定のIAMロールからのアクセスに制限することが可能です。

後で必要になるため先にIAMロール名を控えておきます。

  • IAMロール名:t3-kato-test-workloadIdentity

なお、GCSへのアクセスのためにIAMロールに許可ポリシーを追加する必要はありません。

2. Workload Identityのリソース作成

続いて、Workload Identity周りのリソースを作成していきます。

作成するリソースは以下の2つです。

  • Workload Identityプール:外部IDを管理するエンティティ
  • Workload Identityプールプロバイダー:Google CloudとIdPの間の関係を記述するエンティティ

コンソールの「IAMと管理」から「Workload Identity連携」>「プールを作成」を選択し設定値を入力していきます。

まず、Workload Identityプールの設定です。以下の設定値を入力します。

  • Workload Identityプール名:t3-kato-test-pool

次に、Workload Identityプールプロバイダーの設定です。

  • プロバイダ:AWS
  • Workload Identityプールプロバイダー名:aws-provider
  • Workload IdentityプールプロバイダーID:aws-provider
  • AWSアカウントID:<AWSアカウントID>

Workload Identityプールプロバイダーでは「属性マッピング」と「属性条件」を設定することが出来ます。

属性マッピングは、外部トークンの属性をGoogle Cloudの認証トークン(Google Security Token Service トークン)に埋め込むための定義です。端的に言えば、AWSのリクエストが持つ情報をGoogle Cloud上で利用することが出来る、ということです。

この設定を利用して、IAMロール名をGoogle Cloudの認証トークンに埋め込みます。その上でリソース側(GCS側)で該当の属性に対して条件を設定しアクセス制限を行います。具体的な権限設定は"3. GCSの権限設定"で実施するので、ここでは属性マッピングの定義だけを行います。

また、今回は検証のためattribute.aws_roleのみ設定していますが(google.subjectは必須)、必要に応じて属性マッピングは追加することが出来ます。

  • 属性マッピング:
    • google.subject=assertion.arn
    • attribute.aws_role=assertion.arn.extract('assumed-role/{role}/')

属性条件は、属性をチェックする式です。特定の属性がtrueと評価された場合のみ認証情報を受け入れます。

  • 属性条件:
    • assertion.arn.startsWith('arn:aws:sts::<AWSアカウントID>:assumed-role/')

設定の入力が完了したら「保存」をクリックします。プールの詳細画面が表示されればOKです。

これでWorkload Identity周りのリソースの作成は完了です。

3. GCSの権限設定

次に、GCS側でWorkload Identity経由かつ特定のIAMロールのみアクセス出来るように権限を設定していきます。

冒頭で説明した「サービスアカウントの権限借用」とはこちらの手順が異なります。

コンソールの「Cloud Storage」から「バケット」>「バケットの詳細」>「権限」>「アクセス権を付与」を選択します。

プリンシパルには"2. Workload Identityのリソース作成"の属性マッピングで設定した属性のプリンシパルを設定します。フォーマットはこちらを参照ください。

  • プリンシパル:
    • principalSet://iam.googleapis.com/projects/<プロジェクト番号>/locations/global/workloadIdentityPools/t3-kato-test-pool/attribute.aws_role/t3-kato-test-workloadIdentity

ロールはとりあえずストレージ管理者とします。

  • ロール:ストレージ管理者

「保存」をクリックして完了です。

4. 疎通確認

最後に疎通確認です。EC2からGCSへアクセスしていきます。

4-1. 構成ファイルのダウンロード

まず、認証情報の構成ファイルをダウンロードします。

コンソールの「IAMと管理」から「Workload Identity連携」>「プールの詳細」>「接続済みサービスアカウント」>「構成ファイルをダウンロード」をクリックします。

"2. Workload Identityのリソース作成"で作成したプールプロバイダーを選択し「構成をダウンロード」をクリックします。

取得した構成ファイルは以下の通りです。こちらは秘匿情報ではないためセキュアに管理する必要はありません。(念の為Google Cloudプロジェクト番号は隠しています。)

{
  "universe_domain": "googleapis.com",
  "type": "external_account",
  "audience": "//iam.googleapis.com/projects/<プロジェクト番号>/locations/global/workloadIdentityPools/t3-kato-test-pool/providers/aws-provider",
  "subject_token_type": "urn:ietf:params:aws:token-type:aws4_request",
  "token_url": "https://sts.googleapis.com/v1/token",
  "credential_source": {
    "environment_id": "aws1",
    "region_url": "http://169.254.169.254/latest/meta-data/placement/availability-zone",
    "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials",
    "regional_cred_verification_url": "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15"
  }
}

4-2. EC2セットアップ

次に、EC2のセットアップを行います。

まずgcloudのインストールです。以下の手順に則りgcloudをインストールします。

cloud.google.com

検証時のgcloudのバージョンは以下の通りです。

Google Cloud SDK 477.0.0
bq 2.1.4
bundled-python3-unix 3.11.8
core 2024.05.17
gcloud-crc32c 1.0.0
gsutil 5.29

次に、先ほどダウンロードした構成ファイルをEC2に設置します。

$ cat clientLibraryConfig-aws-provider.json 
{
  "universe_domain": "googleapis.com",
  "type": "external_account",
  "audience": "//iam.googleapis.com/projects/<プロジェクト番号>/locations/global/workloadIdentityPools/t3-kato-test-pool/providers/aws-provider",
  "subject_token_type": "urn:ietf:params:aws:token-type:aws4_request",
  "token_url": "https://sts.googleapis.com/v1/token",
  "credential_source": {
    "environment_id": "aws1",
    "region_url": "http://169.254.169.254/latest/meta-data/placement/availability-zone",
    "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials",
    "regional_cred_verification_url": "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15"
  }

最後に、Google Cloudへの認証を行います。

gcloud auth loginを実行して認証を行うのですが、2024/8時点ではEC2のデフォルト設定だとgcloud auth loginを実行すると以下のエラーが出ます。

$ gcloud auth login --cred-file=clientLibraryConfig-aws-provider.json
ERROR: (gcloud.auth.login) There was a problem refreshing your current auth tokens: ('Unable to retrieve AWS region', '<?xml version="1.0" encoding="iso-8859-1"?>\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n\t"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n <head>\n  <title>401 - Unauthorized</title>\n </head>\n <body>\n  <h1>401 - Unauthorized</h1>\n </body>\n</html>\n')

これは、gcloudIMDSv2に対応していないためのようです。EC2のデフォルト設定ではインスタンスメタデータオプションでIMDSv2が「必須」となっているため、メタ情報の取得に失敗しエラーとなるようです。

github.com

こちらをOptionalに変更した上で、再度gcloud auth loginを実行します。

$ gcloud auth login --cred-file=clientLibraryConfig-aws-provider.json
Authenticated with external account credentials for: [principal://iam.googleapis.com/projects/<プロジェクト番号>/locations/global/workloadIdentityPools/t3-kato-test-pool/subject/arn:aws:sts::<AWSアカウントID>:assumed-role/t3-kato-test-workloadIdentity/i-0eeb513394e5c8a19].

認証が通りました!試しにGCSへファイルをアップロードしてみます。

$ gcloud storage cp upload-test.txt gs://t3-kato-test-bucket                                                                                                                                 
Copying file://upload-test.txt to gs://t3-kato-test-bucket/upload-test.txt
  Completed files 1/1 | 8.0B/8.0B     

$ gcloud storage ls gs://t3-kato-test-bucket
gs://t3-kato-test-bucket/upload-test.txt

アップロード出来てそうですね!

さいごに

Workload Identity連携についての記事は多くみられるのですが、「リソースへの直接アクセス」を検証している記事が少ないように思えたので、詳細手順をまとめてみました。

どなたかの役に立てば幸いです。

執筆者: 加藤 俊稀

🧑‍💻クラウドエンジニア / インフラエンジニア
📝https://tech.nri-net.com/archive/author/t3-kato