Présentation de Azure Automation

Azure Automation est le service proposé par Azure pour l’automatisation de vos processus. Il vous permet notamment de créer des « runbooks » à exécuter à la demande ou à planifier. Le runbook contient la définition du processus à automatiser, ils peuvent être réalisés :

  • en PowerShell classique,
  • en Workflow PowerShell,
  • sous forme graphique : PowerShell ou Workflow PowerShell,
  • en Python.

 

Dans cet article, nous utiliserons un runbook en PowerShell classique.

Vous pouvez par exemple planifier :

  • Des purges dans vos comptes de stockage Azure,
  • L’arrêt et le démarrage de VMs,
  • La copie de bases de données…

Prenons maintenant le cas d’un de vos processus au sein duquel vous souhaitez appeler une de vos APIs sécurisée avec Azure AD. Il va alors falloir que le runbook Azure Automation soit autorisé à appeler l’API en question.

 

Sécurisation avec Azure AD

Dans notre scénario, l’API est déjà déclarée dans Azure AD.

Plus d’informations sur l’enregistrement des applications dans Azure AD : https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications

Pour que le runbook Azure Automation puisse l’appeler, il va également falloir déclarer le runbook en tant qu’application dans Azure AD pour que celui-ci puisse avoir l’autorisation d’appeler l’API.

Runbook Azure Ad

  1. Le runbook pourra ensuite s’authentifier auprès d’Azure AD pour demander un token (jeton d’accès).
  2. Azure AD fournit le token.
  3. Le runbook fournit le token lors de l’appel à l’API pour s’authentifier.
  4. L’API peut répondre si le token est valide.

 

Lors de l’enregistrement du runbook dans Azure AD, nous avons la possibilité de le sécuriser via un secret partagé ou par un certificat. La sécurisation par certificat étant plus sécurisée, nous allons partir sur ce choix !

 

Générer et stocker le certificat dans un Key Vault

Nous allons utiliser Azure Key Vault pour générer le certificat à utiliser pour sécuriser le runbook Azure Automation et pour le stocker de façon sûre.

Azure Key Vault protège les clés de chiffrement, les secrets et les certificats utilisés par vos services et applications. Ces derniers sont chiffrés à l’aide de clés protégées par des modules de sécurité matériels (HSM). Pour plus d’informations : https://docs.microsoft.com/en-us/azure/key-vault/key-vault-whatis

Le script PowerShell suivant se charge de créer un certificat directement dans Azure Key Vault et attend que ce dernier soit disponible.

$policy = New-AzureKeyVaultCertificatePolicy -SubjectName "CN=$azureADAppName" -IssuerName Self -ValidityInMonths 24 

Add-AzureKeyVaultCertificate -VaultName $vaultName -Name $azureADAppName -CertificatePolicy $policy 

    Do{ 
        $cert=Get-AzureKeyVaultCertificate -VaultName $vaultName -Name $azureADAppName 
        $status=$cert.Enabled 
        Write-host "Certificate status: $status" 
        Start-Sleep 5 
    }Until($status -eq 'True')

 

Déclarer le runbook dans Azure AD

Nous avons vu que pour pouvoir gérer les autorisations dans Azure AD, le runbook doit être déclaré dans Azure AD. Il pourra ensuite s’authentifier à l’aide de son certificat afin de récupérer un token d’accès pour appeler l’API.

Créer un service principal

Pour déclarer une application et créer un service principal dans Azure AD, il faut fournir :

  • une URI pour la « homepage », qui est censée décrire l’application cliente. Prenons, par exemple, l’ID de ressource Azure du compte Automation pour construire cette URI.
  • une URI qui identifie de façon unique l’application dans le tenant Azure AD.

 

En PowerShell :

$uri="https://portal.azure.com/#resource"+(Get-AzureRmResource -ResourceName $automationAccount -ResourceGroupName $automationResourceGroup).ResourceId 

$identifierUri="https://spn/$automationAccount" 

$azureAdApplication = New-AzureRmADApplication -DisplayName "$azureADAppName" -HomePage $uri -IdentifierUris $identifierUri 

$servicePrincipal = New-AzureRmADServicePrincipal -ApplicationId $azureAdApplication.ApplicationId  

 

Éditer le manifest pour enregistrer le certificat

Comme nous avons choisi de sécuriser notre runbook à l’aide d’un certificat, il faut également inscrire ce certificat dans Azure AD. Pour cela, on doit modifier le manifeste de l’application pour y ajouter une partie relative au certificat comme ci-dessous, en indiquant les paramètres :

  • customKeyIdentifer : encodage en base64 du hachage du certificat,
  • keyId : un GUID pour identifier la clé dans le manifeste,
  • value : encodage en base64 des données brutes du certificat.
"keyCredentials": [ 
    { 
        "customKeyIdentifier": "$base64Thumbprint", 
        "keyId": "$keyid", 
        "type": "AsymmetricX509Cert", 
        "usage": "Verify", 
        "value":  "$base64Value" 
    } 
] 

Partons donc du certificat stocké dans le Key Vault pour calculer ces valeurs. Ensuite, la commande PowerShell “New-AzureADApplicationKeyCredential” se charge de générer le GUID.

En PowerShell :

$kvcert=Get-AzureKeyVaultCertificate -VaultName $vaultName -Name $azureADAppName 

$kvcertRawData=$kvcert.Certificate.RawData 
$base64Value = [System.Convert]::ToBase64String($kvcertRawData) 

$thumbprint=$kvcert.Certificate.GetCertHash() 
$base64Thumbprint = [System.Convert]::ToBase64String($thumbprint) 

$res=Get-AzureADApplication -ObjectId $azureAdApplication.ObjectId 

New-AzureADApplicationKeyCredential -ObjectId $azureAdApplication.ObjectId -CustomKeyIdentifier $base64Thumbprint -Type AsymmetricX509Cert -Usage Verify -Value $base64Value 

 

Donner les droits au runbook pour appeler l’API

C’est bon, le runbook Azure Automation est bien déclaré dans Azure AD et sécurisé à l’aide d’un certificat ! Dans la partie « Required Permission » nous allons pouvoir lui attribuer les droits nécessaires pour appeler l’API elle-même déclarée dans Azure AD.

Donner les droits au runbook pour appeler l’API

Importer le certificat dans le compte Azure Automation

Avant de pouvoir lancer le runbook, il faut que celui-ci puisse accéder au certificat afin de le fournir à Azure AD. Pour cela, on va charger le certificat dans le compte Azure Automation.

Malheureusement, pour cela, nous sommes obligés de récupérer le certificat en local. Nous n’avons pas la possibilité pour le moment de charger directement le certificat depuis le Key Vault vers le compte Azure Automation.

Nous allons donc importer le certificat en local, depuis le Key Vault, en le protégeant par un mot de passe puis utiliser la commande PowerShell « New-AzureRmAutomationCertificate » qui permet d’ajouter un certificat présent localement.

    $kvSecret = Get-AzureKeyVaultSecret -VaultName $vaultname -Name $appName 
    If ($kvSecret -eq $null) { 
        throw New-Object System.Exception ("$appName not in KeyVault") 
    }  

    $kvSecretBytes = [System.Convert]::FromBase64String($kvSecret.SecretValueText) 
    $certCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection 
    $certCollection.Import($kvSecretBytes,$null,[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable) 

    $protectedCertificateBytes = $certCollection.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $certPassword) 
    $pfxPath = [Environment]::filePath 
    [System.IO.File]::WriteAllBytes($filePath, $protectedCertificateBytes) 

$certName = $appName 
$certPath = $filePath 
$certPwd = ConvertTo-SecureString -String $certPassword -AsPlainText -Force 
 
New-AzureRmAutomationCertificate -AutomationAccountName $automationAccount -Name $certName -Path $certPath –Password $certPwd -Exportable -ResourceGroupName $automationResourceGroup 

Le certificat est bien disponible dans le compte Azure Automation :

 compte Azure Automation

Appeler l’API sécurisée depuis le runbook

Maintenant tout est prêt pour pouvoir récupérer un token depuis un runbook Azure Automation !

Utiliser le certificat

La première étape consiste à pouvoir utiliser le certificat chargé dans le compte Azure Automation. Pour cela nous utilisons la commande PowerShell spécifique à Azure Automation « Get-Automation Certificate ».

Récupérer un token

Pour appeler Azure AD, il faut charger les dll Active Directory dans Azure Automation.

Charger un zip « Microsoft.IdentityModel.Clients.ActiveDirectory.zip » contenant les dll dans la partie « Modules ». Les dll seront ensuite accessibles dans « C:\Modules\User\Microsoft.IdentityModel.Clients.ActiveDirectory ».

La fonction PowerShell suivante se charge d’appeler Azure AD pour récupérer un token à partir du certificat :

function GetToken( 
    [string] $AzureADCertName, 
    [string] $AzureClientId, 
    [string] $AzureDestAppIdUrl, 
    [string] $tenant 
){ 
        $AzureADCert = Get-AutomationCertificate -Name $AzureADCertName 

        $pathAdal="C:\Modules\User\Microsoft.IdentityModel.Clients.ActiveDirectory\Microsoft.IdentityModel.Clients.ActiveDirectory.dll" 
        $pathAdalForms="C:\Modules\User\Microsoft.IdentityModel.Clients.ActiveDirectory\Microsoft.IdentityModel.Clients.ActiveDirectory.dll" 

        Add-Type -Path $pathAdal 
        Add-Type -Path $pathAdalForms 
      
        $authContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext("https://login.microsoftonline.com/$tenant", $false); 

        $clientAssertionCertificate = new-Object Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate($AzureClientId, $AzureADCert); 

        $authResult = $authContext.AcquireToken($AzureDestAppIdUrl, $clientAssertionCertificate) 

        $authResult.AccessToken 
}  

Appeler l’API

Une fois que le runbook a récupéré le token, il peut appeler l’API en lui présentant le token !

 

Conclusion

Vous avez à disposition de plus en plus de services Azure pour vous aider à sécuriser au mieux vos APIs, vos tâches automatisées et vos ressources, alors plus d’excuses 😊

Aller plus loin :

Vous trouverez ci-dessous les liens vers la documentation Azure :

Pour la sécurisation de vos APIs, vous pouvez également utiliser Azure API Management : https://docs.microsoft.com/en-us/azure/api-management/

 

livre blanc From Zero to Hero 1 Infra as code