これは何?
AWS → Google Cloud へのリソースにアクセスするため、以下のリンクの通りに環境を構築し、EC2(AWS) → Cloud Storage(GCP)へアクセスできるかを検証してみました。
検証してみた結果、以下のように認証エラーとなりました。
$ gcloud storage ls
ERROR: (gcloud.storage.ls) 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')
$ gcloud storage ls
ERROR: (gcloud.storage.ls) There was a problem refreshing your current auth tokens: ('Error code invalid_grant: Received invalid AWS response of type SignatureDoesNotMatch with error message: Credential should be scoped to a valid region. ', '{"error":"invalid_grant","error_description":"Received invalid AWS response of type SignatureDoesNotMatch with error message: Credential should be scoped to a valid region. "}')
Please run:
原因としてはGoogle Cloud のサービスアカウントを借用するための認証用トークンの生成をインスタンスメタデータから生成するのですが、EC2のメタデータがIMDSv2であったため、Workload Identity のAWSプロバイダーでIMDSv2を有効にする必要があります。(IMDSv1に一時的に戻したら成功)
今回は、IMDSv2を有効化した状態で、GoogleCloudのリソースにアクセスする方法を解説します。
対処方法
Workload Identity のAWSプロバイダーでIMDSv2用の認証情報の構成ファイルを作成するひつようがあります。
gcloud iam workload-identity-pools create-cred-config
コマンドで、作成済みのAWSプロバイダーに対してIMDSv2用の構成ファイルを作成することができます。
gcloud iam workload-identity-pools create-cred-config \
projects/「プロジェクトナンバー」/locations/global/workloadIdentityPools/「Workload Identity IDプール」/providers/「Workload Identity プロバイダー」 \
--service-account=「サービスアカウントEメールアドレス」 \
--aws \
--enable-imdsv2 \
--output-file=output.json
また、Terraform で実施するには、local-execでgcloud iam workload-identity-pools create-cred-config ..
コマンドを実行するようにします。
// サービスアカウント
resource "google_service_account" "service_account" {
account_id = var.gcp_account_id
display_name = var.desplay_name
description = var.description
}
// サービスアカウント ロール
resource "google_project_iam_member" "role" {
for_each = toset(var.sa_roles)
role = each.value # "roles/storage.admin" etc ..
project = var.gcp_pj_id
member = "serviceAccount:${google_service_account.service_account.email}"
}
// Workload Identity ユーザープール
resource "google_iam_workload_identity_pool" "aws" {
project = var.gcp_pj_id
workload_identity_pool_id = "aws-id-pool"
display_name = "aws-id-pool"
description = "ID Pool for AWS"
}
// Workload Identity ユーザープール プロバイダー
resource "google_iam_workload_identity_pool_provider" "aws" {
workload_identity_pool_id = google_iam_workload_identity_pool.aws.workload_identity_pool_id
workload_identity_pool_provider_id = "aws-provider"
display_name = "aws-provider"
description = "Provider for AWS"
aws {
account_id = var.aws_account_id
}
}
// 認証情報ファイル生成 (INDSv2)
resource "null_resource" "imdsv2" {
provisioner "local-exec" {
command = "gcloud iam workload-identity-pools create-cred-config ${google_iam_workload_identity_pool_provider.aws.id} --service-account=${google_service_account.service_account.email} --aws --enable-imdsv2 --output-file=output_credential.json"
}
depends_on = [google_iam_workload_identity_pool_provider.aws]
}
# サービスアカウント 借用
resource "google_service_account_iam_binding" "aws_sa_role_binging" {
service_account_id = var.service_account_name
role = "roles/iam.workloadIdentityUser"
members = [
"principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.aws.id}/*"
]
}
上記のように実施することで、作成済みのAWSプロバイダーに対してIMDSv2用の構成ファイルを作成することができました。