NOVE 19

Sandbox Azure pour tout le monde

Il y a quelques articles de cela, j’ai écrit une série d’articles pour vous montrer comment j’ai créé une sandbox Azure à SOAT.

Il faut savoir que j’ai aussi sur mon compte Azure une sandbox basée sur les mêmes services à savoir :

  • Azure Functions
  • Managed Service Identity

Cette sandbox est donc moins avancée que celle disponible pour SOAT, mais elle me sert grandement pour tout ce qui est démo pour mes clients ou pour les différents meetups / conférences auxquels je participe.

Elle gère donc uniquement la création et la suppression de mes ResourceGroups, ce qui me suffit amplement, car seul moi ai accès à toutes les ressources de mes souscriptions Azure.

Bien qu’il existe à ce jour la sandbox by Microsoft, j’ai tout de même décidé de vous fournir la mienne, elle est disponible sur le site : https://www.serverlesslibrary.net/, il s’agit du projet Azure Sandbox Utils

Via le site Serverless Library, vous pouvez aller sur le repository de ma sandbox et appuyer sur le bouton déployer afin de mettre cette fameuse sandbox sur votre compte Azure.

Par la suite, il vous suffira d’effectuer les étapes suivantes:

  • Mettre le MSI en tant que contributeur ou ayant les droits Read / write / delete sur les ressources group
  • Ajouter un application insight, car les logs c’est important
  • Appeler l’url de création de ressource group avec les paramètres suivants
{ 
     name: "nameValue", 
     expirationDate: "2018-09-25",
     location: "West Europe" 
}

Et voilà fini les resourcegroups inutilisés dans votre souscription. N’hésitez pas à me faire des retours en cas de bug ou de nouvelles fonctionnalités à implémenter.

J’utilise cette sandbox à la place de celle de Microsoft pour les raisons suivantes :

  • Disponible sur mon tenant Azure (j’ai des clients qui bloquent tous les tenants sauf les leurs)
  • Temps de disponibilité des ressources modifiables
  • Partageable entre plusieurs utilisateurs

OCTO 26

Réaliser une copie de vos bases SQL Database

Lorsque vous voulez créer des environnements identiques à un autre, par exemple pour réaliser une copie de votre PROD vers une PPROD, ou mettre en place un environnement de PRA. Le problème se situe au plus souvent de vos données, puisque si je souhaite utiliser un backup et le restore sur une autre base, cela peut prendre beaucoup de temps entre la réalisation du backup et sa restauration.

Sur SQL Database, il est possible de faire une copie de votre base de données vers un autre SQL Database de manière très simple et très rapide en utiliant la commande suivante:

CREATE DATABASE newDestinationDB AS COPY OF sourcedemo.sourcedb;

Cette commande magique a tout de même quelques contraintes : si vous utilisez uniquement des comptes SQL, il faut que le compte que vous utilisez sur les deux servers ait un login et un mot de passe identique. Si vous utilisez un compte provenant d’un Azure Active Directory, vous n’aurez pas de problème car il s’agira du même compte.

Ayant eu à mettre en place ces comptes récemment et n’ayant pas trouvé la doc Azure très limpide à ce sujet, j’ai décidé d’en écrire un article.

Commençons donc par se connecter sur le SQL Server contenant la base de données que l’on souhaite copier.

Créons notre compte de la manière suivante :

CREATE LOGIN backup_sa WITH PASSWORD = 'topsecure42!'

Puis sur la base de données que l’on souhaite copier

CREATE USER backup_sa FROM LOGIN backup_sa
GO
-- role owner sur la base de données que l'on souhaite copier
sp_addrolemember db_owner, backup_sa

En ce qui concerne votre base de données source, vous avez fini votre setup. Maintenant passons à votre serveur cible, celui où vous voulez copier votre base de données.

Créons notre compte de la même manière que précédemment :

CREATE LOGIN backup_sa WITH PASSWORD = 'topsecure42!'

Puis sur la base de données master il faut ajouter notre utilisateur dans le groupe db_manager

CREATE USER backup_sa FROM LOGIN backup_sa
GO
-- role dbmanager sur la base de données que l'on souhaite copier
sp_addrolemember dbmanager, backup_sa

Il est ensuite possible de réaliser votre copie de base de données via la commande suivante :

CREATE DATABASE destinationdb AS COPY OF sourcedemo.sourcedb;

OCTO 19

Container - Héberger vos sites Web

Depuis un moment, l’utilisation des containers est de plus en plus fréquente, mais attention ce n’est pas parce que c’est à la mode qu’il faut les utiliser à tort et à travers.

La plateforme Azure n’est pas indifférente aux containers, et bien heureusement. Il existe plein de manières de mettre en place des containers dans Azure, nous allons donc voir comment les mettre en place et pourquoi utiliser tel ou tel service sur Azure.

Pour commencer, on va prendre le cas d’un container ou d’un ensemble de containers ayant pour but d’afficher un pur site web, car effectivement l’utilisation des containers n’est pas uniquement exclusive aux architectures microservices.

Prenons en premier exemple un site très simple basé sur un container ayant ce docker file :

FROM nginx:alpine
COPY . /usr/share/nginx/html

Bon comme on peut le voir c’est plus dur de faire compliquer. Mais l’image m’offre l’avantage de ne pas avoir à mettre moi-même en place mon NGINX.

Maintenant si je veux mettre en place ce site Web sur Azure, j’ai plein de possibilités comme celle de créer un cluster AKS ou un cluster Service Fabric, mais vous serez d’accord avec moi sur le fait que ça serait sortir le marteau pour tuer une mouche.

Sur le service de Web Apps d’Azure il est possible d’héberger un container qui se situe dans n’importe quel registry accessible depuis ma Web App.

Pour ma part, je vais créer une registry sur Azure via le Service Azure Container Registry

$registry = New-AzureRmContainerRegistry -ResourceGroupName $rgName -Name $acrName -EnableAdminUser -Sku Basic

Puis j’enregitre ces accès dans mon Docker afin de pouvoir publier mes images dessus.

$credentials = Get-AzureRmContainerRegistryCredential -Registry $registry
docker login $registry.LoginServer -u $credentials.Username -p $credentials.Password

Pour ceux qui n’ont jamais utilisé Docker, et pour les autres un rappel ne faisant jamais de mal, voici comment construire notre image et l’envoyer sur une registry distante

docker build -t sample-web-app .\WebApp\
docker tag sample-web-app ($registry.LoginServer + '/sample-web-app:v1')
docker push ($registry.LoginServer + '/sample-web-app:v1')

Maintenant que notre image est sur notre registry Azure, il est possible de la déployer n’importe où que ce soit dans Azure ou ailleurs.

Je vais donc créer une nouvelle Web App sur Azure via le portail, il est bien entendu possible de faire la même chose via un template ARM ou des scripts.

image

Maintenant que mon container est hébergé, il est automatiquement configuré pour être mis à jour à chaque fois que je pousse une nouvelle version de mon image sur ma registry, il est bien entendu possible de désactiver cette fonctionnalité si besoin.

Il est aussi possible d’utiliser des images plus complexes via l’outil docker compose afin d’avoir de multiples containers qui sont exécutés au sein de votre Web App. Voici un exemple de configuration yml que vous pouvez utiliser, c’est celle qui est disponible sur la documentation Azure :

version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:

Comme vous pouvez le voir, il s’agit ici d’un site Wordpress avec sa base de données. Il n’est par ailleurs actuellement pas possible d’utiliser toutes les fonctionnalités de Docker compose au sein de vos Web Apps, du coup vous pouvez oublier ce service si vous voulez vous servir des éléments suivants :

  • build : Non autorisé
  • depends_on : ignoré
  • networks : ignoré
  • secrets : ignoré

Selon moi le support des containers pour les Web App offre une solution idéale pour vos containers légers qui doivent tourner H24, et pour lesquels vous ne voulez pas à avoir à gérer un cluster sous jacent.


OCTO 12

Générer un token Azure AD via les REST API

Dernièrement j’ai eu le besoin d’accéder à un compte de stockage via un compte applicatif, j’ai donc mis en plac un SPN avec un droit RBAC sur mon compte de stockage, comme je le montre dans cet article : http://blog.woivre.fr/blog/2018/09/connectez-vous-a-vos-comptes-de-stockage-via-azure-active-directory

Maintenant il faut que je génère mon token d’accès, chose qui est assez simple avec les différentes librairies ADAL, cependant pour mon besoin j’avais les contraintes suivantes :

  • Compte applicatif avec une authentification par certificat
  • Pas de librairies supplémentaires (adieu ADAL)
  • Powershell

Première étape, il faut générer un token JWT. Pour rappel un token JWT répond à la structure suivante : base64(header).base64(payload).base64(signature)

Commençons par la construction de notre header, pour cela il nous faut le hash de notre certificat, que l’on peut récupérer de la manière suivante :

$cert = Get-Item Cert:\CurrentUser\My\$ThumbprintValue

$hash = $cert.GetCertHash()
$hashValue = [System.Convert]::ToBase64String($hash)  -replace '\+','-' -replace '/','_' -replace '='

Il est maintenant possible de constuire notre header de la manière suivante, ainsi que notre payload :

[hashtable]$header = @{alg = 'RS256'; typ= "JWT"; x5t = $thumprintValue}
[hashtable]$payload = @{aud = "https://login.microsoftonline.com/$TenantUrl/oauth2/token"; iss = $applicationId; sub=$applicationId; jti = "22b3bb26-e046-42df-9c96-65dbd72c1c81"; exp = $exp; nbf= 1536160449}

Maintenant qu’on a toutes les informations, il faut générer notre signature, et construire notre token

$headerjson = $header | ConvertTo-Json -Compress
$payloadjson = $payload | ConvertTo-Json -Compress

$headerjsonbase64 = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($headerjson)) -replace '\+','-' -replace '/','_' -replace '='
$payloadjsonbase64 = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($payloadjson)) -replace '\+','-' -replace '/','_' -replace '='

$jwt = $headerjsonbase64 + "." + $payloadjsonbase64
$toSign = [System.Text.Encoding]::UTF8.GetBytes($jwt)

$Signature = [Convert]::ToBase64String($rsa.SignData($toSign,[Security.Cryptography.HashAlgorithmName]::SHA256,[Security.Cryptography.RSASignaturePadding]::Pkcs1)) -replace '\+','-' -replace '/','_' -replace '='

$token = "$headerjsonbase64.$payloadjsonbase64.$Signature"

A noter qu’il est possible de valider la création de votre jeton JWT sur des sites comme celui-ci : https://jwt.io/

Et voilà nous avons notre token JWT qui nous servira à avoir notre access Token qu’on va pouvoir récupérer de la manière suivante:


$url = "https://login.microsoftonline.com/$TenantUrl/oauth2/token"
$body = "resource=https%3A%2F%2F$storageAccountName.blob.core.windows.net%2F&client_id=$applicationId&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=$token&grant_type=client_credentials"
$responseToken = Invoke-WebRequest -Method POST -ContentType "application/x-www-form-urlencoded"  -Headers @{"accept"="application/json"} -Body $body $url -Verbose

$accessToken = ($responseToken.Content | ConvertFrom-Json).access_token

Après avoir générer notre token, il est possible de l’utiliser dans nos headers pour appeler les REST API de notre storage.

$headerSMA =  @{"Authorization" = "Bearer " + $accessToken; "x-ms-version" = "2017-11-09"}
Invoke-WebRequest -Headers $headerSMA -Method GET "https://$storageAccountName.blob.core.windows.net/$containerName/$blobName"  -OutFile $outFile

Et voilà comment appeler des API Azure tout en s’affranchissant d’ADAL. Même si on est d’accord créer notre Token avec ADAL c’est beaucoup plus simple. Et surtout moins long à lire.


OCTO 05

Créer vos groupes de ressources via un template ARM

La création des groupes de ressources se fait généralement par le portail Azure, ou via votre terminal préféré (CLI ou PowerShell). Il est posssible dorénavant de créer vos groupes de ressources via un template ARM.

Prenons un exemple de template ARM pour créer notre resource group :

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {
        "location": "West Europe",
        "name": "rg-test"
    },
    "resources": [
        {
            "type": "Microsoft.Resources/resourceGroups",
            "apiVersion": "2018-05-01",
            "location": "[variables('location')]",
            "name": "[variables('name')]",
            "properties": {}
        }
    ],
    "outputs": {}
}

Maintenant pour déployer ce template ARM, il est possible d’utiliser la commande suivante :

New-AzureRmResourceGroupDeployment -Name deploy-rg -TemplateFile .\azuredeploy.json -ResourceGroupName existing-rg

Le problème c’est qu’il faut déjà avoir un resource group dans notre souscription, ce qui n’est pas top pour initier une souscription. Mais depuis peu, il est possible d’utiliser la commande suivante :

New-AzureRmDeployment -Name deploy-rg -TemplateFile .\azuredeploy.json

Il est bien entendu possible de retrouver les déploiements passés via la commande

Get-AzureRmDeployment

Ou alors vous pouvez retrouver vos déploiements dans la blade Souscription dans le portail Azure.

Happy deploy !