Back to Blog
5 min read

Microsoft Fabric Workspace: Organization and Collaboration

Workspaces are the foundation of organization and collaboration in Microsoft Fabric. Today, I will explore how to effectively structure and manage Fabric workspaces for your data platform.

What is a Fabric Workspace?

A workspace in Fabric is a container for your data artifacts that provides:

  • Collaboration space for teams
  • Security boundary for data access
  • Capacity assignment for compute resources
  • Git integration for version control
┌─────────────────────────────────────────────────────┐
│                Fabric Workspace                      │
│              "Sales Analytics"                       │
├─────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────┐│
│  │                   Items                          ││
│  ├─────────────┬─────────────┬─────────────────────┤│
│  │ Lakehouses  │ Warehouses  │ Semantic Models     ││
│  │ Notebooks   │ Pipelines   │ Reports             ││
│  │ KQL DBs     │ Dataflows   │ Spark Job Defs      ││
│  └─────────────┴─────────────┴─────────────────────┘│
├─────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────┐│
│  │              Access Control                      ││
│  │  Admin │ Member │ Contributor │ Viewer          ││
│  └─────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────┤
│  Assigned Capacity: F64                             │
│  Git: Connected to Azure DevOps                     │
└─────────────────────────────────────────────────────┘

Creating Workspaces

Via Fabric Portal

# Workspace creation settings
workspace_settings = {
    "name": "Sales Analytics - Production",
    "description": "Production workspace for Sales Analytics team",
    "license_mode": "Fabric",  # or "Premium", "Pro"
    "capacity": "F64-Capacity",
    "default_storage": "OneLake",
    "contact_list": ["sales-analytics-team@contoso.com"],
    "workspace_admins": ["admin1@contoso.com", "admin2@contoso.com"]
}

Via REST API

import requests

def create_workspace(workspace_name: str, capacity_id: str, access_token: str):
    url = "https://api.powerbi.com/v1.0/myorg/groups"

    headers = {
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json"
    }

    payload = {
        "name": workspace_name,
        "capacityId": capacity_id
    }

    response = requests.post(url, headers=headers, json=payload)
    return response.json()

# Create workspace
workspace = create_workspace(
    "Sales Analytics - Production",
    "capacity-guid-here",
    access_token
)
print(f"Created workspace: {workspace['id']}")

Workspace Roles

# Fabric workspace roles and permissions
workspace_roles = {
    "Admin": {
        "description": "Full control over workspace",
        "permissions": [
            "Add/remove members",
            "Change workspace settings",
            "Delete workspace",
            "Create/edit/delete all items",
            "Publish apps",
            "Manage permissions on all items"
        ]
    },
    "Member": {
        "description": "Create and edit content, share items",
        "permissions": [
            "Create/edit/delete all items",
            "Share items and manage item permissions",
            "Publish apps (with admin approval)",
            "Cannot add/remove members",
            "Cannot change workspace settings"
        ]
    },
    "Contributor": {
        "description": "Create and edit content only",
        "permissions": [
            "Create/edit/delete all items",
            "Cannot share items",
            "Cannot manage permissions",
            "Cannot publish apps"
        ]
    },
    "Viewer": {
        "description": "View content only",
        "permissions": [
            "View all items",
            "Cannot create or edit",
            "Cannot share",
            "Can interact with reports (filters, etc.)"
        ]
    }
}

Assigning Roles

def assign_workspace_role(workspace_id: str, user_email: str, role: str, access_token: str):
    url = f"https://api.powerbi.com/v1.0/myorg/groups/{workspace_id}/users"

    headers = {
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json"
    }

    payload = {
        "emailAddress": user_email,
        "groupUserAccessRight": role  # Admin, Member, Contributor, Viewer
    }

    response = requests.post(url, headers=headers, json=payload)
    return response.status_code == 200

# Add users to workspace
assign_workspace_role(workspace_id, "analyst@contoso.com", "Contributor", token)
assign_workspace_role(workspace_id, "manager@contoso.com", "Member", token)
assign_workspace_role(workspace_id, "executive@contoso.com", "Viewer", token)

Workspace Organization Strategies

By Environment

┌─────────────────────────────────────────────────────┐
│                Development                           │
│  ├── Sales Analytics - Dev                          │
│  ├── Marketing Analytics - Dev                      │
│  └── Finance Analytics - Dev                        │
├─────────────────────────────────────────────────────┤
│                Test/UAT                              │
│  ├── Sales Analytics - Test                         │
│  ├── Marketing Analytics - Test                     │
│  └── Finance Analytics - Test                       │
├─────────────────────────────────────────────────────┤
│                Production                            │
│  ├── Sales Analytics - Prod                         │
│  ├── Marketing Analytics - Prod                     │
│  └── Finance Analytics - Prod                       │
└─────────────────────────────────────────────────────┘

By Domain

┌─────────────────────────────────────────────────────┐
│                    Sales Domain                      │
│  ├── Sales Raw Data (Lakehouse)                     │
│  ├── Sales Curated (Lakehouse)                      │
│  └── Sales Analytics (Reports)                      │
├─────────────────────────────────────────────────────┤
│                  Marketing Domain                    │
│  ├── Marketing Raw Data                             │
│  ├── Marketing Curated                              │
│  └── Marketing Analytics                            │
├─────────────────────────────────────────────────────┤
│                   Shared Data                        │
│  ├── Enterprise Dimensions                          │
│  ├── Common Reference Data                          │
│  └── Master Data                                    │
└─────────────────────────────────────────────────────┘

By Layer (Medallion Architecture)

# Medallion architecture workspace structure
medallion_workspaces = {
    "Bronze Layer": {
        "workspace": "Data Platform - Bronze",
        "purpose": "Raw data ingestion",
        "items": ["Lakehouses for raw data", "Ingestion pipelines"],
        "access": "Data engineers only"
    },
    "Silver Layer": {
        "workspace": "Data Platform - Silver",
        "purpose": "Cleaned and conformed data",
        "items": ["Lakehouses for curated data", "Transformation notebooks"],
        "access": "Data engineers and scientists"
    },
    "Gold Layer": {
        "workspace": "Data Platform - Gold",
        "purpose": "Business-ready aggregations",
        "items": ["Warehouses", "Semantic models", "Reports"],
        "access": "Analysts and business users"
    }
}

Workspace Settings

Configure Spark Settings

# Workspace-level Spark configuration
spark_settings = {
    "spark.executor.memory": "28g",
    "spark.executor.cores": "4",
    "spark.driver.memory": "8g",
    "spark.sql.shuffle.partitions": "200",
    "spark.sql.adaptive.enabled": "true"
}

# Apply via workspace settings in Fabric portal
# Settings > Spark settings > Spark properties

OneLake Settings

# OneLake workspace settings
onelake_settings = {
    "storage_format": "Delta",           # Default format for tables
    "external_data_access": True,        # Allow shortcuts to external data
    "cross_workspace_access": True,      # Allow other workspaces to create shortcuts
    "retention_policy": "30 days"        # Soft delete retention
}

Workspace Governance

Naming Conventions

# Recommended naming convention
naming_convention = {
    "pattern": "{Domain} - {Layer/Purpose} - {Environment}",
    "examples": [
        "Sales - Analytics - Prod",
        "Marketing - Raw Data - Dev",
        "Finance - Reporting - Test",
        "Enterprise - Shared Dimensions - Prod"
    ],
    "rules": [
        "Use consistent capitalization",
        "Include environment suffix",
        "Keep names concise but descriptive",
        "Avoid special characters"
    ]
}

Tagging and Metadata

# Use workspace description for metadata
workspace_metadata = {
    "name": "Sales Analytics - Production",
    "description": """
    Owner: Sales Analytics Team
    Contact: sales-analytics@contoso.com
    Data Classification: Internal
    Business Domain: Sales
    Last Review: 2023-05-01
    SLA: 99.5% availability
    """,
    "contacts": ["sales-analytics-team@contoso.com"]
}

Cross-Workspace Access

# Access data from another workspace via shortcuts
# In Lakehouse: Create shortcut > OneLake > Select workspace > Select item

# Or via Spark with absolute paths
df = spark.read.format("delta").load(
    "abfss://other-workspace@onelake.dfs.fabric.microsoft.com/lakehouse.Lakehouse/Tables/shared_dimensions"
)

# SQL endpoint cross-database query
# FROM other_lakehouse.dbo.shared_dimensions

Tomorrow, I will cover the comparison between Fabric and Azure Synapse Analytics.

Resources

Michael John Peña

Michael John Peña

Senior Data Engineer based in Sydney. Writing about data, cloud, and technology.