Gérer ses VM Azure...

Ceci est un Notepad en évolution... Revenez...

Start / Stop

Un des intérêts d'une VM dans le cloud, c’est de n'en payer que l'usage. Pour la faire courte et pour donner suite à mon article sur les Bureaux à distance, je me suis retrouvé pour ce client avec VM qui n'était pas assez puissante. Sous Azure, c’est facile, en deux clics on change la taille de la VM, on choisit une instance avec plus de CPU, RAM, IO et bien sur le tarif augmente... Et si Azure est fonctionnellement remarquable, les tarifs sont purement stratosphériques si on les compare à une VM sur un serveur dédié chez Scaleway ou OVH (qu'il faudra bien sur géré, ce qui a aussi un coût et n’est pas faisable facilement par tout le monde). Bien sur ont peut facilement imaginer que les grand comptes obtiennent des remises tout aussi conséquents, sauf que pour une PME ça reste bien souvent inaccessible.

Vu que cette VM ne va être utilisée qu'aux heures de bureau, une façon de faire quelques économies va consister à programmer une heure de démarrage et une heure d'arrêt. Pour l’arrêt c’est facile, il suffit de configurer ça dans les paramètres de la VM. Mais allez donc savoir pourquoi il n'y a pas la même facilité pour la démarrer ? Chez Microsoft il appellent ça By Design. Il doit bien y avoir une raison puisque qu'il semblerait que ce soit à peu près le même fonctionnement chez les autres fournisseurs d'instances cloud et même chez OVH ou Scaleway. Bref, ce serait trop facile.

Il y plusieurs solution pour palier à ça !

Azure CLI

On peu bricoler quelque chose avec Azure CLI (Linux, Mac, Windows) et ainsi lancer un script qui va lancer ou stopper a VM. Pas très sexy ni trop sécurisé. 

Attention : Il ne faut pas se contenter d’arrêter la VM depuis l'O/S car si cela arrêtera bien la VM, elle continuera à être facturée, simple, mais sans intérêt. Pour qu'elle ne soit plus facturé il faut la désallouer (Deallocate) et ainsi seul le stockage continuera à être facturée.

Démarrer la VM

az vm start --name MyVM --resource-group MyVMGroup

Arrêter et désallouer

az vm stop --name MyVM --resource-group MyVMGroup
az vm deallocate --name MyVM --resource-group MyVMGroup

Il est également possible de faire ça en utilisant directement les ID des VM

az start --ids "/subscriptions/a35d316a-2a2a-48e2-8834-55481f7bbb48/resourceGroups/WIN16VM/providers/Microsoft.Compute/virtualMachines/Win16VM"
az stop --ids "/subscriptions/a35d316a-2a2a-48e2-8834-55481f7bbb48/resourceGroups/WIN16VM/providers/Microsoft.Compute/virtualMachines/Win16VM"
az deallocate --ids "/subscriptions/a35d316a-2a2a-48e2-8834-55481f7bbb48/resourceGroups/WIN16VM/providers/Microsoft.Compute/virtualMachines/Win16VM"

Azure Automation

Tout ça n'est pas très sexy ni user friendly. Une autre façon de faire va consister pour l'administrateur de programmer le démarrage de la VM et son arrêt en considérant que l'utilisateur s'en servira à heures fixes. Pour l’arrêt on va se servir de la fonction intégrée car elle est capable de base d'envoyer un mail à l’utilisateur lui proposant d'outrepasser l’arrêt programmé sans avoir à se connecter. Pratique.

Pour le démarrage par contre ça va être un peu plus compliqué. On va commencer par créer un compte Automation, simplement en cherchant dans la barre de recherche. Comme tout sur Azure, ce service est également payant, mais dans sa grande bonté Microsoft nous offre (jusqu'à quand ?) un petit forfait gratuit tous les mois qui sera amplement suffisant pour ce qu'on va faire.

Une fois dans notre compte Automation on va créer un Runbook, on lui donne un nom et on choisit un Flux de travail PowerShell (PowerShell Workflow) et on le crée. Une fois créé on va aller l'éditer

workflow Start-Ma-VM
{
# Association to the Azure subscribtion
$Conn = Get-AutomationConnection -Name AzureRunAsConnection
Add-AzureRMAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationId $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint

# Start the virtual machine
Start-AzureRMVM -ResourceGroupName "MonGroupeDeRessources" -Name "MaVM"
}

Il ne reste plus qu'à aller dans le menu Planifications et d'en ajouter une en configurant l'heure de démarrage et la récurrence, sans oublier de choisir le bon fuseau horaire. Si on veut envoyer une notification par un mail ou faire autre chose il est bien sur possible de le faire dans le script.

A ce stade ça reste toutefois limité, la VM va démarrer tous les jours, même quand personne ne travaille.

Heureusement il est également possible de créer un WebHook et ainsi démarrer la VM depuis une URL. Ici depuis PowerShell mais on peut tout à fait imaginer intégrer ça dans un portail intranet ou un simple raccourcis sur le poste de l'utilisateur... Ou mieux utiliser un planificateur évolué tenant compte des jours fériés et des week-ends, voire interagir avec un agenda Google ou Microsoft 365...

PS C:\Users\Lionel> Invoke-WebRequest -Uri https://6bc1fsdfs-aesdf4c2f-8d31dsfsdf7fsd5f.webhook.we.azure-automation.net/webhooks?token=ZHuMYFqgqgfqsqgdgB%2qsdgfqsdgjc%3d -Method POST

Alternatives

Si la lecture de la documentation n'est pas toujours très lisibles, il faut bien admettre qu'Azure est très complet. Et si cela ne vous suffit pas il existe des fournisseurs de service qui se sont spécialisés dans la planification des VM et plus globalement vous aideront à réduire les coûts du cloud, que ce soit sur Azure, AWS ou GoogleCloud. Je pense par exemple à ParkMyCloud ou MyCloudToolbox, mais il y en d'autres. Se posera alors la question de la confiance que vous accorderez à ces services.

L'accès des clients aux VM

Comme on l'a vu le plus simple consiste à utiliser le client d'accès à distance. Le protocole RDP n'étant pas franchement des plus sur. Sécuriser RDP imposerait de passer par des certificats et une passerelle complexe et coûteuse ou par une alternative non Microsoft du genre Royal TS Server. La logique impose de passer par un VPN. Azure propose bien entendu tout une panoplie de solutions de sécurité, n'ayant ni envie de passer à la caisse ni celle de me compliquer la vie pour ce type d'utilisation, je vais simplement utiliser ZeroTier. C'est plus un SDN qu'un VPN, c'est OpenSource et gratuit et ça fait parfaitement le travail (j'en avais déjà parlé et on trouve maintenant une multitude d'articles).

On donnera une IP fixe au serveur et tous les clients autorisés pourront accéder au serveur RDP. Ensuite on prendra soin de ne plus autoriser l'accès via l'IP externe Azure ou de forcer un ACL sur une IP cliente sure. Easy, d'autant plus que mon client utilise déja cette solution pour sécuriser l'accès à des ressources SMB distantes.

Scénario pratique....

Sur le poste de on prépare un script PowerShell qui va lancer le WebHook pour démarrer la VM Azure, attendre que le serveur soit lancé, tester le port RDP et lancer le Bureau à distance, et au passage notifier un IT si quelque chose se passe mal. S'il doit y revenir dans la journée il ne lancera que le client RDP (Bureau à distance), en fin de journée le serveur sera programmé pour s’arrêter tout seul et si l’utilisateur veut faire des heures supplémentaires il n'aura qu'à cliquer dans le mail reçu pour reprogrammer l’arrêt...

On commence par brouiller à minima le mot de passe du mail...

"P4ssww0rd!" | Convertto-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-file C:\Users\User1\admin.txt

Et ensuite on prépare un petit script qui se lancera depuis un raccourcis sur le bureau...

$password = Get-Content C:\Users\User1\admin.txt | Convertto-SecureString # On récupère le mot de passe encrypté dans un fichier...
$username = "[email protected]"
$From = "[email protected]"
$To = "[email protected]"
$SMTPServer = "mail.gandi.net"
$SMTPPort = 587
$subject = "Client : Utilisateur (Machine)"
$Credential = New-Object System.Management.Automation.PSCredential ($username, $password)

try {
    $response = Invoke-WebRequest -Uri https://6bcghgdfh-afgh-4ghgfdf-8ghfgdh5f.webhook.we.azure-automation.net/webhooks?token=ZHuMYFshghshhh5+fgshs+f5h5+65sh -Method POST
    if($response.StatusCode -eq 202) {
        Write-Host "waiting..."
        sleep 60   # Temps d’attente estimé pour le démarrage de la VM
        if (Test-NetConnection 10.17.22.15 -Port 3389 | ? { $_.TcpTestSucceeded } ) {
            C:\Users\User1\vm.rdp  # On lance le client RDP
        } else {
            cls
	    Write-Output "RDP 1" # Si test NetConnection échoue (pas de réponse)
            Send-MailMessage -To $To -From $From -Subject $subject -SmtpServer $SMTPServer -Body 'Erreur NetConnection Fail' -Credential $Credential  -Port $SMTPPort -UseSsl
	    sleep 15
        }
    } else {
        cls
	Write-Output "Erreur RDP (l'administrateur a recu un mail d'avertissement et va intervenir !)" # Si NetConnection code autre que 202
        Send-MailMessage -To $To -From $From -Subject $subject -SmtpServer $SMTPServer -Body 'Erreur NetConnection 40x ou 500x' -Credential $Credential  -Port $SMTPPort -UseSsl
	sleep 15
    }
} catch {
    cls
    Write-Output "Erreur VM (l'administrateur a recu un mail d'avertissement et va intervenir !)" # Erreur NetConnection code 40x ou 50x
    Send-MailMessage -To $To -From $From -Subject $subject -SmtpServer $SMTPServer -Body 'Erreur au lancement de la VM' -Credential $Credential  -Port $SMTPPort -UseSsl
    sleep 15
}

Ainsi, contrairement à une planification en début de journée, la VM ne sera lancée que quand l'utilisateur en a l'usage afin d'économiser sur la facture Azure. Au besoin on peut également faire un petit script pour l'éteindre.

Migration

Dans un autre contexte je dois migrer une VM Azure vers ESXi. Expérience à venir.

Sources

 

Bureau à distance Windows et imprimantes

En ces temps ou les télétravail s'impose, l'IT doit s'adapter et proposer des solutions à chaque cas. Beaucoup de salariés se sont retrouvés à bosser sur le PC familial au détriment des règles de sécurité les plus élémentaires. Sachant par ailleurs que le télétravail comporte un cadre réglementaire  qui impose la fourniture des équipement nécessaires par l'employeur ainsi qu'un défraiement pour les frais occasionnés.

Au delà de ces considérations, s'il est facile de travailler à distance sur des applications web ou sur des fichiers gérés dans le cloud avec des applications classiques du genre Office, la chose se complexifie dès lors que l'on travaille sur des applications lourdes qui nécessitent une installation spécifiques sur le poste de travail. Je pense ici par exemple à des application de compta ou de paie (Sage pour ne pas les citer, mais ils sont loin d'être les seuls) ou le simple fait de déplacer l'application d'un poste à un autre nécessite l'intervention d'un partenaire agréé pendant plusieurs heures, je ne pense pas trop me tromper en affirmant que la complexité est ici orchestrée dans le seul but de générer du revenu... Un vaste débat, un autre débat que je n'aborderais pas ici ou je vais me contenter de contourner le problème.

Au départ j'avais j'avais naïvement pensé mettre les fichiers de données sur un cloud synchronisé. Impossible car au fil du temps ces solutions reposent souvent sur du SQL même en local. Les éditeurs proposent eux de configurer un serveur, solution coûteuse et surdimensionnée dans les TPE ou il n'y a bien souvent qu'un seul utilisateur. Installer ce genre de solutions sur un laptop que le salarié risque de perdre ou de se faire voler n'est pas non plus une solution.

L'alternative consiste à se servir un d'un logiciel de prise de main à distance, genre TeamViewer ou AnyDesk, ou carrément d'une session RDP (Bureau à distance) qui offre un bien meilleur confort. Reste à s'affranchir de la lenteur possible du poste de travail distant et de sa connectivité pas toujours à la hauteur.

Il existe une alternative plus durable et plus fonctionnelle. Isoler nos logiciels lourds sur un serveur dans une session RDP. L'avantage est que cette session sera accessible par la ou le(s) personne(s) qui en ont besoin, ou qu'elle soient et tout en se basant sur une application mono poste (donc une seule licence et donc une seule utilisation concurrente). Cela permet également à des salariés disposant d'un Mac d'utiliser des applications Windows.

Dans la pratique ce serveur, qui peut être un Windows 10 ou un Windows Serveur, sera de préférence installé dans un espace sécurisé (data center, Azure, AWS, un VPS ou encore un serveur dédié). Sécurisé en terme d'accès, sécurisé physiquement (vol, incendie, etc...), mais également au niveau de sauvegardes.

On a deux choix possibles, soit on installe un Windows 10 Pro, soit un Windows Serveur. L'avantage du Windows Serveur étant qu'il permettra de base une session RDP pour l'administrateur et une autre pour le client. Les coûts ne sont pas identiques. De plus selon la taille de l'entreprise une solution Windows Serveur pourra évoluer avec RDS (et les licences qui vont avec) vers une solution multi-utilisateurs distants.

La pratique

Installer une instance Windows, une VM, sur une infrastructure se fait en quelques clics. Ensuite on crée une session pour le client avec des droits utilisateur, on lui permet l'accès distant et le tour est joué. Il n'y a plus qu'à lancer le client Bureau à distance sur le PC ou le Mac de utilisateur et ça fonctionne, en mode fenêtré ou plein écran selon la taille des on écran. De plus RDP est bien pus confortable au quotidien qu'une prise de main à distance. A partir de là on demande au prestataire Sage (ou autre) de venir y transférer ses logiciels dont lui seul possède le savoir faire nécessaire et le tour est joué.

Sauf que...

Les utilisateurs de ce genre de logiciels génèrent beaucoup d’impressions. C'est prévu, le client Bureau à distance (Windows et Mac, mais pas celui que l'on trouve sur le Windows Store) permet d'utiliser ses imprimantes locales qu'il redirige dans la session RDP. Si dans la pratique si ça peut fonctionner de façon transparente pour quelques imprimantes qui utilisent des pilotes standards fournis par Windows, dans la majorité des cas il faudra installer les pilotes des imprimantes du poste client sur le serveur, (sauf peut être si on installe RDS avec EasyPrint, ça reste à vérifier et je n'ai pas pris cette peine). Hélas il sera impossible d’installer directement certains pilotes sur le serveur, soit leur module d’installation ne peux fonctionner que sur Windows 10, soit parce qu’il nécessitent que l'imprimante soit en ligne. Il va donc falloir ruser un peu pour disposer des pilotes correspondant aux imprimantes de nos clients sur le serveur.

Il existe sous Windows (sauf la version Home) un outil de migration qui va permettre d'exporter les files d'impression d'un client ou serveur et de les réimporter en réinstallant les pilotes et les imprimantes sur la cible. On va donc lancer PrintBrmUi.exe sur le poste des clients et réimporter le fichier obtenu sur le serveur avec le même outil. Cette opération permettra également l’importation de pilotes 32 bits si ce genre de poste client existe toujours...

Attention cet outil n’est pas fait pour ça mais pour migrer des serveurs d’impression… donc il exporte / importe des files d’impression avec les drivers. Il faudra donc prendre soin de ne pas écraser les pilotes existants et ensuite d’aller faire le ménage dans les imprimantes déclarées sur le serveur mais inutiles car seule nous importe la présence des pilotes. Le plus simple étant bien sur de tout faire avec la console printmanagement.msc qui va nous permettre de visualiser les pilotes installés et de retirer les imprimantes inutiles tout en conservant les pilotes.

Sources