A la découverte d’Hybrid Worker dans Azure Automation

Après avoir abordé le sujet identité Azure Automation, continuons dans ce domaine avec le mode Hybride d’Azure Automation. Ci-dessous un rappel de Azure Automation pour poser le décor. Par défaut, un Runbook est exécuté dans Azure Automation donc dans Azure. C’est parfait pour manipuler des ressources Azure. Par contre, quand on essaie de l’utiliser pour manipuler les machines virtuelles, cela implique que celles-ci soient accessibles sur Internet. C’est faisable mais d’un point de vue sécurité, c’est tout sauf sexy que ce soit dans Azure ou On-Premises.

clip_image001

 

C’est là que le mode hybride prend tout son intérêt. Azure Automation Hybrid Worker permet d’exécuter nos Runbooks sur un serveur qui a accès à Internet et qui sera le seul à accéder aux machines virtuelles à administrer. Cette approche présente beaucoup d’avantages :

  • L’hôte sur lequel on installe le Hybrid Worker n’a pas besoin d’une adresse IP publique. En fait, l’hôte a juste besoin de pouvoir accéder à Internet
  • D’un point de vue réseau, les flux partent du Hybrid Worker pour aller vers Azure mais l’inverse. Il n’y a donc pas de flux entrant vers nos infrastructures
  • Possibilité de configurer le Hybrid Worker pour utiliser un proxy pour accéder Azure
  • L’hôte sur lequel on installe le Hybrid Worker sera le seul qui devra accéder aux machines virtuelles que l’on va gérer. On peut donc limiter les flux réseau au strict minimum.

 

Mise en œuvre d’un Hybrid Worker

Côté mise en œuvre, il y a quelques prérequis à respecter au niveau OMS Log Analytics :

  • Une instance du service Azure Automation à laquelle on va raccorder notre Hybrid Worker
  • Une instance du service OMS Log Analytics
  • La solution Automation Hybrid Worker préalablement activée dans OMS Log Analytics

 

Pour notre futur Hybrid Worker, nous avons besoin :

  • Une machine virtuelle avec 2VCPU et 4Go de mémoire vive
  • D’un OS Windows Server 2012 minimum disposant d’un Accès Internet
  • L’agent OMS Log Analytics préalablement installé sur notre futur serveur Hybrid Worker

 

Normalement avec le socle Windows Server 2012, on a automatiquement PowerShell 4.0. Ça ne coute rien de vérifier en regardant ce que nous retourne la variable $PSVersionTable.

clip_image002

 

PowerShell 4.0, c’est bien mais en ce qui me concerne je préfère avoir la même version de PowerShell, que nos Runbooks se comportent de la même manière dans Azure que sur notre future instance du Hybrid Worker. On va donc commencer par installer le Management Framework 5.1 disponible ici.

clip_image003

 

Une fois l’installation terminée, on peut constater la nouvelle version de PowerShell qui est maintenant 5.1.

clip_image004

 

Prochaine étape, les modules PowerShell. C’est un prérequis à l’installation qui va suivre mais aussi un process qu’on va devoir gérer. Dans Azure Automation, on est capable de maîtriser les modules PowerShell (modules & version) qui sont utilisés. Au moment de l’écriture de ce billet, il n’est pas encore possible de gérer les modules sur le Hybrid Worker. J’en ai fait l’amère expérience pendant un développement de Runbook. Un des avantages de PowerShell 5.0 (ou supérieur), c’est la capacité à utiliser la PowerShell Gallery comme unique repositoy de nos modules. On doit juste autoriser son utilisation :

Set-PSRepository -Name PSGallery -InstallationPolicy Trusted

clip_image005

 

Etant donné que je vais manipuler beaucoup de ressources Azure, il est logique de demander l’installation des modules PowerShell en relation avec Azure. N’oubliez pas d’installer vos propres modules sinon ça va poser quelques problèmes.

C’est maintenant que commence la configuration de notre futur Hybrid Worker. L’avantage est que tout le paramétrage est prévu dans le script « New-OnPremiseHybridWorker« . Nous n’avons qu’à le télécharger depuis la PowerShell Gallery avec la commande suivante :

Install-Script -Name New-OnPremiseHybridWorker -RequiredVersion 1.0

clip_image006

 

Nous devons accepter l’installation des PowershellGet NuGet.

clip_image007

 

Ne reste plus qu’à réaliser l’installation de notre Hybrid Runbook Worker avec le code ci-dessous :

$AutomationAccountName = « <nom instance Azure Automation> »

$AutomationResourceGroupName = « <groupe de ressources> »

$AzureSubscriptionID = « <Identifiant unique de votre souscription> »

$OMSWorkSpace = « <Nom de votre instance OMS> »

New-OnPremiseHybridWorker.ps1 -AutomationAccountName $AutomationAccountName -ResourceGroupName $AutomationResourceGroupName -HybridGroupName « Hybrid01 » -SubscriptionId $AzureSubscriptionID -WorkspaceName $OMSWorkSpace

clip_image008

 

Comme tout s’est bien passé, on doit pouvoir constater l’arrivée d’une instance Hybrid Worker group dans Azure Automation. C’est à ce groupe qu’a été associé notre serveur. Un groupe peut regrouper plusieurs instances Hybrid Worker, histoire de proposer de la haute disponibilité et la répartition de l’exécution des Runbooks.

clip_image009

 

Maintenant, un sujet sécurité. Dans le billet identité Azure Automation, nous avons abordés le sujet de l’identité sous laquelle nos Runbooks sont exécutés sous Azure. Dans l’état actuel de la configuration, notre Hybrid Worker ne dispose d’aucune identité pour faire fonctionner les Runbooks.

clip_image010

 

On peut tenter de fonctionner dans ces conditions mais on n’ira jamais plus loin que le Hybrid Worker. Le problème c’est qu’avec le contexte d’exécution par défaut, c’est celui du contexte d’exécution du Hybrid Worker. On va donc commencer par mettre en place un contexte d’exécution pour nos Runbooks. Dans Azure Automation, cela prend la forme d’un objet credential. Ce contexte de sécurité, nous le référençons dans Azure sous la forme d’un credential.

clip_image011

 

Inutile de rappeler que le compte devra exister sur toutes les machines virtuelles que l’on voudra manipuler depuis un Runbook exécuté avec notre instance du Hybrid Worker. Ne reste plus qu’à configurer ce contexte d’exécution pour notre instance du Hybrid Worker.

clip_image012

 

Remarque : N’oubliez pas le bouton « Save », …

 

Un dernier détail pour notre Hybrid Worker. Nous allons l’utiliser comme pivot pour exécuter du code PowerShell sur des systèmes distants. Erreur classique en PowerShell, on tente de faire du Remote PowerShell sur un système qui ne peut pas être approuvé (pas membre du domaine), ça échoue. Pourtant, un simple « Get-ChildItem WSMAN:LocalHost\Client » aurait dû vous faire comprendre qu’il y allait avoir un problème.

clip_image013

 

Dans le cadre de ce billet, on va faire au plus simple, en autorisant toutes destinations depuis le serveur Hybrid Worker. Après, d’un point de vue sécurité, c’est très discutable. Les bonnes pratiques de sécurité voudraient qu’on référence la liste des adresses IP vers lesquelles notre serveur va communiquer.

clip_image014

 

Remarque : Volontairement, je suis laxiste sur ce point de sécurité. J’y reviendrai plus tard.

 

Un client pour tester

Pour valider le bon fonctionnement de tout cela, il nous faut un client. J’ai donc mis en œuvre une nouvelle machine virtuelle, sur le même réseau que notre Hybrid Worker. Le Runbook que nous allons créer va s’exécuter sur le Hybrid Worker et devra accéder à notre nouvelle machine virtuelle en PowerShell (Donc du Remote PowerShell). C’est un sujet connu, on va donc aller très vite. Nous avons besoin de :

  • Disposer d’un certificat (auto-signé pour les besoins de ma démonstration)
  • Activer la fonctionnalité PowerShell Remoting
  • Associer le certificat à WINRM pour faire du PowerShell avec un peu de sécurité
  • Créer une règle de pare-feu

Pour faire simple, le code ci-dessous réalise toutes ces opérations. Ici encore, il reste très perfectible d’un point de vue sécurité mais il fonctionnera pour notre démonstration.

$fqdn = $env:computername

$cert = New-SelfSignedCertificate -DNSName $fqdn -certStorelocation « cert:\LocalMachine\My »

Enable-PSRemoting -SkipNetworkProfileCheck -Force

New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint –Force

New-NetFirewallRule -DisplayName « RemotePowerShell » -Direction Inbound –LocalPort 5986 -Protocol TCP -Action Allow -RemoteAddress 10.0.0.5

clip_image015

 

Pour finir on va introduire un peu de sécurité au niveau réseau. Mon client étant une machine virtuelle dans Azure, ci-dessous un extrait des règles entrantes du Network Security Group associé à la carte réseau :

clip_image016

 

Globalement le seul moyen pour joindre cette machine virtuelle, ce sera PowerShell (et en mode sécurisé seulement), uniquement depuis une seule adresse IP, celle de notre Hybrid Worker. Pour les règles sortantes, c’est encore plus strict, aucun moyen de joindre Internet :

clip_image017

 

Un Runbook magique

Notre client est prêt, ne nous manque plus que le Runbook « magique ». En fait, point de magie, juste du Remote PowerShell à l’ancienne. On va juste ajouter un peu d’Azure Automation en récupérant le « SecureString » contenant le compte de service que nous avons mis en œuvre et construire une authentification WSMAN pour exécuter du PowerShell sur une machine virtuelle distante désignée par son adresse IP qui a été passée en paramètre du Runbook.

param (

    [Parameter(Mandatory=$true)]

    [String] $RemoteIP

)

[OutputType([String])]

#

# Récupération des credentials dans un objet SecureString

#

$credential = Get-AutomationPSCredential -Name ‘Hybrid01_Credential’

« Host d’exécution : $env:computername. »

#

# Construction de l’authentification

#

$sessionOptions =New-PSSessionOption -SkipRevocationCheck -SkipCACheck -SkipCNCheck

$session = New-PSSession -ComputerName $RemoteIP -SessionOption $sessionOptions -Credential $Credential -UseSSL

$session

#

# Exécution de code Powershell à distance

#

$retour = Invoke-Command -Session $session -scriptblock { « Host d’exécution : $env:computername. » }

$retour

Remove-PsSession $Session

A l’Exécution de notre Runbook, on constate qu’il est possible de l’exécuter dans Azure et aussi sur un Hybrid Worker que nous pouvons sélectionner dans la liste de liste.

clip_image018

 

En fin d’exécution, on devrait avoir le résultat ci-dessous :

clip_image019

 

Le Runbook a bien commencé son exécution sur le Hybrid Worker pour ensuite créer une session WSMAN distante sur le second serveur et exécuter du code.

 

Bonus : Un peu plus de sécurité

Si vous avez suivi mon billet sur l’identité dans Azure Automation, vous savez comment créer un Service principal qui sera mis en œuvre uniquement pour un Hybrid Worker. Avantage si vous avez plusieurs instances d’Hybrid Worker, chaque instance dispose de sa propre identité pour se connecter à Azure avec un certificat. Pour améliorer la sécurité, on peut aussi :

 

Et continuer avec quelques saines lectures sur la sécurité PowerShell :

 

BenoitS – Simple and Secure by design but Business compliant (with disruptive flag enabled)

Parlons d’identité avec Azure Automation

Azure Automation, est un composant avec lequel je passe beaucoup de temps en ce moment. C’est un composant intéressant qui mérite qu’on y passe un peu de temps, surtout lorsque celui-ci nous parle d’identité. C’est ce qui arrive lors de la création d’une instance de ce service si on ne dispose pas des privilèges nécessaires. C’est le cas illustré ci-dessous. Ce qu’il faut comprendre, c’est que nous ne pouvons pas créer un certain nombre d’objets dans le tenant Azure AD et positionner des permissions.

clip_image001

Pourquoi est-ce important ? Tout simplement parce que c’est sous cette identité que nous allons exécuter nos futurs Runbooks. Dans ma situation, j’ai bien le niveau de privilège « Owner » sur mon groupe de ressources mais absolument aucun privilège dans le tenant Azure AD lié à ma souscription Azure. Du point de vue Azure Automation, il m’indique bien qu’il a un problème avec les « Run As Accounts » ?

clip_image002

 

On notera qu’il existe deux type de « Run As Accounts » :

  • Azure Run As Account
  • Azure Classic Run As Account

Pour faire court, le premier est destiné à gérer les ressources de type ARM et le second les ressources de type ASM, donc l’ancien Azure. Dans mon cas, ça ne sera pas possible puisque je suis sur une souscription Azure CSP. Nous allons donc devoir créer un « Azure Run As Account ». C’est maintenant que cela commence à piquer un peu. Le portail Azure nous donne un indice, ce qui manque, c’est une identité, un Service Principal qui va être associé à une application dans Azure AD. Si nous n’avons pas les privilèges sur le Tenant Azure AD lié à notre souscription Azure, il faudra réaliser la création manuellement. L’opération comprendra plusieurs étapes :

  • La création d’un certificat
  • Créer une application Azure AD
  • Assigner un rôle RBAC
  • Déclaration du Certificat dans Azure Automation
  • Déclaration de la connexion dans Azure Automation
  • Consommer l’identité dans un Runbook

 

La création d’un certificat

L’instance du Service Azure Automation a besoin d’un certificat. Ce certificat sera référencé comme un « Asset » dans Azure Automation., nous y reviendrons. Pour le certificat en lui-même, il peut être auto-signé ou délivré par une autorité de certification. Lorsqu’on laisse faire le portail, il va générer un certificat auto-signé d’une durée de vie d’un an. C’est court. Est-ce qu’on va se souvenir que ce certificat va expirer si le portail a fait tout cela pour nous ? Non. Le portail Azure ne nous préviendra pas. La seule chose qu’il va nous proposer, c’est l’option « Rewnew certificate » comme illustré ci-dessous :

Celui-ci sera lié à notre Application Azure AD. Vu qu’on va avoir besoin du certificat pour créer notre Application Azure AD, on va commencer par lui. Notre première décision sera de définir les caractéristiques principales de ce certificat :

  • Nom
  • Date d’expiration

clip_image003

Par contre, ce qui est bien, c’est qu’on a maintenant sous les yeux tous les ingrédients. Pour notre démonstration, nous allons créer un certificat auto-signé d’une durée de vie de deux ans :

$CertName = « automation.simplebydesignlabs.fr »

$CurrentDate =Get-Date

$EndDate = $currentDate.AddYears(2)

$NotAfter = $endDate.AddYears(2)

$CertStore = “Cert:\LocalMachine\My”

$CertThumbprint =(New-SelfSignedCertificate -DnsName « $certName » -CertStoreLocation $CertStore -KeyExportPolicy Exportable -Provider « Microsoft Enhanced RSA and AES Cryptographic Provider » -NotAfter $notAfter).Thumbprint

$CertThumbprint

clip_image004

Ce n’est pas précisé mais le certificat est exportable et c’est vivement recommandé si on veut plus tard déployer des Hybrid Worker Group. Nous allons exporter ce certificat.

$pfxPassword = ConvertTo-SecureString -String « LeMotDePasseIlAChangé! » -AsPlainText -Force

$pfxFilepath = « C:\Temp\automation.PFX »

Export-PfxCertificate -Cert « $($certStore)\$($certThumbprint) » -FilePath $pfxFilepath -Password $pfxPassword

clip_image005

C’est maintenant que cela se complique. Pour permettre à notre instance Azure Automation de s’authentifier, il faut la référencer sous la forme d’une application Azure AD. Cette application devra présenter le certificat exporté. Ce sera sa méthode d’authentification. Nous devons donc préparer un objet « PSADKeyCredential » dans lequel nous allons référencer le certificat et ses principales caractéristiques :

Import-Module -Name AzureRM.Resources

$Cert =New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate -ArgumentList @($pfxFilepath, $pfxPassword)

$KeyValue =[System.Convert]::ToBase64String($cert.GetRawCertData())

$KeyId =[guid]::NewGuid()

$KeyCredential = New-Object -TypeName Microsoft.Azure.Commands.Resources.Models.ActiveDirectory.PSADKeyCredential

$KeyCredential.StartDate = $currentDate

$KeyCredential.EndDate = $endDate

$KeyCredential.KeyId = $keyId

$KeyCredential.CertValue = $keyValue

$KeyCredential

clip_image006

 

Créer une application Azure AD

Prochaine étape, déclarer notre application dans Azure AD et y associer un Service principal :

$AADAppName = « Automation_APP »

$adAppHomePage = « « 

$adAppIdentifierUri = « « 

$AADApp = New-AzureRmADApplication -DisplayName $AADAppName -HomePage $adAppHomePage -IdentifierUris $adAppIdentifierUri -KeyCredentials $KeyCredential

New-AzureRmADServicePrincipal -ApplicationId $AADApp.ApplicationId -KeyCredential $KeyCredential

clip_image007

 

Assigner un rôle RBAC

Nous avons maintenant une identité. Encore faut-il que celle-ci dispose de privilèges dans la souscription Azure. Dans mon contexte, j’ai fait au plus restreint, à savoir limité à un groupe de ressources nommé Gestion, pour lequel le Service principal dispose du niveau de privilèges « Contributor » (gestion des ressources existantes dans le groupe de ressources).

New-AzureRmRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $($AADApp.ApplicationId) -ResourceGroupName Gestion

clip_image008

Au passage, si on laisse faire le portail, c’est le niveau de privilège « Owner » qui est positionné sur la souscription. Votre RSSI appréciera, ou pas.

 

Déclaration du Certificat dans Azure Automation

La première opération qu’un Runbook Azure Automation, c’est de s’authentifier auprès d’Azure. Cette authentification sera faite sous l’identité du Service Principal. Pour que l’authentification fonctionne, encore faut-il qu’Azure Automation dispose du certificat. Azure Automation va mettre à disposition le certificat lors de chaque exécution de Runbook. On va donc référencer cet « Asset » dans notre instance du service Azure Automation sous le nom « AzureRunAsCertificate ». On verra plus tard que le nom a son importance.

$AutomationCertAsset = « AzureRunAsCertificate »

$AutomationAccountName = « Automation »

$AutomationResourceGroupname = « Gestion »

New-AzureRmAutomationCertificate -Name $AutomationCertAsset -Path $pfxFilepath -Password $pfxPassword -AutomationAccountName $AutomationAccountName -ResourceGroupName $AutomationResourceGroupname

clip_image009

On notera que ce certificat est maintenant impossible à exporter. C’est une bonne chose d’un point de vue sécurité.

Déclaration de la connexion dans Azure Automation

C’est maintenant qu’on va créer le « Run As Account ». Dans notre cas, nous allons créer un « Run As Account » pour un Service Principal qui utilise un certificat pour s’authentifier. Nous devons disposer d’un certain nombre de paramètres :

  • L’identifiant unique de l’application Azure AD précédemment créée
  • L’identifiant unique du tenant Azure AD dans lequel l’Application Azure AD a été créée
  • L’empreinte numérique du certificat que nous avons associé à l’Application Azure AD
  • La souscription Azure dans laquelle l’application Azure AD va se connecter

$ConnectionAssetName = « AzureRunAsConnection »

$ConnectionFieldValues = @{« ApplicationId » = $AADApp.ApplicationId; « TenantId » = (Get-AzureRmContext).Tenant.Id; « CertificateThumbprint » = $CertThumbprint; « SubscriptionId » = (Get-AzureRmContext).Subscription.Id}

$ConnectionFieldValues

New-AzureRmAutomationConnection -ResourceGroupName $AutomationResourceGroupname -AutomationAccountName $AutomationAccountName -Name $ConnectionAssetName -ConnectionTypeName AzureServicePrincipal -ConnectionFieldValues $ConnectionFieldValues

clip_image010

 

Si tout se passe bien, voilà ce que vous devriez avoir dans les « Run As Accounts » de votre instance Azure Automation :

clip_image011

 

On retrouve bien toutes les informations que nous avons renseigné.

clip_image012

 

Maintenant le truc sur lequel j’ai passé le plus de temps. Si vous avez scrupuleusement respecté les étapes indiquées, cela fonctionne. Par contre, si vous avez eu le malheur de changer le nom de l' »Asset » du certificat, le portail n’est pas d’accord. Il vous indique que votre configuration est incomplète. Pour le portail, c’est clairement le certificat qui est en cause.

clip_image013

 

C’est un problème lié au portail, ce qui n’empêche pas le fonctionnement des Runbooks. Le problème a été remonté chez Microsoft car si la configuration est considérée comme incomplète, le portail Azure ne nous permet pas de renouveler notre certificat.

 

Consommer l’identité dans un Runbook

Créer une identité, c’est bien, la consommer c’est mieux. J’ai fait au plus court avec un Runbook PowerShell des familles :

[OutputType([String])]

$connectionName = « AzureRunAsConnection »

try

{

# Get the connection « AzureRunAsConnection « 

$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName

« Logging in to Azure… »

Add-AzureRmAccount `

-ServicePrincipal `

-TenantId $servicePrincipalConnection.TenantId `

-ApplicationId $servicePrincipalConnection.ApplicationId `

-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint

« Logged to Azure »

}

catch {

if (!$servicePrincipalConnection)

{

$ErrorMessage = « Connection $connectionName not found. »

throw $ErrorMessage

} else{

Write-Error -Message $_.Exception

throw $_.Exception

}

}

Get-ChildItem cert:\currentuser\my

 

Lors de l’exécution, vous allez découvrir que le certificat utilisé est dans le magasin de l’utilisateur et non de l’ordinateur :

clip_image014

 

Voilà tout ce qui se cache derrière le portail Azure lors de la création d’une instance du service Azure Automation en mode « Click Next Finish ».

 

BenoitS – Simple and Secure by design but Business compliant (with disruptive flag enabled)

Des certificats gratuits avec Let’s Encrypt dans IIS

Ça fait longtemps que j’avais ce billet dans les cartons, en fait depuis ma série de billets sur Let’s Encrypt avec les WebApp (plus d’un an déjà). Je l’utilise depuis longtemps dans mes machines virtuelles (tant qu’elles sont joignables sur Internet avec un nom public).

Let’s Encrypt, ce n’est pas tout jeune mais c’est toujours pas un citoyen de première classe dans IIS. La solution ne dispose pas d’un client natif, il faut en passer par un client tiers. Personnellement, je suis resté sur le premier que j’ai trouvé à l’époque : LetsEncrypt-Win-Simple, disponible sur Github. Comme MVP, j’ai beau avoir accès à des solutions gratuites comme Digicert mais je suis resté sur Let’s Encrypt, allez savoir, …

Avant de commencer, quelques rappels avec les limitations de Let’s Encrypt disponibles ici. Ceci posé, on va retenir la contrainte suivante :

The main limit is Certificates per Registered Domain (20 per week). A registered domain is, generally speaking, the part of the domain you purchased from your domain name registrar. For instance, in the name www.example.com, the registered domain is example.com. In new.blog.example.co.uk, the registered domain is example.co.uk. We use the Public Suffix List to calculate the registered domain.

Dans le contexte d’Azure, ça prend toute son importance car par défaut, mes machines virtuelles partagent toutes un même domaine DNS public : Azure.com. Si on tente d’utiliser Let’s Encrypt dans ces conditions, on arrive à la situation ci-dessous :

clip_image001

 

Ce point résolu, on sait maintenant il nous faut un nom DNS distinct. J’ai donc créé un enregistrement DNS de type CNAME dans mon domaine DNS public, pointant sur le FQDN public de ma machine virtuelle.

clip_image002

 

Dans ma machine virtuelle, j’ai choisi la simplicité en installant IIS. C’est la méthode la plus simple pour gérer un certificat. Il suffit juste d’ajouter un hostname à un site web existant. Je référence ici l’enregistrement DNS CNAME enregistré dans mon domaine public.

clip_image003

 

Le client Let’s Encrypt utilisé (LetsEncrypt-Win-Simple) détecte automatiquement le FQDN précédemment référencé dans IIS.

clip_image004

 

On notera que le certificat généré est bien exportable. C’est bien pratique.

clip_image005

 

La particularité des certificats délivrés par Let’s Encrypt, c’est leur durée de vie à 90 jours. Pour moi, ce n’est pas une contrainte vue la durée de vie de mes maquettes. Le client LetsEncrypt-Win-Simple propose tout de même de mettre en place une tâche planifiée qui se chargera du renouvellement à votre place, nice to have.

clip_image006

 

Les informations collectées (compte disposant du niveau de privilège administrateur local) sont nécessaires pour mettre en place une tâche planifiée pour gérer le renouvellement automatique de notre certificat tous les trois mois.

clip_image007

 

Dans IIS, on constate bien la présence d’un nouveau binding pour du SSL.

clip_image008

 

Petite subtilité, le certificat n’a pas été placé dans le magasin « LocalMachine\My » mais dans le magasin « LocalMachine\WebHosting ». C’est un peu différent mais c’est très utile quand on a une ferme de serveurs web devant partager le même certificat.

clip_image009

 

Au passage, on remarquera la durée de vie de trois mois. C’est tout pour let’s Encrypt. En même temps, ça respecte ma formule magique : Simple and secure by design but Business compliant.

 

BenoitS – Simple and Secure by design but Business compliant (with disruptive flag enabled)

Azure Site Recovery for Azure Virtual machines (Preview)

I’ve been a big fan of Azure Site Recovery service. The product has evolved a lot since initial release (only capable to orchestrate a failover between two on-premises sites), introducing replication of on-premises workloads to Azure and many more features. Until theses last days, we had to comply with some limitations (Max 64 disks of 1Tb each per protected workload) and a major scenario we could not address. Note that Larger disk sizes just been announced in preview, up to 4Tb per Disk.

Since introduction of ASR replication capabilities (for Hyper-V, VMware or physical), we were not able to protect an Azure Virtual machine with Azure Site Recovery. ASR Team, just announced a preview of Azure Site Recovery for Azure Virtual machines. That was one of the top customer requests about Azure Site Recovery. Introduction of this new Azure Site capability allow to respond to the following scenarios:

  • Can survive to a major Azure Region failure by replicating virtual machines to another region
  • Migrate virtual machines between Azure regions
  • Comply with regulations requesting a Disaster Recovery strategy
  • Ability to clone an application based on Virtual Machines to validate

Feature is now available for public preview. Let’s see how to protect an Azure Virtual machine and develop a Disaster Recovery Plan. Note that even if this preview is available in the Azure portal, it’s still a preview. For example, support for PowerShell and CLI is not yet available.

Prerequisites

  • An instance of the Azure Recovery Site service: We will need to have an instance of the service in the Azure region in which we want to replicate with. This can be strange. If you remember Azure backup limitations, Azure Backup instance service must be in the same region as virtual machines we wish to protect.
  • A resource group in the target Azure region to store
  • A virtual network (and subnet) to connect the future Network interface. It’s not mandatory if you plan to establish RDP between two paired Azure regions (Azure virtual Network span between paired Azure regions).
  • A storage account created in the target Azure region to store virtual machines
  • A storage account created in the source Azure region to cache content to be replicated to the Target storage account
  • An availability set depending of the destination Azure region if protected workloads in the source Azure regions are linked to an existing availability set.

 

Setup

This blog post aim to describe the setup Itself, but also:

  • The Failover of an Azure Virtual machine to the target Azure Region
  • The Rollback of an Azure Virtual machine to its initial Azure region

Enabling and managing this new feature is so simple and very attractive from a financial point of view (no extra-cost for compute), that would be a crime to do not use it.

If you know the Azure Site Recovery portal experience, you should discover Azure as a source of a protected workload. Note that service is now in preview. For this blog post, I will be having a workload to protect located in Central US Azure region. My goal is to use the West Europe Azure region for DRP plan.

clip_image001

Azure Site Recovery service instance cannot be in the same Azure region as workloads to be protected. It’s logic. On this first stage, we only select the source Azure region, the deployment model and the resource group containing the workloads you wish to protect. Azure Site Recovery instance must depend of the same Azure subscription (and of course Azure environment). While writing this blog-post, it was not yet possible to protect workloads from different subscriptions. That’s a scenario that Azure CSP vendors are waiting to offer services. At this stage UX experience does not change so much from protecting other workloads:

clip_image002

That’s here that many UX changes are introduced. For this blog post, I choose to select a target Azure region that is not paired with the source Azure Region. We are not limited to the paired Azure regions. Azure Site Recovery portal make some proposal for some resources:

clip_image003

 

If you click on the « Customize » link in the upper part of the UX, you will be able to change proposal for required resources:

  • A resource Group in the target Azure region
  • A virtual Network in the Target Azure region

 

For each Virtual machine to protect we can customize:

  • The Storage account to be used to store VHD to be used by future replicated virtual machines
  • The Storage account to be used for ASR cache purpose

 

For these two storage Accounts, you don’t need more than a Local Redundant Storage.

clip_image004

 

If your virtual machines to be protected is linked to an Availability set, you will need to select an availability Set in the destination Azure region to offer the same SLA for your virtual machine.

Each Azure Virtual machine to be protected must be associated to a replication Policy.

we can customize the following parameters:

  • Retention policy for the recovery points
  • Frequency for app-consistent snapshot

clip_image005

 

Initial configuration is now over. We can enable replication.

clip_image006

 

Once replication is enabled we can follow the Azure Site Recovery Jobs. Bellow we have all jobs related to the setup of the protection of your Azure virtual machine.

clip_image007

 

If we take a closer look at the jobs related to replication, we will discover that ASR deploy a virtual machine extension in our workload.

clip_image008

 

Watch out, it’s not because initial replication is considered as enabled that its completed. Initial replication will take some times.

clip_image009

 

In my case (standard Windows Virtual machine without any data disks), initial replication took around fifty minutes.

clip_image010

Once initial replication is terminated, we can consider that our workloads is protected.

clip_image011

 

If we take a closer look at virtual machine information page, we discover two type of recovery points:

  • Crash-consistent
  • App-Consistent

 

In DRP situation, we can choose to prefer RTO versus RPO.

clip_image012

If you are familiar with Azure SQL, you should be familiar with that map. Now I have an Azure Virtual machine located in Central US Azure region with a replica in East US Azure region.

clip_image013

 

Now you have a DRP, you can test it. Microsoft recommendation is to perform a test failover from times to times to validate our DRP plan. You can choose to ignore the recommendation is you wish but that’s a good idea to test a DRP.

clip_image014

 

We can select the recovery point using:

  • The latest recovery point (for a lowest RPO)
  • The latest processed (for the best recovery time)
  • The last app-consistent

 

For this test, recommendation is to select a dedicated Virtual Network that is not connected to the source Virtual Network (Virtual Network Gateway or Peering). In the jobs, we can track the progress.

clip_image015

 

At this stage of the test we have two virtual machines running: The original and the test. Because the second one is connected to an isolated network you can check the health of the application and validate the DR plan.

clip_image016

 

Test is now complete we can cleanup used resources.

clip_image017

 

Our workload is now protected. Let’s see how to initiate a « clean failover ».

 

The « Clean Failover »

We will be considering that failover is initiated manually. In fact, using Log Analytics we can:

  • Detect an unhealthy virtual machine and initiate a single failover
  • Detect a major outage in Azure Activity and initiate a complete relocation

 

When initiating the failover process, we need decide if fast service recovery is more important than full service restauration.

clip_image018

 

Because we have both App-Consistent snapshots and Recovery points (up to 24 hours with the default policy), custom recovery point allows us to choose a specific version of my application. That’s great because, nowadays, applications are distributed among many servers. In DR situation, we will need to restore many servers.

clip_image019

 

In Azure Site Recovery Jobs view we can notice that failover was initiated.

clip_image020

 

If we look at the details, we see that the virtual machine located in the source Azure region was shutdown properly and a new virtual machine was provisioned in the target Azure region. In my case, complete failover operation took five minutes and a half (I choose to minimize the Recovery Point objective).

clip_image021

 

Once terminated Job appear as completed in the Azure Site Recovery Jobs view. From a virtual machine point of view we now have two virtual machines but only the one located in the target Azure region is running.

clip_image022

 

Once failover is completed we need to commit the operation. Once commit is performed we select another recovery point.

clip_image023

 

The clean Rollback

Rollback process is named « re-protect ». In fact, it’s the same process but we switched the target and source parameters.

clip_image024

 

By default, ASR will use the same parameters but you can override them if necessary.

clip_image025

 

It’s a little bit longer than on the protection phase, but remain an acceptable

clip_image026

 

Disable replication

That’s the bonus. When failover is committed, you have the choice to disable replication. This option was designed to move a workload from an Azure region to another.

 

Additional readings

To have more information about the feature, I would recommend the following readings :

 

Conclusion

What to say. Even if it’s a preview, it’s almost feature complete (CLI & PowerShell support are missing, just like Managed disks). Once feature will be Generally Available, we will have first-class Disaster Recovery service we cannot not implement.

 

BenoitS – Simple and Secure by design but Business compliant (with disruptive flag enabled)

 

Contrôle budgétaire dans Azure

Lors de mes formations sur Azure, il y a un sujet qui revient régulièrement : Est-on capable de répondre aux exigences d’un DAF qui demande un contrôle budgétaire stricte. Autant vous dire qu’essayer d’argumenter avec de la technique. Genre : Maintenant dans Azure on peut envoyer la facture au DAF par mail, ça ne va pas le faire du tout, …

clip_image001

 

Sans contrôle, le Cloud ne sera qu’une promesse non tenue. Problème, le DAF détient les cordons de la bourse. Si nous ne sommes pas capables de répondre à cette simple question, l’expérimentation Cloud va tourner court. Histoire de poser le décor, voilà une liste des risques auxquels nous devons répondre :

  • Comment limiter la consommation pour une population donnée ?
  • Pouvons-nous accorder un crédit à une population donnée ?
  • Comment suivre facilement l’évolution de la consommation ?

 

Malheureusement, il n’y a que dans le cadre d’une souscription de type Enterprise Agreement qu’on est capable de répondre à ces problématiques :

  • La segmentation en départements avec un budget permet de répartir le crédit Azure
  • Chaque département se voit affecté un crédit qu’il est libre de consommer, charge à l’administrateur de le suivre
  • Le suivi de la consommation est réalisable via l’intégration de Power BI : Microsoft Azure Enterprise content pack for Power BI

 

Voilà pour les grandes lignes d’une souscription de type Enterprise Agreement. Maintenant voyons les moyens dont on dispose pour tous les types de souscription.

Azure Spending Limit

Le premier et le plus ancien de tous est la fonctionnalité Azure Spending Limit. Pour les souscriptions autre que CSP & EA, la fonctionnalité est accessible via l’ancien portail https://account.windowsazure.com. Dans l’illustration ci-dessous, ma souscription « Pass Azure » disposait d’un crédit de 85€ de consommation. Arrivé à 0, la souscription sera automatiquement désactivée. C’est à moi, propriétaire de la souscription de venir supprimer la limite de consommation (et d’indiquer un moyen de paiement).

clip_image002

 

A noter que configurer un moyen de paiement n’est pas obligatoire pour les souscriptions de type « Pay-As you go ». Maintenant, charge au propriétaire de suivre sa consommation, … Pour une souscription de type CSP, c’est le partenaire qui propose ce service en configurant un indicateur qui va l’informer de la consommation de son client. Attention, c’est une limite soft, juste un avertissement.

clip_image003

 

Pour un Enterprise Agreement, c’est un suivi de l’administrateur du département. Une notification par mail lui est automatiquement envoyée chaque semaine.

clip_image004

 

Tagger les ressources

Le premier contact du DAF avec une facture Azure est plutôt violent. Sa première question, c’est comment effectuer un regroupement de ces coûts selon différents critères. Savoir qu’il a payé pour du compute c’est bien mais s’il est capable de le refacturer entre les équipes, on l’aide à définir quelle est la participation de chaque entité de l’entreprise pour le poste budgétaire de l’IT. Attention, on ne parle que de coût IT. Avec le IaaS, on peut assez facilement déduire le nombre d’exploitants nécessaires par rapport au nombre de machines virtuelles et l’utiliser comme clé de répartition pour les couts de personnel. Par contre, ce ne sera plus aussi vrai pour le PaaS, encore moins pour le SaaS.

clip_image005

 

Le simple fait de tagger les ressources ne permet pas de contrôler les coûts. Pour cela, il faut forcer l’usage des tags. C’est là que la fonctionnalité Azure Resource Policy. C’est un sujet que j’avais déjà abordé dans un précédent billet (Découverte d’Azure Resource Policy). Maintenant, la fonctionnalité est présente dans le portail au niveau de la souscription avec bonus en plus quelques policies « built-in » bien pensées :

  • Imposer l’utilisation de Tag (pas de tag, pas de déploiement)
  • Affecter un tag par défaut s’il n’est pas spécifié (Pas de code d’imputation comptable, alors c’est celui de l’IT qui sera utilisé, …)
  • Interdire le déploiement de ressources en dehors des régions Azure sélectionnées
  • Interdire l’usage de certains « Sku » de stockage / machines virtuelles

Après, rien ne vous interdit de développer vos propres policies.

clip_image006

 

Ce qui est bien, c’est que ces Policies peuvent être assignées aussi bien au niveau de la souscription que d’un groupe de ressources. Là on tient une fonctionnalité intéressante puisqu’on se positionne avant même de déployer les ressources. Si on a pensé à mettre en œuvre ce type de fonctionnalité avant même de déployer des ressources dans Azure, on a déjà fait un grand pas pour convaincre le DAF. Maintenant, il faut arriver à lui montrer qu’on est capable de réduire les coûts, …

 

Les Quotas

C’est un des premiers sujets qui remonte au près du support Microsoft, l’augmentation des quotas de votre souscription. Si on peut demander l’augmentation des quotas pour les ressources que nous consommons, nous pouvons aussi demander à en réduire la valeur en fonction de nos besoins.

clip_image007

 

Par contre, attention, c’est un type de contrôle « Soft ». Il suffit d’une demande au support pour faire relever la limite. Ce qui est bien, c’est que la demande est nécessairement tracée, on retrouve donc rapidement celui qui a formulé la demande.

 

La mesure des usages

Mettre en place des Azure Resource Policies ne nous protège pas de tout. En fait, à vouloir tout contrôler, on va perdre en agilité. En plus, on peut passer à côté du plus important : La ressource sera-elle décomptée sur ma consommation Azure ou considérée comme un achat externe ? Dans le portail Azure, lorsqu’on déploie une ressource, si on nous demande de valider un achat, c’est que c’est un achat externe, même si celui-ci coute 0€ comme pour Sendgrid :

clip_image008

J’ai bien pensé à utiliser les Azure Resources Policy pour bloquer les déploiements impliquant des achats externes mais j’ai vite trouvé cela très lourd à mettre en œuvre. Déployer des composants comme le système d’exploitation RedHat ou le composant SendGrid peuvent tout à fait être légitimes. Finalement, c’est en se reposant sur la mesure des usages qu’on sera capable d’adresser ce risque. La simple commande PowerShell ci-dessous nous remonte les déploiements de ressources impliquant une facturation tierce :

Get-AzureRMLog | Where {$_.OperationName -eq « Microsoft.Resources/marketplace/purchase/action »}

clip_image009

 

Avec un peu d’industrialisation avec Azure Automation, on devrait être capable d’envoyer un mail au DSI et agir en conséquence. S’il avait demandé à utiliser du Kemp et qu’il se retrouve avec du F5 à la place, il devrait agir rapidement. Le risque est ainsi mieux maitrisé. Si le sujet vous intéresse, je vous renvoie vers un de mes billets sur le sujet : Mais qui est le Dédé qui a fumé 3k dans ma souscription Azure ?

La fonctionnalité Devtest Labs

La fonctionnalité DevTest est vaste. Simplement, c’est un conteneur qu’on met à disposition des développeurs pour générer leurs environnements de dev/test. L’intérêt de la fonctionnalité est de pouvoir rendre le développeur autonome dans ses activités quotidiennes tout en étant assuré qu’on ne va pas exploser les budgets (tout du moins sans en être préalablement notifié). Globalement, cela passe par un certain nombre de fonctionnalités :

  • Limitation fine des machines virtuelles que le développeur peut déployer (limitation des SKU, limitation du nombre d’instance par développeur, …)
  • Capacité à limiter les choix du développeur pour le déploiement de ressources en provenance du Marketplace
  • Capacité à proposer une liste de Custom Images prêtes à être utilisées
  • Mise à disposition d’un coffre-fort numérique pour stocker les secrets utilisés dans l’environnement de développement.
  • Création de « formules de déploiement » pour faciliter la mise en place d’environnements de tests. Ces « formules » peuvent exploiter les secrets du développeur
  • Capacité à fixer une date d’expiration à une machine virtuelle
  • Capacité à réaliser un « auto-shutdown » (ainsi qu’un « auto-Start ») des ressources pour éviter de facturer du compute inutilement.
  • Capacité à limiter les Virtual Networks sur lequel les développeurs peuvent déployer

Ce qui nous intéresse dans la fonctionnalité DevTest, c’est la possibilité de sélectionner les SKU des machines virtuelles mais aussi le contenu issu du Marketplace, aussi bien dans la SKU sélectionnée que le nombre des instances. Un bon argument pour le contrôle budgétaire.

 

Voilà pour les fonctionnalités techniques, maintenant, celle qui trait à la maitrise de la facturation. Pour chaque instance du service DevTest que l’on met en place, on peut définir des seuils de consommation avec pour chaque seuil, la possibilité de notifier mais aussi de déclencher un WebHook.

clip_image010

 

Avec cela, on peut facilement déclencher des actions avec Azure Automation pour éviter les dépassements de consommation. Exemple, arrivé à 95% du montant fixé, on arrête toutes les ressources. Par contre attention, DevTest ne limite pas la consommation. Il se contente de nous indiquer notre consommation actuelle. La mise en place d’une limite de consommation nécessite déjà d’avoir une harmonisation des API de Facturation entre les différents types de souscription.

En jouant avec les fonctions « Auto-Shutdown » et « Auto-Start », on arrive à limiter la facturation des machines virtuelles. Les environnements de développement n’ont pas besoin de fonctionner pendant les week-ends et les nuits en semaine. On peut ainsi économiser jusqu’à 40% de la facture de compute par machine virtuelle.

clip_image011

 

Azure Advisor

Azure Advisor a pour objectif de nous faire des propositions pour optimiser notre usage d’Azure. Les recommandations peuvent porter sur la disponibilité des ressources, la sécurité, la performance ainsi que les coûts.

clip_image012

 

Si Azure Advisor identifie une ou plusieurs ressources (machines virtuelles par exemples) pour lesquelles notre consommation est bien en dessous des capacités mises à disposition, nous serons informés de la possibilité de revoir le sizing de l’instance de la ressource.

Azure Reserved Instances (Update décembre 2017)

La plateforme Azure évolue. Une de ces évolutions est la possibilité de se voir proposer des prix dégressifs pour les machines virtuelles selon une durée d’engagement de un à trois ans. Aucun DAF ne peut rester insensible à 44% de remise, … Azure Reserved Instances – La fonctionnalité la plus simple à expliquer

 

Azure Cost Management (Update décembre 2017)

Microsoft ayant racheté CloudDyn, c’est Maintenant Azure Cost Management et c’est gratuit. C’est donc criminel de s’en passer.

 

Les outils tiers

Plusieurs partenaires de Microsoft se sont positionnés sur le marché des outils de suivi budgétaire sur le Cloud. Dans la liste, on peut citer :

La solution proposée par Microsoft est disponible sur Github. Elle n’est pas aussi complète que les autres solutions qui sont-elles payantes mais elle a le mérite d’exister.

clip_image013

 

La solution Azure usage and Billing portal permet à un client de s’enregistrer auprès de la solution pour autoriser la collecte des données de facturation pour ensuite leur permettre d’y accéder via Power BI. A ce jour, le support des souscriptions de type CSP n’est pas encore généralisé chez tous les éditeurs. CSP utilise actuellement une API de facturation bien spécifique qui nécessite des développements additionnels.

 

Conclusion

Pour conclure, la maîtrise de la facturation passera aussi par la capacité à votre organisation d’adopter la plateforme Cloud de Microsoft. On peut continuer à déployer des machines virtuelles pour héberger des applications mais on ne tire pas pleinement des capacités de la plateforme Azure. C’est l’automatisation et l’utilisation des solutions PaaS et SaaS (plutôt que IaaS) qui feront que le coût de revient dans Azure baissera. L’exploitation implique des coûts humains incompressibles. Cela ne veut pas dire que dans un futur proche nous n’aurons plus d’IT-Pro pour gérer nos ressources dans Azure mais qu’ils deviendront plus efficaces dans la gestion d’un plus grand nombre de ressources.

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Certification Azure 70-534 : Architecting Microsoft Azure Solutions

Après la certification 70-533, je suis passé à la certification 70-534 : Architecting Microsoft Azure Solutions, avec succès.

clip_image001

 

Ma préparation

Comme base de travail, j’ai utilisé le workshop MOC40442A-Architecting Microsoft Azure Solutions. Je devais donner le cours pour des clients, ça tombait très bien. Avec cette certification, l’objectif n’est pas de savoir mettre en œuvre telle ou telle fonctionnalité d’Azure mais bien de les assembler. Ca implique de se pencher sur les Cloud Design Patterns et comprendre les principales architectures de références. La bonne compréhension des Cloud Design Patterns est essentielle car de là découlent les principales architectures de référence. Il faut prendre un peu de recul par rapport à la technique pure. Rapidement, on va vite s’éloigner de sa zone de confort (la découverte de DocumentDB dans mon cas) et la liste s’allonge rapidement. Ci-dessous quelques sujets que j’ai étudiés et qui peuvent tomber à l’examen :

  • Azure Storage queue versus Service bus queue, lequel choisir ?
  • Service bus topic versus Service bus relay, lequel choisir ?
  • Scénarios autour de Mobile Services & Push Notification
  • Notification hub, quelles sont les limitations de chaque SKU pour bien choisir ?
  • Azure Batch versus Azure HPC, lequel choisir ?
  • Azure HPC : Quelles SKU pour du RDMA ?
  • Redis Cache dans quels scénarios l’utiliser ?
  • Availability Set : Comment assurer la disponibilité d’une application dans Azure (avec contraintes imposées)
  • Haute disponibilité des WebApp dans Azure
  • Une vision générale des limites de chaque service (VM, WebApp, SQL, Event-Hub, Service Bus) pour savoir quelle édition utiliser
  • Media services, comment encore des flux comment les uploader et les diffuser
  • Connaître ses commandes PowerShell voire un peu d’Azure CLI

 

Dans mes révisions j’avais fait le choix de faire l’impasse sur un certain nombre de sujets :

  • Machine Learning : Bonne pioche, je n »ai pas eu de question sur le sujet
  • HD Insight : Bonne pioche, je n’ai pas eu de question sur le sujet
  • Cloud Services : Mauvaise pioche, ça parle encore beaucoup de Cloud Services, donc ne pas le négliger
  • System Center : Mauvaise pioche, avec une unique question sur DPM

Enfin, pour préparer cet examen, j’ai fait le choix d’utiliser les outils de préparation de measureup.com et j’ai été très surpris. Le niveau des questions est très élevé. En fait, les questions du test de préparation de Measureup.com sont bien plus élevées que celles que j’ai eu à l’examen. C’est donc une excellente préparation. Pour information, aucune des questions de Measureup.com ne se retrouve dans l’examen officiel. Donc pour le bachotage, passez votre chemin.

L’examen en lui même

L’examen est organisé de la manière suivante :

  • Une série de questions individuelles (24 de mémoire), un peu comme pour 70-533
  • Trois ou quatre scénarios pour lesquels il faudra élaborer les réponses les plus adaptées en fonction des contraintes exprimées.

 

Pour les questions individuelles, il n’y a pas de mystère, c’est la pratique d’Azure qui fera la différence ainsi que votre logique. Il y a nécessairement des réponses illogiques, à vous de bien lire les questions.

Pour les scénarios, c’est avant tout beaucoup de lecture avant de se précipiter sur les questions, ça permet de bien cadrer le sujet et les contraintes imposées (Business & Sécurité). Point d’attention, les scénarios sont indépendants les uns des autres. Même si on peut marquer les questions pour revenir dessus ultérieurement, rappelez-vous qu’une fois un scénario clos, on ne peut plus revenir dessus.

 

Même si l’examen est aujourd’hui disponible en français, je le déconseille. Toute votre littérature de préparation est en langue anglaise, y compris les tests de préparation. En plus passer l’examen en langue anglaise vous crédite de 30 minutes de plus donc 180 minutes au total.

 

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Azure – Découverte de l’API de Billing

Une habitude que j’ai prise avec Azure, c’est de décortiquer la Release note du module Azure PowerShell tous les mois. C’est le meilleur moyen de détecter les nouvelles fonctionnalités mises à disposition. Donc dans la livraison de Mars 2017, j’ai découvert le module AzureRM.Billing qui contient la commande Get-AzureRMBillingInvoice :

clip_image001

 

Ça vient compléter la capacité à envoyer la facture par mail mise à disposition en Janvier 2017. C’est le prémices d’une API nous permettant d’accéder à la facturation d’Azure. C’est un bon début car lorsqu’on creuse un peu la partie Billing d’Azure, on découvre que cela fonctionne bien différemment pour les souscriptions de type EA ou CSP. Si on tente d’utiliser la commande immédiatement, ça nous répond que nous ne sommes pas autorisés.

Get-AzureRMBillingInvoice -Latest

clip_image002

 

En fait, la fonctionnalité doit être activée au niveau de la souscription dans le nœud « Invoice ».

clip_image003

 

Dès lors que la fonctionnalité est activée et que nous disposons d’un niveau de privilège souscription, nous pouvons extraire les informations de la dernière facture.

Get-AzureRMBillingInvoice -Latest

clip_image004

 

Ceux qui lisent mon blog reconnaissent un Shared Access Signature dans l’URL de téléchargement. On note aussi la présence d’une date d’expiration fixée à une journée. Nous avons là un parfait exemple de mécanisme de type « Key Valet » qui a mis à disposition une clé d’accès pour chaque fichier PDF avec une durée de vie d’une journée. Le contenu de la facture contenant des informations personnelles, il est logique que la date d’expiration soit aussi courte. Pensez juste à préciser ce point à votre DAF lorsque vous lui communiquerez l’URL.

Pour finir, on constatera la présence du rôle Billing Reader qui autorise ceux qui y sont associés d’accéder à la facture. C’est très utile pour votre DAF.

clip_image005

 

Attention : Au moment où j’écris ce billet, la nouvelle API de facturation n’est pas encore utilisable dans tous les types de souscriptions. Techniquement, le rôle Billing Reader est bien disponible en EA/CSP, par contre, vu qu’il n’est pas possible d’activer la fonctionnalité dans le portail, la seule réponse que l’on obtient est Bad Request avec la commande PowerShell. C’est un sujet qui évoluera certainement dans le temps.

Maintenant le DAF n’a plus besoin d’être Owner de vos souscription pour accéder à la facture.

 

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Pourquoi ADCS ne délivre des certificats que de deux ans maximum?

Lorsqu’on une installe une PKI même pour un usage purement technique, on a la tentation de réaliser l’installation via l’interface graphique, en se passant de fichiers CAPolicy.Inf et Policy.Inf. C’est ce que j’ai encore fait cette semaine et c’était une erreur. Dans mon cas, le besoin semblait simple, pourtant, je suis tombé sur un os : Pourquoi ma PKI refuse de me délivrer des certificats d’une durée de vie de plus de deux ans ? Il m’a fallu quelques minutes pour réaliser mon erreur. En l’absence de précision, une installation « Quick/Next/Finish » utilise les valeurs par défaut. Donc sans expression de besoin, il nous faut aller explorer la base de registre :

Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration

clip_image001

En creusant, la configuration, j’ai retrouvé les deux paramètres en relation avec mon problème :

  • ValidityPeriod
  • ValidityPeriodUnits

Le besoin exprimé étant de pouvoir délivrer des certificats d’une durée de vie de trois ans, une petite reconfiguration s’impose. Réalisé à l’ancienne, cela donne cela :

CertUtil.Exe -SetReg CA\ValidityPeriodUnits 3

CertUtil.Exe -GetReg CA\ValidityPeriodUnits

clip_image002

Après un redémarrage du service de l’autorité de certification, mon problème était corrigé. Conclusion, même pour une PKI à usage technique, il faut toujours préparer la mise en œuvre d’une autorité de certification. Une bonne lecture sur le sujet : The DOs and DON’Ts of PKI – Microsoft ADCS.

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Multiples adresses IP par carte réseau dans Azure

Pendant longtemps, Azure nous a limité dans le nombre d’adresses IP que l’on pouvait associer à une seule interface réseau : Une adresse IP publique et une adresse IP privée. La seule solution pour avoir plusieurs adresses IP publiques sur une même machine virtuelle était d’avoir plusieurs adresses IP publiques. Quand on travaille avec des Virtual Appliances dans Azure, c’était une limitation majeure dans le cas de Kemp, ma VLM Kemp ne pouvait avoir qu’une seule VIP. Il n’était pas possible de cumuler plusieurs Virtual Services utilisant chacun une adresse IP publique distincte. La fonctionnalité est GA depuis un peu plus d’un mois, voyons concrètement comment la mettre en œuvre avec la création d’une interface réseau dans les règles de l’art :

Je pars du principe que le Virtual Network existe. On va récupérer les informations le concernant avec la commande « Get-AzureRmVirtualNetwork » :

$vnet = Get-AzureRmVirtualNetwork -ResourceGroupName Network -Name AdatumVnet

$vnet

clip_image001

 

Dans ce Virtual Network, je sais qu’il y a un Subnet nommé « Adatumsubnet ». On va en avoir besoin car c’est à un subnet qu’une interface réseau est lié :

$subnet = Get-AzureRmVirtualNetworkSubnetConfig -Name Adatumsubnet -VirtualNetwork $vnet

$subnet

clip_image002

 

Pour que notre interface réseau puisse avoir plusieurs adresses IP, nous devons mettre en place plusieurs configurations IP. Chaque configuration IP étant composée d’une adresse IP privée voire d’une adresse IP publique. Commençons par créer notre première adresse IP publique :

$publicIP1 = New-AzureRMPublicIpAddress -name « MyPublicIP1 » -ResourceGroupName Network -Location « West Europe » -AllocationMethod static

$publicIP1

clip_image003

 

Nous avons une adresse IP publique, passons à l’adresse IP privée. Par défaut, le DHCP d’Azure nous fournirait la première adresse IP disponible sur le subnet. J’ai fait le choix d’avoir une adresse IP privée statique. La commande « New-AzureRmNetworkInterfaceIpConfig » permet de créer notre première configuration IP dans la variable $Ipconfig1.

$IpConfig1 = New-AzureRmNetworkInterfaceIpConfig -Name « Ipconfig1 » -Subnet $subnet -PrivateIpAddress ‘192.168.1.10’ -PublicIpAddress $PublicIP1 -Primary

$IpConfig1

clip_image004

 

La seconde configuration IP sera beaucoup plus simple, avec uniquement une adresse IP privée allouée en mode dynamique :

$IpConfig2 = New-AzureRmNetworkInterfaceIpConfig -Name « Ipconfig2 » -Subnet $subnet

$IpConfig2

clip_image005

 

Note : On voir bien la différence avec la première configuration IP. La propriété « PrivateIpAllocationMethod » est ici configurée à « Dynamic » alors que pour la première interface, elle était configurée à « Static ».

 

Nous avons tous les éléments pour créer notre interface réseau comprenant nos deux configurations IP. Nous connaissons déjà la commande « New-AzureRMNetworkInterface ».

$NIC = New-AzureRMNetworkInterface -Name « NetworkInterface » -ResourceGroupName Network -Location ‘West Europe’ -IpConfiguration $IpConfig1, $IpConfig2

$NIC

clip_image006

 

Une fois la création terminée, on doit pouvoir constater les résultat suivant dans le portail :

  • Notre interface réseau dispose bien de deux configurations IP
  • La première comprend une adresse IP privée statique et une adresse IP publique elle aussi en statique
  • La seconde comprend uniquement une adresse IP privée allouée dynamiquement

 

clip_image007

 

Dans mon exemple, nous avons simplement illustré le fait d’avoir plusieurs configuration IP. Si nous voulions avoir plusieurs adresses IP publiques associées à une seule interface réseau, il aurait juste fallu avoir plusieurs configuration IP, chacune ayant une adresse IP publique associée.

­

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Configurer sa première Appliance Kemp dans Azure

J’avais déjà utilisé Kemp par le passé pour DirectAccess : Monitoring DirectAccess with Kemp. Vu que sous certains aspects ça ressemble beaucoup à ce que j’ai connu avec du TMG ou de l’UAG, j’ai décidé de passer un peu de temps avec. Vu que je passe beaucoup de temps dans Azure, cela impliquait de pouvoir monter des labs de manière industrielle. Tout de suite on pense à développer un template ARM. Sur le principe, je suis d’accord, cependant, c’est développer beaucoup d’énergie pour un sujet qui n’apportera pas beaucoup de gain. On ne déploie pas autant de machines virtuelles que d’Appliances virtuelles Kemp.

C’est pour cette raison que j’ai décidé d’explorer la création d’une Appliance virtuelle Kemp en PowerShell. Sur le papier, cela ressemble beaucoup à une machine virtuelle pour un quelconque Linux. Pourtant, il y a quelques subtilités à prendre en compte :

  • Kemp est un fournisseur du MarketPlace, ça change un peu les choses pour la déclaration de l’image source à utiliser (notion de plan)
  • L’Appliance virtuelle aura deux interfaces réseau (les templates mis à disposition sont tous mono-carte)
  • Un peu de sécurité (Network Security Group) est nécessaire pour faire les choses dans les règles de l’art

 

Pour les prérequis, je considère que les éléments existent préalablement :

  • Resource Group
  • Storage Account
  • Virtual Network avec ses deux Subnets

 

Mon objectif est de déployer un Load Balancer Kemp avec deux interface réseau. Ci-dessous les prérequis techniques de mon déploiement :

$LocationIPR = ‘<Azure Region Name>’

$ResourceGN = ‘<Resource Group Name>’

$VnetName = ‘<Virtual Network Name>’

$subscriptionname = ‘<Subscription Name>’

$StorageAccountName = « <storage account name> »

$storageAccountResourceGroupName = « <Storage Account Resource Group> »

$FWName = « <Virtual Machine Name> »

$instanceSize = « Standard_D3_v2 »

$subnetFrontName = « Front »

$frontIP = « 10.1.0.4 »

$subnetBackName = « Back »

$backIP = « 10.2.0.4 »

$reservedIPName = « FrontReservedIP »

$publicNICName = $FWName + « _ » +$subnetFrontName + « NIC »

$privateNICName = $FWName + « _ » + $subnetBackName + « NIC »

$FWPublicIPName = $FWName + « _ »+ « PublicIP »

$diskName = $FWName + « _OSDisk »;

clip_image001

Première subtilité Kemp, le nom du compte « root » de l’Appliance, ce sera « BAL ». On peut spécifier ce que l’on veut, ce sera toujours « BAL » pour le compte par défaut. On ne va donc pas le contrarier et générer un objet de type « SecureString » pour personnaliser le mot de passe initial.

$FWAdminUser = « bal »

$FWPassword = « LeMotDePasseIlaChangé! »

$SecurePassword = ConvertTo-SecureString -String $FWPassword -AsPlainText -Force

$FWSecureCredential = New-Object -TypeName « System.Management.Automation.PSCredential » -ArgumentList $FWAdminUser, $SecurePassword

clip_image002

 

No-Comment, …

$cred = Get-Credential

Login-AzureRmAccount -Credential $cred -SubscriptionName $subscriptionname

clip_image003

 

La première étape, c’est d’identifier le fournisseur nommé « Kemp Technologies » dans la région qui nous intéresse : West Europe :

$publisher = « kemptech »

$publishername = Get-AzureRmVMImagePublisher -Location $LocationIPR | Where {$_.Publishername -eq $publisher}

clip_image004

 

Puis d’identifier la ou les offres proposées par ce fournisseur. Avec Kemp, nous avons deux offres. La solution Kemp 360 Central est une Appliance destinée à centraliser l’administration d’un ensemble d’Appliances Kemp, l’offre qui nous intéresse est donc « VLM-Azure ».

Get-AzureRmVMImageOffer -Location $LocationIPR -PublisherName $publishername.PublisherName

clip_image005

 

$Offer = « vlm-azure »

$ImageOffer = Get-AzureRmVMImageOffer -Location $LocationIPR -PublisherName $publishername.PublisherName | Where {$_.Offer -eq $Offer}

clip_image006

 

Prochaine étape, la SKU ou l’édition en français.

Get-AzureRmVMImageSku -Location $LocationIPR -PublisherName $publishername.PublisherName -Offer $ImageOffer.Offer

clip_image007

 

Celui qui va m’intéresser est l’édition « FreeLoadMaster », c’est pour du test :

$skuname = « freeloadmaster »

$sku = Get-AzureRmVMImageSku -Location $LocationIPR -PublisherName $publishername.PublisherName -Offer $ImageOffer.Offer | Where {$_.Skus -eq $skuname}

$sku

clip_image008

 

Le Marketplace propose toujours les trois dernières versions d’une solution. Il est donc logique de trouver cela :

Get-AzureRmVMImage -Location « West Europe » -PublisherName $publishername.PublisherName -Offer $offer -Skus $sku.skus

$image = Get-AzureRmVMImage -Location « West Europe » -PublisherName $publishername.PublisherName -Offer $offer -Skus $sku.skus | Select -Last 1

$image

clip_image009

 

Seconde subtilité, celle du Marketplace et la manière de référencer l’image à utiliser. Celle-ci vient du Marketplace Azure. Pour un déploiement automatisé, il nous faudra deux choses :

  • Définir la notion de plan (quelle ressource déployer)
  • Autoriser le déploiement automatique pour cette ressource

Pour la notion de plan cela se présente ainsi :

$vm1 = New-AzureRmVMConfig -VMName $FWName -VMSize $instanceSize

Set-AzureRMVMOperatingSystem -VM $vm1 -Linux -Credential $FWSecureCredential -ComputerName $FWName

Set-AzureRMVMSourceImage -VM $vm1 -PublisherName $image[0].PublisherName -Offer $image[0].Offer -Skus $image[0].Skus -Version $image[0].Version

$vm1.Plan = @{« name »= $sku.skus; « publisher »= $image.PublisherName; « product » = $image.Offer}

clip_image010

 

Note : Depuis la version 1.2.2 du module AzureRM, on dispose de la commande Set-AzureRmVMPlan.

Pour le second, cela se passera dans le portail, au niveau de la souscription. Nous avons un menu nommé « Programatic Deployment ». On remarque qu’il n’y a pas de menu pour ajouter / supprimer les fournisseurs du MarketPlace. Pour ajouter le fournisseur Kemp Technologies, j’ai dû réaliser un déploiement en utilisant le portail. Attention, le modèle d’autorisation ne considère pas que le fournisseur mais aussi la solution déployée.

clip_image011

Les bases sont posées. On revient maintenant sur du classique avec la déclaration du disque OS de notre future machine virtuelle.

$storageAccount = Get-AzureRmStorageAccount -ResourceGroupName $storageAccountResourceGroupName -Name $StorageAccountName

$osDiskURI = ($storageAccount.PrimaryEndpoints.Blob.ToString() + $FWName + « / » + $diskName + « .vhd »).ToLower()

Set-AzureRMVMOSDisk -VM $vm1 -Name $diskName -VhdUri $osDiskURI -CreateOption fromImage

$osDiskURI

clip_image012

Ma machine virtuelle devra avoir deux interfaces réseau, dont une avec une adresse IP publique et un nom DNS associé.

$vnet = Get-AzureRMVirtualNetwork -Name $VnetName -ResourceGroupName $ResourceGN

$subnetFront = Get-AzureRMVirtualNetworkSubnetConfig -Name $subnetFrontName -VirtualNetwork $vnet

$subnetBack = Get-AzureRMVirtualNetworkSubnetConfig -Name $subnetBackName -VirtualNetwork $vnet

$publicIP = New-AzureRMPublicIpAddress -name $FWPublicIPName -ResourceGroupName $ResourceGN -Location $LocationIPR -AllocationMethod Dynamic -domainNameLabel ($FWName.ToLower() + (Get-Random -Minimum 1 -Maximum 100))

$PublicIP

clip_image013

 

Déployer une machine virtuelle avec une adresse IP publique sans Network Security Group est criminel. Vu que ça coute pas grand-chose et que cela ne nécessite que quelques lignes de PowerShell, nous allons faire l’effort pour filtrer le trafic réseau entrant pour uniquement deux protocoles :

  • Le portail d’administration de l’Appliance (8443 en HTTPS)
  • Le port SSH d’administration de l’Appliance

 

$NSGrule1 = New-AzureRmNetworkSecurityRuleConfig -Name « KempWebConsole » -Description « Allow Kemp web console Access » -Access Allow -Protocol Tcp -Direction Inbound -Priority 100 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 8443

$NSGrule2 = New-AzureRmNetworkSecurityRuleConfig -Name « KempSSHConsole » -Description « Allow Kemp SSH Access » -Access Allow -Protocol Tcp -Direction Inbound -Priority 101 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 22

$NSG = New-AzureRmNetworkSecurityGroup -ResourceGroupName $ResourceGN -Location $LocationIPR -Name ($FWName.ToUpper() + « _NSG ») -SecurityRules $NSGrule1, $NSGrule2

$NSG

clip_image014

 

Nous avons maintenant tout ce qu’il nous faut pour créer la première interface réseau et l’associer à notre objet machine virtuelle en cours de construction :

$frontNIC = New-AzureRMNetworkInterface -Name $publicNICName -ResourceGroupName $ResourceGN -Location $LocationIPR -PrivateIpAddress $frontIP -SubnetId $subnetFront.Id -PublicIpAddressId $publicIP.Id

$frontNIC.NetworkSecurityGroup = $NSG

$frontNIC | Set-AzurermNetworkInterface

Add-AzureRMVMNetworkInterface -VM $vm1 -Id $frontNIC.id -Primary

clip_image015

Note : C’est à cette première interface réseau qu’a été associé notre Network Security Group. Une fois la configuration de notre Appliance Terminée, je recommande vivement de reconfigurer les règles pour limiter l’accès à ces protocoles.

Il y a un sujet que je n’aborde pas dans cet article, c’est comment notre Kemp va-t-il pouvoir porter des VIP? Jusqu’à il y a peu, l’utilisation des adresses IP publiques sur les machines virtuelles étaient limitées en deux points :

  • Seule l’interface réseau « primaire » d’une machine virtuelle peut disposer d’adresse IP publique
  • Une interface réseau « primaire » ne peut avoir qu’une seule adresse IP publique

Au moment où j’écris ce billet, ces limitations sont encore d’actualité mais de nouvelles fonctionnalités actuellement en Preview vont permettre d’oublier ces limitations : Step-by-Step: Setup Multiple Public IPs on a VM in Azure.

La démarche pour la seconde carte réseau est identique à deux subtilités près. La première est que cette seconde interface ne sera pas considérée comme « primaire » mais comme « secondaire » et qu’aucune adresse IP publique n’est associée à cette interface.

$backNIC = New-AzureRMNetworkInterface -Name $privateNICName -ResourceGroupName $ResourceGN -Location $LocationIPR -PrivateIpAddress $backIP -SubnetId $subnetBack.Id

Add-AzureRMVMNetworkInterface -VM $vm1 -Id $backNIC.id

clip_image016

Nous en arrivons à la fin. La construction de notre objet machine virtuelle est terminée. Il ne nous reste plus qu’à ordonner son déploiement avec une dernière commande PowerShell :

New-AzureRMVM -ResourceGroup $ResourceGN -VM $vm1 -Location $LocationIPR

clip_image017

 

Après quelques minutes de déploiement, on devrait être en mesure de joindre le portail d’administration de notre Appliance pour s’authentifier. Dans mon cas, il est accessible à l’URL suivante : . Lors de la première connexion authentifiée, on arrive immédiatement à la configuration de la licence. Munissez-vous de votre Kemp-ID pour réaliser l’activation en ligne et vous pourrez commencer à configurer votre Appliance virtuelle Kemp

clip_image018

 

Maintenant, quelques détails purement Kemp :

  • Ne cherchez pas à déployer une quelconque VM Extension dans la machine virtuelle, le Linux VMAgent ne s’installera pas
  • Ne cherchez pas à activer le mode Transparency dans la configuration vos virtual services.

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)