In this post I want to cover managing Microsoft Fabric connections with Fabric CLI when performing CI/CD.
To clarify, I mean the Microsoft Fabric connections that you work with when you select “Manage connections and gateways” in the settings menu in Microsoft Fabric. Like in the below image.

When I say the Fabric CLI I mean the Fabric Command Line Interface. Which is a command line offering by Microsoft that allows you to perform a variety of tasks. Including managing connections.
You can see a lot of examples relating to managing connections within the Fabric CLI cheatsheet. In this post I take it one step further by showing how to manage Microsoft Fabric connections with the Fabric CLI whilst performing CI/CD with either Azure DevOps or GitHub.
Along the way I share plenty of links.
Managing Fabric connections with Fabric CLI when performing CI/CD
One of the main tasks when working with connections is creating them once you have signed into the Fabric CLI. Like in the below example which would allow you to manually create one of the connections required for FUAM.
# First specify the variables in PowerShell
$pbi_connection_name = "fuam pbi-service-api admin"
$pbibaseUrl = "https://api.powerbi.com/v1.0/myorg/admin"
$pbiaudience = "https://analysis.windows.net/powerbi/api"
$azure_tenant_id = "{YOUR TENANT ID}"
$azure_client_id = "{SERVICE PRINCIPAL CLIENT ID}"
$azure_client_secret = "{SERVICE PRINCIPAL SECRET}"
# Then run the command
fab create .connections/$pbi_connection_name.connection -P connectionDetails.type=WebForPipeline,connectionDetails.creationMethod=WebForPipeline.Contents,connectionDetails.parameters.baseUrl=$pbibaseUrl,connectionDetails.parameters.audience=$pbiaudience,credentialDetails.type=ServicePrincipal,credentialDetails.tenantId=$azure_tenant_id,credentialDetails.servicePrincipalClientId=$azure_client_id,credentialDetails.servicePrincipalSecret=$azure_client_secret
You can see further examples on how to create a connection with Fabric CLI in the Fabric CLI cheatsheet. I showed this particular example since it is an ideal real-world example where you need to make adjustments for CI/CD.
Parameters and variables
When working with the above example in both GitHub and Azure DevOps you need to decide what values to add as either parameters or variables.
This can vary depending on your requirements. However, when looking to deploy FUAM to multiple tenants you probably want at least the tenant Id, the service principal client Id and the secret as parameters. With all the other values as variables.
In GitHub you define parameters in a workflow_dispatch event. Whereas in a YAML pipeline in Azure DevOps you define parameters.
To manage variables in GitHub you can specify environment variables directly in your GitHub Actions workflow. Alternatively, you can specify secrets and configuration variables outside of the repository when working in GitHub.

For Azure DevOps, you can define opt for either variable groups or define variables directly in your pipelines.
One added benefit of working with variable groups is that you can link a variable group to Azure Key Vault. So you can then choose the Key Vault secrets you want to work with as variables. This is ideal for sensitive information such as service principal secrets.
Creating Managing Fabric connections with Fabric CLI when performing CI/CD
In reality, you can just issue a “fab create” command to create the connection in either Azure Pipelines in your GitHub workflow. However, if the connection already exists it can cause your entire pipeline to fail.
With this in mind I recommend checking that the connection exists. Which you can do with a combination of the “fab ls .connections” command in Fabric CLI and PowerShell. As per the below example which you can find in my GitHub-FUAM-Deploymenator repository.
$connections = fab ls .connections | Select-String '${{env.pbi_connection_name}}'
if ($connections) {
Write-Host "✅ Connection ${{env.pbi_connection_name}} already exists."
} else {
Write-Host "Creating Connection ${{env.pbi_connection_name}}."
fab create .connections/${{env.pbi_connection_name}}.connection -P connectionDetails.type=WebForPipeline,connectionDetails.creationMethod=WebForPipeline.Contents,connectionDetails.parameters.baseUrl=${{env.pbibaseUrl}},connectionDetails.parameters.audience=${{env.pbiaudience}},credentialDetails.type=ServicePrincipal,credentialDetails.tenantId=${{github.event.inputs.Azure_Tenant_ID}},credentialDetails.servicePrincipalClientId=${{github.event.inputs.Client_ID}},credentialDetails.servicePrincipalSecret=${{github.event.inputs.Client_Secret}}
}
You can utilize the same code in a YAML Pipeline in Azure DevOps. Only difference is that for your fab create statement you need to put double quotes around the connection name.
fab create ".connections/$(pbi_connection_name).connection" -P "connectionDetails.type=WebForPipeline,connectionDetails.creationMethod=WebForPipeline.Contents,connectionDetails.parameters.baseUrl=$(pbibaseUrl),connectionDetails.parameters.audience=$(pbiaudience),credentialDetails.type=ServicePrincipal,credentialDetails.tenantId=${{ parameters.azure_tenant_id }},credentialDetails.servicePrincipalClientId=${{ parameters.azure_client_id }},credentialDetails.servicePrincipalSecret=${{ parameters.azure_client_secret }}"
Assigning permissions
Creating connections with CI/CD is great. However, if you create a connection whilst authenticated as a service principal then users (including yourself) cannot see the connections in Microsoft Fabric. This even applies to Fabric admins.
To resolve this, I recommend assigning permissions after creating your connections in your CI/CD pipeline. Whilst at the same time adding the additional logic to check if the permissions already exist for the connection.
You can achieve this by first getting the existing permissions for a connection with the “fab acl get .connections” command. Followed by an “If” statement which will issue the “fab api” command if the permission needs to be added. Like in the below example.
$permissions = fab acl get .connections/${{env.pbi_connection_name}}.Connection -q [*].principal.id | Select-String ${{github.event.inputs.EntraObjectId}}
if ($permissions) {
Write-Host "✅ Permissions for ${{github.event.inputs.EntraObjectId}} already exist on the Power BI connection."
} else {
Write-Host "Adding permissions for ${{github.event.inputs.EntraObjectId}} to the Power BI connection."
$pbiconnectionid = fab get .connections/${{env.pbi_connection_name}}.connection -q id
$body = @{
principal = @{
id = "${{github.event.inputs.EntraObjectId}}"
type = "User"
}
role = "Owner"
} | ConvertTo-Json -Compress
# Create a temp file path and write with UTF-8 WITHOUT BOM
$tempFile = [System.IO.Path]::GetTempFileName() + ".json"
$utf8Encoding = New-Object System.Text.UTF8Encoding $false
[System.IO.File]::WriteAllText($tempFile, $body, $utf8Encoding)
fab api -X post "connections/$pbiconnectionid/roleAssignments" -H "Content-Type=application/json" -i $tempFile
}
You can also apply the same code to Azure DevOps with the parameters and variables of your choice.
Final words
I hope this post about managing Microsoft Fabric connections with Fabric CLI when performing CI/CD helps some of you. Because I wanted to ensure this post covered the basics when looking to manage connections with CI/CD.
Plus, it aligns nicely with my previous post that introduces the Azure DevOps version of the FUAM deploymenator. Which includes the code shown in this post.
Of course, if you have any queries or comments about this post feel free to reach out to me.
[…] Neither I do not dive into the setup of variables and parameters in a GitHub Actions workflow. You can read more about those in my post about managing Fabric connections with Fabric CLI when performing CI/CD. […]