🌊

BigLakeでGCSとAzure Blob Storageのデータを統合してみた

に公開

BigLake を使用すると、Google Cloud Storage(GCS)と Azure Blob Storage に保存されたデータを、BigQuery から直接クエリできます。本記事では、実際に動作する最小限の手順で BigLake テーブルを構築する方法を解説します。

BigLake とは

BigLake は、複数のクラウドストレージに分散したデータを BigQuery から直接クエリできる機能です。データの物理的な移動は不要で、以下のストレージに対応しています。

  • Google Cloud Storage(GCS)
  • Azure Blob Storage
  • AWS S3

本記事では GCS と Azure Blob Storage の統合を扱います。

前提条件

以下の準備が必要です。

  • Google Cloud プロジェクト
  • Azure サブスクリプション
  • gcloud CLI のインストール
  • Azure CLI のインストール
  • jq コマンドのインストール(JSON処理用)

実装手順

ステップ 1:Google Cloud の初期設定

# プロジェクトIDを設定(your-project-id を実際のIDに置き換え)
export PROJECT_ID="your-project-id"
gcloud config set project $PROJECT_ID

# 必要な API を有効化
gcloud services enable bigquery.googleapis.com
gcloud services enable bigqueryconnection.googleapis.com

# データセットを作成
bq mk --location=US biglake_demo

# GCS用のBigQuery接続リソースを作成
bq mk --connection \
    --location=US \
    --connection_type=CLOUD_RESOURCE \
    gcs_connection

# 接続のサービスアカウントを取得して変数に保存
export GCS_SERVICE_ACCOUNT=$(bq show --format=json --connection US.gcs_connection | jq -r '.cloudResource.serviceAccountId')
echo "GCS Service Account: $GCS_SERVICE_ACCOUNT"

ステップ 2:GCS にサンプルデータを準備

# GCS バケットを作成
export BUCKET_NAME="${PROJECT_ID}-biglake-demo"
gsutil mb -l us-central1 gs://${BUCKET_NAME}

# サービスアカウントにバケットへのアクセス権限を付与
gsutil iam ch serviceAccount:${GCS_SERVICE_ACCOUNT}:objectViewer gs://${BUCKET_NAME}

# サンプルデータ(売上データ)を作成
cat << EOF > sales_data.csv
transaction_id,customer_id,product_id,amount,transaction_date,region
TRX001,CUST001,PROD001,1500.00,2025-01-15,Tokyo
TRX002,CUST002,PROD002,2300.00,2025-01-15,Osaka
TRX003,CUST003,PROD001,1500.00,2025-01-16,Tokyo
TRX004,CUST001,PROD003,4200.00,2025-01-16,Kyoto
TRX005,CUST004,PROD002,2300.00,2025-01-17,Osaka
EOF

# GCS にアップロード
gsutil cp sales_data.csv gs://${BUCKET_NAME}/sales/

ステップ 3:GCS データの BigLake テーブルを作成

# BigLake テーブルを作成
bq query --use_legacy_sql=false "
CREATE OR REPLACE EXTERNAL TABLE \`${PROJECT_ID}.biglake_demo.gcs_sales_data\`
WITH CONNECTION \`US.gcs_connection\`
OPTIONS (
  format = 'CSV',
  uris = ['gs://${BUCKET_NAME}/sales/*.csv'],
  skip_leading_rows = 1
);"

# データを確認
bq query --use_legacy_sql=false \
"SELECT * FROM \`${PROJECT_ID}.biglake_demo.gcs_sales_data\` LIMIT 5"

ステップ 4:Azure Blob Storage の準備

# Azure にログイン
az login

# リソースグループを作成
export RESOURCE_GROUP="biglake-demo-rg"
az group create --name $RESOURCE_GROUP --location japaneast

# ストレージアカウントを作成(名前は一意である必要があります)
export STORAGE_ACCOUNT="biglake$RANDOM"
echo "Storage Account: $STORAGE_ACCOUNT"

az storage account create \
    --name $STORAGE_ACCOUNT \
    --resource-group $RESOURCE_GROUP \
    --location japaneast \
    --sku Standard_LRS

# コンテナを作成(ユーザーの認証情報を使用)
az storage container create \
    --name customer-data \
    --account-name $STORAGE_ACCOUNT \
    --auth-mode login

# サンプルデータ(顧客データ)を作成
cat << EOF > customer_data.csv
customer_id,customer_name,customer_segment,registration_date
CUST001,田中太郎,Premium,2024-01-10
CUST002,山田花子,Standard,2024-02-15
CUST003,鈴木一郎,Premium,2024-03-20
CUST004,佐藤美咲,Standard,2024-04-25
EOF

# Azure Blob Storage にアップロード(ユーザーの認証情報を使用)
az storage blob upload \
    --account-name $STORAGE_ACCOUNT \
    --container-name customer-data \
    --name customer_data.csv \
    --file customer_data.csv \
    --auth-mode login

ステップ 5:Azure 用の Workload Identity Federation を設定

# Azure テナントIDを取得
export TENANT_ID=$(az account show --query tenantId -o tsv)

# Azure AD アプリケーションを作成
export APP_NAME="biglake-app-${RANDOM}"
export APP_ID=$(az ad app create --display-name $APP_NAME --query appId -o tsv)
echo "Azure App ID: $APP_ID"

# サービスプリンシパルを作成
az ad sp create --id $APP_ID

# BigQuery 接続を作成(フェデレーション認証を使用)
bq mk --connection \
    --location=US \
    --connection_type=AZURE \
    --azure_tenant_id=${TENANT_ID} \
    --azure_federated_app_client_id=${APP_ID} \
    azure_connection

# 接続のサービスアカウント情報を取得
export AZURE_CONNECTION_INFO=$(bq show --format=json --connection US.azure_connection)
export SERVICE_ACCOUNT_ID=$(echo $AZURE_CONNECTION_INFO | jq -r '.azure.identity.uniqueId')
export SERVICE_ACCOUNT_EMAIL=$(echo $AZURE_CONNECTION_INFO | jq -r '.azure.identity.serviceAccountId')

echo "Service Account ID: $SERVICE_ACCOUNT_ID"
echo "Service Account Email: $SERVICE_ACCOUNT_EMAIL"

# Azure AD にフェデレーション認証情報を追加
cat << EOF > credential.json
{
  "name": "BigQueryConnection",
  "issuer": "https://accounts.google.com",
  "subject": "${SERVICE_ACCOUNT_ID}",
  "audiences": [
    "https://bigquery.googleapis.com/projects/${PROJECT_ID}/connections/US/azure_connection"
  ]
}
EOF

az ad app federated-credential create \
    --id $APP_ID \
    --parameters credential.json

# ストレージアカウントへのロールを割り当て
export SUBSCRIPTION_ID=$(az account show --query id -o tsv)
az role assignment create \
    --assignee $APP_ID \
    --role "Storage Blob Data Reader" \
    --scope "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Storage/storageAccounts/${STORAGE_ACCOUNT}"

echo "Azure setup completed. Waiting 30 seconds for propagation..."
sleep 30

ステップ 6:Azure データの BigLake テーブルを作成

# BigLake テーブルを作成
bq query --use_legacy_sql=false "
CREATE OR REPLACE EXTERNAL TABLE \`${PROJECT_ID}.biglake_demo.azure_customer_data\`
WITH CONNECTION \`US.azure_connection\`
OPTIONS (
  format = 'CSV',
  uris = ['https://${STORAGE_ACCOUNT}.blob.core.windows.net/customer-data/customer_data.csv'],
  skip_leading_rows = 1
);"

# データを確認
bq query --use_legacy_sql=false \
"SELECT * FROM \`${PROJECT_ID}.biglake_demo.azure_customer_data\` LIMIT 5"

ステップ 7:マルチクラウドデータの統合分析

# GCS と Azure のデータを結合して分析
bq query --use_legacy_sql=false "
SELECT
  s.transaction_date,
  s.region,
  c.customer_segment,
  COUNT(*) as transaction_count,
  SUM(s.amount) as total_sales,
  AVG(s.amount) as avg_amount
FROM \`${PROJECT_ID}.biglake_demo.gcs_sales_data\` s
LEFT JOIN \`${PROJECT_ID}.biglake_demo.azure_customer_data\` c
  ON s.customer_id = c.customer_id
GROUP BY s.transaction_date, s.region, c.customer_segment
ORDER BY transaction_date DESC, total_sales DESC;"

動作確認

以下のクエリで両方のテーブルからデータが取得できることを確認します。

# GCS のデータを確認
bq query --use_legacy_sql=false \
"SELECT COUNT(*) as gcs_record_count FROM \`${PROJECT_ID}.biglake_demo.gcs_sales_data\`"

# Azure のデータを確認
bq query --use_legacy_sql=false \
"SELECT COUNT(*) as azure_record_count FROM \`${PROJECT_ID}.biglake_demo.azure_customer_data\`"

# 結合結果を確認
bq query --use_legacy_sql=false "
SELECT
  s.customer_id,
  c.customer_name,
  c.customer_segment,
  SUM(s.amount) as total_purchase
FROM \`${PROJECT_ID}.biglake_demo.gcs_sales_data\` s
JOIN \`${PROJECT_ID}.biglake_demo.azure_customer_data\` c
  ON s.customer_id = c.customer_id
GROUP BY s.customer_id, c.customer_name, c.customer_segment
ORDER BY total_purchase DESC;"

まとめ

BigLake を使用することで、以下が実現できました。

  1. GCS のデータを BigQuery 接続リソース経由で BigLake テーブルとして参照
  2. Azure Blob Storage のデータを Workload Identity Federation による安全な認証で参照
  3. 異なるクラウドのデータを JOIN して統合分析

データの物理的な移動なしに、マルチクラウドのデータを BigQuery から直接分析できるのが BigLake の大きな利点です。特に、接続リソースを使用することで、適切な権限委任とセキュリティが確保されます。

参考資料

Discussion