Azure Resource Manager : Microsoft.ClassicCompute osbolete

Je m’amuse depuis hier avec ARM, mais étrangement, si j’arrivais à créer un lab presque entier en ARM, impossible de créer une VM avec une ressource JSON Microsoft.ClassicCompute/virtualMachines : l’erreur indique que mon abonnement ne me permet pas de créer ou de mettre à jour ce type d’objet.

La raison est simple, cette classe est obsolète, et doit être remplacé par un objet de type Microsoft.ClassicCompute/virtualMachines, la dernière APIversion disponible pour celui-ci est 2015-06-15.

On peut récupérer les APIversion utilisables pour l’objet via la cmdlet :

(Get-AzureProvider -ProviderNamespace Microsoft.Compute).ResourceTypes 

Merci à mon collègue Shuresh Shankar qui m’a bien dépanné sur ce coup.

Azure : créer sa première VM en powershell

Lorsque l’on crée une VM sous Azure, on se trouve rapidement limités par les portails, qui sont certes de plus en plus complet mais qui ne permettent pas d’automatiser le déploiement de VM.

Nous allons voir comment déployer rapidement des VM sous Azure en utilisant Powershell et le module Azure. Cette méthode est en cours d’obsolescence (étonnant non ?) et sera remplacée à terme par Azure Ressource Manager, elle permet par contre de créer rapidement quelques VM.

La première étape est l’installation du module Powershell Azure, récupérable sur GitHub. On y retrouve l’installer standalone ainsi qu’un web installer qui permet de télécharger et d’installer outils complémentaires : https://github.com/Azure/azure-powershell

Voici le code complet utilisé pour déployer 2 VMs, je vais ensuite expliquer chaque commande :

Import-Module Azure
Add-AzureAccount

# création d’un service de Cloud et d’un compte de stockage
$service = New-AzureService -ServiceName bjdctest -Location "West Europe"
$storage = New-AzureStorageAccount - StorageAccountName bjdctest -Location "West Europe" -type  Standard_LRS
Set-AzureSubscription -CurrentStorageAccountName bjdctest -SubscriptionId (Get-AzureSubscription).SubscriptionId

# création du Vnet 
$vnetconfig = '<?xml version="1.0" encoding="utf-8"?>
<NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration">
  <VirtualNetworkConfiguration>
    <VirtualNetworkSites>
      <VirtualNetworkSite name="Group WE BJDC" Location="West Europe">
        <AddressSpace>
          <AddressPrefix>10.200.0.0/16</AddressPrefix>
        </AddressSpace>
        <Subnets>
          <Subnet name="WE">
            <AddressPrefix>10.200.0.0/16</AddressPrefix>
          </Subnet>
        </Subnets>
      </VirtualNetworkSite>
    </VirtualNetworkSites>
  </VirtualNetworkConfiguration>
</NetworkConfiguration>'

$vnetconfig | Out-File -FilePath $env:TEMP\VNETCONFIG.xml
Set-AzureVNetConfig -ConfigurationPath $env:TEMP\VNETCONFIG.xml

# récupération de la dernière image 2012 R2
$image = Get-AzureVMImage | where { $_.imagefamily -like "Windows Server 2012 R2 Datacenter"} | Sort-Object -Property publisheddate -Descending | select -First 1

# creation de deux configuration de VM
$conf = @()
$conf +=  New-AzureVMConfig -Name VM1 -InstanceSize Basic_A1 -ImageName $image.imagename
$conf +=  New-AzureVMConfig -Name VM2  -InstanceSize Basic_A1 -ImageName $image.imagename

# creation du compte local d’administration
$conf | Add-AzureProvisioningConfig -AdminUsername “MyAdmin” -Password “motdepasse” –Windows

# ajout de la VM dans son réseau 
$conf | Set-AzureSubnet -SubnetNames 'WE'

# creation de la VM
new-azurevm -ServiceName bjdc  -VMs $conf -VNetName 'Group WE BJDC'

Le détail de chaque étape :

Add-AzureAccount

L’authentification au portail se fait via le portail d’authentification Microsoft classique, le même que l’on utilise pour les autres ressources Microsoft : Add-AzureAccount
Une fois connectée, toutes les cmdlet Azure sont disponibles.

$service = New-AzureService -ServiceName bjdctest -Location "West Europe"

Pour fonctionner, une VM nécessite un service de Cloud, celui-ci représente à la fois une capacité de calcul et le point de publication public des VM contenues dans le service. Chaque service de cloud dispose de sa propre adresse IP public et d’un enregistrement DNS public de la forme nomduservice.cloudapp.net.
Le nom public étant commun à tous les clients Azure, il n’est pas possible de créer deux services de cloud portant le même nom.

La localisation du service de Cloud permet de fixer les VM sur un ensemble de datacenters, c’est un paramètre obligatoire. On peut récupérer la liste des zones géographiques via la cmdlet

Get-AzureLocation | select name

Par exemple aujourd’hui voici la liste des zones où Microsoft Azure dispose de DataCenter :
Get-AzureLocation

New-AzureStorageAccount –StorageAccountName bjdctest -Location "West Europe" -type  Standard_LRS

Le compte de stockage permet de stocker à peu près n’importe quoi sous forme de blob, mais dans notre cas il servira au stockage des VHD, les disques durs de nos VM.
Si l’on ne spécifie par un type particulier, le compte est créer en mode géo réplication, cette option coûte plus cher que le Standard_LRS, qui correspond à un stockage local.

$vnetconfig = '<?xml version="1.0" encoding="utf-8"?>
<NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration">
  <VirtualNetworkConfiguration>
    <VirtualNetworkSites>
      <VirtualNetworkSite name="Group WE BJDC" Location="West Europe">
        <AddressSpace>
          <AddressPrefix>10.200.0.0/16</AddressPrefix>
        </AddressSpace>
        <Subnets>
          <Subnet name="WE">
            <AddressPrefix>10.200.0.0/16</AddressPrefix>
          </Subnet>
        </Subnets>
      </VirtualNetworkSite>
    </VirtualNetworkSites>
  </VirtualNetworkConfiguration>
</NetworkConfiguration>'

$vnetconfig | Out-File -FilePath $env:TEMP\VNETCONFIG.xml
Set-AzureVNetConfig -ConfigurationPath $env:TEMP\VNETCONFIG.xml

Un VNet est un réseau virtuel comprenant un ou plusieurs sous réseaux. La création d’un VNet est pilotée par un fichier XML, pour simplifier l’exercice, nous allons généré et pousser un fichier pour un sous réseau en 10.200.0.0/16.
Si il existe deja un VNet contenant des VM, il ne sera pas possible de pousser ce nouveau VNet, il faudra soit utiliser l’ancien VNet, ou ajouter celui-ci à l’existant, que l’on peut récupérer par :

Get-AzureVNetConfig -ExportToFile vnetconf.xml

Il suffit d’ajouter la section VirtualNetworkSite dans le fichier obtenu.

$image = Get-AzureVMImage | where { $_.imagefamily -like "Windows Server 2012 R2 Datacenter"} | Sort-Object -Property publisheddate -Descending | select -First 1

Cette ligne de commande permet de récupérer la dernière image Windows 2012 R2 publiée sur Azure. Il existe plusieurs centaines d’images publiées, et aujourd’hui il n’existe pas de paramètre dans la cmdlet pour trier les résultats en amont, nous sommes donc obligés de filtrer les résultats récupérés sur des attributs tel que OS, Description, ImageFamily, etc.

$conf = @()
$conf +=  New-AzureVMConfig -Name VM1 -InstanceSize Basic_A1 -ImageName $image.imagename
$conf +=  New-AzureVMConfig -Name VM2 -InstanceSize Basic_A1 -ImageName $image.imagename

Je crée un tableau contenant 2 objets de type AzureVMConfig, il est tout à fait possible de ne créer qu’une VM, ou bien plus. Par contre les VM seront créés de façon séquentielle du côté d’Azure.

La taille de l’instance est sensible à la casse, il est possible de récupérer les gabarits disponibles avec la cmdlet :

Get-AzureRoleSize | select InstanceSize

Attention car tous les gabarits ne sont pas immédiatement disponibles dans toutes les localisations.

$conf | Add-AzureProvisioningConfig -AdminUsername “Admin” -Password “motdepasse” –Windows

Pour chaque VM, je crée un objet de configuration (ConfigurationSet), obligatoire, qui contient le compte local d’administration du serveur. Attention certains noms ne sont pas autorisés (admin par exemple), et le mot de passe doit respecter une certaine complexité.

$conf | Set-AzureSubnet -SubnetNames 'WE'

On configure les VM pour être placé dans le sous réseau WE

new-azurevm -ServiceName bjdc  -VMs $conf -VnetName "Group WE BJDC"

Et il ne reste plus qu’à déployer !

Exchange, virtualisation, CSV et formatage

J’ai effectué pendant plusieurs semaines une campagne de JetStress pour un client dont les serveurs Exchange 2013, virtualisés, utilisaient des disques VHDX posé sur des CSV Hyper-V.

On connait bien sur la recommandation Exchange de faire un formatage 64KB sur les disques de données, mais qu’en est-il des volumes CSV? Dans notre cas de figure, la recommandation avait été suivi sur les VM Exchange, mais pas sur les volumes CSV des hôtes Hyper-V : ceux-ci étaient restés à la taille par défaut (4KB).

La différence n’était pas flagrante au départ, on obtenait au final des courbes de latence correcte en situation nominale. C’est devenu beaucoup plus flagrant lorsqu’on a commencé à stimuler un peu plus le stockage (dans notre vas via une reconstruction de raid group). En observant la latence des IO entre les VM et les hôtes Hyper-V, il y avait certes des courbes ayant la même allure, mais pas la même amplitude : un pic de latence de 200ms côté Hyper-V pouvait se transformer en pic de 1000ms côté VM!

Une fois les volumes CSV formatés en 64KB, nous avons pu récupérer en moyenne 10% de latence en moins et surtout des pics de latence beaucoup moins prononcés pendant les phases de reconstruction raid.

Je n’ai pas l’explication technique, qui est plutôt dans les mains d’un expert stockage, mais je suppose que mes IO random 32KB ou pire mes IO Séquentiels 256KB étaient fragmentés par l’hôte Hyper-V, qui attendait d’avoir l’acquittement de l’ensemble des blocs avant d’acquitter la VM.

Bulletin de sécurité ms15-026

Le bulletin de sécurité MS15-026 a été publié hier, il concerne des vulnérabilités côté OWA sur du cross site scripting (c’est à la mode…).
En attendant un patch, le workaround ne peut être porté que par un parefeu applicatif bloquant certaines chaines particulieres.

Le détail des vulnérabilités n’a pas été publié, cependant les actions de contournement donne une bonne idée des techniques utilisés.

Plus d’information chez Microsoft : https://technet.microsoft.com/en-us/library/security/ms15-026.aspx

Techdays 2015, c’est fini!

Les 3 journées des Techdays 2015 sont terminées, ma toute première sessions aussi devant une salle comble!

En compagnie de Anthony et Guy nous avons présenté une session architecture préférée pour Exchange 2013 en 45mn chrono, celle-ci reprenant les grands concepts présentés par Ross Smith IV au travers du blog EHLO.

Une petite précipitation dans les dernières slides sur la sauvegarde sur le Single Item Recovery et le In-Place Hold, voici la correction :

– le Single Item Recovery ne permet pas de récupérer les éléments supprimés par un utilisateur (c’est la fonctionnalité de dumpster deja présente dans les versions précédentes), mais permet à un administrateur de récupérer les éléments supprimés du dumpster par l’utilisateur ou qui ont été “hard delete” (donc qui ne devraient pas passer par le dumpster). Cette fonctionnalité permet de plus de sauvegarder toutes les versions d’un élément si celui ci est modifié. Les éléments récupérés par le Single Item Recovery conserve leur timestamp d’origine et expire avec le même délai que celui du Dumpster.

– le In-Place Hold va plus loin que le Litigation Hold, il permet d’avoir une meilleur granularité en offrant un filtre sur les messages à conserver ainsi que sur la durée de rétention.

Première session Techdays sur l’architecture préférée Exchange 2013

Cette année j’aurais le plaisir de présenter avec Anthony Costeseque et Guy Groeneveld la session « Préconisation d’architecture type d’Exchange 2013 ».

Dans cette session nous vous donnerons les derniers conseils pour implémenter une architecture Exchange 2013 basée sur les recommandations Microsoft !
Venez nombreux, elle a lieu mercredi 11 février de 12h15 à 13h !

https://techdays.microsoft.fr/programmes/2015/fiche-session.aspx?ID=c19ae9f5-058b-4487-a9ef-c0aeba8530dd

Exchange 2013 : n’oublier pas les mises à jour du schéma de base de données

Lors de chaque mise à jour, Exchange 2013 peut inclure une mise à jour du schéma de la base de données, à ne pas confondre avec la mise à jour du schéma Active Directory. Les modifications effectuées ne sont malheureusement pas documentées, on sait qu’elle concerne la structure des bases ESE, en particulier des tables et des attributs, elle est cependant complémentement transparente pour les utilisateurs.

Chaque base de donnée dispose de la version de son schéma, renseigné directement dans la base de données et non pas dans l’Active Directory. Cette version peut être interrogée par la cmdlet Get-MailboxDatabase -Status en consultant l’attribut CurrentSchemaVersion.

Si le serveur fait partie d’un DAG, lors d’une mise à jour l’attribut MaximumSupportedDatabaseSchemaVersion de chaque copie de base de données hebergée sur le serveur est incrémenté à la version maximale supportée par le CU. Exchange 2013 RTM a commencé à la version 0.121 et nous en sommes à la version 0.128 pour Exchange CU7.

Par contre il ne suffit pas de mettre à jour tous les noeuds d’un DAG pour que les bases de données se mettent à jour automatiquement, celles-ci ont besoin d’être démontées puis remontées.

Pour savoir si une mise à jour est en attente, il faut consulter l’attribut RequestedSchemaVersion obtenu par la cmdlet Get-MailboxDatabase -Status.

Cet attribut correspond à la valeur minimale contenu dans tous les noeuds du DAG pour l’attribut MaximumSupportedDatabaseSchemaVersion, on peut parler de plus grand dénominateur commun. Si il est supérieur à la version courante de la base de données, lors de son prochain redémarrage celle-ci se mettra à jour.

Il suffit alors d’enchainer un Dismount-Database puis un Mount-Database pour que la base se mette à jour.