Azure Citadel
  • Blogs

  • ARM
  • Azure Arc
    • Overview
    • Azure Arc-enabled Servers
      • Prereqs
      • Scenario
      • Hack Overview
      • Azure Landing Zone
      • Arc Pilot resource group
      • Azure Monitoring Agent
      • Additional policy assignments
      • Access your on prem VMs
      • Create onboarding scripts
      • Onboarding using scripts
      • Inventory
      • Monitoring
      • SSH
      • Windows Admin Center
      • Governance
      • Custom Script Extension
      • Key Vault Extension
      • Managed Identity
    • Azure Arc-enabled Kubernetes
      • Prereqs
      • Background
      • Deploy Cluster
      • Connect to Arc
      • Enable GitOps
      • Deploy Application
      • Enable Azure AD
      • Enforce Policy
      • Enable Monitoring
      • Enable Azure Defender
      • Enable Data Services
      • Enable Application Delivery
    • Useful Links
  • Azure CLI
    • Install
    • Get started
    • JMESPATH queries
    • Integrate with Bash
  • Azure Landing Zones
    • Prereqs
    • Day 1
      • Azure Baristas
      • Day 1 Challenge
    • Day 2
      • Example
      • Day 2 Challenge
    • Day 3
      • Day 3 Challenge
    • Useful Links
  • Azure Policy
    • Azure Policy Basics
      • Policy Basics in the Azure Portal
      • Creating Policy via the CLI
      • Deploy If Not Exists
      • Management Groups and Initiatives
    • Creating Custom Policies
      • Customer scenario
      • Policy Aliases
      • Determine the logic
      • Create the custom policy
      • Define, assign and test
  • Azure Stack HCI
    • Overview
    • Useful Links
    • Updates from Microsoft Ignite 2022
  • Marketplace
    • Introduction
      • Terminology
      • Offer Types
    • Partner Center
    • Offer Type
    • Publish a VM Offer HOL
      • Getting Started
      • Create VM Image
      • Test VM Image
      • VM Offer with SIG
      • VM Offer with SAS
      • Publish Offer
    • Other VM Resources
    • Publish a Solution Template HOL
      • Getting Started
      • Create ARM Template
      • Validate ARM Template
      • Create UI Definition
      • Package Assets
      • Publish Offer
    • Publish a Managed App HOL
      • Getting Started
      • Create ARM Template
      • Validate ARM Template
      • Create UI Definition
      • Package Assets
      • Publish Offer
    • Managed Apps with AKS HOL
    • Other Managed App Resources
    • SaaS Offer HOLs
    • SaaS Offer Video Series
      • Video 1 - SaaS Offer Overview
      • Video 2 - Purchasing a SaaS Offer
      • Video 3 - Purchasing a Private SaaS Plan
      • Video 4 - Publishing a SaaS Offer
      • Video 5 - Publishing a Private SaaS Plan
      • Video 6 - SaaS Offer Technical Overview
      • Video 7 - Azure AD Application Registrations
      • Video 8 - Using the SaaS Offer REST Fulfillment API
      • Video 9 - The SaaS Client Library for .NET
      • Video 10 - Building a Simple SaaS Landing Page in .NET
      • Video 11 - Building a Simple SaaS Publisher Portal in .NET
      • Video 12 - SaaS Webhook Overview
      • Video 13 - Implementing a Simple SaaS Webhook in .NET
      • Video 14 - Securing a Simple SaaS Webhook in .NET
      • Video 15 - SaaS Metered Billing Overview
      • Video 16 - The SaaS Metered Billing API with REST
  • Microsoft Fabric
    • Theory
    • Prereqs
    • Fabric Capacity
    • Set up a Remote State
    • Create a repo from a GitHub template
    • Configure an app reg for development
    • Initial Terraform workflow
    • Expanding your config
    • Configure a workload identity
    • GitHub Actions for Microsoft Fabric
    • GitLab pipeline for Microsoft Fabric
  • Packer & Ansible
    • Packer
    • Ansible
    • Dynamic Inventories
    • Playbooks & Roles
    • Custom Roles
    • Shared Image Gallery
  • Partner
    • Lighthouse and Partner Admin Link
      • Microsoft Cloud Partner Program
      • Combining Lighthouse and PAL
      • Minimal Lighthouse definition
      • Using service principals
      • Privileged Identity Management
    • Useful Links
  • REST API
    • REST API theory
    • Using az rest
  • Setup
  • Terraform
    • Fundamentals
      • Initialise
      • Format
      • Validate
      • Plan
      • Apply
      • Adding resources
      • Locals and outputs
      • Managing state
      • Importing resources
      • Destroy
    • Working Environments for Terraform
      • Cloud Shell
      • macOS
      • Windows with PowerShell
      • Windows with Ubuntu in WSL2
    • Using AzAPI
      • Using the REST API
      • azapi_resource
      • Removing azapi_resource
      • azapi_update_resource
      • Data sources and outputs
      • Removing azapi_update_resource
  • Virtual Machines
    • Azure Bastion with native tools & AAD
    • Managed Identities

  • About
  • Archive
  1. Home
  2. Microsoft Fabric
  3. Configure a workload identity

Table of Contents

  • Introduction
  • Service Principal / Managed Identity overview
  • Creating a managed identity
  • Add to an Entra ID security group (optional)
  • Enable use within Fabric
    • Configure Developer settings in Tenant settings
    • Add access to the capacity (F-SKU only)
  • Azure RBAC role assignments
  • Entra ID app roles (optional)
  • Next

Configure a workload identity

Configure a managed identity ready for use with the fabric Terraform provider in a pipeline context.

Introduction

On this page we will create a managed identity that can be used by CI/CD pipelines and configuring the Fabric tenant settings to permit its use. You will also add some additional permissions, at the very least the Storage Blob Data Contributor role for the storage account.

Note that this will won’t touch any CI/CD platform specifics until the following GitHub page. This will be a cleaner break point for those of you who want to look at Azure DevOps or GitLab as alternatives to using GitHub as we will follow a similar process.

The process follows the Creating an App Registration for the Service Principal context (SPN) page but for a user assigned managed identity instead of a service principal.

Service Principal / Managed Identity overview

Is the service principal / managed identity configuration non-standard for Fabric?

A little, yes. It is defined by the Fabric REST API authentication that propagates through the Go SDK for Fabric.

There is a tenant setting in the Fabric admin pages, “Service principals can use Fabric APIs”, and this can be configured either

  • for all service principals, or
  • to a specific Entra security group

So no role API permissions?

No. Usually when looking at app registrations and API permissions you have either

  • Delegated API permissions for delegated access or user impersonation, which is access on behalf of a user. Also known as scoped permissions.
  • Role API permissions for apps that require standalone authentication and authorisation.

With the Fabric model it allows either service principals or managed identities, but it does not make use of app roles and therefore is no granularity to control which REST API calls are permitted. The only real control point is the tenant setting.

Could I use a managed identity?

Yes, and we are here. We will define a managed identity and use it for fabric terraform provider. You can also create add Azure RBAC role assignments for the azurerm and azapi providers. We’ll add one for writing remote state as a blob to the storage account. We’ll also show how to add app roles for the Microsoft Graph for the azuread provider.

Managed identities are a good security recommendation when combined with OpenId Connect as there is no risk of secret leakage or burden of secret rotation.

Creating a managed identity

We will create the user assigned managed identity in the same resource group as the storage account you made earlier.

  1. Define variables

    Set the resource group name and region

    rg=terraform
    loc=uksouth
    managed_identity_name="mi-terraform"
    management_subscription_id="<subscription_guid>"
    
  2. Switch subscriptions (optional)

    If you created the terraform resource group in another subscription then switch to it now. For example:

    az account set --subscription <management subscription>
    
  3. Create the user assigned managed identity

    az identity create --name fabric_terraform_provider --resource-group $rg --location $loc
    

Add to an Entra ID security group (optional)

This step is recommended but you will need the appropriate permissions to create groups within Entra ID.

  1. Create the group

    az ad group create --display-name "Microsoft Fabric Workload Identities" --description "Service Principals and Managed Identities used for Fabric automation." --mail-nickname FabricWorkloadIdentities
    
  2. Add the managed identity

    objectId=$(az identity show --name fabric_terraform_provider --resource-group $rg --query principalId -otsv)
    az ad group member add --group "Microsoft Fabric Workload Identities" --member-id $objectId
    

Enable use within Fabric

Configure Developer settings in Tenant settings

  • Open Fabric Portal

    • click on the bottom left to toggle between Power BI and Fabric experiences
  • click on the Settings cog at the top right

  • Admin Portal

  • Tenant settings

    • filter on “principal”
    • the Developer Settings sections should come immediately into view
  • Toggle to Enabled

  • Set apply to either

    • the entire organisation
    • a specific security group (preferred)

    Screenshot of the Fabric Admin Portal showing the new security group in the developer settings

Add access to the capacity (F-SKU only)

You can either add it as an Administrator to the F-SKU or a Contributor.

Administrator

  1. Variables

    identity_name="fabric_terraform_provider"
    identity_resource_group="terraform"
    capacity_name="example"
    capacity_resource_group="fabric"
    
  2. Work out the extended administrators property

    identityObjectId=$(az identity show --name fabric_terraform_provider --resource-group terraform --query principalId -otsv)
    current=$(az fabric capacity show --name example --resource-group fabric --query administration.members -ojson)
    updated=$(jq -c --arg oid "$identityObjectId" '. + [$oid]|{members: .}' <<< $current)
    

    Note that in the administrators array you must specify the

    • user principal name (UPN) for users
    • object ID for workload identities (service principals and managed identities)
  3. Update the Fabric SKU

    az fabric capacity update --name example --resource-group fabric --administration $updated
    

    Example output:

    {
      "administration": {
        "members": [
          "admin@MngEnvMCAP520989.onmicrosoft.com",
          "806dac5a-24b9-49ae-8e2b-4b777e8eaaf8"
        ]
      },
      "id": "/subscriptions/73568139-5c52-4066-a406-3e8533bb0f15/resourceGroups/fabric/providers/Microsoft.Fabric/capacities/example",
      "location": "UK South",
      "name": "example",
      "provisioningState": "Succeeded",
      "resourceGroup": "fabric",
      "sku": {
        "name": "F2",
        "tier": "Fabric"
      },
      "state": "Active",
      "tags": {},
      "type": "Microsoft.Fabric/capacities"
    }
    

Azure RBAC role assignments

The identity needs to be able to write to the storage account’s prod container for the Terraform state file.

  1. Assign Storage Blob Data Contributor to the prod container

    objectId=$(az identity show --name fabric_terraform_provider --resource-group $rg --query principalId -otsv)
    storageAccountId=$(az storage account list --resource-group terraform --query "[?starts_with(name, 'terraformfabric')]|[0].id" -otsv)
    az role assignment create --assignee-object-id $objectId --assignee-principal-type ServicePrincipal --scope "$storageAccountId/blobServices/default/containers/prod" --role "Storage Blob Data Contributor"
    
  2. Assign additional roles as required (optional)

    For example:

    scope="/subscriptions/$(az account show --name "<fabric subscription>" --query id -otsv)
    az role assignment create --assignee-object-id $objectId --assignee-principal-type ServicePrincipal --scope "$scope" --role "Contributor"
    

Entra ID app roles (optional)

You can also add app roles to the managed identity for use with Microsoft Graph and other APIs. As an example, here are the steps to add User.Read.All and Group.Read.All if you want to use the data sources in the azuread provider.

⚠️ This section is entirely optional and a little lengthy, so feel free to skip to Next.

This configuration is not as common for managed identities as it is for service principals. It requires a few REST API calls if you’re not using PowerShell. This section makes use of jq.

  1. Get the objectId for the Graph App ID

    The Graph App ID is a well known value and is consistent across all tenants, but the REST API calls need the objectId and this is unique within each tenant.

    graph_app_id="00000003-0000-0000-c000-000000000000"
    graph_object_id=$(az ad sp show --id "$graph_app_id" --query id -otsv)
    
  2. Set the roles

    roles="User.Read.All Group.Read.All"
    

    To display all possible roles:

    az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[].value" -otsv
    
  3. Set the main part of the URI

    objectId=$(az identity show --name fabric_terraform_provider --resource-group $rg --query principalId -otsv)
    uri="https://graph.microsoft.com/v1.0/servicePrincipals/${objectId}"
    
  4. Create the app roles

    Loop through the appRoleIs, generating the JSON body and calling the API**

    for role in $roles
    do
      app_role_id=$(az ad sp show --id $graph_app_id --query "appRoles[?value == '"$role"'].id" -otsv)
      body=$(jq -nc --arg graph "$graph_object_id" --arg mi "$managed_identity_object_id" --arg role "$app_role_id" '{principalId:$mi,resourceId:$graph,appRoleId:$role}')
      echo "Adding app role $role:"
      jq . <<< $body
      az rest --method post --uri "${uri}/appRoleAssignments" --body "$body"
    done
    

    An example JSON body for User.ReadBasic.All would be:

    {
      "principalId": "<objectId for the managed identity>",
      "resourceId":"<objectId for the Microsoft Graph in my tenant>",
      "appRoleId":"5b567255-7703-4780-807c-7be8301ae99b"
    }
    
  5. Viewing resulting app roles

    Again the Azure CLI doesn’t yet support viewing app roles with either az identity or az ad sp, so this is another REST API call.

    az rest --method get --uri "$uri?\$expand=appRoleAssignments" --query appRoleAssignments --output jsonc
    

    Or go into the Entra admin portal

    • switch the type to Managed identities
    • filter Enterprise applications to “fabric”

    Screenshot of the Enterprise Applications page in Entra admin portal, filtered to show managed identities related to ‘fabric’

    Click on Permissions.

    Screenshot of the Permissions tab for a managed identity, showing assigned app roles in the Entra admin portal

Next

The managed identity is ready for use for the fabric terraform provider. Time to work with GitHub.

Expanding your config Configure a workload identity GitHub Actions for Microsoft Fabric