Azure Devops Pipeline (CI/CD) – Secrets

Cet article concerne le secret de certaine informations, comme un mot de passe, un clé privée etc.  Dutant mon apprentissage sur azure devops, je suis passé par cette étape. Cependant je ne me suis pas servi précisément de ces varibles/files secrets au final car j’ai utilisé le "service connexions" . Néanmoins je trouve cela instrucif, alors je partage. YAML – sécurité Vous avez remarqué, je ne vous ai pas communiqué ma passphrase ni ma clé privée. Sinon vous auriez accès a mon serveur. Ma clé est sur mon poste de dev. La passphrase lisible dans mes scripts d’upload automatique. C’est pas ouf question sécu. Mais vu que je bosse tout seul dessus… ça va, ça passe.  Qu’en est il lorsque l’on travaille à plusieurs dev, avec des sys admins, du cloisement et un niveau de sécurité qui nécessite de pas trop déconner ? Il faut trouver un moyen de sécuriser ces données. Azure Devops utilise des "secure files" et des "secure variables" pour faire cela.  https://docs.microsoft.com/en-us/azure/devops/pipelines/library/secure-files?view=azure-devops Ces données sont HORS repo git. Ainsi personne n’y aura accès en dehors de vous et des autorisations que vous leurs donnerez sur Azure Devops. Par contre elles seront stockées sur Azure Devops… les américains, la CIA, la NSA tout ça tout ça…   Commençons par enregistrer notre passphrase et lui donner la permission pour la pipeline du projet Azure Devops "Blazor Sandbox". Pour cela on va créer une nouveau groupe de variables que j’ai nommé IKoulaGroup. Il faut aller dans Pipelines/Library et cliquer sur Variable group.  Ajouter une variable, donner lui un nom (ex MyPassPhraseIkoula) et une valeur (dans l’exemple Bangali) Notez qu’à droite de la valeur d’une variable se trouve un petit bouton cadena qui permet de masquer celle ci. On y reviendra. Retour sur le YAML Maintenant que l’on a notre variable stockée sur Azure Devops on va pouvoir la récupérer dans notre pipeline Voici comment : On a une première variable qui était déjà là, celle qui concerne le type de build ‘Release’. Elle a un nom et une valeur. Celle ci ne concerne que la pipeline et ne sera vu que de l’agent qui s’occupe de cette pipeline.  Ensuite on a la déclaration du groupe IkoulaGroup qui contient une variable dont le nom est "MyPassPhrase" avec une valeur. Plus d’info sur la doc officielle ici. Plus loin on affiche ces variables avec un echo. Deux façons de récupérer notre variable MyPassPhrase.  tout simplement en l’appellant par $(MyPassPhrase) en utilisant une « expression de runtime » avec $[variables.MyPassPhraseIkoula]. Je pige pas trop ce truc, mais je pose ça la des fois que ça serve plus tard.  Concrètement, je n’arrive pas à récupérer la variable avec cette deuxième technique. Par contre j’ai bien ma variable avec la première façon :On a récupéré notre passphrase "Bangali" de tout à l’heure.  Maintenant un mot de passe ou une passphrase c’est pas censé être affiché tel quel. Vous vous souvenez du petit bouton cadena de tout à l’heure, qui se trouve a droite de votre variable dans la library de pipeline, cliquez dessus pour le vérouiller ainsi : penser à sauvegarder et relancer la même pipeline : notez que cette fois ci, le contenu de la variable est masqué par des **** On sait maintenant comment cacher des informations. 

Azure Devops Pipeline (CI/CD) – Deploy

Objectif : déploiement en production Dans la précédente partie on a déployé une pipeline sur Azure DevOps. Celle ci nous permet de lancer une build dès que la branche master de notre repo Blazor Sandbox reçoit un nouveau commit. De cette manière on s’assure que le build fonctionne ou pas. On est prévenu du résultat par email.  Ce qui serait intéressant, c’est de pouvoir la déployer sur un serveur web automatiquement en cas de succès.  Ma config J’ai un serveur VPS chez iKoula pour 4€/mois, avec une debian linux.  Ca tourne plutot bien. Mais bon, j’ai pas beaucoup de traffic 🙂 Donc j’ai un site web https://dev.blazordemo.reactor.fr et https://blazordemo.reactor.fr qui tournent tous les deux sous Nginx. Derrière chez deux services kestrel asp.net core sous .net 6.0. (pour faire bien, il aurait fallut dissocier la prod de mon dev (ou recette, staging). Petit budget… Dans /var/www/blazordemo.reactor.fr et /var/www/dev.blazordemo.reactor.fr j’ai mes publications de site web asp.net core Blazor WASM (le serveur et le client WASM "all in one"). L’idée est de dire à Azure Devops Pipeline, lorsque la branche master reçoit un nouveau commit, tu publies une version du serveur et tu balances le tout via SSH (sftp). Pipeline YAML On est fixé sur les objectifs. Maintenant il faut traduire cela en YAML. Voici un bout de doc : https://docs.microsoft.com/fr-fr/azure/devops/pipelines/tasks/deploy/copy-files-over-ssh?view=azure-devops En premier lieu, je vais reprendre la précédente pipeline et modifier build par publish. La différence est notable pour Blazor Server WASM. (voir mon article) Un petit commit + push et on voit que Azure Devops lance un nouveau job. On attend qu’il termine et passe au vert. Je pense qu’on va procédé ainsi, à taton. Petit pas par petit pas.  Une modif + commit + push + retour du Job.  Point SSH/SFTP Pour accéder à mon serveur en toute sécurité, je me connecte via SSH. Je prends donc la main à distance depuis mon poste windows sur mon serveur debian linux, qq part en France. J’ai un mot de passe et un login. Et roule ma poule.  Mais on peut faire mieux. J’ai ajouté une paire de clé privée/publique et une passphrase. Ainsi, il faut avoir la clé privée + la passphrase pour accéder.  C’est plus sécurisant pour moi. Je laisse l’accès SSH classique pour des opérations plus ponctuelles. J’ai de mon côté une serie de fichier .bat qui lance une commande de publication .net core et des commandes winscp (permet de lancer des commandes SFTP depuis Windows). La connection se fait via cette clé et cette passphrase. Ainsi, je peux en un double clic mettre à jour ma prod/staging/recette/dev depuis mon poste, sans lacher mon mdp. Au lieu de le faire à la main depuis un client sftp. Ca marche ! C’est moins rapide qu’un client sftp (car les fichiers uplodé ne sont pas lancés en parrallele). J’ai deux types de scripts. La totale, qui met a jour toute la publication : et un autre "rapide" qui ne mets a jours que le minimum pour aller vite : et son fichier .bat  Donc l’idée, c’est de faire pareil sous Azure Devops. Yaml On va rajouter une nouvelle tâche dans notre pipeline YAML avec CopyFilesOverSSH 4 éléments sont à renseigner : sshEndPoint : c’est le nom de notre connexion SSH que l’on va configurer plus loin sourceFolder : le chemin relatif de votre publish. L’agent de build va s’occuper de récupérer votre publish au bon endroit. Attention au majuscule et minuscule si l’agent est sur linux !!! targetFolder: le chemin de destination de votre publication sur la machine cible.  cleanTargetFolder : facultatif, mais effacer le contenu de la destination fait pas de mal.  Service Connections Le sshEndpoint de tout à l’heure est à configurer dans les "project settings" dans la section Pieplines/Service Connections  Il reste plus qu’à créer la votre en cliquant sur le bouton new connection Sélectionnez SSH : puis remplissez selon votre config, en uploadant votre clé privée. Attention, celle ci doit être au format .pem. Et voila. C’est tout.  Relancer votre pipeline avec un petit git add commit push.  Normalement vous devriez avoir que du vert !

Azure Devops Pipeline (CI/CD) – First Build

Intro En général, quand on découvre une techno, on fonce direct en dev local et on s’amuse. C’est ce que j’ai fait aussi, mais j’ai pas tardé à mettre en prod. Car par expérience,  mieux vaut avoir les problèmes au début, tant que le projet est pas trop gros ou trop compliqué.  Donc l’idée de ce billet, c’est voir comment on pourrait monter une chaine CI/CD (continious intergration/ continuious deployement) sur un projet blazor de base.  Projet de base Blazor Avec Visual Studio 2022 Community, on créer un projet Blazor WASM, avec Hebergement Asp.net core et PWA : Pour ma part je l’ai nommé BlazorDemo.  Je me suis permis de modifier qu’une seule ligne, dans program.cs du projet server. Je spécifie juste un port pour ma prod. Voir artile https://reactor.fr/net-core-sous-linux-nginx-80-http-443-https-firewall/ Azure DevOps Pipelines Azure Devops, c’est GitHub, Maven, Jenkins et j’en passe tout ça dans une appli web.  Ca nous permet de faire du CI/CD depuis nos propres repos (qu’ils soient sur BitBucket, Azure devops, GitHub, ou autre…) L’idée est de partir sur deux branches git, une master et une develop.  La master sera considéré comme la Prod. La develop comme la branche de travail.  A chaque fois que la branche master recevra un commit, on lancera une "pipeline" qui fera plusieurs actions, comme builder, lancer des tests et deployer.   A l’avenir, la branche master ne pourra plus recevoir de commit directement, ceci sera bloqué par defaut. Le seul moyen sera de faire une Pull Request depuis la branche develop vers la branche master. Ceci afin de mettre en place de bonne pratique de développement et de gestion de code source.  Bien sûr on pourrait pousser le concept plus loin, en pratiquant du Git Flow par exemple. Mais restons simple pour bien comprendre les mécanismes d’AzureDevOps 1ere pipeline Commençons par créer notre première pipeline. Menu Pipeline Cliquez sur New Pipeline Comme je le disais tout à l’heure, notre code source peut se situer sur différent repos, choisissez le votre : On choisit ensuite son repos, dans mon cas ceci :  Ensuite il faut choisir un modèle de script YAML. Alors ici, c’est pas clair je trouve. J’ai choisis "Asp.net Core" qui n’est pas présenté comme premier choix. Ce qui pourrait m’induire en erreur. Enfin de toute manière, c’est qu’un modèle, qu’on peut modifier par la suite. Voici le résultat : En cliquant sur Save and Run, puis valider l’écran suivant par defaut, vous allez ajouter un fichier "azure-pipelines.yml" a la racine de votre repo, sur la branche master. S’en suit un run automatique, qui au bout de qq seconde va échouer : En cliquant dessus pour voir le détail : Puis sur Job et sur l’élément en rouge : On a le détail du pourquoi le job a échoué. On a le détail du pourquoi le job a échoué. Ca nous dit que l’on a pas spécifier de projet à compiler… et c’est vrai MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file. Correctif de la 1ere pipeline Vous pouvez corriger directement depuis la plateforme azure devops pour bien le faire depuis votre editeur préféré et jouer qq commande git. Pour ma part je préfère cette derniere.  Je récupère donc via un git pull ma branche master sur mon visual studio code et je modifie le fichier azure-pipelines.yml avec cette ligne script: dotnet build –configuration $(buildConfiguration) src/BlazorDemo/BlazorDemo/Server/BlazorDemo.Server.csproj Le path ici peut différer selon votre répertoire repos. (moi j’ai mis tout ca dans un folder src, qui contient un répertoire  blazordemo qui contient un répertoire "solution" blazordemo. Quand votre modification est faites, il faut alors mettre a jour le repo distant avec un commit.  Rappelons que lorsque la branche master subit un nouveau commit, ca lance automatiquement cette pipeline. Et normalement vous obtenez un build vert :  Et voila, on a fait notre première pipelines qui fait qq chose de très basique pour le moment, builder !