デモのデプロイ

デモのデプロイでは、事前定義された未加工のサンプル データセットを使用して、効率的なエクスペリエンスを提供します。オーケストレーション用に Cortex Framework Dataform パイプラインをデプロイし、対応する BigQuery データセットをサンプルデータで初期化するエンドツーエンドのワークフローを提供します。

始める前に

デモのデプロイを続行する前に、前提条件ページに記載されている前提条件を満たしていることを確認してください。

必要な IAM ロールと権限を取得する

ターゲットの Google Cloud プロジェクト内に Cortex Framework コンテンツをデプロイするために必要な Identity and Access Management(IAM)権限を取得します。

ターゲット プロジェクトのロール

Cortex Framework のデプロイに必要な権限を取得するには、ターゲット プロジェクトに対する次の IAM ロールを付与するよう管理者に依頼してください。

ロールの付与については、プロジェクト、フォルダ、組織へのアクセスを管理するをご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

コマンドを使用してトリガーできます。

リクエストされたロールをユーザーに付与するには、次のスクリプトを使用します。

# Grant BigQuery JobUser to the user
gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_EMAIL" \
        --role="roles/bigquery.jobUser"

# Grant BigQuery DataEditor to the user
gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_EMAIL" \
        --role="roles/bigquery.dataEditor"

# Grant BigQuery Dataform admin to the user
gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_EMAIL" \
        --role="roles/dataform.admin"

# Grant Service Usage Consumer to the user
gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_EMAIL" \
        --role="roles/serviceusage.serviceUsageConsumer"

省略可: サービス アカウントを使用してデモ デプロイに必要な IAM ロールを取得する

次のロールは、オプションの --service_account パラメータが有効になっているデモ環境のデプロイでのみ必要です。サービス アカウントを指定すると、データ パイプラインのスケジューリングが設定されるため、デプロイ後のタスクが簡素化されます。このワークフロー構成は、Dataform の [リリースとスケジューリング] タブで、3 つのドットメニューを使用して手動でトリガーできます。

Cortex Framework のデモをデプロイするために必要な権限を取得するには、ソース プロジェクトとターゲット プロジェクトに対するサービス アカウント トークン作成者 roles/iam.serviceAccountTokenCreator)IAM ロールを付与するよう管理者に依頼してください。ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

サービス アカウントを作成して必要なロールを付与するには、次のスクリプトを使用します。

# Create the service account
gcloud iam service-accounts create cortex-dataform \
        --description="Service account for Cortex Dataform execution" \
        --display-name="Cortex Dataform Service Account" \
        --project=PROJECT_ID

# Wait for the service account to propagate (IAM eventual consistency)
sleep 10

# Grant BigQuery DataEditor to the service account
gcloud projects add-iam-policy-binding PROJECT_ID \
        --member="serviceAccount:cortex-dataform@PROJECT_ID.iam.gserviceaccount.com" \
        --role="roles/bigquery.dataEditor"

# Grant BigQuery jobUser to the service account
gcloud projects add-iam-policy-binding PROJECT_ID \
        --member="serviceAccount:cortex-dataform@PROJECT_ID.iam.gserviceaccount.com" \
        --role="roles/bigquery.jobUser"

# Grant Dataform Editor to the service account
gcloud projects add-iam-policy-binding PROJECT_ID \
        --member="serviceAccount:cortex-dataform@PROJECT_ID.iam.gserviceaccount.com" \
        --role="roles/dataform.editor"

# Grant the user Service Account Token Creator role on the Cortex service account
gcloud iam service-accounts add-iam-policy-binding \
        cortex-dataform@PROJECT_ID.iam.gserviceaccount.com \
        --member="user:USER_EMAIL" \
        --role="roles/iam.serviceAccountTokenCreator" \
        --project=PROJECT_ID

PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format="value(projectNumber)")

## Note: In case the commands below should fail with message: 
# "serviceAccount:service-$PROJECT_NUMBER@gcp-sa-dataform.iam.gserviceaccount.com" not found
# the default dataform service accounts hasn't been yet provisioned for given project.
# In such case, please execute the commands after initial run of `uv run cortex-*`

# Grant the Dataform Service Account the Token Creator role on the Cortex service account
gcloud iam service-accounts add-iam-policy-binding \
        cortex-dataform@PROJECT_ID.iam.gserviceaccount.com \
        --member="serviceAccount:service-$PROJECT_NUMBER@gcp-sa-dataform.iam.gserviceaccount.com" \
        --role="roles/iam.serviceAccountTokenCreator" \
        --project=PROJECT_ID

# Grant the Dataform Service Account the Service Account User role on the Cortex service account
gcloud iam service-accounts add-iam-policy-binding \
        cortex-dataform@PROJECT_ID.iam.gserviceaccount.com \
        --member="serviceAccount:service-$PROJECT_NUMBER@gcp-sa-dataform.iam.gserviceaccount.com" \
        --role="roles/iam.serviceAccountUser" \
        --project=PROJECT_ID

デプロイ

仮想 Python 環境を作成し、依存関係を同期して、データ パイプラインをトリガーする手順は次のとおりです。Cortex Framework の uv スクリプトを使用して、データアセットを Google Cloud プロジェクトにビルドして push し、ローカル構成をライブでスケーラブルなデータ アーキテクチャに変換してください。詳細については、前提条件セクションの uv のインストールをご覧ください。

デモのデプロイを実行する

次のコマンドを実行して、デプロイをトリガーします。このプロセスでは、次のアクションが実行されます。

  • すべての前提条件が満たされていることを確認します。
  • デモンストレーション用に、サンプルデータを BigQuery データセットに読み込んで、未加工レイヤとして使用します。
  • Cortex Framework データレイヤを介してサンプルデータを処理する Dataform パイプラインを構築します。
  • Dataform リポジトリとワークスペースを作成し、コンパイルされたアーティファクトをリポジトリと同期します。*省略可: サービス アカウントに --service_account が指定されている場合は、ワークフロー スケジュールを作成し、最初の Dataform ワークフローの実行をトリガーします。

デフォルト値でデモ デプロイを行うには、次のコマンドを実行します。

uv run cortex-demo --project_id=PROJECT_ID --sap_version s4

サービス アカウントを使用したデモ デプロイの場合は、次のコマンドを実行します。

uv run cortex-demo --project_id=PROJECT_ID \
  --service_account="cortex-dataform@PROJECT_ID.iam.gserviceaccount.com" \
  --create_workflow_configs 

検証

デプロイが完了したら:

  1. Dataform を開いて、リポジトリに作成された新しいコードを調べます。

    1. Dataform リポジトリが作成されました: cortex-framework-demo
    2. Dataform 開発ワークスペースを作成しました: demo
    3. コンパイルされ同期されたコード。
  2. Dataform アクションの手動実行:

    1. Google Cloud Dataform コンソールで、リポジトリ cortex-framework-demodemo Dataform ワークスペースを開きます。
    2. [実行を開始] をクリックします。
    3. [操作を実行] をクリックします。
    4. [すべてのアクション] をクリックします。
    5. [実行を開始] をクリックします。

    6. [ワークフロー実行ログ] タブを使用して、Dataform リポジトリ内のすべてのアクションの実行が成功したかどうかをモニタリングします。

  3. スケジュールされた Dataform アクションの実行

デプロイ時に --service_account パラメータと --create_workflow_configs パラメータを使用していた場合にのみ適用されます。

  1. Google Cloud Dataform コンソールで Dataform リポジトリ cortex-framework-demo を開きます。
  2. [リリースとスケジュール] をクリックします。
  3. [ワークフロー構成] セクションで、実行するアクションのその他メニューをクリックし、[今すぐ開始] をクリックします。

  4. [ワークフロー実行ログ] タブを使用して、Dataform リポジトリ内のすべてのアクションの実行が成功したかどうかをモニタリングします。

  5. BigQuery コンソールに移動して、作成したデータセットを表示し、スキーマとデータを確認します。作成したデータセット:

    • cortex_demo_sap_s4_raw: このデータセットには、ソースシステム(この例では SAP S/4HANA)の元データが含まれています。
    • cortex_demo_sap_s4_data_foundation: このデータセットは、データ基盤レイヤを表します。このレイヤでは、元データレイヤの元データが CDC 処理されます。
    • cortex_demo_data_product: このデータセットには、エンドユーザーが使用するために設計された、デモ データ プロダクトの精製された高性能ビューまたはテーブルが含まれています。
    • cortex_demo_samples: このデータセットには、サンプル消費データ プロダクトのデモデータが含まれています。

デモ デプロイ リソースをクリーンアップする

デモのデプロイが正常に完了したら、使用した Google Cloud リソースを削除して、継続的な課金が発生しないようにします。次のスクリプトは、作成した BigQuery データセット、Dataform ワークスペース、Dataform リポジトリを削除します。

#!/bin/bash

# Define variables using names from uv-run-cortex-demo.md
PROJECT_ID="PROJECT_ID"
SAP_VERSION="s4"

DATAFORM_REGION="us-central1"
SOURCE_SAP_RAW_DATASET_ID="cortex_demo_sap_s4_raw"
TARGET_SAP_FOUNDATION_DATASET_ID="cortex_demo_sap_s4_data_foundation"
if [[ "$SAP_VERSION" == "ecc" ]]; then
  SOURCE_SAP_RAW_DATASET_ID="cortex_demo_sap_ecc_raw"
  TARGET_SAP_FOUNDATION_DATASET_ID="cortex_demo_sap_ecc_data_foundation"
fi
TARGET_DP_DATASET_ID="cortex_demo_data_product"
TARGET_SAMPLES_DATASET_ID="cortex_demo_samples"
REPOSITORY_NAME="cortex-framework-demo"
WORKSPACE_NAME="demo"
SERVICE_ACCOUNT_NAME="cortex-dataform"


# Color codes for formatting status output
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color

# Helper function to delete a resource and report status
delete_resource() {
    local label=$1
    local url=$2
    local resource_type=$3
    
    echo -n "${label}... "
    
    local temp_file=$(mktemp)
    local code=$(curl -s -o "${temp_file}" -w "%{http_code}" -X DELETE \
        -H "Authorization: Bearer ${ACCESS_TOKEN}" \
        "${url}")
        
    if [ "$code" -eq 200 ] || [ "$code" -eq 204 ]; then
        echo -e "${GREEN}ok${NC}"
    elif [ "$code" -eq 404 ]; then
        echo -e "${YELLOW}skipped, ${resource_type} not found${NC}"
    else
        echo -e "${RED}failed (HTTP ${code})${NC}"
        if [ -s "${temp_file}" ]; then
            echo "  Error details:"
            sed 's/^/    /' "${temp_file}"
        fi
    fi
    rm -f "${temp_file}"
}

echo "Deleting BigQuery datasets..."
for DATASET_ID in "${SOURCE_SAP_RAW_DATASET_ID}" \
                  "${TARGET_SAP_FOUNDATION_DATASET_ID}" \
                  "${TARGET_DP_DATASET_ID}" \
                  "${TARGET_SAMPLES_DATASET_ID}"; do
    echo "deleting ${PROJECT_ID}:${DATASET_ID}"
    bq rm -r -f "${PROJECT_ID}:${DATASET_ID}"
done

ACCESS_TOKEN=$(gcloud auth print-access-token)
delete_resource "Deleting Dataform workspace ${WORKSPACE_NAME}" \
    "https://dataform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${DATAFORM_REGION}/repositories/${REPOSITORY_NAME}/workspaces/${WORKSPACE_NAME}" \
    "workspace"

echo "Deleting Dataform workflow configurations..."
WORKFLOW_CONFIGS_JSON=$(curl -s -H "Authorization: Bearer ${ACCESS_TOKEN}" \
    "https://dataform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${DATAFORM_REGION}/repositories/${REPOSITORY_NAME}/workflowConfigs")

WORKFLOW_CONFIGS=$(echo "${WORKFLOW_CONFIGS_JSON}" | grep '"name":' | sed -E 's/.*"name": "([^"]+)".*/\1/')

if [ -z "${WORKFLOW_CONFIGS}" ]; then
    echo -e "  No workflow configurations found. ${YELLOW}skipped${NC}"
else
    for config in ${WORKFLOW_CONFIGS}; do
        delete_resource "  Deleting workflow config: ${config##*/}" \
            "https://dataform.googleapis.com/v1beta1/${config}" \
            "workflow config"
    done
fi

echo "Deleting Dataform release configurations..."
RELEASE_CONFIGS_JSON=$(curl -s -H "Authorization: Bearer ${ACCESS_TOKEN}" \
    "https://dataform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${DATAFORM_REGION}/repositories/${REPOSITORY_NAME}/releaseConfigs")

RELEASE_CONFIGS=$(echo "${RELEASE_CONFIGS_JSON}" | grep '"name":' | sed -E 's/.*"name": "([^"]+)".*/\1/')

if [ -z "${RELEASE_CONFIGS}" ]; then
    echo -e "  No release configurations found. ${YELLOW}skipped${NC}"
else
    for config in ${RELEASE_CONFIGS}; do
        delete_resource "  Deleting release config: ${config##*/}" \
            "https://dataform.googleapis.com/v1beta1/${config}" \
            "release config"
    done
fi

delete_resource "Deleting Dataform repository ${REPOSITORY_NAME}" \
    "https://dataform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${DATAFORM_REGION}/repositories/${REPOSITORY_NAME}?force=true" \
    "repository"

if gcloud iam service-accounts describe "${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" --project="${PROJECT_ID}" >/dev/null 2>&1; then
    read -p "Do you want to delete the service account ${SERVICE_ACCOUNT_NAME}? (y/N): " -r
    if [[ "$REPLY" =~ ^[Yy]$ ]]; then
        echo -n "Deleting service account ${SERVICE_ACCOUNT_NAME}... "
        ERROR_MSG=$(gcloud iam service-accounts delete "${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" --project="${PROJECT_ID}" --quiet 2>&1)
        EXIT_CODE=$?
        if [ ${EXIT_CODE} -eq 0 ]; then
            echo -e "${GREEN}ok${NC}"
        else
            echo -e "${RED}failed${NC}"
            echo "  Error details:"
            echo "${ERROR_MSG}" | sed 's/^/    /'
        fi
    else
        echo -e "Deleting service account ${SERVICE_ACCOUNT_NAME}... ${YELLOW}skipped (user cancelled)${NC}"
    fi
else
    echo -e "Deleting service account ${SERVICE_ACCOUNT_NAME}... ${YELLOW}skipped, service account not found${NC}"
fi

echo "Cortex Framework demo deployment cleanup complete."

次のステップ