Managed Service for Apache Spark を使用すると、Spark ワークロードから外部のビジネスデータを直接クエリして分析できます。Workday Live Data Query JDBC ドライバを使用すると、Workday テナントに接続し、ライブ Workday データセットを Spark DataFrame に読み込んで、そのデータを Google Cloudの分析パイプラインに統合できます。
このガイドでは、Workday Live Data Query を構成し、秘密鍵を Secret Manager に安全に保存します。また、Google Cloud Data Agent Kit 拡張機能を使用して、Visual Studio Code または Cloud Shell エディタで PySpark ノートブックを Managed Service for Apache Spark に対して実行します。
費用
Data Agent Kit 拡張機能は追加料金なしでご利用いただけます。ただし、このガイドでは、課金対象である次の Google Cloudコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
始める前に
- Google Cloud アカウントにログインします。 Google Cloudを初めて使用する場合は、 アカウントを作成して、実際のシナリオで Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that you have the permissions required to complete this guide.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Dataproc, Dataplex, Cloud Storage, and Secret Manager APIs, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that you have the permissions required to complete this guide.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Dataproc, Dataplex, Cloud Storage, and Secret Manager APIs, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.
必要な Identity and Access Management(IAM)ロール
このページの例を実行するには、特定の IAM ロールが必要です。組織のポリシーによっては、これらのロールがすでに付与されている場合があります。ロールの付与を確認するには、ロールを付与する必要があるかどうかをご覧ください。ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。
必要なロールは、ワークロードの実行方法によって異なります。Managed Service for Apache Spark サーバーレス 2.3 以前のサーバーレス ランタイムは、サービス アカウントとしてワークロードを実行します。Managed Service for Apache Spark サーバーレス ランタイム 3.0 以降は、デフォルトでエンドユーザー認証情報(EUC)を使用してワークロードを実行します。そのため、サービス アカウントではなくユーザー アカウントにデータアクセス ロールを付与します。3.0 以降のランタイムにカスタム サービス アカウントを指定すると、ワークロードはサービス アカウントの認証情報を使用して実行されます。詳細については、サーバーレス デプロイのロールをご覧ください。
ユーザーロール
Managed Service for Apache Spark のインタラクティブ ノートブック セッションを作成してリソースにアクセスするために必要な権限を取得するには、次の IAM ロールを付与するよう管理者に依頼してください。
-
サーバーレス ランタイム 2.3 以前を使用します。
- プロジェクトに対する Dataproc 編集者 (
roles/dataproc.editor) - Compute Engine のデフォルトのサービス アカウントまたはカスタム サービス アカウントに対するサービス アカウント ユーザー (
roles/iam.serviceAccountUser)
- プロジェクトに対する Dataproc 編集者 (
-
サーバーレス ランタイム 3.0 以降を使用する: プロジェクトに対する Dataproc Serverless 編集者(
roles/dataproc.serverlessEditor) -
エンドユーザーの認証情報を使用して Cloud Storage から JDBC ドライバを読み取る: ドライバを含むバケットに対する Storage オブジェクト閲覧者(
roles/storage.objectViewer) -
エンドユーザーの認証情報を使用して Secret Manager から秘密鍵のシークレットを読み取る: シークレットまたはプロジェクトに対する Secret Manager のシークレット アクセサー(
roles/secretmanager.secretAccessor)
サービス アカウントのロール
ワークロードを実行するサービス アカウントに次のロールを付与します。Managed Service for Apache Spark サーバーレス ランタイム 3.0 以降では、ワークロードがデフォルトのエンドユーザー認証情報(EUC)ではなくサービス アカウント認証情報で実行される場合にのみ、これらのロールが必要です。
Compute Engine のデフォルト サービス アカウントまたはカスタム サービス アカウントに、Managed Service for Apache Spark ワークロードの実行、ドライバの読み取り、シークレットへのアクセスに必要な権限が付与されるようにするには、Compute Engine のデフォルト サービス アカウントまたはカスタム サービス アカウントに次の IAM ロールを付与するよう管理者に依頼してください。
-
サーバーレス ランタイム 2.3 以前を使用する: プロジェクトに対する Dataproc ワーカー(
roles/dataproc.worker) -
デフォルトのエンドユーザー認証情報(EUC)の代わりに、サービス アカウントの認証情報でサーバーレス ランタイム 3.0 以降を使用します。
- プロジェクトに対する Dataproc Serverless ノード(
roles/dataproc.serverlessNode) - プロジェクトに対する Dataproc Resource Manager ノード サービス エージェント(
roles/dataprocrm.nodeServiceAgent)
- プロジェクトに対する Dataproc Serverless ノード(
-
Cloud Storage から JDBC ドライバを読み取る: ドライバを含むバケットに対する Storage オブジェクト閲覧者(
roles/storage.objectViewer) -
Secret Manager から秘密鍵シークレットを読み取る: シークレットまたはプロジェクトに対する Secret Manager のシークレット アクセサー(
roles/secretmanager.secretAccessor)
Workday の前提条件
Live Data Query を使用して Workday に接続する前に、次の設定を完了します。
Workday から Workday Live Data Query JDBC ドライバをダウンロードします。
ダウンロードした JDBC ドライバの JAR ファイルを、プロジェクトの Cloud Storage バケットにアップロードします。
Workday Live Data Query のドキュメントの説明に沿って、Workday テナントで Live Data Query を設定するための構成手順を完了します。
Workday での構成中に、統合システム ユーザー(ISU)を作成し、API クライアントを登録して、秘密鍵ペアを生成します。
次の Workday 構成値をメモします。
Workday ホスト: Workday テナントホスト(例:
services1.workday.com)。テナント名: Workday のテナント名。
クライアント ID: Workday テナントの登録済み API クライアント ID。
ISU ユーザー名: 統合システム ユーザーのユーザー名。
秘密鍵を Secret Manager に保存する
Workday Live Data Query の構成中に生成された秘密鍵ファイルを Secret Manager に安全に保存します。
Cloud Shell で次のコマンドを実行して、x509 鍵ペアを生成します。
openssl req -x509 -newkey rsa:2048 -keyout private-key.pem -out public-key.cert -sha256 -days 365 -nodes秘密鍵を表示するには、次のコマンドを実行します。
cat private-key.pem秘密鍵を Secret Manager に保存します。
Google Cloud コンソールで、[Secret Manager] ページに移動します。
[シークレットの作成] をクリックします。
[名前] フィールドに、シークレットの名前を入力します(例:
workday-private-key)。[シークレットの値] で、
private-key.pemをアップロードするか、秘密鍵の内容(-----BEGIN PRIVATE KEY-----ヘッダー行と-----END PRIVATE KEY-----フッター行を含む)を貼り付けます。[シークレットの作成] をクリックします。
公開鍵を表示するには、次のコマンドを実行します。
cat public-key.certWorkday で [Create x509 Public Key] を検索し、
public-key.certの公開鍵を貼り付けて [OK] をクリックします。先ほど作成した Workday API クライアントで、[x509 Certificate] を新しい x509 鍵に更新します。
IDE で Data Agent Kit を設定する
Data Agent Kit を設定するには、Visual Studio Code またはサポートされている別の IDE に拡張機能をインストールするか、Cloud Shell エディタにプリインストールされている拡張機能を使用します。
IDE または Cloud Shell エディタで Data Agent Kit を構成する手順は次のとおりです。
Data Agent Kit を設定して構成します。
ノートブックを作成する
Data Agent Kit を使用して、インタラクティブな PySpark ノートブックを作成します。
IDE または Cloud Shell エディタで、[Data Agent Kit] パネルを開きます。
[Apache Spark] で [New Notebook] を選択し、[Local Kernel] を選択します。
利用可能なランタイム(セッション テンプレートとも呼ばれます)のリストからランタイムを選択します。
[新しいノートブックから始める] を選択します。
新しいノートブックが開き、Spark Connect セッション初期化コードが入力された初期セルが表示されます。
ノートブック エディタの上部にある [Select Kernel] をクリックし、ノートブックのローカル Python カーネルを選択します。
PySpark で Workday データをクエリする
ノートブックの最初のセルで、必要なクライアント ライブラリをインストールし、環境変数を設定します。
%pip install dataproc-spark-connect google-cloud-dataproc google-cloud-secret-manager google-cloud-storage #@title Set up all environment variables # Replace with your Project ID %env PROJECT_ID=PROJECT_ID # Replace with the name of the Secret Manager global secret in the project %env SECRET_NAME=workday-private-key # Replace with the version of the secret to use %env SECRET_VERSION=latest # Replace with the Cloud Storage bucket where you have the Workday Data Cloud JDBC Driver file stored %env JDBC_DRIVER_GCS_BUCKET=BUCKET_NAME # Replace with the name of the Workday Data Cloud JDBC Driver file in the Cloud Storage bucket %env JDBC_DRIVER_FILE_NAME=ldq-jdbc-driver-1.1.0-all.jar # Replace with the local directory of the notebook to copy the JDBC Driver File to %env JDBC_DRIVER_LOCAL_DIRECTORY=/tmp # Replace with the Driver Class for the Workday Data Cloud JDBC Driver %env WORKDAY_DRIVER_CLASS=com.workday.ldq.jdbc.Driver # ------------------------------------------------------------------------------ # Replace with the Workday URL of your tenant %env WORKDAY_HOST=WORKDAY_HOST # Replace with your Workday tenant name %env TENANT_NAME=TENANT_NAME # Replace with the Client ID of the "API Client" %env CLIENT_ID=CLIENT_ID # Replace with the Integration System User username %env ISU_USERNAME=ISU_USERNAME新しいセルで、Compute Engine のデフォルト サービス アカウントに Secret Manager Secret アクセサーのロール(
roles/secretmanager.secretAccessor)を付与します。%%bash COMPUTE_ENGINE_DEFAULT_SERVICE_ACCOUNT=$(gcloud iam service-accounts list --project="${PROJECT_ID}" \ --filter="email ~ -compute@developer.gserviceaccount.com" \ --format="value(email)") echo "COMPUTE_ENGINE_DEFAULT_SERVICE_ACCOUNT: ${COMPUTE_ENGINE_DEFAULT_SERVICE_ACCOUNT}" gcloud secrets add-iam-policy-binding ${SECRET_NAME} \ --project="${PROJECT_ID}" \ --member="serviceAccount:${COMPUTE_ENGINE_DEFAULT_SERVICE_ACCOUNT}" \ --role="roles/secretmanager.secretAccessor"新しいセルで、JDBC ドライバを Cloud Storage からローカル ディレクトリにコピーします。
gsutil cp gs://$JDBC_DRIVER_GCS_BUCKET/$JDBC_DRIVER_FILE_NAME $JDBC_DRIVER_LOCAL_DIRECTORY新しいセルで、Secret Manager クライアント ライブラリをインストールします。
%%bash pip install google-cloud-secret-manager新しいセルで、ドライバの JAR ファイルがローカルにダウンロードされていることを確認します。
!gsutil cp gs://$JDBC_DRIVER_GCS_BUCKET/$JDBC_DRIVER_FILE_NAME /tmp/ !ls -lh /tmp/ldq-jdbc-driver-1.1.0-all.jar新しいセルで、Workday ドライバ JAR を PySpark jars ディレクトリに挿入します。
%%bash echo "Downloading Workday JAR from Cloud Storage..." # Downloads your specific 1.1.0 driver JAR into the notebook's /tmp folder gcloud storage cp gs://$JDBC_DRIVER_GCS_BUCKET/$JDBC_DRIVER_FILE_NAME /tmp/ echo "Dynamically finding the PySpark jars directory..." PYSPARK_JARS=$(python -c "import os, pyspark; print(os.path.join(os.path.dirname(pyspark.__file__), 'jars'))") echo "Found PySpark jars at: $PYSPARK_JARS" echo "Injecting Workday driver into PySpark core..." cp /tmp/$JDBC_DRIVER_FILE_NAME "$PYSPARK_JARS/" echo "Success! The driver is now a native part of PySpark."新しいセルで、Spark 環境を構成し、Secret Manager から x509 秘密鍵を取得します。
#@title Configure the Spark environment and retrieve the x509 private key from Secret Manager import os import pyspark from pyspark.sql import SparkSession from google.cloud import secretmanager PROJECT_ID = os.environ["PROJECT_ID"] SECRET_NAME = os.environ["SECRET_NAME"] SECRET_VERSION = os.environ["SECRET_VERSION"] JDBC_DRIVER_LOCAL_DIRECTORY = os.environ["JDBC_DRIVER_LOCAL_DIRECTORY"] JDBC_DRIVER_FILE_NAME = os.environ["JDBC_DRIVER_FILE_NAME"] LOCAL_JAR_PATH = JDBC_DRIVER_LOCAL_DIRECTORY + "/" + JDBC_DRIVER_FILE_NAME WORKDAY_HOST = os.environ["WORKDAY_HOST"] TENANT_NAME = os.environ["TENANT_NAME"] CLIENT_ID = os.environ["CLIENT_ID"] ISU_USERNAME = os.environ["ISU_USERNAME"] WORKDAY_DRIVER_CLASS = os.environ["WORKDAY_DRIVER_CLASS"] jdbc_url = f"jdbc:workday://{WORKDAY_HOST}:443/system/information_schema?SSLVerification=CA" def access_private_key_secret(): print(f"Fetching secret contents from Secret Manager: {SECRET_NAME}...") client = secretmanager.SecretManagerServiceClient() secret_name = f"projects/{PROJECT_ID}/secrets/{SECRET_NAME}/versions/{SECRET_VERSION}" response = client.access_secret_version(request={"name": secret_name}) print(f"Fetched secret contents from Secret Manager: {SECRET_NAME}") return response.payload.data.decode("UTF-8") private_key_content = access_private_key_secret()新しいセルで、クラスパス構成を使用して Spark セッションを初期化します。
# Stop the old cached Spark session so your newly downloaded JAR is not ignored! try: spark.stop() print("Stopped existing Spark session.") except Exception: pass print("Initializing fresh Spark session with Classpath configuration...") print(f"Loading JAR from: {LOCAL_JAR_PATH}") # Rebuild Spark session with explicit Driver & Executor classpaths spark = SparkSession.builder \ .appName("WorkdayJDBC Connection Example") \ .config("spark.jars", LOCAL_JAR_PATH) \ .config("spark.driver.extraClassPath", LOCAL_JAR_PATH) \ .config("spark.executor.extraClassPath", LOCAL_JAR_PATH) \ .getOrCreate() print("Spark Session successfully booted with JAR!")最後のセルで、接続を開始して Workday にクエリを実行します。
import os import subprocess import zipfile from pyspark.sql import SparkSession LOCAL_JAR_PATH = "/tmp/ldq-jdbc-driver-1.1.0-all.jar" # Load bucket and file name from your Cell 1 environment variables GCS_BUCKET = os.environ.get("JDBC_DRIVER_GCS_BUCKET", "BUCKET_NAME") GCS_FILE = os.environ.get("JDBC_DRIVER_FILE_NAME", "ldq-jdbc-driver-1.1.0-all.jar") GCS_URI = f"gs://{GCS_BUCKET}/{GCS_FILE}" # 1. Ensure the JAR file is in the notebook's /tmp directory if not os.path.exists(LOCAL_JAR_PATH): print(f"Downloading {GCS_URI} to {LOCAL_JAR_PATH}...") subprocess.run(["gsutil", "cp", GCS_URI, LOCAL_JAR_PATH], check=True) print(f"JAR verified on disk: {LOCAL_JAR_PATH} ({os.path.getsize(LOCAL_JAR_PATH):,} bytes)") # 2. Read the real JDBC driver class name (skipping any '#' comment lines!) with zipfile.ZipFile(LOCAL_JAR_PATH, "r") as z: raw_lines = ( z.read("META-INF/services/java.sql.Driver") .decode("utf-8") .splitlines() ) # Filter out empty lines and '#' comment lines valid_classes = [ line.strip() for line in raw_lines if line.strip() and not line.strip().startswith("#") ] driver_class = valid_classes[0] print(f"Real Driver Class inside JAR: {driver_class}") # 3. Get or create the Spark session spark = SparkSession.builder.appName("WorkdayJDBC Connection Example").getOrCreate() # 4. Inject the JAR directly into the running Java URLClassLoader (and Scala SparkContext) jvm = spark.sparkContext._jvm jar_url = jvm.java.io.File(LOCAL_JAR_PATH).toURI().toURL() # Add to both the Spark classloader and the current thread's context classloader jvm.org.apache.spark.util.Utils.getContextOrSparkClassLoader().addURL(jar_url) jvm.java.lang.Thread.currentThread().getContextClassLoader().addURL(jar_url) spark.sparkContext._jsc.sc().addJar(LOCAL_JAR_PATH) # Register the driver class with Spark's JDBC DriverRegistry jvm.org.apache.spark.sql.execution.datasources.jdbc.DriverRegistry.register(driver_class) print(f"Successfully registered {driver_class} in Spark's live JVM!") # 5. Query Workday print("Querying Workday...") df_data = ( spark.read.format("jdbc") .option("driver", driver_class) .option("url", jdbc_url) .option("wd.authn.clientId", CLIENT_ID) .option("wd.authn.isu", ISU_USERNAME) .option( "wd.authn.accessTokenEndpoint", f"https://{WORKDAY_HOST}/ccx/oauth2/{TENANT_NAME}/token", ) .option("wd.authn.privateKey", private_key_content) .option("query", "SELECT * FROM system.jdbc.catalogs") .load() ) print("Connection Successful! Data Retrieved:") df_data.show(50, truncate=False)次のように置き換えます。
PROJECT_ID: 実際の Google Cloud プロジェクト ID。LOCATION: Managed Service for Apache Spark セッション テンプレートの Google Cloud リージョン(例:us-central1)。RUNTIME_ID: Managed Service for Apache Spark セッション テンプレートの ID。BUCKET_NAME: Workday JDBC ドライバを含む Cloud Storage バケットの名前。PATH/workday-live-data-query-jdbc-driver.jar: Cloud Storage バケット内の Workday JDBC ドライバ JAR のオブジェクト パス。WORKDAY_HOST: Workday テナントホスト(例:services1.workday.com)。TENANT_NAME: Workday テナント名。CLIENT_ID: Workday テナントから登録された API クライアント ID。ISU_USERNAME: Workday テナントの統合システム ユーザーのユーザー名。
セルの横にある [Execute Cell](再生アイコン)をクリックするか、Shift+Enter キーを押します。
Managed Service for Apache Spark がクエリを実行し、セルの下に Workday DataFrame の出力が表示されます。
クリーンアップ
このガイドで使用したリソースについて Google Cloud アカウントに課金されないようにするには、アクティブなインタラクティブ セッションを終了するか、作成したリソースを削除します。
インタラクティブ セッションの終了
IDE または Cloud Shell Editor で、ワークロードが終了したらアクティブなノートブック セッションを終了します。
省略可: 不要になった Cloud Storage バケットまたは JDBC ドライバ JAR ファイルを削除します。
省略可: 不要になったシークレットを Secret Manager から削除します。
gcloud secrets delete workday-private-key
次のステップ
Data Agent Kit の詳細を確認する。
Spark JDBC 接続オプションについて読む。