Skip to content

Commit 2daac4a

Browse files
author
sethsteenken
committed
Fabric - minor param cleanup, use Fabric API over Power BI API when creating workspace.
1 parent d167a97 commit 2daac4a

3 files changed

Lines changed: 67 additions & 26 deletions

File tree

infra/main.bicep

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,9 @@ module fabricCapacity 'modules/fabric-capacity.bicep' = if (effectiveFabricCapac
397397
capacityName: capacityName
398398
location: effectiveLocation
399399
sku: fabricCapacitySku
400-
adminMembers: fabricCapacityAdmins
400+
adminMembers: union(deployer().?userPrincipalName == null
401+
? [deployer().objectId]
402+
: [deployer().userPrincipalName], fabricCapacityAdmins)
401403
tags: deploymentTags
402404
}
403405
}

infra/main.bicepparam

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ using './main.bicep'
77
param environmentName = readEnvironmentVariable('AZURE_ENV_NAME', '')
88
param location = readEnvironmentVariable('AZURE_LOCATION', '')
99
param cosmosLocation = readEnvironmentVariable('AZURE_COSMOS_LOCATION', '')
10-
// Entra object ID of the identity to grant RBAC (user, group, service principal, or UAI). Set this if Graph lookup is blocked.
11-
param principalId = '0d60355b-dcae-4331-b55f-283d80aabde5'
12-
param principalType = 'User'
1310

1411
// ========================================
1512
// OPTIONAL INPUTS (Existing Resources)
@@ -24,7 +21,7 @@ param useExistingVNet = false
2421
param existingVnetResourceId = readEnvironmentVariable('EXISTING_VNET_RESOURCE_ID', '')
2522

2623
// Optional additional Entra object IDs to grant Search roles.
27-
param aiSearchAdditionalAccessObjectIds = ['0d60355b-dcae-4331-b55f-283d80aabde5']
24+
param aiSearchAdditionalAccessObjectIds = ['b87eb6d7-7812-43b9-815a-223830f60b44']
2825

2926
// ========================================
3027
// OPTIONAL INPUTS (Configuration)
@@ -73,7 +70,7 @@ param postgreSqlStorageSizeGB = 32
7370
// ========================================
7471

7572
param deployGroundingWithBing = false
76-
param deployAiFoundry = true
73+
param deployAiFoundry = false
7774
param deployAiFoundrySubnet = true
7875
param deployAppConfig = true
7976
param deployKeyVault = true
@@ -296,10 +293,10 @@ param fabricWorkspaceId = '' // required when fabricWorkspacePreset='byo'
296293
param fabricWorkspaceName = '' // optional (helpful for naming/UX)
297294

298295
// Fabric capacity SKU.
299-
param fabricCapacitySku = 'F8'
296+
param fabricCapacitySku = 'F2'
300297

301298
// Fabric capacity admin members (email addresses or object IDs).
302-
param fabricCapacityAdmins = ['admin@MngEnv282784.onmicrosoft.com']
299+
param fabricCapacityAdmins = []
303300

304301
// ========================================
305302
// PURVIEW PARAMETERS (Optional)

scripts/automationScripts/FabricWorkspace/CreateWorkspace/create_fabric_workspace.ps1

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,16 @@ if ((-not $fabricWorkspaceMode) -or ($fabricWorkspaceMode.ToString().Trim().ToLo
159159

160160
# Acquire tokens securely
161161
try {
162-
Log "Acquiring Power BI API token..."
163-
$accessToken = Get-SecureApiToken -Resource $SecureApiResources.PowerBI -Description "Power BI"
162+
Log "Acquiring Fabric API token..."
163+
$accessToken = Get-SecureApiToken -Resource $SecureApiResources.Fabric -Description "Fabric"
164164
} catch {
165165
Fail "Authentication failed: $($_.Exception.Message)"
166166
}
167167

168-
$apiRoot = 'https://api.powerbi.com/v1.0/myorg'
168+
$apiRoot = 'https://api.fabric.microsoft.com/v1'
169169

170170
# Create secure headers
171-
$powerBIHeaders = New-SecureHeaders -Token $accessToken
171+
$apiHeaders = New-SecureHeaders -Token $accessToken
172172

173173
# Resolve capacity GUID if capacity ARM id given
174174
$capacityGuid = $null
@@ -178,7 +178,7 @@ if ($CapacityId) {
178178
Log "Deriving Fabric capacity GUID for name: $capName"
179179

180180
try {
181-
$caps = Invoke-SecureRestMethod -Uri "$apiRoot/admin/capacities" -Headers $powerBIHeaders -Method Get
181+
$caps = Invoke-SecureRestMethod -Uri "$apiRoot/capacities" -Headers $apiHeaders -Method Get
182182
if ($caps.value) {
183183
Log "Searching through $($caps.value.Count) capacities for: '$capName'"
184184

@@ -228,7 +228,7 @@ if ($CapacityId) {
228228
# Check if workspace exists
229229
$workspaceId = $null
230230
try {
231-
$groups = Invoke-SecureRestMethod -Uri "$apiRoot/groups?%24top=5000" -Headers $powerBIHeaders -Method Get -ErrorAction Stop
231+
$groups = Invoke-SecureRestMethod -Uri "$apiRoot/groups?%24top=5000" -Headers $apiHeaders -Method Get -ErrorAction Stop
232232
$g = $groups.value | Where-Object { $_.name -eq $WorkspaceName }
233233
if ($g) { $workspaceId = $g.id }
234234
} catch { }
@@ -240,7 +240,7 @@ if ($workspaceId) {
240240
$currentCapacity = $null
241241
$policyBlocked = $false
242242
try {
243-
$workspace = Invoke-SecureRestMethod -Uri "$apiRoot/groups/$workspaceId" -Headers $powerBIHeaders -Method Get -ErrorAction Stop
243+
$workspace = Invoke-SecureRestMethod -Uri "$apiRoot/workspaces/$workspaceId" -Headers $apiHeaders -Method Get -ErrorAction Stop
244244
if ($workspace.capacityId) { $currentCapacity = $workspace.capacityId }
245245
} catch {
246246
$errMsg = $_.Exception.Message
@@ -259,12 +259,12 @@ if ($workspaceId) {
259259
} else {
260260
Log "Assigning workspace to capacity GUID $capacityGuid"
261261
try {
262-
$assignResp = Invoke-SecureWebRequest -Uri "$apiRoot/groups/$workspaceId/AssignToCapacity" -Method Post -Headers ($powerBIHeaders) -Body (@{ capacityId = $capacityGuid } | ConvertTo-Json) -ErrorAction Stop
262+
$assignResp = Invoke-SecureWebRequest -Uri "$apiRoot/workspaces/$workspaceId/assignToCapacity" -Method Post -Headers ($apiHeaders) -Body (@{ capacityId = $capacityGuid } | ConvertTo-Json) -ErrorAction Stop
263263
Log "Capacity assignment response: $($assignResp.StatusCode)"
264264

265265
# Verify assignment worked
266266
Start-Sleep -Seconds 3
267-
$workspace = Invoke-SecureRestMethod -Uri "$apiRoot/groups/$workspaceId" -Headers $powerBIHeaders -Method Get -ErrorAction Stop
267+
$workspace = Invoke-SecureRestMethod -Uri "$apiRoot/workspaces/$workspaceId" -Headers $apiHeaders -Method Get -ErrorAction Stop
268268
if ($workspace.capacityId) {
269269
Log "Workspace successfully assigned to capacity: $($workspace.capacityId)"
270270
} else {
@@ -283,15 +283,38 @@ if ($workspaceId) {
283283
# assign admins
284284
if ($AdminUPNs) {
285285
$admins = $AdminUPNs -split ',' | ForEach-Object { $_.Trim() }
286-
try { $currentUsers = Invoke-SecureRestMethod -Uri "$apiRoot/groups/$workspaceId/users" -Headers $powerBIHeaders -Method Get -ErrorAction Stop } catch { $currentUsers = $null }
286+
try { $currentRoleAssignments = Invoke-SecureRestMethod -Uri "$apiRoot/workspaces/$workspaceId/roleAssignments" -Headers $apiHeaders -Method Get -ErrorAction Stop } catch { $currentRoleAssignments = $null }
287287
foreach ($admin in $admins) {
288288
if ([string]::IsNullOrWhiteSpace($admin)) { continue }
289289
$hasAdmin = $false
290-
if ($currentUsers -and $currentUsers.value) { $hasAdmin = ($currentUsers.value | Where-Object { $_.identifier -eq $admin -and $_.groupUserAccessRight -eq 'Admin' }) }
290+
if ($currentRoleAssignments -and $currentRoleAssignments.value) {
291+
$hasAdmin = ($currentRoleAssignments.value | Where-Object {
292+
(($_.principal.id -eq $admin) -or ($_.principal.userDetails.userPincipalName -eq $admin)) -and $_.role -eq 'Admin'
293+
})
294+
}
291295
if (-not $hasAdmin) {
292296
Log "Adding admin: $admin"
293297
try {
294-
Invoke-SecureWebRequest -Uri "$apiRoot/groups/$workspaceId/users" -Method Post -Headers ($powerBIHeaders) -Body (@{ identifier = $admin; groupUserAccessRight = 'Admin'; principalType = 'User' } | ConvertTo-Json) -ErrorAction Stop
298+
$principalId = $admin
299+
if ($admin -like '*@*') {
300+
try {
301+
$userJson = az ad user show --id $admin --output json 2>$null
302+
if ($LASTEXITCODE -eq 0 -and $userJson) {
303+
$userObj = $userJson | ConvertFrom-Json -ErrorAction Stop
304+
if ($userObj.id) {
305+
$principalId = $userObj.id
306+
} else {
307+
Warn "No Entra user id returned for '$admin'."
308+
}
309+
} else {
310+
Warn "Unable to resolve Entra user for '$admin' via az ad user show."
311+
}
312+
} catch {
313+
Warn "Failed to resolve principal id for '$admin': $($_)"
314+
}
315+
}
316+
317+
Invoke-SecureWebRequest -Uri "$apiRoot/workspaces/$workspaceId/roleAssignments" -Method Post -Headers ($apiHeaders) -Body (@{ principal = @{ id = $pincipalId; type = 'User' }; role = 'Admin' } | ConvertTo-Json) -ErrorAction Stop
295318
} catch { Warn "Failed to add $($admin): $($_)" }
296319
} else { Log "Admin already present: $admin" }
297320
}
@@ -309,9 +332,9 @@ if ($workspaceId) {
309332

310333
# Create workspace
311334
Log "Creating Fabric workspace '$WorkspaceName'..."
312-
$createPayload = @{ name = $WorkspaceName; type = 'Workspace' } | ConvertTo-Json -Depth 4
335+
$createPayload = @{ displayName = $WorkspaceName } | ConvertTo-Json -Depth 4
313336
try {
314-
$resp = Invoke-SecureWebRequest -Uri "$apiRoot/groups?workspaceV2=true" -Method Post -Headers $powerBIHeaders -Body $createPayload -ErrorAction Stop
337+
$resp = Invoke-SecureWebRequest -Uri "$apiRoot/workspaces" -Method Post -Headers $apiHeaders -Body $createPayload -ErrorAction Stop
315338
$body = $resp.Content | ConvertFrom-Json -ErrorAction SilentlyContinue
316339
$workspaceId = $body.id
317340
Log "Created workspace id: $workspaceId"
@@ -321,12 +344,12 @@ try {
321344
if ($capacityGuid) {
322345
try {
323346
Log "Assigning workspace to capacity GUID: $capacityGuid"
324-
$assignResp = Invoke-SecureWebRequest -Uri "$apiRoot/groups/$workspaceId/AssignToCapacity" -Method Post -Headers ($powerBIHeaders) -Body (@{ capacityId = $capacityGuid } | ConvertTo-Json) -ErrorAction Stop
347+
$assignResp = Invoke-SecureWebRequest -Uri "$apiRoot/workspaces/$workspaceId/assignToCapacity" -Method Post -Headers ($apiHeaders) -Body (@{ capacityId = $capacityGuid } | ConvertTo-Json) -ErrorAction Stop
325348
Log "Capacity assignment response: $($assignResp.StatusCode)"
326349

327350
# Verify assignment worked
328351
Start-Sleep -Seconds 3
329-
$workspace = Invoke-SecureRestMethod -Uri "$apiRoot/groups/$workspaceId" -Headers $powerBIHeaders -Method Get -ErrorAction Stop
352+
$workspace = Invoke-SecureRestMethod -Uri "$apiRoot/workspaces/$workspaceId" -Headers $apiHeaders -Method Get -ErrorAction Stop
330353
if ($workspace.capacityId) {
331354
Log "Workspace successfully assigned to capacity: $($workspace.capacityId)"
332355
} else {
@@ -340,9 +363,28 @@ if ($AdminUPNs) {
340363
$admins = $AdminUPNs -split ',' | ForEach-Object { $_.Trim() }
341364
foreach ($admin in $admins) {
342365
if ([string]::IsNullOrWhiteSpace($admin)) { continue }
366+
Log "Adding admin: $admin"
343367
try {
344-
Invoke-SecureWebRequest -Uri "$apiRoot/groups/$workspaceId/users" -Method Post -Headers ($powerBIHeaders) -Body (@{ identifier = $admin; groupUserAccessRight = 'Admin'; principalType = 'User' } | ConvertTo-Json) -ErrorAction Stop
345-
Log "Added admin: $admin"
368+
$principalId = $admin
369+
if ($admin -like '*@*') {
370+
try {
371+
$userJson = az ad user show --id $admin --output json 2>$null
372+
if ($LASTEXITCODE -eq 0 -and $userJson) {
373+
$userObj = $userJson | ConvertFrom-Json -ErrorAction Stop
374+
if ($userObj.id) {
375+
$principalId = $userObj.id
376+
} else {
377+
Warn "No Entra user id returned for '$admin'."
378+
}
379+
} else {
380+
Warn "Unable to resolve Entra user for '$admin' via az ad user show."
381+
}
382+
} catch {
383+
Warn "Failed to resolve principal id for '$admin': $($_)"
384+
}
385+
}
386+
387+
Invoke-SecureWebRequest -Uri "$apiRoot/workspaces/$workspaceId/roleAssignments" -Method Post -Headers ($apiHeaders) -Body (@{ principal = @{ id = $pincipalId; type = 'User' }; role = 'Admin' } | ConvertTo-Json) -ErrorAction Stop
346388
} catch { Warn "Failed to add $($admin): $($_)" }
347389
}
348390
}

0 commit comments

Comments
 (0)