演示部署

演示部署使用预定义的原始示例数据集,可提供简化的体验。它提供了一个端到端工作流,用于部署 Cortex Framework Dataform 流水线以进行编排,并使用示例数据初始化相应的 BigQuery 数据集。

准备工作

在继续进行演示部署之前,请确保您已完成前提条件页面上列出的前提条件。

获取所需的 IAM 角色和权限

获取所需的 Identity and Access Management (IAM) 权限,以便在目标 Google Cloud 项目中部署 Cortex Framework 内容。

目标项目的角色

如需获得部署 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 的发布和调度标签页中手动触发此工作流配置。

如需获得部署 Cortex Framework 演示版所需的权限,请让您的管理员为您授予源项目和目标项目的 Service Account Token Creator (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 项目,从而将本地配置转换为可伸缩的实时数据架构。如需了解详情,请参阅前提条件部分中的 uv 安装

执行演示部署

运行以下命令以触发部署。此流程将执行以下操作:

  • 确认已完成所有前提条件。
  • 将示例数据加载到 BigQuery 数据集中,以用作演示的原始层。
  • 构建 Dataform 流水线,以通过 Cortex Framework 数据层处理示例数据。
  • 创建 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-demo 中的 Dataform 工作区“demo”。
    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."

后续步骤