Sur un App Service, l'activation de Managed Service Identity vous simplifie la gestion des permissions. Plus besoin de gérer vos accès par une "App Registered" que vous devez créer mais il vous reste tout de même à positionner les permissions. Nous allons voir comment scripter ces permissions, ce qui vous permettra de l'automatiser.

Retrouver l'identité de l'App Service

Lorsque vous activez Managed Service Identity sur un App Service, vous pouvez affecter des permissions sur les différentes ressources Azure. Ainsi, pas de besoin d'identifiants.

Tout d'abord si vous n'avez pas activé Managed Service Service Identity, voici comment le faire :

Set-AzureRmWebApp -AssignIdentity $true -Name $webAppName -ResourceGroupName $resourceGroupName

Une fois que c'est activé, il vous faut récupérer le "Service Principal" de votre App Service qui correspond à son identité. C'est sur ce "Service Principal" que les droits vont être positionnés. Nous récupérons donc l'identifiant de ce Service Principal :

$servicePricipalId=(Get-AzureRmWebApp -Name "scheduler-appservice-dev").Identity

Droits d'accès à un Data Lake Store

Si votre application doit accéder à un Data Lake Store, il faut lui donner des permissions d'accès. Il ne s'agit pas de permission sur la ressource Data Lake mais sur le système de fichier. Voici comment donner les droits d'accès :

Set-AdlStoreItemAclEntry  `
     -AccountName $adlsAccountName `
     -Path '/' `
     -AceType User `
     -Permissions All `
     -Id $servicePricipalId.PrincipalId -Recurse -ShowProgress

Quelques explications sur les paramètres de la commande :

  • Path : Ici, les droits sont positionnés depuis la racine. A vous de personnaliser ce chemin en fonction de vos besoins.
  • Permissions : dans cet exemple, l'application aura tous les droits (lecture, écriture et exécution). Vous pouvez limiter par exemple en lecture seule en mettant "Read". Voir les valeurs possibles sur sur la documentation de Microsoft
  • -Recurse : applique les droits récursivement à tous fichiers contenus dans les sous-dossiers
  • -ShowProgress : affiche l'avancement. Ça peut être utile si vous avez une grande volumétrie dans votre Data Lake car cette commande va prendre beaucoup de temps.

Attention, cette commande peut prendre beaucoup de ressource processeur car elle génère plusieurs threads pour aller plus vite. Vous pouvez toutefois limiter le nombre de thread avec le paramètre Concurrency

Ce n'est pas fini, car une fois que vous avez positionné les droits d'accès, il faut positionner les accès par défaut. En effet, la commande précédente positionne des droits d'accès sur les fichiers et répertoires existants mais si de nouveaux fichiers ou répertoires sont créés, ils ne bénéficieront pas de ces droits. Il faut pour cela rejouer la même commande mais avec le paramètre "-Default" :

Set-AzureRmDataLakeStoreItemAclEntry  `
     -AccountName $adlsAccountName `
     -Path '/' `
     -AceType User `
     -Permissions All `
     -Id $servicePricipalId.PrincipalId -Default -Recurse -ShowProgress

Ces 2 commandes sont à jouer dans cet ordre là.

Droits d'accès à un groupe de ressource

Si votre application doit accéder à des différentes ressources azure, il peut être intéressant de positionner les permissions sur le groupe de ressource.

Voici la commande qui permet de le faire :

New-AzureRmRoleAssignment -ResourceGroupName $resourceGroupName -ObjectId $servicePricipalId.PrincipalId -RoleDefinitionName 'Contributor'

Ici, dans "-RoleDefinitionName", on affecte le rôle "Contributor", c'est un exemple, à vous d'affecter le bon rôle : "Reader", "Backup Operator", ... ou bien même un rôle personnalisé.

Droits sur une base de données

On aborde ici le cas le plus courant : une application web qui accède à une base de données. Tout l'avantage de Managed Service Identity nous permet de ne plus avoir à stocker d'identifiant dans la chaîne de connexion à notre base de données.

Le positionnement des droits est moins simple car en plus des commandes PowerShell, nous devrons effectuer des commandes SQL.

Avant d'effectuer les commandes SQL, il faut se positionner en tant qu'adminitrateur du server SQL. Voici la commande qui le permet :

Set-AzureRmSqlServerActiveDirectoryAdministrator -ResourceGroupName $resourceGroupName -ServerName $sqlServerName -DisplayName $adminUser

La variable $adminUser doit contenir l'email de l'utilisateur qui sera utilisé pour lancer les requêtes SQL qui suivront.

Sur une base de données, nous ne pouvons pas donner accès directement à l'App Service mais à un groupe AD. Nous créons donc un groupe AD dans lequel nous plaçons notre application :

New-AzureRmADGroup -DisplayName $adGroupName -MailNickName $adGroupName | Add-AzureRmADGroupMember -MemberObjectId $servicePricipalId.PrincipalId

Pour les commandes suivantes, nous allons utiliser "sqlcmd", ce qui nous permet de tout mettre dans un même script sans avoir à utiliser d'autres outils tels que SSMS ou Visual Studio pour exécuter du SQL. Mais attention pour utiliser sqlcmd sur des bases de données Azure, il faut utiliser la version 13.1 minimum : lien de téléchargement

Pour nous connecter à la base de données, nous allons réutiliser la variable $adminUser qui contient l'utilisateur auquel nous avons affecté les droits admin précédemment. Puis nous allons afficher un prompt pour saisir le mot de passe. Enfin, nous allons exécuter 2 requêtes SQL : une pour créer l'utilisateur SQL qui n'est autre que le groupe AD que nous avons créé précédemment et une autre pour lui affecter un rôle :

$credential = Get-Credential -credential $adminUser
$credential.GetNetworkCredential().Password
sqlcmd -S "$sqlServerName.database.windows.net" -d $databaseName -U $adminUser -P $credential.GetNetworkCredential().Password -Q "CREATE USER [$adGroupName] FROM EXTERNAL PROVIDER" -G -l 30
sqlcmd -S "$sqlServerName.database.windows.net" -d $databaseName -U $adminUser -P $credential.GetNetworkCredential().Password -Q "ALTER ROLE db_datareader ADD MEMBER [$adGroupName]" -G -l 30

Ici, nous affectons le rôle db_datareader, à vous de donner les droits nécessaires à votre application.

Conclusion

Vous pouvez voir que les droits à un App Service peuvent vite se retrouver à différents endroits et si vous ne le scriptez pas, vous en perdrez la trace. Vous pourrez versionner votre script sur un gestionnaire de code source et ainsi suivre l'historique de votre script. Ce qui permet de mieux contrôler qui fait quoi sur vos ressources Azure.

Voici le script complet :

#Affectation des variables
$webAppName="MaWebApp"
$resourceGroupName="MonRessourceGroupe"
$adlsAccountName="MonDataLake"
$adminUser="admin@contoso.com"
$sqlServerName="MonServerSql"
$databaseName="MaBaseDeDonnees"
$adGroupName="MonGroupeAD"

#Mise en place de MSI sur l'App Service
Set-AzureRmWebApp -AssignIdentity $true -Name $webAppName -ResourceGroupName $resourceGroupName

#Récupération de l'identifiant du Service Principal de la Web App
$servicePricipalId=(Get-AzureRmWebApp -Name "scheduler-appservice-dev").Identity

#Affection des droits sur le Data Lake
Set-AdlStoreItemAclEntry  `
     -AccountName $adlsAccountName `
     -Path '/' `
     -AceType User `
     -Permissions All `
     -Id $servicePricipalId.PrincipalId -Recurse -ShowProgress
Set-AzureRmDataLakeStoreItemAclEntry  `
     -AccountName $adlsAccountName `
     -Path '/' `
     -AceType User `
     -Permissions All `
     -Id $servicePricipalId.PrincipalId -Default -Recurse -ShowProgress

#Affectation des droits sur un groupe de ressource
New-AzureRmRoleAssignment -ResourceGroupName $resourceGroupName -ObjectId $servicePricipalId.PrincipalId -RoleDefinitionName 'Contributor'

#le user $adminUser est mis admin du server Sql
Set-AzureRmSqlServerActiveDirectoryAdministrator -ResourceGroupName $resourceGroupName -ServerName $sqlServerName -DisplayName $adminUser

#Création du groupe AD
New-AzureRmADGroup -DisplayName $adGroupName -MailNickName $adGroupName | Add-AzureRmADGroupMember -MemberObjectId $servicePricipalId.PrincipalId

#Affectation des permissions sur la base de données
$credential = Get-Credential -credential $adminUser
$credential.GetNetworkCredential().Password
sqlcmd -S "$sqlServerName.database.windows.net" -d $databaseName -U $adminUser -P $credential.GetNetworkCredential().Password -Q "CREATE USER [$adGroupName] FROM EXTERNAL PROVIDER" -G -l 30
sqlcmd -S "$sqlServerName.database.windows.net" -d $databaseName -U $adminUser -P $credential.GetNetworkCredential().Password -Q "ALTER ROLE db_datareader ADD MEMBER [$adGroupName]" -G -l 30

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.