Autoriser une ressource via RBAC avec un ARM autonome

Oguzhan Yigit
Publié par Oguzhan
Catégorie : Azure / Template ARM
30/11/2020

J’utilise depuis assez longtemps des Template ARM pour déployer les ressources Azure. De manière générale, l’utilisation de ces templates est plutôt simple mais certaines actions peuvent être un peu laborieuses.

Prenons un exemple concret. J’ai besoin de déployer une Function App Azure qui va devoir accéder à Azure App Configuration. Mon service Azure doit donc être autorisé via le via le système d’autorisations Azure RBAC.

 

Assigner une identité à la ressource Azure

Pour mon cas, je vais attribuer une identité système à ma Function App. L’assignation de l’identité peut se faire via le Template ARM de déploiement de la Function App.

"resources": [
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2016-08-01",
      "name": "[parameters('azureServiceName')]",
      "location": "[parameters('azureLocation')]",
      "tags": {
      },
      "kind": "functionapp",
      "identity": {
        "type": "SystemAssigned"
      },
      "properties": {
        "enabled": true,

Dans l’exemple ci-dessus, la propriété “identity” précise un type “SystemAssigned”. Azure se chargera de créer une identité pour mon service. Par ailleurs, Azure supprime cette identité de manière automatique au décommissionnement de cette ressource.

 

Assigner le rôle via un Template ARM

C’est assez simple d’assigner le rôle au moment du déploiement de Azure App Configuration. Mais dans mon cas, ce n’est pas envisageable car mon service Azure App Configuration existe depuis longtemps et je ne souhaite pas le redéployer. Par ailleurs, il est aussi possible de réaliser cette assignation de rôle dans le même Template ARM que celui de ma Function App Azure. Mais je souhaite réutiliser mon Template ARM pour d’autres services Azure. Donc je vais réaliser cette assignation de rôle dans un fichier ARM autonome que voici :

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "azureServiceName": {
      "type": "String",
      "defaultValue": "",
      "metadata": {
        "description": "Azure service name to grant access"
      }
    },
    "appConfigurationName": {
      "type": "String",
      "defaultValue": "",
      "metadata": {
        "description": "App configuration name"
      }
    }
  },
  "variables": {
    "appConfigurationDataReaderRoleId": "[concat(subscription().Id, '/providers/Microsoft.Authorization/roleDefinitions/516239f1-63e1-4d78-a4de-a74fb236a071')]",
    "azureServicePrincipalId": "[resourceId('Microsoft.Web/sites', parameters('azureServiceName'))]",
    "appConfigurationId": "[resourceId('Microsoft.AppConfiguration/configurationStores', parameters('appConfigurationName'))]"
  },
  "resources": [
    {
      "type": "Microsoft.AppConfiguration/configurationStores/providers/roleAssignments",
      "apiVersion": "2018-01-01-preview",
      "name": "[concat(parameters('appConfigurationName'), '/Microsoft.Authorization/', guid(uniqueString(parameters('azureServiceName'))))]",
      "properties": {
        "roleDefinitionId": "[variables('appConfigurationDataReaderRoleId')]",
        "principalId": "[reference(variables('azureServicePrincipalId'), '2018-11-01', 'Full').identity.principalId]",
        "scope": "[variables('appConfigurationId')]"
      }
    }
  ],
  "outputs": {}
}

 

Paramètres du Template ARM

Sans le pousser à l’extrême, j’ai rendu cet ARM un paramétrable. Il y a donc deux paramètres qui sont le nom du service Azure (nom de la Function App) et le nom du service Azure App Configuration.

Pour attribuer un rôle à une identité, il est nécessaire d’aller chercher l’identifiant du rôle comme définit par Azure. Dans mon cas, je souhaite donner le rôle “App Configuration Data Reader”. C’est un rôle natif Azure et ces identifiants sont fournis par Microsoft. C’est pourquoi, ma variable “appCofnigurationDataReaderRoleId” se compose d’une chaîne de caractères qui se termine par un Guid.

Ensuite, j’ai besoin de l’identité du service Azure à laquelle je vais assigner le rôle (dans mon cas, ma Function App). Je récupère une référence à la ressource que je stock dans la variable “azureServicePrincipalId”.

Puis, j’ai besoin de l’identifiant de ma ressource sur laquelle je vais assigner l’autorisation (dans mon cas c’est Azure App Configuration). Cela est réalisé dans ma variable “appConfigurationId”.

 

Nommage de le ressource

Finalement, il y a 2 spécificités très importantes à noter:

  • le type de ressource : traditionnellement, le type de ressource pour déployer une assignation de rôle est “Microsoft.Authorization/roleAssignments”. Or cela ne fonctionne que pour les souscriptions ou pour les groupes de ressources. Lorsque nous souhaitons attribuer un droit sur une ressource précise, le type doit être “imbriqué”, d’où l’utilisation de “Microsoft.AppConfiguration/configurationStores/providers/roleAssignments”
  • le nom de la ressource : le nom de la ressource doit être unique et ne pas changer. De manière similaire au type, lorsque nous assignons un rôle sur une souscription ou un groupe de ressource, un Guid suffit pour le nom. Cependant, lors d’une assignation de droit sur une ressource précise, il faut utiliser un notation imbriquer en suivant le schéma de l’exemple.