Files
sql-server-samples/samples/manage/azure-sql-db-managed-instance/automation-functions
..
2019-01-27 23:51:20 +01:00
2019-01-27 23:57:33 +01:00
2019-01-28 00:13:01 +01:00

Function App that helps automate Managed Instance related tasks

Contents

About this sample
Before you begin
Deploy and configure this sample
Run this sample
Troubleshoot
Disclaimers
Related links

About this sample

  • Applies to: Azure SQL Database
  • Key features: Managed Instance
  • Workload: n/a
  • Programming Language: C#, PowerShell
  • Authors: Srdan Bozovic
  • Update history: n/a

This sample shows one approach to Managed Instance management automation using Function App and system-assigned identity.

With system-assigned identity, Function App could be assigned permissions to invoke proper actions in a safe way.

Instead of granting excessive permissions to users, admins could grant required permissions to Function App that exposes very restrained set of functionalities through API. Code running on Function App doesn't have any secrets configured or hardcoded.

Currently available functions:

  • Assign Azure AD Directory Readers permissions to Managed Instance principal

Before you begin

To run this sample, you need the following prerequisites.

Software prerequisites:

  1. PowerShell 5.1
  2. Azure PowerShell 5.4.2 or higher
  3. Visual Studio 2017

Azure prerequisites:

  1. Azure AD Privileged Role Administrator role
  2. Permissions to add Readers permission for Function App principal on any of the following resource levels: Managed Instance, Resource group, Subscription

Deploy and configure this sample

Steps below show how to deploy pre-build package. Alternatively you could deploy Function App using Visual Studio and source code provided with this sample.

  1. Create Function App by following [Create your first function in the Azure portal].(https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-azure-function) quickstart
  2. Download package.
  3. Publish package using Azure CLI, with cURL or with [PowerShell].(https://docs.microsoft.com/en-us/azure/azure-functions/deployment-zip-push#with-powershell)
  4. Grant access to Function App by following Grant access. For easier selection, choose Function App in Assign access to dropbox. In some situations this might take up to an hour to propagate.
  5. Add system-assigned identity by following Adding a system-assigned identity and note generated Object ID.
  6. Run PowerShell below to provide Function App required Azure AD permissions.

Connect-AzureAD

$managedInstanceAutomationObjectId = '<function-app-object-id>'

# Get Azure AD role "Directory Users" and create if it doesn't exist
$roleName = "Privileged Role Administrator"
$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq $roleName}
if ($role -eq $null) {
    # Instantiate an instance of the role template
    $roleTemplate = Get-AzureADDirectoryRoleTemplate | Where-Object {$_.displayName -eq $roleName}
    Enable-AzureADDirectoryRole -RoleTemplateId $roleTemplate.ObjectId
    $role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq $roleName}
}

# Check if service principal is already member of readers role
$allDirReaders = Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId
$selDirReader = $allDirReaders | where{$_.ObjectId -match $managedInstanceAutomationObjectId}

if ($selDirReader -eq $null)
{
    # Add principal to privileged role admins role
    Write-Output "Adding service principal to 'Privileged Role Administrator' role..."
    Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $managedInstanceAutomationObjectId
    Write-Output "Service principal added to 'Privileged Role Administrator' role'."
}
else
{
    Write-Output "Service principal is already member of 'Privileged Role Administrator' role'."
}

Note

In step 3. use Get publish profile to get user name and password. If you are using PowerShell to upload package, you will need to escape character $ wherever it appears in user name or password.

Run this sample

Function App exposes functionality through REST API. Sample below shows how you could invoke function using PowerShell. Here you can find how to get Function App key.

This article shows how you can invoke Function App from Azure Pipeline | TFS 2018 | TFS 2017.


$subscriptionId = "<subscription-id>"
$resourceGroupName = "<managed-instance-resource-group>"
$managedInstanceName = "<managed-instance-name>"

$functionAppName = "<function-app-name>"
$code = "<function-app-key>"

$managedInstanceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Sql/managedInstances/$managedInstanceName"
$apiUrl="https://$functionAppName.azurewebsites.net/api/AssignDirectoryReadersRoleFunction?code=$code"
$body =  @{id=$managedInstanceId} | ConvertTo-Json

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-RestMethod $apiUrl -Method POST -ContentType "application/json" -Body $body

Troubleshoot

If Function App is not configured or doesn't run properly you will get HTTP 400 error with error message in plain text.

Below is list of errors with actions to resolve them.

Managed Service Identity (MSI) is not assigned.

Add system-asigned identity as described at step 5. in deploy and configure this sample section.

[Forbidden]: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Sql/managedInstances/{name}'.

Function App doesn't have permissions to read Managed Instance properties. Add permission as described at step 4. in deploy and configure this sample section.

[Not Found]: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Sql/managedInstances/{name}'.

Function App doesn't have permissions to read Managed Instance properties. Add permission as described at step 4. in deploy and configure this sample section.

[MSI Not Assigned]: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Sql/managedInstances/{name}'.

Managed Instance you want to enable for Azure AD authentication doesn't have it's own system-asigned identity (this is different from first error in this section where Function App doesn't have identity assigned).

[Forbidden]: '/{tenantId}/directoryRoles'.

Function App doesn't have permissions to read Azure AD. Add permission as described at step 6. in deploy and configure this sample section.

Disclaimers

The scripts and this guide are copyright Microsoft Corporations and are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them.

For more information, see these articles: