зеркало из https://github.com/Azure/ipam.git
set default parameter values for engine and ui app names, update name of deployscript to something more pertinent
This commit is contained in:
Коммит
39da8ded93
|
@ -1,5 +1,6 @@
|
|||
CLIENT_ID=<SERVICE PRINCIPAL CLIENT ID>
|
||||
CLIENT_SECRET=<SERVICE PRINCIPAL SECRET>
|
||||
ENGINE_APP_ID=<ENGINE SERVICE PRINCIPAL CLIENT ID>
|
||||
ENGINE_APP_SECRET=<ENGINE SERVICE PRINCIPAL SECRET>
|
||||
UI_APP_ID=<UI SERVICE PRINCIPAL CLIENT ID>
|
||||
TENANT_ID=<AZURE AD TENANT ID>
|
||||
COSMOS_URL=https://<COSMOS NAME>.documents.azure.com
|
||||
COSMOS_KEY=<COSMOS ACCESS KEY>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
{
|
||||
"editor.tabSize": 2
|
||||
"editor.tabSize": 2,
|
||||
"editor.detectIndentation": false
|
||||
}
|
|
@ -56,6 +56,7 @@ resource appService 'Microsoft.Web/sites@2021-02-01' = {
|
|||
serverFarmId: appServicePlan.id
|
||||
keyVaultReferenceIdentity: managedIdentityId
|
||||
siteConfig: {
|
||||
alwaysOn: true
|
||||
linuxFxVersion: 'COMPOSE|${dockerCompose}'
|
||||
acrUseManagedIdentityCreds: true
|
||||
acrUserManagedIdentityID: managedIdentityClientId
|
||||
|
@ -77,7 +78,7 @@ resource appService 'Microsoft.Web/sites@2021-02-01' = {
|
|||
value: '@Microsoft.KeyVault(SecretUri=${keyVaultUri}secrets/ENGINE-ID/)'
|
||||
}
|
||||
{
|
||||
name: 'ENGINE_SECRET'
|
||||
name: 'ENGINE_APP_SECRET'
|
||||
value: '@Microsoft.KeyVault(SecretUri=${keyVaultUri}secrets/ENGINE-SECRET/)'
|
||||
}
|
||||
{
|
||||
|
|
|
@ -10,331 +10,535 @@
|
|||
#Requires -Modules @{ ModuleName="Microsoft.Graph"; ModuleVersion="1.9.6"}
|
||||
|
||||
# Intake and set global parameters
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$location="westus3",
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$namePrefix="ipam",
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$tags
|
||||
[CmdletBinding(DefaultParameterSetName = 'Full')]
|
||||
param(
|
||||
[Parameter(Mandatory = $true,
|
||||
ParameterSetName = 'Full')]
|
||||
[Parameter(Mandatory = $true,
|
||||
ParameterSetName = 'TemplateOnly')]
|
||||
[string]
|
||||
$Location,
|
||||
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'Full')]
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'AppsOnly')]
|
||||
[string]
|
||||
$UIAppName = 'ipam-ui-app',
|
||||
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'Full')]
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'AppsOnly')]
|
||||
[string]
|
||||
$EngineAppName = 'ipam-engine-app',
|
||||
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'Full')]
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'TemplateOnly')]
|
||||
[string]
|
||||
$NamePRefix,
|
||||
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'Full')]
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'TemplateOnly')]
|
||||
[hashtable]
|
||||
$Tags,
|
||||
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'TemplateOnly')]
|
||||
[switch]
|
||||
$TemplateOnly,
|
||||
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'AppsOnly')]
|
||||
[switch]
|
||||
$AppsOnly,
|
||||
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'Full')]
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'AppsOnly')]
|
||||
[switch]
|
||||
$NoConsent,
|
||||
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'Full')]
|
||||
[Parameter(Mandatory = $false,
|
||||
ParameterSetName = 'AppsOnly')]
|
||||
[switch]
|
||||
$SubscriptionScope,
|
||||
|
||||
[Parameter(Mandatory = $true,
|
||||
ParameterSetName = 'TemplateOnly')]
|
||||
[ValidateScript({
|
||||
if(-Not ($_ | Test-Path) ){
|
||||
throw "File or does not exist."
|
||||
}
|
||||
if(-Not ($_ | Test-Path -PathType Leaf) ){
|
||||
throw "The ParameterFile argument must be a file, folder paths are not allowed."
|
||||
}
|
||||
if($_ -notmatch "(\.json)"){
|
||||
throw "The file specified in the ParameterFile argument must be of type json."
|
||||
}
|
||||
return $true
|
||||
})]
|
||||
[System.IO.FileInfo]$ParameterFile
|
||||
)
|
||||
$engineApiGuid = New-Guid
|
||||
$logFile = "./deploy_$(get-date -format `"yyyyMMddhhmmsstt`").log"
|
||||
$tenantId = (Get-AzContext).Tenant.Id
|
||||
|
||||
# Set preference variables
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Function validateLocation {
|
||||
# Validate Azure Region
|
||||
Write-Host "INFO: Validating Azure Region selected for deployment" -ForegroundColor green
|
||||
Write-Verbose -Message "Validating Azure Region selected for deployment"
|
||||
|
||||
$validLocations = Get-AzLocation
|
||||
if ($location -in ($validLocations | Select-Object -ExpandProperty Location)) {
|
||||
foreach ($l in $validLocations) {
|
||||
if ($location -eq $l.Location) {
|
||||
$script:locationName = $l.DisplayName
|
||||
# Hide Azure PowerShell SDK Warnings
|
||||
$Env:SuppressAzurePowerShellBreakingChangeWarnings = $true
|
||||
|
||||
Write-Host "INFO: Azure Region validated successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Azure Region validated successfully"
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host "ERROR: Location provided is not a valid Azure Region!" -ForegroundColor red
|
||||
exit
|
||||
|
||||
}
|
||||
# Set Log File Location
|
||||
$logFile = "./deploy_$(get-date -format `"yyyyMMddhhmmsstt`").log"
|
||||
|
||||
Function Test-Location {
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Location
|
||||
)
|
||||
|
||||
$validLocations = Get-AzLocation | Select-Object -ExpandProperty Location
|
||||
|
||||
return $validLocations.Contains($Location)
|
||||
}
|
||||
|
||||
Function deployEngineApplication {
|
||||
$azureSvcMgmtApiPermissionsScope = "user_impersonation"
|
||||
$azureSvcMgmtAppId ="797f4846-ba00-4fd7-ba43-dac1f8f63013"
|
||||
$msGraphApiPermissionsScope = "offline_access openid profile User.Read"
|
||||
$msGraphAppId = "00000003-0000-0000-c000-000000000000"
|
||||
$engineResourceAccess = [System.Collections.ArrayList]@(
|
||||
Function Deploy-IPAMApplications {
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$EngineAppName,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$UIAppName,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$TenantId,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[bool]$SubscriptionScope
|
||||
)
|
||||
|
||||
$uiResourceAccess = [System.Collections.ArrayList]@(
|
||||
@{
|
||||
ResourceAppId = "00000003-0000-0000-c000-000000000000"; # Microsoft Graph
|
||||
ResourceAccess = @(
|
||||
@{
|
||||
ResourceAppId = "00000003-0000-0000-c000-000000000000";
|
||||
ResourceAccess = @(
|
||||
@{
|
||||
Id = "7427e0e9-2fba-42fe-b0c0-848c9e6a8182";
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d";
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "37f7f235-527c-4136-accd-4a02d197296e";
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "14dad69e-099b-42c9-810b-d002981feec1";
|
||||
Type = "Scope"
|
||||
}
|
||||
)
|
||||
Id = "37f7f235-527c-4136-accd-4a02d197296e"; # openid
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
ResourceAppId = "797f4846-ba00-4fd7-ba43-dac1f8f63013";
|
||||
ResourceAccess = @(
|
||||
@{
|
||||
Id = "41094075-9dad-400e-a0bd-54e686782033";
|
||||
Type = "Scope"
|
||||
}
|
||||
)
|
||||
Id = "14dad69e-099b-42c9-810b-d002981feec1"; # profile
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "7427e0e9-2fba-42fe-b0c0-848c9e6a8182"; # offline_access
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d"; # User.Read
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "06da0dbc-49e2-44d2-8312-53f166ab848a"; # Directory.Read.All
|
||||
Type = "Scope"
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
# Create IPAM engine application
|
||||
Write-Host "INFO: Creating Azure IPAM Engine Service Principal" -ForegroundColor green
|
||||
Write-Verbose -Message "Creating Azure IPAM Engine Service Principal"
|
||||
$global:engineApp = New-AzADApplication `
|
||||
-DisplayName "ipam-engine-app" `
|
||||
$uiWebSettings = @{
|
||||
ImplicitGrantSetting = @{
|
||||
EnableAccessTokenIssuance = $true
|
||||
EnableIdTokenIssuance = $true
|
||||
}
|
||||
}
|
||||
|
||||
# Create IPAM UI Application
|
||||
Write-Host "INFO: Creating Azure IPAM UI Application" -ForegroundColor green
|
||||
Write-Verbose -Message "Creating Azure IPAM UI Application"
|
||||
$uiApp = New-AzADApplication `
|
||||
-DisplayName $UiAppName `
|
||||
-SPARedirectUri "https://replace-this-value.azurewebsites.net" `
|
||||
-Web $uiWebSettings
|
||||
|
||||
$engineResourceAccess = [System.Collections.ArrayList]@(
|
||||
@{
|
||||
ResourceAppId = "797f4846-ba00-4fd7-ba43-dac1f8f63013"; # Azure Service Management
|
||||
ResourceAccess = @(
|
||||
@{
|
||||
Id = "41094075-9dad-400e-a0bd-54e686782033"; # user_impersonation
|
||||
Type = "Scope"
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
$engineApiGuid = New-Guid
|
||||
|
||||
$engineApiSettings = @{
|
||||
KnownClientApplication = @(
|
||||
$uiApp.AppId
|
||||
)
|
||||
Oauth2PermissionScope = @(
|
||||
@{
|
||||
AdminConsentDescription = "Allows the IPAM UI to access IPAM Engine API as the signed-in user."
|
||||
AdminConsentDisplayName = "Access IPAM Engine API"
|
||||
Id = $engineApiGuid
|
||||
IsEnabled = $true
|
||||
Type = "User"
|
||||
UserConsentDescription = "Allow the IPAM UI to access IPAM Engine API on your behalf."
|
||||
UserConsentDisplayName = "Access IPAM Engine API"
|
||||
Value = "access_as_user"
|
||||
}
|
||||
)
|
||||
RequestedAccessTokenVersion = 2
|
||||
}
|
||||
|
||||
# Create IPAM Engine Application
|
||||
Write-Host "INFO: Creating Azure IPAM Engine Application" -ForegroundColor green
|
||||
Write-Verbose -Message "Creating Azure IPAM Engine Application"
|
||||
$engineApp = New-AzADApplication `
|
||||
-DisplayName $EngineAppName `
|
||||
-Api $engineApiSettings `
|
||||
-RequiredResourceAccess $engineResourceAccess
|
||||
|
||||
# Update IPAM engine application with API endpoint
|
||||
Update-AzADApplication -ApplicationId $global:engineApp.AppId -IdentifierUri "api://$($global:engineApp.AppId)"
|
||||
|
||||
# Create IPAM engine service principal
|
||||
$engineSpn = New-AzADServicePrincipal `
|
||||
-ApplicationObject $global:engineApp `
|
||||
-Role "Reader" `
|
||||
-Scope "/providers/Microsoft.Management/managementGroups/$($tenantId)"
|
||||
# Update IPAM Engine API endpoint
|
||||
Write-Host "INFO: Updating Azure IPAM Engine API Endpoint" -ForegroundColor green
|
||||
Write-Verbose -Message "Updating Azure IPAM UI Engine API Endpoint"
|
||||
Update-AzADApplication -ApplicationId $engineApp.AppId -IdentifierUri "api://$($engineApp.AppId)"
|
||||
|
||||
# Create IPAM engine service principal credential
|
||||
$global:engineSecret = New-AzADAppCredential -ApplicationObject $global:engineApp -StartDate (Get-Date) -EndDate (Get-Date).AddYears(2)
|
||||
|
||||
Write-Host "INFO: Azure IPAM Engine Application & Service Principal created successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Azure IPAM Engine Application & Service Principal created successfully"
|
||||
|
||||
# Instantiate Microsoft Graph service principal object
|
||||
$msGraphSpn = Get-AzADServicePrincipal `
|
||||
-ApplicationId $msGraphAppId
|
||||
|
||||
# Instantiate Azure Service Management service principal object
|
||||
$azureSvcMgmtSpn = Get-AzADServicePrincipal `
|
||||
-ApplicationId $azureSvcMgmtAppId
|
||||
|
||||
# Grant admin consent for Microsoft Graph API permissions assigned to IPAM engine application
|
||||
Write-Host "INFO: Granting admin consent for Microsoft Graph API permissions assigned to IPAM Engine Application" -ForegroundColor Green
|
||||
Write-Verbose -Message "Granting admin consent for Microsoft Graph API permissions assigned to IPAM Engine Application"
|
||||
New-MgOauth2PermissionGrant `
|
||||
-ResourceId $msGraphSpn.Id `
|
||||
-Scope $msGraphApiPermissionsScope `
|
||||
-ClientId $engineSpn.Id `
|
||||
-ConsentType AllPrincipals `
|
||||
| Out-Null
|
||||
|
||||
Write-Host "INFO: Admin consent for Microsoft Graph API permissions granted successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Admin consent for Microsoft Graph API permissions granted successfully"
|
||||
|
||||
# Grant admin consent for Azure Service Management API permissions assigned to IPAM application
|
||||
Write-Host "INFO: Granting admin consent for Azure Service Management API permissions assigned to IPAM ENgine Application" -ForegroundColor Green
|
||||
Write-Verbose -Message "Granting admin consent for Azure Service Management API permissions assigned to IPAM Engine Application"
|
||||
New-MgOauth2PermissionGrant `
|
||||
-ResourceId $azureSvcMgmtSpn.Id `
|
||||
-Scope $azureSvcMgmtApiPermissionsScope `
|
||||
-ClientId $engineSpn.Id `
|
||||
-ConsentType AllPrincipals `
|
||||
| Out-Null
|
||||
|
||||
Write-Host "INFO: Admin consent for Azure Service Management API permissions granted successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Admin consent for Azure Service Management API API permissions granted successfully"
|
||||
|
||||
}
|
||||
|
||||
Function deployUiApplication {
|
||||
$engineApiPermissionsScope = "access_as_user"
|
||||
$msGraphAppId = "00000003-0000-0000-c000-000000000000"
|
||||
$msGraphApiPermissionsScope = "Directory.Read.All openid User.Read"
|
||||
$uiResourceAccess = [System.Collections.ArrayList]@(
|
||||
@{
|
||||
ResourceAppId = "00000003-0000-0000-c000-000000000000";
|
||||
ResourceAccess = @(
|
||||
@{
|
||||
Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d";
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "37f7f235-527c-4136-accd-4a02d197296e";
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "06da0dbc-49e2-44d2-8312-53f166ab848a";
|
||||
Type = "Scope"
|
||||
}
|
||||
)
|
||||
},
|
||||
@{
|
||||
ResourceAppId = $global:engineApp.AppId;
|
||||
ResourceAccess = @(
|
||||
@{
|
||||
Id = $engineApiGuid;
|
||||
Type = "Scope"
|
||||
}
|
||||
)
|
||||
}
|
||||
$uiEngineApiAccess =@{
|
||||
ResourceAppId = $engineApp.AppId
|
||||
ResourceAccess = @(
|
||||
@{
|
||||
Id = $engineApiGuid
|
||||
Type = "Scope"
|
||||
}
|
||||
)
|
||||
$uiWebSettings = @{
|
||||
ImplicitGrantSetting = @{
|
||||
EnableAccessTokenIssuance = $true
|
||||
EnableIdTokenIssuance = $true
|
||||
}
|
||||
}
|
||||
|
||||
$uiResourceAccess.Add($uiEngineApiAccess) | Out-Null
|
||||
|
||||
# Update IPAM UI Application Resource Access
|
||||
Write-Host "INFO: Updating Azure IPAM UI Application Resource Access" -ForegroundColor green
|
||||
Write-Verbose -Message "Updating Azure IPAM UI Application Resource Access"
|
||||
Update-AzADApplication -ApplicationId $uiApp.AppId -RequiredResourceAccess $uiResourceAccess
|
||||
|
||||
$uiObject = Get-AzADApplication -ApplicationId $uiApp.AppId
|
||||
$engineObject = Get-AzADApplication -ApplicationId $engineApp.AppId
|
||||
|
||||
# Create IPAM UI Service Principal
|
||||
Write-Host "INFO: Creating Azure IPAM UI Service Principal" -ForegroundColor green
|
||||
Write-Verbose -Message "Creating Azure IPAM UI Service Principal"
|
||||
New-AzADServicePrincipal -ApplicationObject $uiObject | Out-Null
|
||||
|
||||
if ($SubscriptionScope) {
|
||||
$subscriptionId = $(Get-AzContext).Subscription.Id
|
||||
$scope = "/subscriptions/$subscriptionId"
|
||||
} else {
|
||||
$scope = "/providers/Microsoft.Management/managementGroups/$TenantId"
|
||||
}
|
||||
|
||||
# Create IPAM Engine Service Principal
|
||||
Write-Host "INFO: Creating Azure IPAM Engine Service Principal" -ForegroundColor green
|
||||
Write-Verbose -Message "Creating Azure IPAM Engine Service Principal"
|
||||
New-AzADServicePrincipal -ApplicationObject $engineObject `
|
||||
-Role "Reader" `
|
||||
-Scope $scope `
|
||||
| Out-Null
|
||||
|
||||
# Create IPAM Engine Secret
|
||||
Write-Host "INFO: Creating Azure IPAM Engine Secret" -ForegroundColor green
|
||||
Write-Verbose -Message "Creating Azure IPAM Engine Secret"
|
||||
$engineSecret = New-AzADAppCredential -ApplicationObject $engineObject -StartDate (Get-Date) -EndDate (Get-Date).AddYears(2)
|
||||
|
||||
Write-Host "INFO: Azure IPAM Engine & UI Applications/Service Principals created successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Azure IPAM Engine & UI Applications/Service Principals created successfully"
|
||||
|
||||
$appDetails = @{
|
||||
UIAppId = $uiApp.AppId
|
||||
EngineAppId = $engineApp.AppId
|
||||
EngineSecret = $engineSecret.SecretText
|
||||
}
|
||||
|
||||
return $appDetails
|
||||
}
|
||||
|
||||
Function Grant-AdminConsent {
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$UIAppId,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$EngineAppId
|
||||
)
|
||||
|
||||
$uiGraphScopes = [System.Collections.ArrayList]@(
|
||||
@{
|
||||
scopeId = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
|
||||
scopes = " openid profile offline_access User.Read Directory.Read.All"
|
||||
}
|
||||
)
|
||||
|
||||
# Create IPAM UI Application
|
||||
Write-Host "INFO: Creating Azure IPAM UI Application" -ForegroundColor green
|
||||
Write-Verbose -Message "Creating Azure IPAM UI Application"
|
||||
$global:uiApp = New-AzADApplication `
|
||||
-DisplayName "ipam-ui-app" `
|
||||
-Web $uiWebSettings `
|
||||
-RequiredResourceAccess $uiResourceAccess
|
||||
$engineGraphScopes = [System.Collections.ArrayList]@(
|
||||
@{
|
||||
scopeId = "797f4846-ba00-4fd7-ba43-dac1f8f63013" # Azure Service Management
|
||||
scopes = "user_impersonation"
|
||||
}
|
||||
)
|
||||
|
||||
# Create IPAM UI service principal
|
||||
$uiSpn = New-AzADServicePrincipal -ApplicationObject $global:uiApp
|
||||
# Get Microsoft Graph Access Token
|
||||
$accesstoken = (Get-AzAccessToken -Resource "https://graph.microsoft.com/").Token
|
||||
|
||||
Write-Host "INFO: Azure IPAM UI Application & Service Principal created successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Azure IPAM UI Application & Service Principal created successfully"
|
||||
|
||||
# Instantiate Microsoft Graph service principal object
|
||||
$msGraphSpn = Get-AzADServicePrincipal `
|
||||
-ApplicationId $msGraphAppId
|
||||
# Connect to Microsoft Graph
|
||||
Write-Host "INFO: Logging in to Microsoft Graph" -ForegroundColor green
|
||||
Write-Verbose -Message "Logging in to Microsoft Graph"
|
||||
Connect-MgGraph -AccessToken $accesstoken | Out-Null
|
||||
|
||||
# Instantiate Azure IPAM engine service principal object
|
||||
$engineSpn = Get-AzADServicePrincipal `
|
||||
-ApplicationId $global:engineApp.AppId
|
||||
# Fetch Azure IPAM UI Service Principal
|
||||
$uiSpn = Get-AzADServicePrincipal `
|
||||
-ApplicationId $UIAppId
|
||||
|
||||
# Grant admin consent for Microsoft Graph API permissions assigned to IPAM UI application
|
||||
Write-Host "INFO: Granting admin consent for Microsoft Graph API permissions assigned to IPAM UI Application" -ForegroundColor Green
|
||||
Write-Verbose -Message "Granting admin consent for Microsoft Graph API permissions assigned to IPAM UI Application"
|
||||
# Fetch Azure IPAM Engine Service Principal
|
||||
$engineSpn = Get-AzADServicePrincipal `
|
||||
-ApplicationId $EngineAppId
|
||||
|
||||
# Grant admin consent for Microsoft Graph API permissions assigned to IPAM UI application
|
||||
Write-Host "INFO: Granting admin consent for Microsoft Graph API permissions assigned to IPAM UI Application" -ForegroundColor Green
|
||||
Write-Verbose -Message "Granting admin consent for Microsoft Graph API permissions assigned to IPAM UI Application"
|
||||
foreach($scope in $uiGraphScopes) {
|
||||
$msGraphId = Get-AzADServicePrincipal `
|
||||
-ApplicationId $scope.scopeId
|
||||
|
||||
New-MgOauth2PermissionGrant `
|
||||
-ResourceId $msGraphSpn.Id `
|
||||
-Scope $msGraphApiPermissionsScope `
|
||||
-ClientId $uiSpn.Id `
|
||||
-ConsentType AllPrincipals `
|
||||
| Out-Null
|
||||
-ResourceId $msGraphId.Id `
|
||||
-Scope $scope.scopes `
|
||||
-ClientId $uiSpn.Id `
|
||||
-ConsentType AllPrincipals `
|
||||
| Out-Null
|
||||
}
|
||||
|
||||
Write-Host "INFO: Admin consent for Microsoft Graph API permissions granted successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Admin consent for Microsoft Graph API permissions granted successfully"
|
||||
Write-Host "INFO: Admin consent for Microsoft Graph API permissions granted successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Admin consent for Microsoft Graph API permissions granted successfully"
|
||||
|
||||
# Grant admin consent for Azure Service Management API permissions assigned to IPAM application
|
||||
Write-Host "INFO: Granting admin consent for Azure IPAM Engine API permissions assigned to IPAM UI Application" -ForegroundColor Green
|
||||
Write-Verbose -Message "Granting admin consent for Azure IPAM Engine API permissions assigned to IPAM UI Application"
|
||||
New-MgOauth2PermissionGrant `
|
||||
# Grant admin consent for Azure Service Management API permissions assigned to IPAM application
|
||||
Write-Host "INFO: Granting admin consent for Azure Service Management API permissions assigned to IPAM Engine Application" -ForegroundColor Green
|
||||
Write-Verbose -Message "Granting admin consent for Azure Service Management API permissions assigned to IPAM Engine Application"
|
||||
New-MgOauth2PermissionGrant `
|
||||
-ResourceId $engineSpn.Id `
|
||||
-Scope $engineApiPermissionsScope `
|
||||
-Scope "access_as_user" `
|
||||
-ClientId $uiSpn.Id `
|
||||
-ConsentType AllPrincipals `
|
||||
| Out-Null
|
||||
|
||||
Write-Host "INFO: Admin consent for Azure IPAM Engine API permissions granted successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Admin consent for Azure IPAM Engine API API permissions granted successfully"
|
||||
Write-Host "INFO: Admin consent for Azure Service Management API permissions granted successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Admin consent for Azure Service Management API API permissions granted successfully"
|
||||
|
||||
# Grant admin consent for Microsoft Graph API permissions assigned to IPAM engine application
|
||||
Write-Host "INFO: Granting admin consent for Microsoft Graph API permissions assigned to IPAM Engine Application" -ForegroundColor Green
|
||||
Write-Verbose -Message "Granting admin consent for Microsoft Graph API permissions assigned to IPAM Engine Application"
|
||||
foreach($scope in $engineGraphScopes) {
|
||||
$msGraphId = Get-AzADServicePrincipal `
|
||||
-ApplicationId $scope.scopeId
|
||||
|
||||
New-MgOauth2PermissionGrant `
|
||||
-ResourceId $msGraphId.Id `
|
||||
-Scope $scope.scopes `
|
||||
-ClientId $engineSpn.Id `
|
||||
-ConsentType AllPrincipals `
|
||||
| Out-Null
|
||||
}
|
||||
|
||||
Write-Host "INFO: Admin consent for Microsoft Graph API permissions granted successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Admin consent for Microsoft Graph API permissions granted successfully"
|
||||
}
|
||||
|
||||
Function updateEngineApplication {
|
||||
$engineApiSettings = @{
|
||||
KnownClientApplication = @(
|
||||
$global:uiApp.AppId
|
||||
)
|
||||
Oauth2PermissionScope = @(
|
||||
@{
|
||||
AdminConsentDescription = "Allows the IPAM UI to access IPAM Engine API as the signed-in user."
|
||||
AdminConsentDisplayName = "Access IPAM Engine API"
|
||||
Id = $engineApiGuid
|
||||
IsEnabled = $true
|
||||
Type = "User"
|
||||
UserConsentDescription = "Allow the IPAM UI to access IPAM Engine API on your behalf."
|
||||
UserConsentDisplayName = "Access IPAM Engine API"
|
||||
Value = "access_as_user"
|
||||
}
|
||||
)
|
||||
RequestedAccessTokenVersion = 2
|
||||
}
|
||||
Function Save-Parameters {
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$UIAppId,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$EngineAppId,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$EngineSecret
|
||||
)
|
||||
|
||||
# Update IPAM engine application API settings
|
||||
Write-Host "INFO: Updating Azure IPAM Engine Application" -ForegroundColor green
|
||||
Write-Verbose -Message "Updating Azure IPAM Engine Application"
|
||||
Update-AzADApplication -ApplicationId $global:engineApp.AppId -Api $engineApiSettings
|
||||
Write-Host "INFO: Populating Bicep parameter file for infrastructure deployment" -ForegroundColor Green
|
||||
Write-Verbose -Message "Populating Bicep parameter file for infrastructure deployment"
|
||||
|
||||
|
||||
Write-Host "INFO: Updated Azure IPAM Engine Application successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Updated Azure IPAM Engine Application successfully"
|
||||
# Retrieve JSON object from sample parameter file
|
||||
$parametersObject = Get-Content main.parameters.example.json | ConvertFrom-Json
|
||||
|
||||
# Update Parameter Values
|
||||
$parametersObject.parameters.uiAppId.value = $UIAppId
|
||||
$parametersObject.parameters.engineAppId.value = $EngineAppId
|
||||
$parametersObject.parameters.engineAppSecret.value = $EngineSecret
|
||||
$parametersObject.parameters = $parametersObject.parameters | Select-Object * -ExcludeProperty namePrefix, tags
|
||||
|
||||
# Output updated parameter file for Bicep deployment
|
||||
$parametersObject | ConvertTo-Json -Depth 4 | Out-File -FilePath main.parameters.json
|
||||
|
||||
Write-Host "INFO: Bicep parameter file populated successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Bicep parameter file populated successfully"
|
||||
}
|
||||
|
||||
Function deployBicep {
|
||||
Write-Host "INFO: Deploying IPAM bicep templates" -ForegroundColor green
|
||||
Write-Verbose -Message "Deploying bicep templates"
|
||||
Function Import-Parameters {
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[System.IO.FileInfo]$ParameterFile
|
||||
)
|
||||
|
||||
# Instantiate deployment parameter object
|
||||
$deploymentParameters = @{
|
||||
'engineAppId' = $global:engineApp.AppId
|
||||
'engineAppSecret' = $global:engineSecret.SecretText
|
||||
'namePrefix' = $namePrefix
|
||||
'uiAppId' = $global:uiApp.AppId
|
||||
}
|
||||
Write-Host "INFO: Importing values from Bicep parameters file" -ForegroundColor Green
|
||||
Write-Verbose -Message "Importing values from Bicep parameters file"
|
||||
|
||||
# If tags are defined, add them to deployment parameters object
|
||||
if ($tags) {
|
||||
$tagsParameter = $tags | ConvertFrom-Json -AsHashtable
|
||||
|
||||
$deploymentParameters.Add('tags',$tagsParameter)
|
||||
}
|
||||
# Retrieve JSON object from sample parameter file
|
||||
$parametersObject = Get-Content $ParameterFile | ConvertFrom-Json
|
||||
|
||||
# Deploy IPAM bicep template
|
||||
$global:deployment = New-AzSubscriptionDeployment `
|
||||
# Read Values from Parameters
|
||||
$UIAppId = $parametersObject.parameters.uiAppId.value
|
||||
$EngineAppId = $parametersObject.parameters.engineAppId.value
|
||||
$EngineSecret = $parametersObject.parameters.engineAppSecret.value
|
||||
|
||||
Write-Host "INFO: Successfully import Bicep parameter values" -ForegroundColor green
|
||||
Write-Verbose -Message "Successfully import Bicep parameter values"
|
||||
|
||||
$appDetails = @{
|
||||
UIAppId = $UIAppId
|
||||
EngineAppId = $EngineAppId
|
||||
EngineSecret = $EngineSecret
|
||||
}
|
||||
|
||||
return $appDetails
|
||||
}
|
||||
|
||||
Function Deploy-Bicep {
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$UIAppId,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$EngineAppId,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$EngineSecret,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$NamePrefix,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[hashtable]$Tags
|
||||
)
|
||||
|
||||
Write-Host "INFO: Deploying IPAM bicep templates" -ForegroundColor green
|
||||
Write-Verbose -Message "Deploying bicep templates"
|
||||
|
||||
# Instantiate deployment parameter object
|
||||
$deploymentParameters = @{
|
||||
engineAppId = $EngineAppId
|
||||
engineAppSecret = $EngineSecret
|
||||
uiAppId = $UiAppId
|
||||
}
|
||||
|
||||
if($NamePrefix) {
|
||||
$deploymentParameters.Add('namePrefix', $NamePrefix)
|
||||
}
|
||||
|
||||
if($Tags) {
|
||||
$deploymentParameters.Add('tags', $Tags)
|
||||
}
|
||||
|
||||
# Deploy IPAM bicep template
|
||||
$deployment = New-AzSubscriptionDeployment `
|
||||
-Name "ipamInfraDeploy-$(Get-Date -Format `"yyyyMMddhhmmsstt`")" `
|
||||
-Location $location `
|
||||
-TemplateFile main.bicep `
|
||||
-TemplateParameterObject $deploymentParameters
|
||||
|
||||
Write-Host "INFO: IPAM bicep templates deployed successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "IPAM bicep template deployed successfully"
|
||||
|
||||
Write-Host "INFO: IPAM bicep templates deployed successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "IPAM bicep template deployed successfully"
|
||||
|
||||
return $deployment
|
||||
}
|
||||
|
||||
Function updateUiApplication {
|
||||
Write-Host "INFO: Updating UI Application with SPA configuration" -ForegroundColor green
|
||||
Write-Verbose -Message "Updating UI Application with SPA configuration"
|
||||
|
||||
$uiAppId = $global:deployment.Parameters["uiAppId"].Value
|
||||
$appServiceEndpoint = "https://$($global:deployment.Outputs["appServiceHostName"].Value)"
|
||||
|
||||
# Update UI Application with single-page application configuration
|
||||
Update-AzADApplication -ApplicationId $uiAppId -SPARedirectUri $appServiceEndpoint
|
||||
|
||||
Write-Host "INFO: UI Application SPA configuration update complete" -ForegroundColor green
|
||||
Write-Verbose -Message "UI Application SPA configuration update complete"
|
||||
|
||||
Function Update-UIApplication {
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$UIAppId,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Endpoint
|
||||
)
|
||||
|
||||
Write-Host "INFO: Updating UI Application with SPA configuration" -ForegroundColor green
|
||||
Write-Verbose -Message "Updating UI Application with SPA configuration"
|
||||
|
||||
$appServiceEndpoint = "https://$Endpoint"
|
||||
|
||||
# Update UI Application with single-page application configuration
|
||||
Update-AzADApplication -ApplicationId $UIAppId -SPARedirectUri $appServiceEndpoint
|
||||
|
||||
Write-Host "INFO: UI Application SPA configuration update complete" -ForegroundColor green
|
||||
Write-Verbose -Message "UI Application SPA configuration update complete"
|
||||
}
|
||||
|
||||
try {
|
||||
# Connect to Microsoft Graph
|
||||
$accesstoken = (Get-AzAccessToken -Resource "https://graph.microsoft.com/").Token
|
||||
if ($PSCmdlet.ParameterSetName -in ('Full', 'AppsOnly')) {
|
||||
# Fetch Tenant ID
|
||||
Write-Host "INFO: Fetching Tenant ID from Azure PowerShell SDK" -ForegroundColor green
|
||||
Write-Verbose -Message "Fetching Tenant ID from Azure PowerShell SDK"
|
||||
$tenantId = (Get-AzContext).Tenant.Id
|
||||
}
|
||||
|
||||
Connect-MgGraph -AccessToken $accesstoken
|
||||
if ($PSCmdlet.ParameterSetName -in ('Full', 'TemplateOnly')) {
|
||||
# Validate Azure Region
|
||||
Write-Host "INFO: Validating Azure Region selected for deployment" -ForegroundColor green
|
||||
Write-Verbose -Message "Validating Azure Region selected for deployment"
|
||||
|
||||
validateLocation $location
|
||||
if (Test-Location -Location $Location) {
|
||||
Write-Host "INFO: Azure Region validated successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Azure Region validated successfully"
|
||||
} else {
|
||||
Write-Host "ERROR: Location provided is not a valid Azure Region!" -ForegroundColor red
|
||||
exit
|
||||
}
|
||||
}
|
||||
|
||||
deployEngineApplication
|
||||
if ($PSCmdlet.ParameterSetName -in ('Full', 'AppsOnly')) {
|
||||
$appDetails = Deploy-IPAMApplications `
|
||||
-UIAppName $UIAppName `
|
||||
-EngineAppName $EngineAppName `
|
||||
-TenantId $tenantId `
|
||||
-SubscriptionScope $SubscriptionScope
|
||||
|
||||
deployUiApplication
|
||||
if (-not $NoConsent) {
|
||||
Grant-AdminConsent `
|
||||
-UIAppId $appDetails.UIAppId `
|
||||
-EngineAppId $appDetails.EngineAppId
|
||||
}
|
||||
}
|
||||
|
||||
updateEngineApplication
|
||||
if ($PSCmdlet.ParameterSetName -eq 'AppsOnly') {
|
||||
Save-Parameters @appDetails
|
||||
}
|
||||
|
||||
deployBicep
|
||||
if ($PSCmdlet.ParameterSetName -eq 'TemplateOnly') {
|
||||
$appDetails = Import-Parameters `
|
||||
-ParameterFile $ParameterFile
|
||||
}
|
||||
|
||||
updateUiApplication
|
||||
if ($PSCmdlet.ParameterSetName -in ('Full', 'TemplateOnly')) {
|
||||
$deployment = Deploy-Bicep @appDetails `
|
||||
-NamePrefix $NamePrefix `
|
||||
-Tags $Tags
|
||||
}
|
||||
|
||||
Write-Host "INFO: Azure IPAM Solution deployed successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Azure IPAM Solution deployed successfully"
|
||||
if ($PSCmdlet.ParameterSetName -eq 'Full') {
|
||||
Update-UIApplication `
|
||||
-UIAppId $appDetails.UIAppId `
|
||||
-Endpoint $deployment.Outputs["appServiceHostName"].Value
|
||||
}
|
||||
|
||||
Write-Host "INFO: Azure IPAM Solution deployed successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Azure IPAM Solution deployed successfully"
|
||||
}
|
||||
catch {
|
||||
$_ | Out-File -FilePath $logFile -Append
|
||||
Write-Host "ERROR: Unable to deploy Azure IPAM solution due to an exception, see $logFile for detailed information!" -ForegroundColor red
|
||||
exit
|
||||
|
||||
$_ | Out-File -FilePath $logFile -Append
|
||||
Write-Host "ERROR: Unable to deploy Azure IPAM solution due to an exception, see $logFile for detailed information!" -ForegroundColor red
|
||||
exit
|
||||
}
|
||||
|
|
|
@ -1,292 +0,0 @@
|
|||
###############################################################################################################
|
||||
##
|
||||
## Azure IPAM Application & Service Principal Deployment Script
|
||||
##
|
||||
###############################################################################################################
|
||||
|
||||
# Set minimum version requirements
|
||||
#Requires -Version 7.2
|
||||
#Requires -Modules @{ ModuleName="Az"; ModuleVersion="7.5.0"}
|
||||
#Requires -Modules @{ ModuleName="Microsoft.Graph"; ModuleVersion="1.9.6"}
|
||||
|
||||
# Set global parameters
|
||||
$engineApiGuid = New-Guid
|
||||
$logFile = "./deploy_$(get-date -format `"yyyyMMddhhmmsstt`").log"
|
||||
$tenantId = (Get-AzContext).Tenant.Id
|
||||
|
||||
# Set preference variables
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Function deployEngineApplication {
|
||||
$azureSvcMgmtApiPermissionsScope = "user_impersonation"
|
||||
$azureSvcMgmtAppId ="797f4846-ba00-4fd7-ba43-dac1f8f63013"
|
||||
$msGraphApiPermissionsScope = "offline_access openid profile User.Read"
|
||||
$msGraphAppId = "00000003-0000-0000-c000-000000000000"
|
||||
$engineResourceAccess = [System.Collections.ArrayList]@(
|
||||
@{
|
||||
ResourceAppId = "00000003-0000-0000-c000-000000000000";
|
||||
ResourceAccess = @(
|
||||
@{
|
||||
Id = "7427e0e9-2fba-42fe-b0c0-848c9e6a8182";
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d";
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "37f7f235-527c-4136-accd-4a02d197296e";
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "14dad69e-099b-42c9-810b-d002981feec1";
|
||||
Type = "Scope"
|
||||
}
|
||||
)
|
||||
},
|
||||
@{
|
||||
ResourceAppId = "797f4846-ba00-4fd7-ba43-dac1f8f63013";
|
||||
ResourceAccess = @(
|
||||
@{
|
||||
Id = "41094075-9dad-400e-a0bd-54e686782033";
|
||||
Type = "Scope"
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
# Create IPAM engine application
|
||||
Write-Host "INFO: Creating Azure IPAM Engine Service Principal" -ForegroundColor green
|
||||
Write-Verbose -Message "Creating Azure IPAM Engine Service Principal"
|
||||
|
||||
$global:engineApp = New-AzADApplication `
|
||||
-DisplayName "ipam-engine-app" `
|
||||
-RequiredResourceAccess $engineResourceAccess
|
||||
|
||||
# Update IPAM engine application with API endpoint
|
||||
Update-AzADApplication -ApplicationId $global:engineApp.AppId -IdentifierUri "api://$($global:engineApp.AppId)"
|
||||
|
||||
# Create IPAM engine service principal
|
||||
$engineSpn = New-AzADServicePrincipal `
|
||||
-ApplicationObject $global:engineApp `
|
||||
-Role "Reader" `
|
||||
-Scope "/providers/Microsoft.Management/managementGroups/$($tenantId)"
|
||||
|
||||
# Create IPAM engine service principal credential
|
||||
$global:engineSecret = New-AzADAppCredential -ApplicationObject $global:engineApp -StartDate (Get-Date) -EndDate (Get-Date).AddYears(2)
|
||||
|
||||
Write-Host "INFO: Azure IPAM Engine Application & Service Principal created successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Azure IPAM Engine Application & Service Principal created successfully"
|
||||
|
||||
# Instantiate Microsoft Graph service principal object
|
||||
$msGraphSpn = Get-AzADServicePrincipal `
|
||||
-ApplicationId $msGraphAppId
|
||||
|
||||
# Instantiate Azure Service Management service principal object
|
||||
$azureSvcMgmtSpn = Get-AzADServicePrincipal `
|
||||
-ApplicationId $azureSvcMgmtAppId
|
||||
|
||||
# Grant admin consent for Microsoft Graph API permissions assigned to IPAM engine application
|
||||
Write-Host "INFO: Granting admin consent for Microsoft Graph API permissions assigned to IPAM Engine Application" -ForegroundColor Green
|
||||
Write-Verbose -Message "Granting admin consent for Microsoft Graph API permissions assigned to IPAM Engine Application"
|
||||
|
||||
New-MgOauth2PermissionGrant `
|
||||
-ResourceId $msGraphSpn.Id `
|
||||
-Scope $msGraphApiPermissionsScope `
|
||||
-ClientId $engineSpn.Id `
|
||||
-ConsentType AllPrincipals `
|
||||
| Out-Null
|
||||
|
||||
Write-Host "INFO: Admin consent for Microsoft Graph API permissions granted successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Admin consent for Microsoft Graph API permissions granted successfully"
|
||||
|
||||
# Grant admin consent for Azure Service Management API permissions assigned to IPAM application
|
||||
Write-Host "INFO: Granting admin consent for Azure Service Management API permissions assigned to IPAM ENgine Application" -ForegroundColor Green
|
||||
Write-Verbose -Message "Granting admin consent for Azure Service Management API permissions assigned to IPAM Engine Application"
|
||||
|
||||
New-MgOauth2PermissionGrant `
|
||||
-ResourceId $azureSvcMgmtSpn.Id `
|
||||
-Scope $azureSvcMgmtApiPermissionsScope `
|
||||
-ClientId $engineSpn.Id `
|
||||
-ConsentType AllPrincipals `
|
||||
| Out-Null
|
||||
|
||||
Write-Host "INFO: Admin consent for Azure Service Management API permissions granted successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Admin consent for Azure Service Management API API permissions granted successfully"
|
||||
|
||||
}
|
||||
|
||||
Function deployUiApplication {
|
||||
$engineApiPermissionsScope = "access_as_user"
|
||||
$msGraphAppId = "00000003-0000-0000-c000-000000000000"
|
||||
$msGraphApiPermissionsScope = "Directory.Read.All openid User.Read"
|
||||
$uiResourceAccess = [System.Collections.ArrayList]@(
|
||||
@{
|
||||
ResourceAppId = "00000003-0000-0000-c000-000000000000";
|
||||
ResourceAccess = @(
|
||||
@{
|
||||
Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d";
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "37f7f235-527c-4136-accd-4a02d197296e";
|
||||
Type = "Scope"
|
||||
},
|
||||
@{
|
||||
Id = "06da0dbc-49e2-44d2-8312-53f166ab848a";
|
||||
Type = "Scope"
|
||||
}
|
||||
)
|
||||
},
|
||||
@{
|
||||
ResourceAppId = $global:engineApp.AppId;
|
||||
ResourceAccess = @(
|
||||
@{
|
||||
Id = $engineApiGuid;
|
||||
Type = "Scope"
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
$uiWebSettings = @{
|
||||
ImplicitGrantSetting = @{
|
||||
EnableAccessTokenIssuance = $true
|
||||
EnableIdTokenIssuance = $true
|
||||
}
|
||||
}
|
||||
|
||||
# Create IPAM UI Application
|
||||
Write-Host "INFO: Creating Azure IPAM UI Application" -ForegroundColor green
|
||||
Write-Verbose -Message "Creating Azure IPAM UI Application"
|
||||
|
||||
$global:uiApp = New-AzADApplication `
|
||||
-DisplayName "ipam-ui-app" `
|
||||
-Web $uiWebSettings `
|
||||
-RequiredResourceAccess $uiResourceAccess `
|
||||
-SPARedirectUri "https://ipam-placeholder-replace-me.azurewebsites.net"
|
||||
|
||||
# Create IPAM UI service principal
|
||||
$uiSpn = New-AzADServicePrincipal -ApplicationObject $global:uiApp
|
||||
|
||||
Write-Host "INFO: Azure IPAM UI Application & Service Principal created successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Azure IPAM UI Application & Service Principal created successfully"
|
||||
|
||||
# Instantiate Microsoft Graph service principal object
|
||||
$msGraphSpn = Get-AzADServicePrincipal `
|
||||
-ApplicationId $msGraphAppId
|
||||
|
||||
# Instantiate Azure IPAM engine service principal object
|
||||
$engineSpn = Get-AzADServicePrincipal `
|
||||
-ApplicationId $global:engineApp.AppId
|
||||
|
||||
# Grant admin consent for Microsoft Graph API permissions assigned to IPAM UI application
|
||||
Write-Host "INFO: Granting admin consent for Microsoft Graph API permissions assigned to IPAM UI Application" -ForegroundColor Green
|
||||
Write-Verbose -Message "Granting admin consent for Microsoft Graph API permissions assigned to IPAM UI Application"
|
||||
|
||||
New-MgOauth2PermissionGrant `
|
||||
-ResourceId $msGraphSpn.Id `
|
||||
-Scope $msGraphApiPermissionsScope `
|
||||
-ClientId $uiSpn.Id `
|
||||
-ConsentType AllPrincipals `
|
||||
| Out-Null
|
||||
|
||||
Write-Host "INFO: Admin consent for Microsoft Graph API permissions granted successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Admin consent for Microsoft Graph API permissions granted successfully"
|
||||
|
||||
# Grant admin consent for Azure Service Management API permissions assigned to IPAM application
|
||||
Write-Host "INFO: Granting admin consent for Azure IPAM Engine API permissions assigned to IPAM UI Application" -ForegroundColor Green
|
||||
Write-Verbose -Message "Granting admin consent for Azure IPAM Engine API permissions assigned to IPAM UI Application"
|
||||
|
||||
New-MgOauth2PermissionGrant `
|
||||
-ResourceId $engineSpn.Id `
|
||||
-Scope $engineApiPermissionsScope `
|
||||
-ClientId $uiSpn.Id `
|
||||
-ConsentType AllPrincipals `
|
||||
| Out-Null
|
||||
|
||||
Write-Host "INFO: Admin consent for Azure IPAM Engine API permissions granted successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Admin consent for Azure IPAM Engine API API permissions granted successfully"
|
||||
|
||||
}
|
||||
|
||||
Function updateEngineApplication {
|
||||
$engineApiSettings = @{
|
||||
KnownClientApplication = @(
|
||||
$global:uiApp.AppId
|
||||
)
|
||||
Oauth2PermissionScope = @(
|
||||
@{
|
||||
AdminConsentDescription = "Allows the IPAM UI to access IPAM Engine API as the signed-in user."
|
||||
AdminConsentDisplayName = "Access IPAM Engine API"
|
||||
Id = $engineApiGuid
|
||||
IsEnabled = $true
|
||||
Type = "User"
|
||||
UserConsentDescription = "Allow the IPAM UI to access IPAM Engine API on your behalf."
|
||||
UserConsentDisplayName = "Access IPAM Engine API"
|
||||
Value = "access_as_user"
|
||||
}
|
||||
)
|
||||
RequestedAccessTokenVersion = 2
|
||||
}
|
||||
|
||||
# Update IPAM engine application API settings
|
||||
Write-Host "INFO: Updating Azure IPAM Engine Application" -ForegroundColor green
|
||||
Write-Verbose -Message "Updating Azure IPAM Engine Application"
|
||||
|
||||
Update-AzADApplication -ApplicationId $global:engineApp.AppId -Api $engineApiSettings
|
||||
|
||||
Write-Host "INFO: Updated Azure IPAM Engine Application successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Updated Azure IPAM Engine Application successfully"
|
||||
|
||||
}
|
||||
|
||||
Function populateBicepParameters {
|
||||
Write-Host "INFO: Populating Bicep parameter file for infrastructure deployment" -ForegroundColor Green
|
||||
Write-Verbose -Message "Populating Bicep parameter file for infrastructure deployment"
|
||||
|
||||
# Retrieve JSON object from sample parameter file
|
||||
$parametersObject = Get-Content main.parameters.example.json | ConvertFrom-Json
|
||||
|
||||
# update parameter values
|
||||
$parametersObject.parameters.engineAppId.value = $global:engineApp.AppId
|
||||
|
||||
$parametersObject.parameters.engineAppSecret.value = $global:engineSecret.SecretText
|
||||
|
||||
$parametersObject.parameters.uiAppId.value = $global:uiApp.AppId
|
||||
|
||||
# Output updated parameter file for Bicep deployment
|
||||
$parametersObject | ConvertTo-Json -Depth 3 | Out-File -FilePath main.parameters.json
|
||||
|
||||
Write-Host "INFO: Bicep parameter file populated successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Bicep parameter file populated successfully"
|
||||
}
|
||||
|
||||
try {
|
||||
# Connect to Microsoft Graph
|
||||
$accesstoken = (Get-AzAccessToken -Resource "https://graph.microsoft.com/").Token
|
||||
|
||||
Connect-MgGraph -AccessToken $accesstoken
|
||||
|
||||
deployEngineApplication
|
||||
|
||||
deployUiApplication
|
||||
|
||||
updateEngineApplication
|
||||
|
||||
populateBicepParameters
|
||||
|
||||
Write-Host "INFO: IPAM Engine Application Deployment Complete" -ForegroundColor Green
|
||||
Write-Host "INFO: IPAM Engine Application Display Name: $($global:engineApp.DisplayName)" -ForegroundColor Green
|
||||
Write-Host "INFO: IPAM Engine Application ID: $($global:engineApp.AppId)" -ForegroundColor Green
|
||||
Write-Host "INFO: IPAM Engine Application Secret: $($global:engineSecret.SecretText)" -ForegroundColor Green
|
||||
Write-Host "INFO: IPAM UI Application Deployment Complete" -ForegroundColor Green
|
||||
Write-Host "INFO: IPAM UI Application Display Name: $($global:uiApp.DisplayName)" -ForegroundColor Green
|
||||
Write-Host "INFO: IPAM UI Application ID: $($global:uiApp.AppId)" -ForegroundColor Green
|
||||
|
||||
}
|
||||
catch {
|
||||
$_ | Out-File -FilePath $logFile -Append
|
||||
Write-Host "ERROR: Unable to create Azure IPAM Applications due to an exception, see $logFile for detailed information!" -ForegroundColor red
|
||||
exit
|
||||
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
###############################################################################################################
|
||||
##
|
||||
## Azure IPAM Infrastructure Deployment Script
|
||||
##
|
||||
###############################################################################################################
|
||||
|
||||
# Set minimum version requirements
|
||||
#Requires -Version 7.2
|
||||
#Requires -Modules @{ ModuleName="Az"; ModuleVersion="7.5.0"}
|
||||
|
||||
# Intake and set global parameters
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$location="westus3"
|
||||
)
|
||||
$logFile = "./deploy_$(Get-Date -Format `"yyyyMMddhhmmsstt`").log"
|
||||
|
||||
# Set preference variables
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Function validateLocation {
|
||||
$validLocations = Get-AzLocation
|
||||
|
||||
Write-Host "INFO: Validating Azure Region selected for deployment" -ForegroundColor green
|
||||
Write-Verbose -Message "Validating Azure Region selected for deployment"
|
||||
|
||||
# Validate Azure Region
|
||||
if ($location -in ($validLocations | Select-Object -ExpandProperty Location)) {
|
||||
foreach ($l in $validLocations) {
|
||||
if ($location -eq $l.Location) {
|
||||
$script:locationName = $l.DisplayName
|
||||
|
||||
Write-Host "INFO: Azure Region validated successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "Azure Region validated successfully"
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host "ERROR: Location provided is not a valid Azure Region!" -ForegroundColor red
|
||||
exit
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Function deployBicep {
|
||||
Write-Host "INFO: Deploying IPAM bicep templates" -ForegroundColor green
|
||||
Write-Verbose -Message "Deploying bicep templates"
|
||||
|
||||
# Deploy Bicep templates
|
||||
$global:deployment = New-AzSubscriptionDeployment `
|
||||
-Name "ipamInfraDeploy-$(Get-Date -Format `"yyyyMMddhhmmsstt`")" `
|
||||
-Location $location `
|
||||
-TemplateFile main.bicep `
|
||||
-TemplateParameterFile main.parameters.json
|
||||
|
||||
Write-Host "INFO: IPAM bicep templates deployed successfully" -ForegroundColor green
|
||||
Write-Verbose -Message "IPAM bicep templates deployed successfully"
|
||||
}
|
||||
|
||||
try {
|
||||
validateLocation $location
|
||||
|
||||
deployBicep
|
||||
|
||||
Write-Host "WARNING: Remember to update Single-Page Application Redirect URI for UI Application with value: https://$($global:deployment.Outputs["appServiceHostName"].Value)" -ForegroundColor yellow
|
||||
Write-Verbose -Message "Remember to update Single-Page Application Redirect URI for UI Application with value: https://$($global:deployment.Outputs["appServiceHostName"].Value)"
|
||||
}
|
||||
catch {
|
||||
$_ | Out-File -FilePath $logFile -Append
|
||||
Write-Host "ERROR: Unable to deploy IPAM Infrastructure due to an exception, see $logFile for detailed information!" -ForegroundColor red
|
||||
exit
|
||||
|
||||
}
|
|
@ -8,7 +8,7 @@ param guid string = newGuid()
|
|||
param location string = deployment().location
|
||||
|
||||
@description('Prefix for Resource Naming')
|
||||
param namePrefix string
|
||||
param namePrefix string = 'ipam'
|
||||
|
||||
@description('IPAM-UI App Registration Client/App ID')
|
||||
param uiAppId string
|
||||
|
@ -21,7 +21,7 @@ param engineAppId string
|
|||
param engineAppSecret string
|
||||
|
||||
@description('Tags')
|
||||
param tags object
|
||||
param tags object = {}
|
||||
|
||||
// Resource naming variables
|
||||
var appServiceName = '${namePrefix}-${uniqueString(guid)}'
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"namePrefix": {
|
||||
"value": "ipam"
|
||||
"value": "<AZURE RESOURCE NAME PREFIX>"
|
||||
},
|
||||
"tags": {
|
||||
"value": {
|
||||
|
|
|
@ -47,7 +47,7 @@ resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-prev
|
|||
}
|
||||
|
||||
resource copyNginxConfig 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
|
||||
name: 'exampleScript'
|
||||
name: 'copyNginxConfig'
|
||||
location: location
|
||||
kind: 'AzurePowerShell'
|
||||
identity: {
|
||||
|
|
|
@ -140,7 +140,10 @@ async def get_user(
|
|||
|
||||
admins = await cosmos_query("admins")
|
||||
|
||||
is_admin = next((x for x in admins['admins'] if x['id'] == target_user['id']), None)
|
||||
if admins['admins']:
|
||||
is_admin = next((x for x in admins['admins'] if x['id'] == target_user['id']), None)
|
||||
else:
|
||||
is_admin = True
|
||||
|
||||
target_user['isAdmin'] = True if is_admin else False
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ export default function NavDrawer() {
|
|||
const [menuAnchorEl, setMenuAnchorEl] = React.useState(null);
|
||||
const [mobileMenuAnchorEl, setMobileMenuAnchorEl] = React.useState(null);
|
||||
const [graphData, setGraphData] = React.useState(null);
|
||||
const [graphError, setGraphError] = React.useState(false);
|
||||
const [navChildOpen, setNavChildOpen] = React.useState({});
|
||||
const [drawerState, setDrawerState] = React.useState(false);
|
||||
const [settingsOpen, setSettingsOpen] = React.useState(false);
|
||||
|
@ -221,19 +222,29 @@ export default function NavDrawer() {
|
|||
];
|
||||
|
||||
React.useEffect(() => {
|
||||
const request = {
|
||||
// ...loginRequest,
|
||||
scopes: ["User.Read"],
|
||||
account: accounts[0],
|
||||
forceRefresh: true,
|
||||
};
|
||||
let graphTimer = setTimeout(() => {
|
||||
const request = {
|
||||
// ...loginRequest,
|
||||
scopes: ["User.Read"],
|
||||
account: accounts[0],
|
||||
forceRefresh: true,
|
||||
};
|
||||
|
||||
(async() => {
|
||||
try {
|
||||
const response = await instance.acquireTokenSilent(request);
|
||||
const graphResponse = await callMsGraph(response.accessToken);
|
||||
await setGraphData(graphResponse);
|
||||
} catch {
|
||||
setGraphError(x => !x);
|
||||
}
|
||||
})();
|
||||
}, 5000);
|
||||
|
||||
(async() => {
|
||||
const response = await instance.acquireTokenSilent(request);
|
||||
const graphResponse = await callMsGraph(response.accessToken);
|
||||
await setGraphData(graphResponse);
|
||||
})();
|
||||
}, []);
|
||||
return () => {
|
||||
clearTimeout(graphTimer);
|
||||
};
|
||||
}, [graphError]);
|
||||
|
||||
// React.useEffect(() => {
|
||||
// const request = {
|
||||
|
|
|
@ -23,6 +23,15 @@ const Login = () => {
|
|||
}
|
||||
}, [isAuthenticated, inProgress, instance]);
|
||||
|
||||
// React.useEffect(() => {
|
||||
// instance.loginRedirect(loginRequest).catch((e) => {
|
||||
// console.log("LOGIN ERROR:");
|
||||
// console.log("--------------");
|
||||
// console.error(e);
|
||||
// console.log("--------------");
|
||||
// });
|
||||
// }, []);
|
||||
|
||||
return(null)
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче