チュートリアル:Fabricにおけるエンドツーエンドの自動化

このチュートリアルでは、インフラストラクチャをコードとして使ってMicrosoft Fabricの完全で繰り返し可能なリリースフローを構築します。 Terraformで2つのワークスペース(devとtest)をプロビジョニングし、DevワークスペースをGitに接続し、devでアイテムを作成し、それをfabric-cicd Pythonライブラリでテストにプロモートします。 すべては単一のサービスプリンシパルの下で動作しているので、今日のノートパソコンでも明日のCI/CDパイプラインでも同じ流れが使えます。

このチュートリアルでは、次の操作を行います。

  • Terraformで開発・テストワークスペース、Git接続、ロール割り当てをプロビジョニングできます。
  • dev workspace を Azure DevOps Git リポジトリに接続してください。
  • 開発環境でノートブックとレイクハウスを作成し、それらをGitにコミットしてください。
  • fabric-cicd を使用して、コンテンツを dev から test 環境へ昇格してください。
  • デプロイ済みノートブックがテスト用レイクハウスにリバウンドされているか確認してください。

二つの飛行機、二つの道具

Fabricリリースの自動化には2つの明確な懸念があり、それらを分けておくことが役立ちます。安定したコントロールプレーン(コンテンツが存在するインフラ)と揮発性データプレーン(毎日編集するコンテンツ)です。 デプロイツールは、各項目がどれくらい頻繁に変更されるかに合わせて調整してください。

Terraformで一度プロビジョニングされた制御面と、Gitおよびfabric-cicdを連続的に流れるデータプレーンを比較した図。

  • コントロールプレーンには 、一度だけプロビジョニングしほとんど変更しない不揮発性インフラが保管されています:容量、ワークスペースとその設定、ドメイン、接続、テナント設定、RBACやGit配線などです。 このチュートリアルでは、それを Terraform でプロビジョニングします。
  • データプレーンには 、各スプリントごとに進化しGitを流れるボラタイルなコンテンツ、ノートブック、レイクハウスやウェアハウス、セマンティックモデルやレポート、パイプラインやデータフロー、変数ライブラリの値などが収められています。 このチュートリアルでは fabric-cicdで移動させています。

指針としては、 安定したプラットフォームに一度Terraformを導入し、その後、揮発性アイテムをGitとfabric-cicdを通じて継続的に流すようにするというものです。

これはFabricの自動化の一つのアプローチであり、すでにインフラをコードとして扱い、スクリプト可能でソース制御型のセットアップを求めるチームに有利です。 FabricはポータルベースのデプロイパイプラインGit連携も提供しており、TerraformやPythonを書かずにUIから駆動できます。 オプションの比較については、FabricのCI/CDワークフローオプションをご覧ください。

データプレーン展開に関しては、 ファブリックCICDが一つの選択肢です。 ライブラリに依存しずに、作成、更新、削除のコールを完全に制御したいなら、Fabricのバルク(CRUD)REST APIを直接呼び出すこともできます。 このチュートリアルは環境特有の再バインド処理を行うためにfabric-cicdを使っています。

なぜコントロールプレーンにテラフォームを選ぶのか

  • 宣言的で冪能的です。 あなたは一度、作業スペースの望ましい状態を説明しました。Terraformは欠けている部分を作り、残りはそのままにします。
  • ドリフト検出。 terraform plan ライブテナントがあなたの真実の情報源とどのように異なるかを正確に示し、ポータルのバンド外の変化が可視化かつ元に戻せるようになります。
  • 多くのリソースを一つの提供者に提供できます。 Microsoft Fabricプロバイダーは、ワークスペース、キャパシティ、接続、Gitリンク、RBACをFabric REST APIを通じて管理します。

データプレーンに fabric-cicd を使う理由とは##

  • Fabricが期待する通りに展開します。 fabric-cicdはアイテムのGit表現を読み取り、正しい作成・更新の意味論で公開するため、RESTコールを手動ロールする必要がありません。
  • パラメータ化。 parameter.ymlファイルは、ノートブックのデフォルトレイクハウスやセマンティックモデルの接続を環境ごとに適切なターゲットに指し示すなど、環境固有の値を再割り当てします。
  • クリーンアップ。 Git から削除された項目を公開解除し、各環境が追跡対象のブランチを忠実に反映した状態に保つことができます。

エンドツーエンドのフロー

この二つの飛行機は一つの連続した自動化として一体化します。 プラットフォームを 一度プロビジョニングし、それ以降のすべてのコンテンツ変更は同じ繰り返しのループをたどります。エディターからGitを経てテスト環境へと移行し、手動ポータルのステップは一切ありません。

フロー図: Terraformはボックス(開発環境とテスト環境のプロビジョニング、開発環境のGitへの接続、RBAC)を作成し、その後、継続的インテグレーションで開発環境での作成作業、Gitへのコミット、Gitからの更新をカバーし、継続的デプロイでテスト環境へのデプロイと検証をカバーする繰り返しループがあります。

同じサービスプリンシパルがすべての段階を認証しているので、このチュートリアルで手動で実行するフローは、CI/CDパイプラインがあなたの代わりに実行するものとまったく同じです。プロ ビジョニング ステージ(Terraform)、その後 展開ステージ( ファブリックCICD)が続き、トラッキングブランチが変更されるたびに実行されます。 各ステージは以下のステップに対応しています:

段階 ツール チュートリアルステップ
プラットフォームのプロビジョニング(一度) Terraform ステップ 1
変更を書いてコミットする(CI) Fabric + Git ステップ2ステップ3
dev を test にデプロイ(CD) ファブリックCICD ステップ 4
結果を確認する 手順 5

Important

このエンドツーエンドの自動化は、開発ワークスペースとGitを サービスプリンシパルを介して非対話的に接続します。 同じサービスプリンシパルは関連するAzure DevOps組織、プロジェクト、リポジトリにもアクセス権を持っていなければならず、接続を確立し、あなたの代わりに同期を行えます。 サービスプリンシパルを使ってワークスペースをGitHubに接続することは現在サポートされていないため、このフローにはAzure DevOpsを使います。 ポータルベースのGit連携を通じてGitHubは使えますが、このチュートリアルの自動接続ステップは適用されません。

Prerequisites

  • Fabricの能力。 このチュートリアルの両ワークスペースは同じ容量に割り当てられています。 トライアル能力は有効です。
  • クライアント シークレットを備えたサービス プリンシパル(Microsoft Entra アプリの登録)。 この単一のアイデンティティがワークスペースのプロビジョニング デプロイメントを実行します。
  • テナント設定のサービスプリンシパルは、サービスプリンシパルを含むセキュリティグループで有効化されたFabric APIを使用できます。 詳細については、「Fabric APIのサービス主体認証を有効にする」をご覧ください。
  • サービスプリンシパルがアクセスできるAzure DevOps組織、プロジェクト、Gitリポジトリです。 リポジトリにはすでにブランチ(例:main)ado_directory_nameで設定したフォルダ(例:/workspace)が含まれている必要があります。 Git接続は PreferRemoteを使い、接続時にそのフォルダを読み込むので、両方とも事前に存在している必要があります。 フォルダが欠けている場合、terraform applyGitProviderResourceNotFoundで失敗します。 作成するには、Terraformを実行する前にブランチ上のそのパスに空のプレースホルダーファイル( .gitkeepなど)をコミットしてください。
  • 以下のツールはローカルにインストールされています:

Important

サービスプリンシパルは、そのキャパシティ上でワークスペースを作成するための十分な権限と、ワークスペース管理者として追加される権限が必要です。容量貢献者(または管理者)権限を付与し、上記のテナント設定で指定されたセキュリティグループに属していることを確認してください。

認証の設定

TerraformもFabric-cicdもサービスプリンシパルとして認証されています。 両方のツールが認証情報を取得できるように環境変数としてエクスポートしてください:

export FABRIC_TENANT_ID="<tenant-id>"
export FABRIC_CLIENT_ID="<app-client-id>"
export FABRIC_CLIENT_SECRET="<client-secret>"

# fabric-cicd (via DefaultAzureCredential) reads the AZURE_* names:
export AZURE_TENANT_ID="$FABRIC_TENANT_ID"
export AZURE_CLIENT_ID="$FABRIC_CLIENT_ID"
export AZURE_CLIENT_SECRET="$FABRIC_CLIENT_SECRET"

Tip

パイプラインでは、これらの値をシェルで入力するのではなく、サービス接続やAzure Key Vaultのような秘密ストアから取得してください。 Gitに秘密をコミットしないでください。

ステップ1:Terraformでワークスペースをプロビジョニングする

このステップでは、制御面をコードとして定義し、それを適用します。 Terraformの設定用のフォルダを作成し、以下のファイルを追加します。

プロバイダーの設定

provider.tf を作りましょう。 プロバイダーバージョンをピンインすることで、すべてのエンジニアが同じ動作を保ちます。

# We strongly recommend using the required_providers block to set the Fabric Provider source and version being used
terraform {
  required_version = ">= 1.8, < 2.0"
  required_providers {
    fabric = {
      source  = "microsoft/fabric"
      version = "1.12.0"
    }
  }
}

# Configure the Microsoft Fabric Terraform Provider.
# Auth is via the service principal exported as FABRIC_TENANT_ID /
# FABRIC_CLIENT_ID / FABRIC_CLIENT_SECRET. Never hard-code secrets here.
provider "fabric" {
  # Configuration options
}

入力を宣言します

作成 variables.tf:

variable "capacity_name" {
  description = "Name of an existing Fabric capacity that backs both workspaces."
  type        = string
}

variable "workspace_prefix" {
  description = "Prefix for the workspace display names."
  type        = string
  default     = "releaseflow"
}

# Azure DevOps Git settings for the DEV workspace.
variable "ado_organization_name" {
  type = string
}
variable "ado_project_name" {
  type = string
}
variable "ado_repository_name" {
  type = string
}
variable "ado_branch_name" {
  type    = string
  default = "main"
}
variable "ado_repo_url" {
  type = string
}
variable "ado_directory_name" {
  type    = string
  default = "/workspace"
}

# Service principal used by the source-control connection.
variable "tenant_id" {
  type = string
}
variable "client_id" {
  type = string
}
variable "client_secret" {
  type      = string
  sensitive = true
}

# Object id of the developer or group to grant Contributor on DEV.
variable "contributor_principal_id" {
  type = string
}

リソースを定義する

main.tf を作りましょう。 この構成により、2つのワークスペース、ソースコントロール接続、開発上のGitリンク、そしてロール割り当てが作成されます。

data "fabric_capacity" "capacity" {
  display_name = var.capacity_name
}

# DEV workspace — authored here, committed to Git.
resource "fabric_workspace" "dev" {
  display_name = "${var.workspace_prefix}-dev"
  description  = "Development workspace."
  capacity_id  = data.fabric_capacity.capacity.id
}

# TEST workspace — populated by fabric-cicd from the Git repo.
resource "fabric_workspace" "test" {
  display_name = "${var.workspace_prefix}-test"
  description  = "Test workspace."
  capacity_id  = data.fabric_capacity.capacity.id
}

# Source-control connection (service principal).
resource "fabric_connection" "ado" {
  display_name      = "${var.workspace_prefix}-ado-conn"
  connectivity_type = "ShareableCloud"
  privacy_level     = "Organizational"

  connection_details = {
    type            = "AzureDevOpsSourceControl"
    creation_method = "AzureDevOpsSourceControl.Contents"
    parameters = [{ name = "url", value = var.ado_repo_url }]
  }

  credential_details = {
    credential_type      = "ServicePrincipal"
    skip_test_connection = false
    service_principal_credentials = {
      client_id                = var.client_id
      client_secret_wo         = var.client_secret
      client_secret_wo_version = 1
      tenant_id                = var.tenant_id
    }
  }
}

# Connect the DEV workspace to Git.
resource "fabric_workspace_git" "dev" {
  workspace_id            = fabric_workspace.dev.id
  initialization_strategy = "PreferRemote"

  git_provider_details = {
    git_provider_type = "AzureDevOps"
    organization_name = var.ado_organization_name
    # The Fabric API returns project/repository names lowercased. Pass them
    # lowercased so Terraform's post-apply consistency check matches.
    project_name    = lower(var.ado_project_name)
    repository_name = lower(var.ado_repository_name)
    branch_name     = var.ado_branch_name
    directory_name  = var.ado_directory_name
  }

  git_credentials = {
    source        = "ConfiguredConnection"
    connection_id = fabric_connection.ado.id
  }
}

# RBAC: grant the dev team Contributor on DEV.
# If contributor_principal_id is a security group rather than a user, change
# type to "Group".
resource "fabric_workspace_role_assignment" "dev_contributor" {
  workspace_id = fabric_workspace.dev.id
  role         = "Contributor"
  principal = {
    id   = var.contributor_principal_id
    type = "User"
  }
}

出力を宣言します

outputs.tf を創りましょう。 テストワークスペース名がデプロイステップに入力されます。

output "dev_workspace_id"   { value = fabric_workspace.dev.id }
output "test_workspace_id"  { value = fabric_workspace.test.id }
output "test_workspace_name" {
  description = "Pass this as --workspace_name to the fabric-cicd deploy step."
  value       = fabric_workspace.test.display_name
}

構成を適用する

変数の値を指定します(例えば、Gitに含まない terraform.tfvars ファイルに)、そして実行します:

terraform init
terraform plan
terraform apply

Terraformは作成したリソースを報告し、出力を印刷します。

チェックポイント。 Fabricポータルで、releaseflow-devreleaseflow-testワークスペースが存在し、あなたのキャパシティに割り当てられているか確認してください。

知っておくべきプロビジョニングの課題

Fabric プロバイダーは強力ですが、いくつかの挙動はユーザーを戸惑わせることがあります。 本番環境で実行する前に、以下の点を念頭に置いてください:

  • Git接続はインポートできません。 fabric_workspace_gitリソースはterraform importをサポートしていません。 これを一度限りのブートストラップとして扱い、後続の実行で再作成を試みないよう、リモートステートに保存してください。 状態は、単一のノートパソコンではなく、Azure Storage のような共有バックエンドに保存しましょう。
  • 大文字と小文字を区別する Git の名前。 Fabric APIはAzure DevOpsプロジェクトとリポジトリ名を小文字で返します。 混合ケースで合格した場合、Terraformは 「申請後に提供者が一貫した結果を出した」 と報告します。上記のように、それらを lower()で包みます。
  • サービスプリンシパルの範囲。 同じアイデンティティがキャパシティ上でワークスペースを作成し ワークスペースメンバーとして追加できなければなりません。 もしプロビジョニングが認可エラーで失敗した場合は、テナント設定と 前提条件のキャパシティロール割り当てを再確認してください。
  • 秘密は可能な限り州外に保管してください。 接続秘密は書き込み専用の client_secret_wo 引数を使用しているため、平文状態で保存されません。 それでも、州のファイルを機密扱いとして保護してください。

ステップ2:Git接続の確認

Terraformはすでに開発用ワークスペースを ステップ1でGitに接続しています。 確認してください:

  1. Fabricポータルでreleaseflow-devワークスペースを開きます。
  2. ワークスペース の設定>Git 統合を選択します。
  3. ワークスペースがAzure DevOps組織、プロジェクト、リポジトリ、ブランチ、そしてado_directory_nameで設定したフォルダに接続されているか確認してください。

チェックポイント。 開発者ワークスペースは ソース管理 の状態を示し、指定されたブランチと同期されています。

ステップ3:開発中のコンテンツを作成し、コミットする

次に、開発ワークスペースにコンテンツを追加し、それをGitにプッシュします。 このチュートリアルでは、湖の家とそこから読み上げるノートの2つのアイテムを作成します。

  1. releaseflow-dev で、demoLakehouse という名前のレイクハウスを作成します。
  2. demoNotebookという名前のノートを作成します。 demoLakehouseをデフォルトのレイクハウスとして付け、テーブルを読み取ったりサンプルデータを書き込むセルを追加してください。
  3. ノートブックを一度実行して、Dev Lakehouseに対して動作するか確認してください。
  4. ワークスペースでソース管理を開き、両方の項目を選択して、自分のブランチにコミットしてください。

コミット後、リポジトリには設定したディレクトリの下に demoLakehouse.Lakehouse フォルダと demoNotebook.Notebook フォルダが入ります。

チェックポイント。 コミット後、ソースコントロールパネルには保留中の変更が0と表示され、アイテムフォルダはAzure DevOpsに表示されます。

ステップ4:開発からFabric-CICDでテストするためにデプロイする

テスト作業スペースはまだ空っぽです。 fabric-cicdを使ってGitからテストにアイテムを公開し、その途中でノートブックをテストのレイクハウスに再バインドします。

Tip

Fabric-CICDはデータプレーンを展開する一つの方法です。 RESTコールを自分でスクリプト化したい方は、チュートリアル:Fabric bulk APIを使ったCI/CDを参照してください。

fabric-cicd のインストール

requirements.txt作成:

fabric-cicd>=0.1.20
azure-identity>=1.17.0

インストール:

pip install -r requirements.txt

Fabric-CICDはPython 3.9から3.13までをサポートしています。 他のプロジェクトから隔離するために、仮想環境にインストールしてください。

パラメータファイルを追加してください

Git に格納されているノートブックは、dev lakehouse と dev workspace を参照しています。 テストにデプロイする際には、ノートブックがテストデータを読み書きするように参照が変更されなければなりません。 Fabric-CICDは parameter.yml ファイルでこれを行います。

デプロイスクリプトの横に parameter.yml を作成します。 コミットしたノートブックのコンテンツに表示されている2つのプレースホルダーGUIDを、実際のdev lakehouse IDとdev workspace IDに置き換えてください。

find_replace:
  # DEV lakehouse id -> the deployed demoLakehouse id in the target workspace.
  - find_value: "<dev-lakehouse-guid>"
    replace_value:
      test: "$items.Lakehouse.demoLakehouse.$id"
    item_type: "Notebook"
    item_name: "demoNotebook"
    file_path: "/demoNotebook.Notebook/notebook-content.py"

  # DEV workspace id -> the target workspace id.
  - find_value: "<dev-workspace-guid>"
    replace_value:
      test: "$workspace.$id"
    item_type: "Notebook"
    item_name: "demoNotebook"
    file_path: "/demoNotebook.Notebook/notebook-content.py"

$items.Lakehouse.demoLakehouse.$id トークンと $workspace.$id トークンは、デプロイ時に fabric-cicd によって target ワークスペース内の GUID に解決されます。

デプロイスクリプトを書きます

作成 deploy.py:

import argparse
from azure.identity import DefaultAzureCredential
from fabric_cicd import (
    FabricWorkspace,
    publish_all_items,
    unpublish_all_orphan_items,
)

ITEM_TYPES = ["Lakehouse", "Notebook"]


def main() -> None:
    p = argparse.ArgumentParser()
    p.add_argument("--workspace_name", required=True)
    p.add_argument("--environment", required=True)
    p.add_argument("--repository_directory", default="./workspace")
    p.add_argument("--parameter_file", default="./parameter.yml")
    args = p.parse_args()

    target = FabricWorkspace(
        workspace_name=args.workspace_name,
        environment=args.environment,
        repository_directory=args.repository_directory,
        item_type_in_scope=ITEM_TYPES,
        parameter_file_path=args.parameter_file,
        token_credential=DefaultAzureCredential(),
    )

    # Create or update every item, applying parameter.yml.
    publish_all_items(target)
    # Remove items deleted from the repo so test mirrors the branch.
    unpublish_all_orphan_items(target)

    print(f"Deployment to '{args.workspace_name}' complete.")


if __name__ == "__main__":
    main()

デプロイを実行する

スクリプトを、Terraform が test_workspace_name として表示したテストワークスペース名に向けます。 リポジトリをクローンするか、開発者がコミットしたローカルコピーを再利用してアイテムフォルダをローカルで利用できるようにし、その後実行します:

python deploy.py \
  --workspace_name releaseflow-test \
  --environment test \
  --repository_directory ./workspace \
  --parameter_file ./parameter.yml

fabric-cicd は test で Lakehouse と Notebook を作成し、find_replace ルールを適用して、公開された各項目を報告します。

チェックポイント。 コマンドはエラーなく Deployment to 'releaseflow-test' complete. を印刷します。

ステップ5:昇進の確認

テストで、コンテンツの正しく再バインドされたコピーを受け取ったことを確認してください:

  1. Fabricポータルでreleaseflow-testワークスペースを開きます。
  2. demoLakehousedemoNotebookが現在存在しているか確認してください。
  3. demoNotebookを開いて、デフォルトのlakehouseがテスト用であって開発者用ではないdemoLakehouseを確認してください。
  4. ノートブックを実行します。 テスト用レイクハウスの読み取りと書き込みができる必要があります。

チェックポイント。 ノートブックはテスト用レイクハウスに対してテスト環境で実行され、fabric-cicd が環境固有の参照を再バインドしたことを示しています。

これで、反復可能なライフサイクルができました。dev 環境で項目を変更し、Git にコミットして、deploy.py を再実行すれば、test 環境に昇格できます。

Azure DevOps で自動化

ローカルで実行したすべてのものはパイプラインと同じサービスプリンシパルを使っているので、CI/CDに移行する際は主にこれらのコマンドをパイプライン段階に配置するだけです。1つのステージは terraform apply (制御プレーン)、後のステージは deploy.py (データプレーン)を実行します。 Fabric-CICD導入段階の完全なゲート付きAzure Pipelinesウォークスルー(変数グループや承認を含む)については、「Tutorial: CI/CD using Azure DevOps and the fabric-cicd library」をご覧ください。

このチュートリアルを拡張してください

このチュートリアルではノートと湖畔の家を展開します。 同じパターンはデータプレーンのより広い範囲にスケールします:

  • SemanticModelReportITEM_TYPESに追加し、semantic_model_bindingparameter.ymlルールを追加して各環境の接続をモデルに指し示します。
  • VariableLibrary を追加すると、fabric-cicd が渡した --environment に一致する値セットを有効化します。
  • publish_all_items後にデプロイ後のステップ(例えば、セマンティックモデルの更新やスモークテストノートブックの実行など)を追加します。

リソースをクリーンアップする

容量を消費しないために、作成したワークスペースを削除してください。 Terraformフォルダから:

terraform destroy

あるいは、Fabricポータルからreleaseflow-devreleaseflow-testワークスペースを削除してください。