Generated banner for Synapse Migration
Generated logo for Synapse Migration

Synapse Migration

MicrosoftOfficialPublished by Microsoft

  • Skill
  • Workflow
  • Software development
  • MIT
  • Low risk
  • Has scripts

From the author

Converts Synapse workspaces to Fabric: Spark items, Lake Databases, Linked Services, and Dedicated SQL Pool schema/procedures for Lakehouse or Warehouse. During Pool-to-Lakehouse migration only, can migrate approved dependent procedure callers after notebook readiness. Excludes standalone pipelines and Warehouse administration. Triggers: Synapse workspace to Fabric, Dedicated SQL Pool to Lakehouse, Dedicated SQL Pool to Fabric Warehouse.
— the description by Microsoft

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

The synapse-migration skill provides a structured, phased workflow for transitioning Synapse Analytics workspaces to Microsoft Fabric. It covers the migration of Spark items, Lake Databases, Linked Services, and Dedicated SQL Pool schema and stored procedures. The skill emphasizes a dependency-ordered approach, requiring gap assessment and explicit approval before conversion. It distinguishes between migrating to a Fabric Lakehouse (schema and code only, no data movement) and a Fabric Warehouse, while providing specific routing for dependent pipeline callers.

What it does

  • Discovers and classifies Synapse workspace artifacts.
  • Converts Dedicated SQL Pool schema and stored procedures to Spark SQL notebooks or Warehouse objects.
  • Migrates Spark items, including notebooks and Spark Job Definitions, to Fabric equivalents.
  • Maps Linked Services to Fabric Data Connections or OneLake Shortcuts.
  • Manages the migration of approved dependent pipeline callers.
  • Validates persisted definitions and artifacts against established contracts.

When to use it

  • When migrating a full Synapse workspace to Microsoft Fabric.
  • When converting Dedicated SQL Pool schema and procedures to a Lakehouse or Warehouse.
  • When porting Spark pools, notebooks, or Spark Job Definitions to Fabric.
  • When replacing Synapse Linked Services with Fabric-native connectivity.

Advantages

  • Ensures dependency-ordered migration to maintain system integrity.
  • Provides clear routing for different workload types (Lakehouse vs. Warehouse).
  • Enforces strict validation and approval gates for behavior-changing decisions.
  • Supports incremental migration rather than high-risk big-bang cutovers.
  • Standardizes the conversion of T-SQL procedures to executable Spark SQL notebooks.

Usage examples

“Migrate this Dedicated SQL Pool DACPAC to a Fabric Lakehouse and convert the procedures.”
The agent will assess gaps, obtain approval for procedure-to-notebook mappings, create a migration manifest, convert schema/code artifacts, and validate the results.
“Migrate this Dedicated SQL Pool to Fabric Warehouse.”
The agent will assess DDL compatibility, remove unsupported distribution/index declarations, obtain provisioning consent, and prepare for potential data migration.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/microsoft/synapse-migration/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip synapse-migration.zip -d .agents/skills

Documentation by Microsoft

Telemetry — MANDATORY. Every api.fabric.microsoft.com call must carry x-ms-fabric-skill: synapse-migration (az rest: --headers "x-ms-fabric-skill=synapse-migration"), including every LRO poll, fabric_lro and retry. Snippets omit it — add it anyway.

OFFLINE LAKEHOUSE ARTIFACT FAST PATH — DECIDE FIRST. For a no-live-call request with complete supplied inputs and contracts, load only the fast path; do not load migration-planning-reference.md, dedicated-pool-conversion.md, or implementation scripts. Use one generator for artifacts and final-byte hashes, then one verifier. Do not inspect generated files or run post-pass spot checks. For every optional non-null source default, set missingValueBehavior to UseSourceDefault and restore that default before validation. Do not use this path for a Warehouse target; incomplete and large-procedure requests use their own routes.

CRITICAL NOTES

  1. To find workspace details (including its ID) from a workspace name: list all workspaces, then use JMESPath filtering.

  2. To find item details (including its ID) from workspace ID, item type, and item name: list all items of that type in that workspace, then use JMESPath filtering.

  3. Treat a source Dedicated SQL Pool as read-only. Do not run source DDL, DML, stored procedures, or create sample objects.

  4. Dedicated Pool-to-Lakehouse data movement is out of scope. Migrate schema and executable code artifacts only; do not copy source rows or run row-level/business-result equivalence queries. The separate Warehouse route may move data only from a separately approved restored export copy under its own consent gate and restored-source contract.

  5. For Dedicated Pool-to-Lakehouse requests, complete gap assessment, explicit mapping approval, manifest creation, conversion, deployment, and validation in order. Read dedicated-pool-to-lakehouse.md once as the router, then load only the current phase reference.

  6. Stored-procedure 1:1, N:1, and N:N mappings never apply to views. Views remain schema objects; procedures become traceable Spark SQL notebooks with executable %%sql transformation cells.

  7. Dependent ADF/Synapse callers are conditional scope, not automatic scope. Discover them during assessment, require a separate complete-closure approval, and migrate them only after notebook readiness. Route standalone pipeline requests to pipeline-migration.

  8. Before executing a specialized Dedicated Pool workflow, read the matching contract in dedicated-pool-execution-contracts.md. Its validation, hashing, request-body, resume, and completion-language requirements are mandatory.

  9. Keep Lakehouse and Warehouse paths separate. If the target is unclear, ask before loading path-specific resources. Lakehouse conversion never moves source rows; Warehouse data migration requires its own explicit consent gate and restored-source contract.

  10. For a Fabric Warehouse target, explicitly state that the complete DISTRIBUTION and CLUSTERED COLUMNSTORE INDEX declarations are removed because Fabric manages distribution, storage, and indexing; a bare mention of either source clause is insufficient.

  11. Run setup DDL and CETAS only against the separately approved restored export copy after proving it is not the original production source.

Synapse Analytics to Microsoft Fabric Migration

Core Workflow

  1. Discover the Synapse workspace and classify every source artifact.

  2. Choose targets using workload-routing.md.

  3. Assess gaps before conversion, including runtime, library, connectivity, T-SQL, security, and capacity constraints.

  4. Obtain approval for behavior-changing decisions, target placement, and every stored-procedure-to-notebook mapping.

  5. Create or update migration-manifest.json and persist approval, per-object status, hashes, and checkpoints atomically.

  6. Convert and deploy in dependency order, loading only the current phase resource.

  7. Validate persisted definitions and artifacts without executing generated notebooks or pipelines unless a separately approved workflow explicitly requires execution.

  8. Report completed, blocked, skipped, and pending objects without exposing credentials or sensitive values.

For full-workspace orchestration, read migration-orchestrator.md. For a Dedicated Pool-to-Lakehouse migration, use dedicated-pool-to-lakehouse.md as the phase router. For a Warehouse target, load only the matching dw-* resource.

Scope Routing

RequestActionLoad
Full Synapse workspace migrationRun phased discovery and migrationmigration-orchestrator.md
Dedicated SQL Pool schema/code to LakehouseRun the strict assessment-to-validation workflow. For guidance-only notebook publication, explicitly state: "The stored procedures were converted from T-SQL to Spark SQL before publication."dedicated-pool-to-lakehouse.md
Guidance-only Dedicated Pool incremental deployment hardeningAnswer directly from the focused checklist; do not search scripts or load phase resources. State: "For columns with special characters, enable Delta columnMapping selectively and only with approval."dedicated-pool-execution-contracts.md
Large or complex stored procedureFor a complete offline contract, read only the audit resource once, use one run-local generator and one verifier, do not inspect implementation scripts or generated outputs, and stop after successful verificationdedicated-pool-large-procedure-audit.md
Spark poolConvert configuration and libraries to a Fabric Environmentspark-pool-migration.md
Lake Database or HMSCreate or bind the target Lakehouselake-database-migration.md or external-hms-migration.md
Notebook or Spark Job DefinitionPort code, bindings, parameters, and runtime settingsspark-item-migration.md
Linked ServiceChoose a Fabric Data Connection for external services or a OneLake Shortcut for ADLS Gen2/Blobconnectivity-migration.md
Approved dependent procedure callersRun the internal closure-preserving sub-flow after notebook readbackdedicated-pool-dependent-pipelines.md
Standalone pipeline migrationDelegatepipeline-migration
Dedicated SQL Pool to Fabric WarehouseRun the source extraction, DDL compatibility, approval, optional data, security, and validation routedw-source-and-extraction.md, then the matching dw-* phase resource
Standalone Fabric Warehouse administrationDelegatesqldw-cli
Synapse LinkUse Fabric Mirroring; not covered here—

Always report the Lake Database/HMS phase. If none is discovered, mark it NotApplicable (none discovered) while retaining the required target Lakehouse binding.

Load References On Demand

Do not preload all files. Load only the references needed for the current phase:

NeedReference
Routing, phase order, API audiences, quick examples, troubleshooting, or post-migration handoffworkload-routing.md
Dedicated Pool execution variants and response contractsdedicated-pool-execution-contracts.md
Dedicated Pool discoverydedicated-pool-discovery.md
Gap assessment and mapping approvaldedicated-pool-gap-assessment.md
Procedure conversion and notebook shapededicated-pool-conversion.md
Schema/notebook deploymentdedicated-pool-deployment.md
Dedicated Pool validationdedicated-pool-validation.md
Runtime/library compatibilityfeature-parity.md and library-compatibility.md
mssparkutils and connector refactoringutility-api-mapping.md, connector-refactoring.md, and code-patterns.md
Capacity planningcapacity-sizing.md
Dedicated Pool-to-Warehouse source discovery and extractiondw-source-and-extraction.md
Warehouse DDL compatibility and deploymentdw-ddl-compatibility.md
Separately approved Warehouse data migrationdw-data-migration.md
Warehouse security and validationdw-security-validation.md
Validation, reporting, and production readinessvalidation-testing.md, migration-report.md, and security-governance.md

Use COMMON-CLI.md only for shared authentication and az rest mechanics not already covered by the phase resource. Use COMMON-CORE.md only for shared Fabric REST patterns.

Must

  • Preserve every stored-procedure input contract, source default, source decision, and approved target mapping.

  • Block conversion until gap dispositions, notebook names, dependency grouping, and target workspace placement are explicitly approved.

  • Use SqlPackage/DMVs for source discovery, Fabric REST for item management, and Fabric Livy statements for Lakehouse schema and Delta execution.

  • Run the maintained validators required by the selected execution contract; never replace them with ad hoc JSON or cell-shape checks.

  • Choose the Lakehouse or Warehouse target before loading implementation resources; never apply Warehouse data-movement rules to Lakehouse artifact conversion.

  • Before persisting any dependent-pipeline source definition, recursively inspect it for secret-bearing or uncertain properties; block the complete selected closure without writing the artifact or mutating a target when any are found.

  • In every dependent-pipeline response, including guidance-only and pre-approval explanations, state: "Use a TridentNotebook activity with exact target identities typeProperties.notebookId and typeProperties.workspaceId, and pass inputs through typeProperties.notebookParameters." Then state: "After deployment, read back each pipeline with POST /v1/workspaces/{workspaceId}/items/{dataPipelineId}/getDefinition and validate its canonical hash and structural bindings."

  • For every Linked Service response, first state both replacement classes: Fabric Data Connections for external databases/services and OneLake Shortcuts for ADLS Gen2/Blob storage; then identify which class applies.

  • Replace mssparkutils with notebookutils, Linked Services with the correct Fabric connection class, and spark.read.synapsesql() with a supported OneLake or JDBC pattern.

  • Externalize workspace and item IDs through parameters or Variable Libraries.

  • Keep phase status concise, emit bounded heartbeats for long operations, and persist per-object evidence in the manifest.

Prefer

  • OneLake Shortcuts over copying data.

  • Fabric Environments for reproducible libraries and Spark settings.

  • Incremental, dependency-ordered migration over big-bang cutover.

  • Parameterized notebooks and Variable Libraries for environment promotion.

  • Lakehouse SQL Endpoint for compatible Serverless SQL Pool read workloads.

Avoid

  • Do not execute generated notebooks or pipelines as part of artifact migration.

  • Do not broaden a selected dependent-pipeline closure or route that internal sub-flow to pipeline-migration.

  • Do not use sqlcmd against the target Fabric Warehouse; use the registered SQL endpoint tooling required by the Warehouse resource.

  • Do not preserve Synapse distribution/storage hints, PolyBase DDL, Linked Service connection strings, or pool-level library installation patterns verbatim.

  • Do not use target notebooks to orchestrate the migration itself.

  • Do not hardcode workspace IDs, item IDs, credentials, connection strings, or environment-specific paths.

Examples

Prompt: "Migrate this Dedicated SQL Pool DACPAC to a Fabric Lakehouse and convert the procedures."

Response behavior: Assess gaps first, present and obtain approval for the complete procedure-to-notebook mapping and workspace placement, create the manifest, convert approved schema/code artifacts without moving source rows, validate persisted definitions, and report the resolved Lakehouse and artifact evidence.

Prompt: "Migrate this ADF pipeline to Fabric."

Response behavior: Route to pipeline-migration. Keep it here only when the pipeline is an explicitly approved dependent caller discovered inside an active Dedicated Pool-to-Lakehouse migration.

Prompt: "Migrate this Dedicated SQL Pool to Fabric Warehouse."

Response behavior: Keep this inside synapse-migration, assess DDL compatibility, remove unsupported distribution and columnstore declarations, obtain provisioning consent, and ask separately before any restored-source data migration.

For code transformations and edge cases, load workload-routing.md and the phase-specific resource rather than expanding the main instructions.

Files

resources/spark-item-migration.md

Synapse Spark Item Migration — Notebooks & Spark Job Definitions

Migrate Synapse Notebooks and Spark Job Definitions (SJDs) to Fabric via REST APIs.

Prerequisite: Complete Lake Database Migration first so Fabric Lakehouses exist for notebook/SJD binding.

Auth tokens (see COMMON-CLI.md § Authentication Recipes for commands):

  • Synapse data-plane audience: https://dev.azuresynapse.net

  • Fabric audience: https://api.fabric.microsoft.com


Migration Workflow

Phase 2: Notebook Migration
├── Step 1: List/export notebooks from Synapse          (REQUIRED)
├── Step 2: Transform notebook code                     (OPTIONAL — code refactoring)
├── Step 3: Strip Synapse-specific fields                (OPTIONAL — cleanup)
├── Step 4: Add Fabric lakehouse binding                 (OPTIONAL — attach to Phase 1 Lakehouse)
├── Step 5: Base64-encode .ipynb and build payload       (REQUIRED)
├── Step 6: POST to Fabric Items API                     (REQUIRED)
└── Step 7: (Optional) Validate before proceeding to Phase 3

Phase 3: Spark Job Definition Migration
├── Step 1: List/export SJDs from Synapse                (REQUIRED)
├── Step 2: Update file paths and code                   (OPTIONAL — refactoring)
├── Step 3: Remap pool → Environment                     (OPTIONAL — compute binding)
├── Step 4: Create SJD in Fabric                         (REQUIRED)
└── Step 5: (Optional) Validate before cutover

Two migration scenarios:

ScenarioSteps UsedWhen
Lift-and-shift (copy as-is, refactor later)1 → 5 → 6Fast migration; refactor post-cutover
Migrate-and-modernize (refactor during migration)1 → 2 → 3 → 4 → 5 → 6Clean migration; notebooks ready to run in Fabric

Phase 2: Notebook Migration

Step 1: Export Notebooks from Synapse
List All Notebooks

Endpoint: GET {endpoint}/notebooks?api-version=2020-12-01

GET https://{workspaceName}.dev.azuresynapse.net/notebooks?api-version=2020-12-01

Response: { "value": [ ...NotebookResource[] ] } — paginated via nextLink.

Each NotebookResource contains:

  • name — notebook name

  • properties — the notebook content (standard .ipynb structure)

    • properties.nbformat / properties.nbformat_minor — Jupyter format version

    • properties.metadata — kernel info, language info

    • properties.cells[] — array of notebook cells

    • properties.bigDataPool — Synapse Spark pool reference (Synapse-specific). Can be null — not just absent. Always use (props.get("bigDataPool") or {}).get("referenceName", "") to safely extract the pool name.

    • properties.sessionProperties — driver/executor config (Synapse-specific)

    • properties.folder — folder structure ({ "name": "path/to/folder" })

    • properties.description — notebook description

    • properties.targetSparkConfiguration — Spark config reference (Synapse-specific)

Get Single Notebook

Endpoint: GET {endpoint}/notebooks/{notebookName}?api-version=2020-12-01

Same response structure as above, for a single notebook.

Extract the .ipynb Content

The properties object is the notebook content in .ipynb format. To build a valid .ipynb file:

{
  "nbformat": properties.nbformat,
  "nbformat_minor": properties.nbformat_minor,
  "metadata": properties.metadata,
  "cells": properties.cells
}

Important: Do NOT include bigDataPool, sessionProperties, description, folder, or targetSparkConfiguration in the .ipynb — these are Synapse envelope fields, not standard Jupyter fields.


Step 2: (Optional) Transform Notebook Code

Apply code refactoring to notebook cells. For each cell in cells[] where cell_type == "code", scan source lines for Synapse-specific patterns and replace.

See utility-api-mapping.md for the full mssparkutils → notebookutils mapping. See connectivity-migration.md for linked service replacements. See code-patterns.md for before/after examples.

Pre-Refactoring Audit — Search Patterns

Scan all notebook cell sources for these patterns to identify what needs changing:

Search PatternCategoryAction
mssparkutilsSpark UtilsReplace with notebookutils
spark.synapse.linkedServiceLinked ServicesRemove; replace with Key Vault or Fabric Connection
getSecretWithLSCredentialsReplace with getSecret(vaultUrl, secretName)
TokenLibraryToken/AuthRemove; use notebookutils.credentials or direct OAuth
synapsesqlSQL ConnectorReplace spark.read.synapsesql() with Delta reads
spark.catalog.listDatabasesCatalog APIReplace with spark.sql("SHOW DATABASES")
spark.catalog.currentDatabaseCatalog APIReplace with spark.sql("SELECT CURRENT_DATABASE()")
spark.catalog.getDatabaseCatalog APIReplace with spark.sql("DESCRIBE DATABASE ...")
spark.catalog.listFunctionsCatalog APINot supported in Fabric — remove
spark.catalog.registerFunctionCatalog APIReplace with spark.udf.register()
spark.catalog.functionExistsCatalog APINot supported in Fabric — remove
LinkedServiceBasedTokenProviderAuth ProviderReplace with ClientCredsTokenProvider
getPropertiesAsMapLinked ServicesRemove; configure storage directly
spark.storage.synapseLinked ServicesRemove — not supported in Fabric
/user/trusted-service-user/File PathsReplace with OneLake path or shortcut path
cosmos.oltpCosmos DBUpdate to Key Vault for secrets
kusto.spark.synapseKusto/ADXReplace linked service auth with accessToken via getToken()

Notebooks with zero matches are safe to migrate as-is (lift-and-shift).


Step 3: (Optional) Strip Synapse-Specific Fields

Remove Synapse-only fields from the notebook .ipynb before uploading to Fabric:

Fields to remove from the notebook JSON:

  • bigDataPool — Synapse Spark pool binding (no Fabric equivalent at notebook level)

  • sessionProperties — driver/executor memory config (use Fabric Environment instead)

  • targetSparkConfiguration — Synapse Spark config reference

Fields to preserve:

  • nbformat, nbformat_minor — required Jupyter fields

  • metadata.kernelspec, metadata.language_info — keep for proper editor rendering

  • cells[] — all cell content

  • Cell-level metadata, outputs, execution_count — preserve for round-trip safety

Note: Fabric will accept the notebook even with Synapse-specific fields present — it ignores unrecognized top-level fields. Stripping is recommended for cleanliness but not strictly required.


Step 4: (Optional) Add Fabric Lakehouse Binding

Inject the metadata.dependencies.lakehouse section to bind the notebook to a Fabric Lakehouse created in Phase 1:

{
  "metadata": {
    "dependencies": {
      "lakehouse": {
        "default_lakehouse": "{lakehouseId}",
        "default_lakehouse_workspace_id": "{workspaceId}",
        "default_lakehouse_name": "{lakehouseName}"
      }
    },
    "kernelspec": { ... },
    "language_info": { ... }
  }
}
  • default_lakehouse — the Lakehouse item ID from Phase 1

  • default_lakehouse_workspace_id — the Fabric workspace ID

  • default_lakehouse_name — the Lakehouse display name

Without this binding: The notebook will open in Fabric but have no default Lakehouse. Users must manually attach one before running. Relative paths like Tables/mytable will fail until a Lakehouse is attached.


Step 5: Base64-Encode and Build Payload
  1. Serialize the (optionally transformed) notebook to JSON

  2. Base64-encode the JSON string (standard encoding, not URL-safe)

  3. Build the Fabric Items API payload:

{
  "displayName": "{notebookName}",
  "type": "Notebook",
  "description": "{description from Synapse}",
  "definition": {
    "format": "ipynb",
    "parts": [
      {
        "path": "notebook-content.ipynb",
        "payload": "{base64-encoded-ipynb-json}",
        "payloadType": "InlineBase64"
      }
    ]
  }
}
Fabric .ipynb Nuances

Ensure the notebook JSON follows these Fabric-specific rules before encoding:

  • Every code cell must have outputs (use [] if empty) and execution_count (use null if not executed)

  • Every cell must have a metadata object (use {} if empty)

  • Each source line must end with \n except the last line of a cell

  • Keep kernel/language metadata consistent with notebook language/runtime


Step 6: POST to Fabric Items API

Endpoint: POST /v1/workspaces/{workspaceId}/items

POST https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/items
Authorization: Bearer {fabricToken}
Content-Type: application/json

{body from Step 5}

Response: HTTP 202 Accepted (async LRO).

  1. Capture the Location header URL

  2. Poll GET {Location} until status == "Succeeded"

  3. Response includes id (the new notebook item ID)

Preserving Folder Structure

Synapse notebooks may have folder paths (properties.folder.name). Fabric supports up to 10 levels of folder nesting. Include the folder path in displayName is not supported — Fabric uses a flat namespace per item type. To preserve folder organization:

  • After creation, use PATCH /v1/workspaces/{workspaceId}/items/{itemId} to update metadata if folder support is added

  • Alternatively, prefix notebook names with folder paths: ETL_Bronze_LoadCustomers instead of ETL/Bronze/LoadCustomers

  • Or use Fabric workspace folders if available in the target workspace

Batch Migration

For workspaces with many notebooks, process sequentially to avoid API throttling:

  • Respect HTTP 429 (Too Many Requests) — retry with the Retry-After header value

  • Process 5–10 notebooks at a time, waiting for each LRO to complete before starting the next batch

  • Log success/failure for each notebook to produce a migration report


Phase 3: Spark Job Definition Migration

Step 1: Export SJDs from Synapse
List All SJDs

Endpoint: GET {endpoint}/sparkJobDefinitions?api-version=2020-12-01

GET https://{workspaceName}.dev.azuresynapse.net/sparkJobDefinitions?api-version=2020-12-01

Response: { "value": [ ...SparkJobDefinitionResource[] ] } — paginated via nextLink.

Each SparkJobDefinitionResource contains:

  • name — SJD name

  • properties.description — SJD description

  • properties.targetBigDataPool.referenceName — Synapse Spark pool name. Can be null — not just absent. Always use (props.get("targetBigDataPool") or {}).get("referenceName", "") to safely extract.

  • properties.requiredSparkVersion — e.g., "3.3", "3.4", "3.5"

  • properties.language — "python", "scala", "r"

Language value mapping: Synapse returns lowercase ("python", "scala", "r"). Fabric's SparkJobDefinitionV1.json requires: "Python", "Scala/Java", "R". Critically, Synapse "scala" must be mapped to "Scala/Java" — submitting "scala" returns SparkJobDefinitionInvalid. Apply this mapping before uploading definitions:

LANGUAGE_MAP = {"python": "Python", "scala": "Scala/Java", "r": "R"}
fabric_language = LANGUAGE_MAP.get(synapse_language.lower(), synapse_language)
  • properties.jobProperties:

    • className — main class for Java/Scala (empty for Python)

    • args[] — command-line arguments

    • jars[] — additional JAR files

    • pyFiles[] — additional Python files

    • files[] — additional resource files

    • archives[] — archive files

    • conf — Spark configuration properties

    • driverMemory, driverCores, executorMemory, executorCores, numExecutors — compute settings

Get Single SJD

Endpoint: GET {endpoint}/sparkJobDefinitions/{sparkJobDefinitionName}?api-version=2020-12-01


Step 2: (Optional) Update File Paths and Code
File Path Updates

If jobProperties.file, jars[], pyFiles[], or files[] reference Synapse workspace-internal storage, update to accessible paths:

Synapse PathAction
abfss://.../{workspace}/warehouse/... (workspace storage)Re-upload to Fabric Lakehouse Files or accessible ADLS Gen2; update path
abfss://{container}@{storage}.dfs.core.windows.net/... (external ADLS)Keep if accessible from Fabric; or update to OneLake path via shortcut
Source Code Changes

If the main .py/.jar file contains Synapse-specific code, the same refactoring patterns from Phase 2 apply:

  • Replace mssparkutils with notebookutils

  • Update hardcoded file paths to OneLake abfss:// paths

  • Replace linked service references with Key Vault secrets or Fabric Connections

Note: DMTS Connections are not yet supported in Fabric Spark Job Definitions (supported in notebooks only). If SJD code uses DMTS, refactor to direct endpoint authentication.

Command-Line Argument Updates

If args[] contain Synapse-specific paths or connection strings, update them to Fabric equivalents.


Step 3: (Optional) Remap Pool → Environment

Synapse SJDs are bound to a Spark pool (targetBigDataPool). In Fabric, SJDs are bound to an Environment.

SynapseFabric
targetBigDataPool.referenceName: "MyPool"Fabric Environment item ID
driverMemory, executorMemory, etc.Configured in Fabric Environment Spark compute settings
Pool-level librariesConfigured in Fabric Environment library management

If no specific Environment is needed, the SJD will use the Fabric workspace default settings (Starter Pool).


Step 4: Create SJD in Fabric

Endpoint: POST /v1/workspaces/{workspaceId}/items

{
  "displayName": "{sjdName}",
  "type": "SparkJobDefinition",
  "description": "{description}"
}

After creation, update the SJD definition with the job properties:

Endpoint: POST /v1/workspaces/{workspaceId}/items/{sjdId}/updateDefinition

Note: Use the /items/{id}/updateDefinition path (not /sparkJobDefinitions/{id}/). The /items/ path is the canonical Fabric endpoint for all item types.

SparkJobDefinitionV1.json — Config Structure

Build this JSON from the Synapse SJD's jobProperties, then base64-encode it:

{
  "executableFile": "{jobProperties.file}",
  "defaultLakehouseArtifactId": "{lakehouseId from Phase 1, or empty string}",
  "mainClass": "{jobProperties.className, or empty for Python}",
  "additionalLakehouseIds": [],
  "retryPolicy": null,
  "commandLineArguments": "{jobProperties.args joined by spaces}",
  "additionalLibraryUris": ["{jobProperties.jars[] + jobProperties.pyFiles[]}"],
  "language": "{mapped language — see Language value mapping above}",
  "environmentArtifactId": "{Environment ID from Phase 0 poolMappings, or null for default}"
}
Field Mapping: Synapse → Fabric SJD
Synapse jobProperties FieldFabric SparkJobDefinitionV1.json FieldTransform
fileexecutableFileDirect copy — keep abfss:// paths as-is if storage is accessible from Fabric
classNamemainClassDirect copy (empty for Python)
args[]commandLineArgumentsJoin array into space-separated string
jars[] + pyFiles[]additionalLibraryUrisMerge into single array; filter out empty strings
languagelanguageMap: "python" → "Python", "scala" → "Scala/Java", "r" → "R"
Pool referenceenvironmentArtifactIdUse Phase 0 poolMappings to resolve Environment ID
N/AdefaultLakehouseArtifactIdLakehouse from Phase 1 (required for Fabric SJDs)
Upload Definition Payload
{
  "definition": {
    "format": "SparkJobDefinitionV1",
    "parts": [
      {
        "path": "SparkJobDefinitionV1.json",
        "payload": "{base64-encoded config JSON from above}",
        "payloadType": "InlineBase64"
      }
    ]
  }
}

Returns HTTP 200 (synchronous) or 202 (LRO). Poll Location header until status == "Succeeded".

V2 format: For Python/R SJDs where the source file should be bundled inline (rather than referenced by abfss:// path), use format: "SparkJobDefinitionV2" and add a Main/{filename} part. V2 does not support JAR files inline.

Key Differences: Synapse SJD vs. Fabric SJD
AspectSynapseFabric
Lakehouse contextNot required (uses workspace default ADLS)Required — every SJD must have at least one Lakehouse
Supported languagesPython, Scala/Java, R, .NETPython, Scala/Java, R — .NET not supported
Retry policiesNot built-inBuilt-in retry (max retries, retry interval)
SchedulingRequires pipeline with Spark Job activityBuilt-in scheduling (Settings → Schedule)
Pool bindingSpark pool referenceEnvironment binding
Import/ExportUI-based JSON import/exportNo UI import/export — REST API only

.NET for Spark: Synapse SJDs using C#/F# must be rewritten in Python or Scala before migration. There is no Fabric equivalent.


Step 7 (Phase 2): (Optional) Validate Before Proceeding to Phase 3

Run migrated notebooks to catch refactoring issues before moving to SJDs.

CheckHowPass Criteria
Notebook executionRun each notebook via Job API (POST /workspaces/{wsId}/items/{itemId}/jobs/instances?jobType=RunNotebook)All complete with status == "Completed"
Common failuresCheck error messages against the failure patterns tableAll fixable errors resolved and re-tested
Output comparisonFor notebooks that produce output tables, compare row counts / checksums with Synapse resultsMatch within tolerance

Do not proceed to Phase 3 until critical notebooks execute successfully. SJDs often depend on tables or files produced by notebooks — a broken notebook means broken SJD inputs.

See validation-testing.md → V3: Notebook Execution Testing for batch execution scripts and the common failure patterns table.


Step 5 (Phase 3): (Optional) Validate Before Cutover

Run migrated SJDs and perform final end-to-end verification.

CheckHowPass Criteria
SJD executionRun each SJD via Job API (POST /workspaces/{wsId}/items/{itemId}/jobs/instances?jobType=SparkJob)All complete with status == "Completed"
Query result comparisonCompare checksums / sample rows for critical tables between Synapse and FabricMatch
Full validation reportRun the V6 report generator from validation-testing.mdAll categories show PASS; verdict is READY FOR CUTOVER

See validation-testing.md → V4–V6 for SJD batch testing, query comparison, and report generation.


Migration Report

After migration, generate a comprehensive report with clickable Fabric portal links for every migrated item.

See migration-report.md for:

  • Fabric portal URL patterns for all item types (Lakehouse, Notebook, SJD, Environment)

  • Python script that queries the Fabric workspace and produces a Markdown report

  • Incremental tracking (log_migrated_item()) to build the report during migration

  • Synapse Studio source links for side-by-side comparison

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs Python

Security

What our scanner noticed· Low risk

  • Instructions that use the network
  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Microsoft
Publisher
Microsoft (Official)
Source
microsoft/skills-for-fabric · skills/synapse-migration · commit f8fac11
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Also distributed in
microsoft/skills-for-fabric

AutoGineer is not affiliated with or endorsed by Microsoft or Microsoft.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download synapse-migration.zip