# Fichier: python_cheats/cheatsheets/azure.txt
# Cheatsheet Microsoft Azure - Guide Complet pour Débutants


[OK] INTRODUCTION À AZURE

# Qu'est-ce qu'Azure ?
# Microsoft Azure est une plateforme cloud computing qui offre:
# - Infrastructure as a Service (IaaS): Machines virtuelles, stockage, réseau
# - Platform as a Service (PaaS): App Services, bases de données managées
# - Software as a Service (SaaS): Office 365, Dynamics 365
# - Serverless: Functions, Logic Apps
# - AI/ML: Cognitive Services, Machine Learning
# - IoT, Big Data, Analytics, et bien plus

# Concepts clés:
# - Subscription: Conteneur de facturation pour vos ressources
# - Resource Group: Conteneur logique pour regrouper des ressources
# - Region: Localisation géographique des datacenters
# - Resource: Service Azure (VM, database, storage, etc.)
# - Azure Resource Manager (ARM): Couche de gestion unifié


[OK] CRÉER UN COMPTE AZURE

# === Compte gratuit Azure ===
# Visitez: https://azure.microsoft.com/free/
# Inclut:
# - 200$ de crédits pour 30 jours
# - 12 mois de services populaires gratuits
# - 25+ services toujours gratuits

# Ce qui est gratuit pendant 12 mois:
# - 750h/mois de machines virtuelles B1S
# - 5 GB Blob Storage
# - 250 GB SQL Database
# - 1 million requests Azure Functions
# - Et plus...

# Services toujours gratuits:
# - App Service (10 web apps)
# - Functions (1 million requests/mois)
# - Cosmos DB (1000 RU/s)
# - DevOps (5 utilisateurs)
# - Et plus...

# Requis pour créer un compte:
# - Numéro de téléphone
# - Carte de crédit (non débitée pour compte gratuit)
# - Compte Microsoft (ou créer nouveau)

# Types de comptes:
# - Free Account: Pour commencer gratuitement
# - Pay-As-You-Go: Payer ce que vous utilisez
# - Enterprise Agreement: Pour grandes entreprises
# - Student: Avec email étudiant (100$ gratuit, pas de carte)


[OK] AZURE PORTAL (INTERFACE WEB)

# Accéder au portail:
# https://portal.azure.com

# === Navigation portail ===

# Tableau de bord (Dashboard)
# - Page d'accueil personnalisable
# - Épingler des ressources favorites
# - Créer plusieurs tableaux de bord

# Menu latéral gauche:
# - Create a resource: Créer nouvelles ressources
# - Home: Retour accueil
# - Dashboard: Tableaux de bord
# - All services: Tous les services Azure
# - All resources: Toutes vos ressources
# - Resource groups: Vos groupes de ressources
# - Cost Management: Gestion des coûts
# - Subscriptions: Vos abonnements

# Barre de recherche (haut):
# - Rechercher ressources, services, documentation
# - Raccourci: G + /

# Cloud Shell (icône >_):
# - Terminal bash ou PowerShell dans le navigateur
# - Outils pré-installés (az cli, kubectl, terraform, etc.)
# - Stockage personnel de 5 GB

# Notifications (icône cloche):
# - Activité des déploiements
# - Alertes et erreurs

# Paramètres (icône engrenage):
# - Thème clair/sombre
# - Langue et région
# - Timeout de session

# === Raccourcis clavier portail ===
G + N          # Créer nouvelle ressource
G + /          # Recherche globale
G + D          # Dashboard
G + A          # All resources
?              # Afficher tous les raccourcis


[OK] AZURE CLI (LIGNE DE COMMANDE)

# === Installation ===

# === Windows ===
# Méthode 1: MSI Installer
# Télécharger: https://aka.ms/installazurecliwindows

# Méthode 2: winget
winget install -e --id Microsoft.AzureCLI

# Méthode 3: PowerShell
Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi
Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'

# === Linux ===
# Ubuntu/Debian
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

# RHEL/Fedora/CentOS
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo dnf install azure-cli

# Installation manuelle (toutes distributions)
curl -L https://aka.ms/InstallAzureCli | bash

# === macOS ===
# Homebrew
brew update && brew install azure-cli

# === Via pip (toutes plateformes) ===
pip install azure-cli

# === Docker ===
docker run -it mcr.microsoft.com/azure-cli

# === Vérifier installation ===
az --version
az version

# === Mise à jour ===
# Windows (MSI)
# Télécharger et réinstaller dernière version

# Linux
sudo apt-get update && sudo apt-get upgrade azure-cli

# macOS
brew upgrade azure-cli

# pip
pip install --upgrade azure-cli

# === Configuration ===
# Se connecter à Azure
az login

# Se connecter avec device code (pour serveurs/CI)
az login --use-device-code

# Se connecter avec service principal
az login --service-principal -u <app-id> -p <password> --tenant <tenant-id>

# Lister comptes connectés
az account list
az account list --output table

# Voir compte actuel
az account show

# Changer d'abonnement
az account set --subscription "Nom ou ID de l'abonnement"
az account set --subscription "12345678-1234-1234-1234-123456789012"

# Se déconnecter
az logout

# === Configuration CLI ===
# Définir format de sortie par défaut
az config set core.output=table
az config set core.output=json
az config set core.output=jsonc          # JSON coloré
az config set core.output=yaml
az config set core.output=tsv            # Tab-separated

# Désactiver télémétrie
az config set core.collect_telemetry=false

# Afficher configuration
az config get

# Réinitialiser configuration
az config unset core.output

# === Complétion automatique ===
# Bash
echo "source /etc/bash_completion.d/azure-cli" >> ~/.bashrc

# Zsh
autoload -U +X bashcompinit && bashcompinit
source /etc/bash_completion.d/azure-cli

# PowerShell
Register-ArgumentCompleter -Native -CommandName az -ScriptBlock {
    param($commandName, $wordToComplete, $cursorPosition)
    $completion_file = New-TemporaryFile
    $env:ARGCOMPLETE_USE_TEMPFILES = 1
    $env:_ARGCOMPLETE_STDOUT_FILENAME = $completion_file
    $env:COMP_LINE = $wordToComplete
    $env:COMP_POINT = $cursorPosition
    $env:_ARGCOMPLETE = 1
    $env:_ARGCOMPLETE_SUPPRESS_SPACE = 0
    $env:_ARGCOMPLETE_IFS = "`n"
    az 2>&1 | Out-Null
    Get-Content $completion_file | Sort-Object | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_, $_, "ParameterValue", $_)
    }
    Remove-Item $completion_file, Env:\_ARGCOMPLETE, Env:\ARGCOMPLETE_USE_TEMPFILES, Env:\COMP_LINE, Env:\COMP_POINT, Env:\_ARGCOMPLETE_SUPPRESS_SPACE, Env:\_ARGCOMPLETE_IFS, Env:\_ARGCOMPLETE_STDOUT_FILENAME
}


[OK] AZURE POWERSHELL

# === Installation ===
# Windows PowerShell 5.1 ou PowerShell 7+
Install-Module -Name Az -Repository PSGallery -Force

# Mettre à jour
Update-Module -Name Az

# === Connexion ===
Connect-AzAccount

# Avec device code
Connect-AzAccount -UseDeviceAuthentication

# Avec service principal
$credential = Get-Credential
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant <tenant-id>

# === Commandes de base ===
# Lister abonnements
Get-AzSubscription

# Sélectionner abonnement
Set-AzContext -Subscription "Nom ou ID"

# Voir contexte actuel
Get-AzContext

# Se déconnecter
Disconnect-AzAccount


[OK] RESOURCE GROUPS (GROUPES DE RESSOURCES)

# Concept: Conteneur logique pour organiser ressources Azure
# Toutes les ressources doivent être dans un resource group
# Facilite gestion, monitoring, contrôle d'accès, facturation

# === Créer un resource group ===

# CLI
az group create --name MyResourceGroup --location eastus

# Locations courantes:
# eastus, westus, westeurope, northeurope, francecentral
# southeastasia, japaneast, australiaeast, brazilsouth

# Lister toutes les locations disponibles
az account list-locations --output table

# PowerShell
New-AzResourceGroup -Name MyResourceGroup -Location eastus

# === Lister resource groups ===
# CLI
az group list
az group list --output table

# PowerShell
Get-AzResourceGroup

# === Voir détails d'un resource group ===
# CLI
az group show --name MyResourceGroup

# PowerShell
Get-AzResourceGroup -Name MyResourceGroup

# === Lister ressources dans un group ===
# CLI
az resource list --resource-group MyResourceGroup
az resource list -g MyResourceGroup --output table

# PowerShell
Get-AzResource -ResourceGroupName MyResourceGroup

# === Ajouter tags (étiquettes) ===
# CLI
az group update --name MyResourceGroup --tags Environment=Dev Project=WebApp

# PowerShell
Set-AzResourceGroup -Name MyResourceGroup -Tag @{Environment="Dev"; Project="WebApp"}

# === Supprimer resource group ===
# ATTENTION: Supprime TOUTES les ressources dans le groupe!

# CLI
az group delete --name MyResourceGroup --yes --no-wait

# Sans confirmation
az group delete -n MyResourceGroup -y

# PowerShell
Remove-AzResourceGroup -Name MyResourceGroup -Force

# === Exporter template ARM ===
# CLI
az group export --name MyResourceGroup > template.json

# PowerShell
Export-AzResourceGroup -ResourceGroupName MyResourceGroup -Path ./template.json


[OK] STORAGE ACCOUNTS (COMPTES DE STOCKAGE)

# Services de stockage Azure:
# - Blob Storage: Stockage d'objets (fichiers, images, vidéos)
# - File Storage: Partages de fichiers SMB
# - Queue Storage: Files d'attente de messages
# - Table Storage: NoSQL key-value store

# === Créer un storage account ===

# CLI
az storage account create \
    --name mystorageaccount123 \
    --resource-group MyResourceGroup \
    --location eastus \
    --sku Standard_LRS

# Nom doit être:
# - Unique globalement
# - 3-24 caractères
# - Lettres minuscules et chiffres uniquement

# SKU (types de réplication):
# Standard_LRS: Locally Redundant Storage
# Standard_GRS: Geo-Redundant Storage
# Standard_ZRS: Zone-Redundant Storage
# Premium_LRS: Premium (SSD)

# PowerShell
New-AzStorageAccount `
    -ResourceGroupName MyResourceGroup `
    -Name mystorageaccount123 `
    -Location eastus `
    -SkuName Standard_LRS

# === Obtenir clés d'accès ===
# CLI
az storage account keys list \
    --account-name mystorageaccount123 \
    --resource-group MyResourceGroup

# Obtenir connection string
az storage account show-connection-string \
    --name mystorageaccount123 \
    --resource-group MyResourceGroup

# PowerShell
Get-AzStorageAccountKey -ResourceGroupName MyResourceGroup -Name mystorageaccount123

# === BLOB STORAGE ===

# Créer un container (conteneur)
az storage container create \
    --name mycontainer \
    --account-name mystorageaccount123 \
    --auth-mode login

# Avec clé d'accès
az storage container create \
    --name mycontainer \
    --account-name mystorageaccount123 \
    --account-key <storage-key>

# Lister containers
az storage container list \
    --account-name mystorageaccount123 \
    --auth-mode login

# Upload fichier (blob)
az storage blob upload \
    --container-name mycontainer \
    --file ./monimage.jpg \
    --name monimage.jpg \
    --account-name mystorageaccount123 \
    --auth-mode login

# Upload multiple fichiers
az storage blob upload-batch \
    --destination mycontainer \
    --source ./myfolder \
    --account-name mystorageaccount123

# Lister blobs
az storage blob list \
    --container-name mycontainer \
    --account-name mystorageaccount123 \
    --output table

# Download blob
az storage blob download \
    --container-name mycontainer \
    --name monimage.jpg \
    --file ./downloaded.jpg \
    --account-name mystorageaccount123

# Download tous les blobs
az storage blob download-batch \
    --destination ./downloads \
    --source mycontainer \
    --account-name mystorageaccount123

# Supprimer blob
az storage blob delete \
    --container-name mycontainer \
    --name monimage.jpg \
    --account-name mystorageaccount123

# Générer SAS token (accès temporaire)
az storage blob generate-sas \
    --container-name mycontainer \
    --name monimage.jpg \
    --permissions r \
    --expiry 2024-12-31T23:59:00Z \
    --account-name mystorageaccount123 \
    --account-key <storage-key>

# URL avec SAS
az storage blob url \
    --container-name mycontainer \
    --name monimage.jpg \
    --account-name mystorageaccount123

# === FILE STORAGE (Partages de fichiers) ===

# Créer file share
az storage share create \
    --name myfileshare \
    --account-name mystorageaccount123 \
    --quota 100

# Upload fichier
az storage file upload \
    --share-name myfileshare \
    --source ./document.pdf \
    --path document.pdf \
    --account-name mystorageaccount123

# Lister fichiers
az storage file list \
    --share-name myfileshare \
    --account-name mystorageaccount123

# Download fichier
az storage file download \
    --share-name myfileshare \
    --path document.pdf \
    --dest ./downloaded.pdf \
    --account-name mystorageaccount123

# Créer répertoire
az storage directory create \
    --share-name myfileshare \
    --name myfolder \
    --account-name mystorageaccount123

# Monter file share (Windows)
# Via portail Azure, obtenir script PowerShell de montage
net use Z: \\mystorageaccount123.file.core.windows.net\myfileshare /u:AZURE\mystorageaccount123 <storage-key>

# Monter file share (Linux)
sudo mount -t cifs //mystorageaccount123.file.core.windows.net/myfileshare /mnt/myfileshare -o vers=3.0,username=mystorageaccount123,password=<storage-key>,dir_mode=0777,file_mode=0777

# === QUEUE STORAGE ===

# Créer queue
az storage queue create \
    --name myqueue \
    --account-name mystorageaccount123

# Ajouter message
az storage message put \
    --queue-name myqueue \
    --content "Hello, World!" \
    --account-name mystorageaccount123

# Lire messages
az storage message peek \
    --queue-name myqueue \
    --account-name mystorageaccount123

# === TABLE STORAGE ===

# Créer table
az storage table create \
    --name mytable \
    --account-name mystorageaccount123

# === Supprimer storage account ===
az storage account delete \
    --name mystorageaccount123 \
    --resource-group MyResourceGroup \
    --yes


[OK] VIRTUAL MACHINES (MACHINES VIRTUELLES)

# === Créer une VM Linux ===

# CLI
az vm create \
    --resource-group MyResourceGroup \
    --name MyLinuxVM \
    --image Ubuntu2204 \
    --size Standard_B2s \
    --admin-username azureuser \
    --generate-ssh-keys \
    --public-ip-sku Standard

# Images courantes:
# Ubuntu2204, Ubuntu2004
# Debian11, Debian12
# CentOS85
# RHEL8, RHEL9
# Win2022Datacenter, Win2019Datacenter
# Win11Enterprise

# Tailles (sizes) courantes:
# Standard_B1s: 1 vCPU, 1 GB RAM (économique)
# Standard_B2s: 2 vCPU, 4 GB RAM
# Standard_D2s_v3: 2 vCPU, 8 GB RAM
# Standard_D4s_v3: 4 vCPU, 16 GB RAM

# Lister toutes les images
az vm image list --output table
az vm image list --all

# Lister tailles disponibles
az vm list-sizes --location eastus --output table

# PowerShell
New-AzVm `
    -ResourceGroupName MyResourceGroup `
    -Name MyLinuxVM `
    -Image Ubuntu2204 `
    -Size Standard_B2s `
    -Location eastus

# === Créer VM Windows ===

# CLI
az vm create \
    --resource-group MyResourceGroup \
    --name MyWindowsVM \
    --image Win2022Datacenter \
    --size Standard_B2ms \
    --admin-username azureadmin \
    --admin-password 'P@ssw0rd1234!'

# Avec disque managé SSD Premium
az vm create \
    --resource-group MyResourceGroup \
    --name MyVM \
    --image Ubuntu2204 \
    --size Standard_DS2_v2 \
    --storage-sku Premium_LRS \
    --admin-username azureuser \
    --generate-ssh-keys

# Avec script d'initialisation (cloud-init)
az vm create \
    --resource-group MyResourceGroup \
    --name MyVM \
    --image Ubuntu2204 \
    --custom-data cloud-init.txt \
    --admin-username azureuser \
    --generate-ssh-keys

# === Lister VMs ===
# CLI
az vm list
az vm list --output table
az vm list --resource-group MyResourceGroup

# PowerShell
Get-AzVM
Get-AzVM -ResourceGroupName MyResourceGroup

# === Obtenir infos VM ===
# CLI
az vm show --name MyVM --resource-group MyResourceGroup
az vm get-instance-view --name MyVM --resource-group MyResourceGroup

# Obtenir IP publique
az vm list-ip-addresses --name MyVM --resource-group MyResourceGroup
az vm show -d --name MyVM --resource-group MyResourceGroup --query publicIps -o tsv

# PowerShell
Get-AzVM -Name MyVM -ResourceGroupName MyResourceGroup

# === Gérer l'état de la VM ===

# Démarrer VM
az vm start --name MyVM --resource-group MyResourceGroup

# Arrêter VM (continue à facturer)
az vm stop --name MyVM --resource-group MyResourceGroup

# Deallocate (arrête et libère ressources, pas de facturation compute)
az vm deallocate --name MyVM --resource-group MyResourceGroup

# Redémarrer VM
az vm restart --name MyVM --resource-group MyResourceGroup

# PowerShell
Start-AzVM -Name MyVM -ResourceGroupName MyResourceGroup
Stop-AzVM -Name MyVM -ResourceGroupName MyResourceGroup -Force
Restart-AzVM -Name MyVM -ResourceGroupName MyResourceGroup

# === Redimensionner VM ===
# CLI
az vm resize \
    --resource-group MyResourceGroup \
    --name MyVM \
    --size Standard_D4s_v3

# PowerShell
$vm = Get-AzVM -ResourceGroupName MyResourceGroup -Name MyVM
$vm.HardwareProfile.VmSize = "Standard_D4s_v3"
Update-AzVM -VM $vm -ResourceGroupName MyResourceGroup

# === Se connecter à la VM ===

# SSH (Linux)
ssh azureuser@<public-ip>
ssh -i ~/.ssh/id_rsa azureuser@<public-ip>

# RDP (Windows)
# Télécharger fichier RDP
az vm show --name MyWindowsVM --resource-group MyResourceGroup --query publicIps -o tsv
# Puis utiliser client RDP avec IP

# Depuis Azure CLI
az ssh vm --name MyVM --resource-group MyResourceGroup

# === Exécuter commandes sur VM ===

# CLI
az vm run-command invoke \
    --resource-group MyResourceGroup \
    --name MyVM \
    --command-id RunShellScript \
    --scripts "sudo apt-get update && sudo apt-get install -y nginx"

# Windows
az vm run-command invoke \
    --resource-group MyResourceGroup \
    --name MyWindowsVM \
    --command-id RunPowerShellScript \
    --scripts "Get-Process"

# PowerShell
Invoke-AzVMRunCommand `
    -ResourceGroupName MyResourceGroup `
    -VMName MyVM `
    -CommandId 'RunShellScript' `
    -Script 'sudo apt-get update'

# === Gérer les disques ===

# Créer disque managé
az disk create \
    --resource-group MyResourceGroup \
    --name MyDataDisk \
    --size-gb 128 \
    --sku Premium_LRS

# Attacher disque à VM
az vm disk attach \
    --resource-group MyResourceGroup \
    --vm-name MyVM \
    --name MyDataDisk

# Détacher disque
az vm disk detach \
    --resource-group MyResourceGroup \
    --vm-name MyVM \
    --name MyDataDisk

# Lister disques
az disk list --output table

# === Snapshots et images ===

# Créer snapshot du disque OS
az snapshot create \
    --resource-group MyResourceGroup \
    --name MySnapshot \
    --source MyVM

# Créer image à partir de VM
az image create \
    --resource-group MyResourceGroup \
    --name MyCustomImage \
    --source MyVM

# Créer VM à partir d'image personnalisée
az vm create \
    --resource-group MyResourceGroup \
    --name NewVM \
    --image MyCustomImage \
    --admin-username azureuser \
    --generate-ssh-keys

# === Extensions VM ===

# Installer extension
az vm extension set \
    --resource-group MyResourceGroup \
    --vm-name MyVM \
    --name customScript \
    --publisher Microsoft.Azure.Extensions \
    --settings '{"fileUris": ["https://raw.githubusercontent.com/script.sh"],"commandToExecute": "./script.sh"}'

# Lister extensions
az vm extension list --resource-group MyResourceGroup --vm-name MyVM

# === Supprimer VM ===
# CLI
az vm delete --name MyVM --resource-group MyResourceGroup --yes

# Supprimer VM et toutes les ressources associées
az vm delete --name MyVM --resource-group MyResourceGroup --yes
az disk delete --name MyVM_OsDisk_1 --resource-group MyResourceGroup --yes
az network nic delete --name MyVMVMNic --resource-group MyResourceGroup
az network public-ip delete --name MyVMPublicIP --resource-group MyResourceGroup

# PowerShell
Remove-AzVM -Name MyVM -ResourceGroupName MyResourceGroup -Force


[OK] APP SERVICE (WEB APPS)

# Service managé pour héberger web apps sans gérer infrastructure

# === Créer App Service Plan ===
# Le plan définit compute resources pour vos apps

# CLI
az appservice plan create \
    --name MyAppServicePlan \
    --resource-group MyResourceGroup \
    --location eastus \
    --sku B1 \
    --is-linux

# SKU (tiers):
# F1: Free (partagé)
# D1: Shared
# B1, B2, B3: Basic
# S1, S2, S3: Standard
# P1v2, P2v2, P3v2: Premium v2
# P1v3, P2v3, P3v3: Premium v3

# PowerShell
New-AzAppServicePlan `
    -ResourceGroupName MyResourceGroup `
    -Name MyAppServicePlan `
    -Location eastus `
    -Tier Basic `
    -NumberofWorkers 1 `
    -WorkerSize Small `
    -Linux

# === Créer Web App ===

# CLI - App Node.js
az webapp create \
    --resource-group MyResourceGroup \
    --plan MyAppServicePlan \
    --name myuniquewebapp123 \
    --runtime "NODE:18-lts"

# Runtimes disponibles:
az webapp list-runtimes --linux
az webapp list-runtimes --os-type windows

# Exemples:
# "NODE:18-lts", "NODE:20-lts"
# "PYTHON:3.11", "PYTHON:3.12"
# "DOTNET:8.0"
# "PHP:8.2"
# "JAVA:17-java17"

# App Python
az webapp create \
    --resource-group MyResourceGroup \
    --plan MyAppServicePlan \
    --name mywebapp123 \
    --runtime "PYTHON:3.11"

# PowerShell
New-AzWebApp `
    -ResourceGroupName MyResourceGroup `
    -Name mywebapp123 `
    -AppServicePlan MyAppServicePlan

# === Déployer code ===

# Depuis dossier local (zip deploy)
az webapp deploy \
    --resource-group MyResourceGroup \
    --name mywebapp123 \
    --src-path ./app.zip \
    --type zip

# Depuis Git (Azure DevOps, GitHub, etc.)
az webapp deployment source config \
    --name mywebapp123 \
    --resource-group MyResourceGroup \
    --repo-url https://github.com/user/repo \
    --branch main \
    --manual-integration

# Avec credentials Git local
az webapp deployment source config-local-git \
    --name mywebapp123 \
    --resource-group MyResourceGroup

# Obtenir URL git
az webapp deployment list-publishing-credentials \
    --name mywebapp123 \
    --resource-group MyResourceGroup

# Puis:
git remote add azure <git-url>
git push azure main

# Depuis GitHub Actions
az webapp deployment github-actions add \
    --repo user/repo \
    --resource-group MyResourceGroup \
    --name mywebapp123 \
    --branch main

# === Configuration App ===

# Définir variables d'environnement (App Settings)
az webapp config appsettings set \
    --resource-group MyResourceGroup \
    --name mywebapp123 \
    --settings DB_HOST=myserver.database.windows.net DB_NAME=mydb

# Lister settings
az webapp config appsettings list \
    --resource-group MyResourceGroup \
    --name mywebapp123

# Connection strings
az webapp config connection-string set \
    --resource-group MyResourceGroup \
    --name mywebapp123 \
    --connection-string-type SQLAzure \
    --settings DefaultConnection='Server=myserver.database.windows.net;Database=mydb;'

# Configurer Python startup command
az webapp config set \
    --resource-group MyResourceGroup \
    --name mywebapp123 \
    --startup-file "gunicorn --bind=0.0.0.0 --timeout 600 app:app"

# === Custom domains & SSL ===

# Ajouter domaine personnalisé
az webapp config hostname add \
    --webapp-name mywebapp123 \
    --resource-group MyResourceGroup \
    --hostname www.mydomain.com

# Bind SSL certificate
az webapp config ssl bind \
    --certificate-thumbprint <thumbprint> \
    --ssl-type SNI \
    --name mywebapp123 \
    --resource-group MyResourceGroup

# Certificat SSL gratuit (managed certificate)
az webapp config ssl create \
    --resource-group MyResourceGroup \
    --name mywebapp123 \
    --hostname www.mydomain.com

# === Scaling ===

# Scale up (changer SKU)
az appservice plan update \
    --name MyAppServicePlan \
    --resource-group MyResourceGroup \
    --sku S1

# Scale out (plus d'instances)
az appservice plan update \
    --name MyAppServicePlan \
    --resource-group MyResourceGroup \
    --number-of-workers 3

# Autoscaling
az monitor autoscale create \
    --resource-group MyResourceGroup \
    --resource MyAppServicePlan \
    --resource-type Microsoft.Web/serverfarms \
    --name autoscale-rule \
    --min-count 1 \
    --max-count 5 \
    --count 2

# === Logs et monitoring ===

# Enable application logging
az webapp log config \
    --name mywebapp123 \
    --resource-group MyResourceGroup \
    --application-logging filesystem \
    --level information

# Stream logs en temps réel
az webapp log tail \
    --name mywebapp123 \
    --resource-group MyResourceGroup

# Download logs
az webapp log download \
    --name mywebapp123 \
    --resource-group MyResourceGroup \
    --log-file logs.zip

# === Deployment slots (staging) ===

# Créer slot de staging
az webapp deployment slot create \
    --name mywebapp123 \
    --resource-group MyResourceGroup \
    --slot staging

# Déployer sur staging
az webapp deploy \
    --resource-group MyResourceGroup \
    --name mywebapp123 \
    --slot staging \
    --src-path ./app.zip

# Swap staging vers production
az webapp deployment slot swap \
    --resource-group MyResourceGroup \
    --name mywebapp123 \
    --slot staging \
    --target-slot production

# === Redémarrer app ===
az webapp restart \
    --name mywebapp123 \
    --resource-group MyResourceGroup

# === Supprimer Web App ===
az webapp delete \
    --name mywebapp123 \
    --resource-group MyResourceGroup


[OK] AZURE FUNCTIONS (SERVERLESS)

# Compute serverless pour exécuter code sans gérer infrastructure

# === Créer Function App ===

# Créer storage account (requis pour Functions)
az storage account create \
    --name mystorageaccount123 \
    --resource-group MyResourceGroup \
    --location eastus \
    --sku Standard_LRS

# Créer Function App (Linux, Python)
az functionapp create \
    --resource-group MyResourceGroup \
    --consumption-plan-location eastus \
    --runtime python \
    --runtime-version 3.11 \
    --functions-version 4 \
    --name myfunctionapp123 \
    --storage-account mystorageaccount123 \
    --os-type Linux

# Runtimes disponibles:
# python (3.8, 3.9, 3.10, 3.11)
# node (16, 18, 20)
# dotnet (6.0, 8.0)
# java (8, 11, 17)
# powershell (7.2)

# Avec plan App Service (pas consumption)
az functionapp create \
    --resource-group MyResourceGroup \
    --name myfunctionapp123 \
    --storage-account mystorageaccount123 \
    --plan MyAppServicePlan \
    --runtime python \
    --runtime-version 3.11 \
    --functions-version 4

# === Développer localement avec Azure Functions Core Tools ===

# Installer Core Tools
# Windows (via npm)
npm install -g azure-functions-core-tools@4

# macOS
brew tap azure/functions
brew install azure-functions-core-tools@4

# Linux
wget -q https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install azure-functions-core-tools-4

# Créer nouveau projet Functions
func init MyFunctionProject --python
cd MyFunctionProject

# Créer nouvelle function
func new --name HttpTriggerFunction --template "HTTP trigger"

# Templates disponibles:
# HTTP trigger, Timer trigger, Blob trigger, Queue trigger
# Cosmos DB trigger, Event Hub trigger, Service Bus trigger

# Démarrer localement
func start

# === Structure projet Python Functions ===
# MyFunctionProject/
#   HttpTriggerFunction/
#     __init__.py           # Code de la function
#     function.json         # Configuration bindings
#   host.json              # Configuration globale
#   local.settings.json    # Settings locaux (pas déployé)
#   requirements.txt       # Dépendances Python

# Exemple function.json (HTTP trigger)
{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": ["get", "post"]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

# Exemple __init__.py
import logging
import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    
    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')
    
    if name:
        return func.HttpResponse(f"Hello, {name}!")
    else:
        return func.HttpResponse(
            "Please pass a name on the query string or in the request body",
            status_code=400
        )

# === Déployer Function App ===

# Depuis dossier local
func azure functionapp publish myfunctionapp123

# Avec build distant (recommandé pour Python)
func azure functionapp publish myfunctionapp123 --build remote

# Depuis zip
az functionapp deployment source config-zip \
    --resource-group MyResourceGroup \
    --name myfunctionapp123 \
    --src function.zip

# === Configuration Function App ===

# Définir app settings
az functionapp config appsettings set \
    --name myfunctionapp123 \
    --resource-group MyResourceGroup \
    --settings MY_SETTING=value DB_CONNECTION_STRING=xxx

# Lister settings
az functionapp config appsettings list \
    --name myfunctionapp123 \
    --resource-group MyResourceGroup

# === Obtenir Function URLs ===
az functionapp function show \
    --name myfunctionapp123 \
    --resource-group MyResourceGroup \
    --function-name HttpTriggerFunction

# Obtenir clés d'accès (function keys)
az functionapp function keys list \
    --name myfunctionapp123 \
    --resource-group MyResourceGroup \
    --function-name HttpTriggerFunction

# Obtenir master key
az functionapp keys list \
    --name myfunctionapp123 \
    --resource-group MyResourceGroup

# === Exemples de triggers ===

# Timer trigger (CRON)
{
  "bindings": [
    {
      "name": "myTimer",
      "type": "timerTrigger",
      "direction": "in",
      "schedule": "0 */5 * * * *"
    }
  ]
}

# Blob trigger
{
  "bindings": [
    {
      "name": "myBlob",
      "type": "blobTrigger",
      "direction": "in",
      "path": "samples-workitems/{name}",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

# Queue trigger
{
  "bindings": [
    {
      "name": "msg",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "myqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

# === Logs et monitoring ===

# Stream logs
func azure functionapp logstream myfunctionapp123

# CLI
az webapp log tail \
    --name myfunctionapp123 \
    --resource-group MyResourceGroup

# === Supprimer Function App ===
az functionapp delete \
    --name myfunctionapp123 \
    --resource-group MyResourceGroup


[OK] AZURE SQL DATABASE

# Base de données relationnelle managée (SQL Server)

# === Créer SQL Server ===

# CLI
az sql server create \
    --name mysqlserver123 \
    --resource-group MyResourceGroup \
    --location eastus \
    --admin-user sqladmin \
    --admin-password 'P@ssw0rd1234!'

# Nom doit être unique globalement

# PowerShell
New-AzSqlServer `
    -ResourceGroupName MyResourceGroup `
    -ServerName mysqlserver123 `
    -Location eastus `
    -SqlAdministratorCredentials (Get-Credential)

# === Configurer firewall ===

# Autoriser IP spécifique
az sql server firewall-rule create \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name AllowMyIP \
    --start-ip-address 1.2.3.4 \
    --end-ip-address 1.2.3.4

# Autoriser services Azure
az sql server firewall-rule create \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name AllowAllAzureIPs \
    --start-ip-address 0.0.0.0 \
    --end-ip-address 0.0.0.0

# Autoriser votre IP actuelle
MY_IP=$(curl -s ifconfig.me)
az sql server firewall-rule create \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name AllowMyCurrentIP \
    --start-ip-address $MY_IP \
    --end-ip-address $MY_IP

# === Créer database ===

# CLI
az sql db create \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name mydatabase \
    --service-objective S0

# Service objectives (pricing tiers):
# Basic: Basic
# Standard: S0, S1, S2, S3, S4, S6, S7, S9, S12
# Premium: P1, P2, P4, P6, P11, P15
# GeneralPurpose: GP_Gen5_2, GP_Gen5_4, etc.
# BusinessCritical: BC_Gen5_2, BC_Gen5_4, etc.

# Avec compute serverless (économique)
az sql db create \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name mydatabase \
    --edition GeneralPurpose \
    --compute-model Serverless \
    --family Gen5 \
    --capacity 2 \
    --auto-pause-delay 60

# PowerShell
New-AzSqlDatabase `
    -ResourceGroupName MyResourceGroup `
    -ServerName mysqlserver123 `
    -DatabaseName mydatabase `
    -RequestedServiceObjectiveName S0

# === Se connecter à la database ===

# Connection string
Server=tcp:mysqlserver123.database.windows.net,1433;
Database=mydatabase;
User ID=sqladmin;
Password=P@ssw0rd1234!;
Encrypt=yes;
TrustServerCertificate=no;
Connection Timeout=30;

# Avec sqlcmd (outil CLI SQL Server)
sqlcmd -S mysqlserver123.database.windows.net -d mydatabase -U sqladmin -P 'P@ssw0rd1234!'

# Avec Azure Data Studio ou SQL Server Management Studio (SSMS)
# Server: mysqlserver123.database.windows.net
# Authentication: SQL Login
# Login: sqladmin
# Password: P@ssw0rd1234!

# === Gérer database ===

# Lister databases
az sql db list \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --output table

# Obtenir détails database
az sql db show \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name mydatabase

# Modifier service tier
az sql db update \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name mydatabase \
    --service-objective S1

# === Backup et restore ===

# Backup automatique activé par défaut
# Rétention: 7-35 jours (configurable)

# Point-in-time restore
az sql db restore \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name mydatabase-restored \
    --source-database mydatabase \
    --time "2024-01-15T10:00:00Z"

# Export vers blob storage (BACPAC)
az sql db export \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name mydatabase \
    --storage-key-type StorageAccessKey \
    --storage-key <storage-key> \
    --storage-uri https://mystorageaccount.blob.core.windows.net/backups/mydatabase.bacpac \
    --admin-user sqladmin \
    --admin-password 'P@ssw0rd1234!'

# Import depuis BACPAC
az sql db import \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name mydatabase-imported \
    --storage-key-type StorageAccessKey \
    --storage-key <storage-key> \
    --storage-uri https://mystorageaccount.blob.core.windows.net/backups/mydatabase.bacpac \
    --admin-user sqladmin \
    --admin-password 'P@ssw0rd1234!'

# === Geo-replication ===

# Créer replica secondaire (différente région)
az sql db replica create \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name mydatabase \
    --partner-server mysqlserver-west \
    --partner-resource-group MyResourceGroup

# === Monitoring ===

# Voir métriques
az monitor metrics list \
    --resource /subscriptions/<sub-id>/resourceGroups/MyResourceGroup/providers/Microsoft.Sql/servers/mysqlserver123/databases/mydatabase \
    --metric-names cpu_percent

# === Supprimer database ===
az sql db delete \
    --resource-group MyResourceGroup \
    --server mysqlserver123 \
    --name mydatabase \
    --yes

# Supprimer SQL server (et toutes les databases)
az sql server delete \
    --resource-group MyResourceGroup \
    --name mysqlserver123 \
    --yes


[OK] AZURE COSMOS DB

# Base de données NoSQL globalement distribuée

# === Créer Cosmos DB account ===

# API Core (SQL) - API par défaut
az cosmosdb create \
    --name mycosmosdb123 \
    --resource-group MyResourceGroup \
    --locations regionName=eastus failoverPriority=0

# APIs disponibles:
# --kind GlobalDocumentDB (SQL API - par défaut)
# --kind MongoDB
# --kind Cassandra
# --kind Gremlin (Graph)
# --kind Table

# Avec multiple régions
az cosmosdb create \
    --name mycosmosdb123 \
    --resource-group MyResourceGroup \
    --locations regionName=eastus failoverPriority=0 \
    --locations regionName=westus failoverPriority=1 \
    --enable-automatic-failover true

# === Créer database ===
az cosmosdb sql database create \
    --account-name mycosmosdb123 \
    --resource-group MyResourceGroup \
    --name mydatabase

# Avec throughput (RU/s)
az cosmosdb sql database create \
    --account-name mycosmosdb123 \
    --resource-group MyResourceGroup \
    --name mydatabase \
    --throughput 400

# Avec autoscale
az cosmosdb sql database create \
    --account-name mycosmosdb123 \
    --resource-group MyResourceGroup \
    --name mydatabase \
    --max-throughput 4000

# === Créer container ===
az cosmosdb sql container create \
    --account-name mycosmosdb123 \
    --resource-group MyResourceGroup \
    --database-name mydatabase \
    --name mycontainer \
    --partition-key-path "/userId" \
    --throughput 400

# === Obtenir connection strings ===
az cosmosdb keys list \
    --name mycosmosdb123 \
    --resource-group MyResourceGroup \
    --type connection-strings

# Obtenir clés
az cosmosdb keys list \
    --name mycosmosdb123 \
    --resource-group MyResourceGroup

# === Utiliser avec Python SDK ===
# pip install azure-cosmos

from azure.cosmos import CosmosClient

endpoint = "https://mycosmosdb123.documents.azure.com:443/"
key = "<your-key>"

client = CosmosClient(endpoint, key)
database = client.get_database_client("mydatabase")
container = database.get_container_client("mycontainer")

# Create item
container.create_item({
    'id': '1',
    'userId': 'user123',
    'name': 'John Doe',
    'email': 'john@example.com'
})

# Read item
item = container.read_item(item='1', partition_key='user123')

# Query items
items = list(container.query_items(
    query="SELECT * FROM c WHERE c.userId = @userId",
    parameters=[{"name": "@userId", "value": "user123"}]
))

# === Supprimer Cosmos DB ===
az cosmosdb delete \
    --name mycosmosdb123 \
    --resource-group MyResourceGroup \
    --yes


[OK] AZURE CONTAINER INSTANCES (ACI)

# Exécuter containers Docker sans gérer VMs

# === Créer container instance ===

# CLI - Container simple
az container create \
    --resource-group MyResourceGroup \
    --name mycontainer \
    --image mcr.microsoft.com/azuredocs/aci-helloworld \
    --ports 80 \
    --dns-name-label mycontainer123 \
    --location eastus

# URL publique sera: mycontainer123.eastus.azurecontainer.io

# Avec variables d'environnement
az container create \
    --resource-group MyResourceGroup \
    --name mycontainer \
    --image nginx \
    --environment-variables KEY1=value1 KEY2=value2

# Avec Azure Container Registry
az container create \
    --resource-group MyResourceGroup \
    --name mycontainer \
    --image myregistry.azurecr.io/myapp:latest \
    --registry-login-server myregistry.azurecr.io \
    --registry-username <username> \
    --registry-password <password> \
    --dns-name-label myapp123

# Spécifier CPU et mémoire
az container create \
    --resource-group MyResourceGroup \
    --name mycontainer \
    --image nginx \
    --cpu 2 \
    --memory 4

# Monter Azure Files
az container create \
    --resource-group MyResourceGroup \
    --name mycontainer \
    --image nginx \
    --azure-file-volume-account-name mystorageaccount \
    --azure-file-volume-account-key <key> \
    --azure-file-volume-share-name myshare \
    --azure-file-volume-mount-path /mnt/files

# === Gérer container ===

# Lister containers
az container list --output table

# Voir logs
az container logs \
    --resource-group MyResourceGroup \
    --name mycontainer

# Logs en temps réel
az container attach \
    --resource-group MyResourceGroup \
    --name mycontainer

# Exécuter commande dans container
az container exec \
    --resource-group MyResourceGroup \
    --name mycontainer \
    --exec-command "/bin/bash"

# Redémarrer container
az container restart \
    --resource-group MyResourceGroup \
    --name mycontainer

# Arrêter container
az container stop \
    --resource-group MyResourceGroup \
    --name mycontainer

# Démarrer container
az container start \
    --resource-group MyResourceGroup \
    --name mycontainer

# === Container groups (multi-container) ===

# Via fichier YAML
az container create \
    --resource-group MyResourceGroup \
    --file container-group.yaml

# Exemple container-group.yaml
apiVersion: 2019-12-01
location: eastus
name: mycontainergroup
properties:
  containers:
  - name: webapp
    properties:
      image: nginx
      ports:
      - port: 80
      resources:
        requests:
          cpu: 1.0
          memoryInGB: 1.5
  - name: sidecar
    properties:
      image: busybox
      command: ["/bin/sh", "-c", "while true; do echo hello; sleep 10; done"]
      resources:
        requests:
          cpu: 0.5
          memoryInGB: 0.5
  osType: Linux
  ipAddress:
    type: Public
    ports:
    - protocol: TCP
      port: 80

# === Supprimer container ===
az container delete \
    --resource-group MyResourceGroup \
    --name mycontainer \
    --yes


[OK] AZURE KUBERNETES SERVICE (AKS)

# Service Kubernetes managé

# === Créer cluster AKS ===

# CLI - Cluster simple
az aks create \
    --resource-group MyResourceGroup \
    --name myAKSCluster \
    --node-count 2 \
    --node-vm-size Standard_DS2_v2 \
    --enable-addons monitoring \
    --generate-ssh-keys

# Avec version Kubernetes spécifique
az aks get-versions --location eastus --output table

az aks create \
    --resource-group MyResourceGroup \
    --name myAKSCluster \
    --kubernetes-version 1.28.3 \
    --node-count 3

# Avec autoscaling
az aks create \
    --resource-group MyResourceGroup \
    --name myAKSCluster \
    --node-count 2 \
    --enable-cluster-autoscaler \
    --min-count 2 \
    --max-count 5

# Avec Azure Container Registry integration
az aks create \
    --resource-group MyResourceGroup \
    --name myAKSCluster \
    --attach-acr myregistry

# PowerShell
New-AzAksCluster `
    -ResourceGroupName MyResourceGroup `
    -Name myAKSCluster `
    -NodeCount 2

# === Obtenir credentials kubectl ===
az aks get-credentials \
    --resource-group MyResourceGroup \
    --name myAKSCluster

# Avec admin credentials
az aks get-credentials \
    --resource-group MyResourceGroup \
    --name myAKSCluster \
    --admin

# === Utiliser kubectl ===

# Vérifier connexion
kubectl get nodes
kubectl cluster-info

# Déployer application
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=LoadBalancer

# Voir services
kubectl get services
kubectl get deployments
kubectl get pods

# === Gérer AKS cluster ===

# Scale node pool
az aks scale \
    --resource-group MyResourceGroup \
    --name myAKSCluster \
    --node-count 5

# Upgrade Kubernetes version
az aks upgrade \
    --resource-group MyResourceGroup \
    --name myAKSCluster \
    --kubernetes-version 1.29.0

# Arrêter cluster (économiser coûts)
az aks stop \
    --resource-group MyResourceGroup \
    --name myAKSCluster

# Démarrer cluster
az aks start \
    --resource-group MyResourceGroup \
    --name myAKSCluster

# === Node pools ===

# Ajouter node pool
az aks nodepool add \
    --resource-group MyResourceGroup \
    --cluster-name myAKSCluster \
    --name gpunodepool \
    --node-count 2 \
    --node-vm-size Standard_NC6

# Lister node pools
az aks nodepool list \
    --resource-group MyResourceGroup \
    --cluster-name myAKSCluster \
    --output table

# === Monitoring ===

# Voir logs
az aks browse \
    --resource-group MyResourceGroup \
    --name myAKSCluster

# Dashboard Kubernetes (si activé)
kubectl proxy
# Puis visiter: http://localhost:8001/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/

# === Supprimer cluster ===
az aks delete \
    --resource-group MyResourceGroup \
    --name myAKSCluster \
    --yes


[OK] AZURE CONTAINER REGISTRY (ACR)

# Registry Docker privé pour stocker images containers

# === Créer registry ===
az acr create \
    --resource-group MyResourceGroup \
    --name myregistry123 \
    --sku Basic

# SKU: Basic, Standard, Premium

# PowerShell
New-AzContainerRegistry `
    -ResourceGroupName MyResourceGroup `
    -Name myregistry123 `
    -Sku Basic

# === Se connecter au registry ===

# Avec Azure CLI
az acr login --name myregistry123

# Avec Docker directement
docker login myregistry123.azurecr.io
# Username: myregistry123
# Password: (obtenir avec az acr credential show)

# Obtenir credentials
az acr credential show --name myregistry123

# === Push image vers ACR ===

# Tag image
docker tag nginx:latest myregistry123.azurecr.io/nginx:v1

# Push
docker push myregistry123.azurecr.io/nginx:v1

# === Lister images ===
az acr repository list --name myregistry123
az acr repository show-tags --name myregistry123 --repository nginx

# === Pull image ===
docker pull myregistry123.azurecr.io/nginx:v1

# === Build image dans ACR (ACR Tasks) ===
az acr build \
    --registry myregistry123 \
    --image myapp:v1 \
    --file Dockerfile \
    .

# === Supprimer image ===
az acr repository delete \
    --name myregistry123 \
    --image nginx:v1 \
    --yes


[OK] NETWORKING (RÉSEAUX)

# === Virtual Network (VNet) ===

# Créer VNet
az network vnet create \
    --resource-group MyResourceGroup \
    --name MyVNet \
    --address-prefix 10.0.0.0/16 \
    --subnet-name MySubnet \
    --subnet-prefix 10.0.1.0/24

# Ajouter subnet
az network vnet subnet create \
    --resource-group MyResourceGroup \
    --vnet-name MyVNet \
    --name MySubnet2 \
    --address-prefix 10.0.2.0/24

# Lister VNets
az network vnet list --output table

# === Network Security Group (NSG) ===

# Créer NSG
az network nsg create \
    --resource-group MyResourceGroup \
    --name MyNSG

# Ajouter règle (ouvrir port 80)
az network nsg rule create \
    --resource-group MyResourceGroup \
    --nsg-name MyNSG \
    --name AllowHTTP \
    --priority 100 \
    --source-address-prefixes '*' \
    --source-port-ranges '*' \
    --destination-address-prefixes '*' \
    --destination-port-ranges 80 \
    --access Allow \
    --protocol Tcp \
    --direction Inbound

# Associer NSG à subnet
az network vnet subnet update \
    --resource-group MyResourceGroup \
    --vnet-name MyVNet \
    --name MySubnet \
    --network-security-group MyNSG

# === Public IP ===

# Créer IP publique
az network public-ip create \
    --resource-group MyResourceGroup \
    --name MyPublicIP \
    --sku Standard

# Obtenir adresse IP
az network public-ip show \
    --resource-group MyResourceGroup \
    --name MyPublicIP \
    --query ipAddress \
    --output tsv

# === Load Balancer ===

# Créer load balancer
az network lb create \
    --resource-group MyResourceGroup \
    --name MyLoadBalancer \
    --sku Standard \
    --public-ip-address MyPublicIP \
    --frontend-ip-name MyFrontEnd \
    --backend-pool-name MyBackEndPool

# === Application Gateway ===

# Créer Application Gateway (Layer 7 load balancer)
az network application-gateway create \
    --resource-group MyResourceGroup \
    --name MyAppGateway \
    --location eastus \
    --capacity 2 \
    --sku Standard_v2 \
    --vnet-name MyVNet \
    --subnet MySubnet \
    --public-ip-address MyPublicIP

# === VPN Gateway ===

# Créer gateway subnet
az network vnet subnet create \
    --resource-group MyResourceGroup \
    --vnet-name MyVNet \
    --name GatewaySubnet \
    --address-prefix 10.0.255.0/27

# Créer public IP pour VPN
az network public-ip create \
    --resource-group MyResourceGroup \
    --name VPNGatewayIP \
    --allocation-method Dynamic

# Créer VPN Gateway
az network vnet-gateway create \
    --resource-group MyResourceGroup \
    --name MyVPNGateway \
    --public-ip-address VPNGatewayIP \
    --vnet MyVNet \
    --gateway-type Vpn \
    --vpn-type RouteBased \
    --sku VpnGw1

# === DNS Zone ===

# Créer DNS zone
az network dns zone create \
    --resource-group MyResourceGroup \
    --name mydomain.com

# Ajouter record A
az network dns record-set a add-record \
    --resource-group MyResourceGroup \
    --zone-name mydomain.com \
    --record-set-name www \
    --ipv4-address 1.2.3.4


[OK] AZURE ACTIVE DIRECTORY (ENTRA ID)

# Service de gestion d'identité et d'accès

# === Utilisateurs ===

# Créer utilisateur
az ad user create \
    --display-name "John Doe" \
    --user-principal-name john@yourdomain.onmicrosoft.com \
    --password "P@ssw0rd123!" \
    --force-change-password-next-sign-in false

# Lister utilisateurs
az ad user list --output table

# Obtenir détails utilisateur
az ad user show --id john@yourdomain.onmicrosoft.com

# Supprimer utilisateur
az ad user delete --id john@yourdomain.onmicrosoft.com

# === Groupes ===

# Créer groupe
az ad group create \
    --display-name "Developers" \
    --mail-nickname developers

# Ajouter membre au groupe
az ad group member add \
    --group "Developers" \
    --member-id <user-object-id>

# Lister groupes
az ad group list --output table

# === Service Principals (pour applications) ===

# Créer service principal
az ad sp create-for-rbac --name MyApp

# Sortie contient: appId, password, tenant
# Sauvegarder ces credentials de manière sécurisée!

# Créer avec rôle spécifique et scope
az ad sp create-for-rbac \
    --name MyApp \
    --role Contributor \
    --scopes /subscriptions/{subscription-id}/resourceGroups/MyResourceGroup

# Lister service principals
az ad sp list --output table

# === App Registrations ===

# Créer app registration
az ad app create --display-name MyApplication

# Créer secret pour app
az ad app credential reset --id <app-id>


[OK] ROLE-BASED ACCESS CONTROL (RBAC)

# Gestion des permissions et accès aux ressources

# === Rôles built-in courants ===
# Owner: Accès complet
# Contributor: Créer/gérer ressources, pas gérer accès
# Reader: Lecture seule
# User Access Administrator: Gérer accès utilisateurs
# Virtual Machine Contributor: Gérer VMs
# Storage Blob Data Contributor: Lire/écrire blobs
# SQL DB Contributor: Gérer SQL databases

# Lister tous les rôles
az role definition list --output table

# Chercher rôle spécifique
az role definition list --name "Virtual Machine Contributor"

# === Assigner rôle ===

# À un utilisateur sur un resource group
az role assignment create \
    --assignee john@yourdomain.onmicrosoft.com \
    --role "Contributor" \
    --resource-group MyResourceGroup

# À un service principal sur une souscription
az role assignment create \
    --assignee <service-principal-app-id> \
    --role "Reader" \
    --scope /subscriptions/{subscription-id}

# À un groupe sur une ressource spécifique
az role assignment create \
    --assignee-object-id <group-object-id> \
    --role "Storage Blob Data Contributor" \
    --scope /subscriptions/{subscription-id}/resourceGroups/MyResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount

# Lister assignments
az role assignment list --output table
az role assignment list --assignee john@yourdomain.onmicrosoft.com

# Supprimer assignment
az role assignment delete \
    --assignee john@yourdomain.onmicrosoft.com \
    --role "Contributor" \
    --resource-group MyResourceGroup

# === Créer rôle personnalisé ===

# Fichier role.json
{
  "Name": "Custom Virtual Machine Operator",
  "IsCustom": true,
  "Description": "Can start and stop virtual machines",
  "Actions": [
    "Microsoft.Compute/virtualMachines/start/action",
    "Microsoft.Compute/virtualMachines/restart/action",
    "Microsoft.Compute/virtualMachines/deallocate/action",
    "Microsoft.Compute/virtualMachines/read"
  ],
  "NotActions": [],
  "AssignableScopes": [
    "/subscriptions/{subscription-id}"
  ]
}

# Créer rôle
az role definition create --role-definition role.json

# Mettre à jour rôle
az role definition update --role-definition role.json


[OK] AZURE KEY VAULT

# Stockage sécurisé de secrets, clés, certificats

# === Créer Key Vault ===
az keyvault create \
    --name mykeyvault123 \
    --resource-group MyResourceGroup \
    --location eastus

# Nom doit être unique globalement

# Avec soft-delete et purge protection
az keyvault create \
    --name mykeyvault123 \
    --resource-group MyResourceGroup \
    --location eastus \
    --enable-soft-delete true \
    --enable-purge-protection true

# === SECRETS ===

# Créer/définir secret
az keyvault secret set \
    --vault-name mykeyvault123 \
    --name DatabasePassword \
    --value "P@ssw0rd123!"

# Obtenir secret
az keyvault secret show \
    --vault-name mykeyvault123 \
    --name DatabasePassword

# Obtenir uniquement la valeur
az keyvault secret show \
    --vault-name mykeyvault123 \
    --name DatabasePassword \
    --query value \
    --output tsv

# Lister secrets
az keyvault secret list \
    --vault-name mykeyvault123 \
    --output table

# Supprimer secret
az keyvault secret delete \
    --vault-name mykeyvault123 \
    --name DatabasePassword

# === KEYS (clés cryptographiques) ===

# Créer clé
az keyvault key create \
    --vault-name mykeyvault123 \
    --name MyEncryptionKey \
    --protection software

# Types: software, hsm

# Lister clés
az keyvault key list \
    --vault-name mykeyvault123

# === CERTIFICATES ===

# Créer certificat auto-signé
az keyvault certificate create \
    --vault-name mykeyvault123 \
    --name MyCertificate \
    --policy "$(az keyvault certificate get-default-policy)"

# Importer certificat
az keyvault certificate import \
    --vault-name mykeyvault123 \
    --name ImportedCert \
    --file certificate.pfx \
    --password "certpassword"

# === Access policies ===

# Donner accès à un utilisateur
az keyvault set-policy \
    --name mykeyvault123 \
    --upn john@yourdomain.onmicrosoft.com \
    --secret-permissions get list set delete

# Donner accès à service principal
az keyvault set-policy \
    --name mykeyvault123 \
    --spn <service-principal-app-id> \
    --secret-permissions get list

# Permissions disponibles:
# Secrets: get, list, set, delete, backup, restore, recover, purge
# Keys: get, list, create, delete, update, import, backup, restore, recover, purge, encrypt, decrypt, sign, verify, wrapKey, unwrapKey
# Certificates: get, list, create, delete, update, import, managecontacts, getissuers, listissuers, setissuers, deleteissuers

# === Utiliser dans applications ===

# Python
# pip install azure-identity azure-keyvault-secrets

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

credential = DefaultAzureCredential()
client = SecretClient(vault_url="https://mykeyvault123.vault.azure.net/", credential=credential)

# Obtenir secret
secret = client.get_secret("DatabasePassword")
print(secret.value)

# Node.js
# npm install @azure/identity @azure/keyvault-secrets

const { DefaultAzureCredential } = require("@azure/identity");
const { SecretClient } = require("@azure/keyvault-secrets");

const credential = new DefaultAzureCredential();
const client = new SecretClient("https://mykeyvault123.vault.azure.net/", credential);

async function main() {
  const secret = await client.getSecret("DatabasePassword");
  console.log(secret.value);
}


[OK] AZURE MONITOR & APPLICATION INSIGHTS

# Monitoring et diagnostics des applications et infrastructure

# === Application Insights ===

# Créer Application Insights
az monitor app-insights component create \
    --app MyAppInsights \
    --location eastus \
    --resource-group MyResourceGroup \
    --application-type web

# Obtenir instrumentation key
az monitor app-insights component show \
    --app MyAppInsights \
    --resource-group MyResourceGroup \
    --query instrumentationKey

# === Utiliser dans applications ===

# Python (Flask/Django)
# pip install applicationinsights

from applicationinsights import TelemetryClient

tc = TelemetryClient('<instrumentation-key>')
tc.track_event('User logged in')
tc.track_metric('Request duration', 42.0)
tc.flush()

# Node.js
# npm install applicationinsights

const appInsights = require("applicationinsights");
appInsights.setup("<instrumentation-key>").start();

let client = appInsights.defaultClient;
client.trackEvent({name: "User logged in"});
client.trackMetric({name: "Request duration", value: 42.0});

# === Log Analytics ===

# Créer workspace
az monitor log-analytics workspace create \
    --resource-group MyResourceGroup \
    --workspace-name MyWorkspace

# Query logs (Kusto Query Language - KQL)
az monitor log-analytics query \
    --workspace <workspace-id> \
    --analytics-query "AzureActivity | where TimeGenerated > ago(1h) | summarize count() by ResourceProvider"

# Exemples de requêtes KQL:

# Erreurs dernières 24h
requests
| where timestamp > ago(24h)
| where success == false
| summarize count() by resultCode

# Performance moyenne
requests
| where timestamp > ago(1h)
| summarize avg(duration) by bin(timestamp, 5m)

# Exceptions
exceptions
| where timestamp > ago(24h)
| summarize count() by type

# === Alertes ===

# Créer action group (notification)
az monitor action-group create \
    --name MyActionGroup \
    --resource-group MyResourceGroup \
    --short-name myag \
    --email-receiver admin admin@example.com

# Créer metric alert
az monitor metrics alert create \
    --name HighCPUAlert \
    --resource-group MyResourceGroup \
    --scopes /subscriptions/{subscription-id}/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/MyVM \
    --condition "avg Percentage CPU > 80" \
    --window-size 5m \
    --evaluation-frequency 1m \
    --action MyActionGroup

# === Diagnostics Settings ===

# Activer diagnostics pour envoyer logs vers Log Analytics
az monitor diagnostic-settings create \
    --name SendToLogAnalytics \
    --resource /subscriptions/{subscription-id}/resourceGroups/MyResourceGroup/providers/Microsoft.Web/sites/mywebapp \
    --workspace <workspace-id> \
    --logs '[{"category": "AppServiceHTTPLogs", "enabled": true}]' \
    --metrics '[{"category": "AllMetrics", "enabled": true}]'


[OK] AZURE DEVOPS & CI/CD

# === Azure DevOps CLI ===

# Installer extension
az extension add --name azure-devops

# Configurer organization par défaut
az devops configure --defaults organization=https://dev.azure.com/yourorg

# Login
az devops login

# === Projects ===

# Créer projet
az devops project create --name MyProject

# Lister projets
az devops project list

# === Repos ===

# Lister repos
az repos list --project MyProject

# Créer repo
az repos create --name MyRepo --project MyProject

# Clone repo
git clone https://yourorg@dev.azure.com/yourorg/MyProject/_git/MyRepo

# === Pipelines ===

# Créer pipeline depuis YAML
az pipelines create \
    --name MyPipeline \
    --repository MyRepo \
    --branch main \
    --yml-path azure-pipelines.yml

# Lister pipelines
az pipelines list --project MyProject

# Run pipeline
az pipelines run --name MyPipeline

# Exemple azure-pipelines.yml (Python app)
trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.11'
  
- script: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt
  displayName: 'Install dependencies'

- script: |
    pip install pytest pytest-cov
    pytest --cov=./ --cov-report=xml
  displayName: 'Run tests'

- task: PublishTestResults@2
  inputs:
    testResultsFiles: '**/test-*.xml'
    
- task: AzureWebApp@1
  inputs:
    azureSubscription: 'MyServiceConnection'
    appName: 'mywebapp123'
    package: '$(System.DefaultWorkingDirectory)/**/*.zip'

# === GitHub Actions pour Azure ===

# Exemple .github/workflows/azure.yml
name: Deploy to Azure

on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.11'
    
    - name: Install dependencies
      run: |
        pip install -r requirements.txt
    
    - name: Login to Azure
      uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}
    
    - name: Deploy to Azure Web App
      uses: azure/webapps-deploy@v2
      with:
        app-name: 'mywebapp123'
        package: .

# Créer service principal pour GitHub Actions
az ad sp create-for-rbac \
    --name "github-actions" \
    --role contributor \
    --scopes /subscriptions/{subscription-id}/resourceGroups/MyResourceGroup \
    --sdk-auth

# Copier output JSON dans GitHub Secrets (AZURE_CREDENTIALS)


[OK] AZURE COGNITIVE SERVICES (AI)

# Services d'IA pré-entraînés

# === Créer Cognitive Services account ===
az cognitiveservices account create \
    --name MyCognitiveServices \
    --resource-group MyResourceGroup \
    --kind CognitiveServices \
    --sku S0 \
    --location eastus

# Types (kind) disponibles:
# CognitiveServices (multi-service)
# ComputerVision
# Face
# TextAnalytics
# TranslatorText
# SpeechServices
# AnomalyDetector
# OpenAI (Azure OpenAI Service)

# Obtenir keys
az cognitiveservices account keys list \
    --name MyCognitiveServices \
    --resource-group MyResourceGroup

# Obtenir endpoint
az cognitiveservices account show \
    --name MyCognitiveServices \
    --resource-group MyResourceGroup \
    --query properties.endpoint

# === Computer Vision ===

# Créer service
az cognitiveservices account create \
    --name MyComputerVision \
    --resource-group MyResourceGroup \
    --kind ComputerVision \
    --sku S1 \
    --location eastus

# Python example
# pip install azure-cognitiveservices-vision-computervision

from azure.cognitiveservices.vision.computervision import ComputerVisionClient
from msrest.authentication import CognitiveServicesCredentials

endpoint = "https://eastus.api.cognitive.microsoft.com/"
key = "<your-key>"

client = ComputerVisionClient(endpoint, CognitiveServicesCredentials(key))

# Analyser image
url = "https://example.com/image.jpg"
analysis = client.analyze_image(url, visual_features=["Categories", "Description", "Color"])

print(analysis.description.captions[0].text)

# === Text Analytics ===

# Python
# pip install azure-ai-textanalytics

from azure.ai.textanalytics import TextAnalyticsClient
from azure.core.credentials import AzureKeyCredential

endpoint = "https://eastus.api.cognitive.microsoft.com/"
key = "<your-key>"

client = TextAnalyticsClient(endpoint, AzureKeyCredential(key))

documents = ["I love using Azure services!"]
response = client.analyze_sentiment(documents)

print(f"Sentiment: {response[0].sentiment}")
print(f"Scores: positive={response[0].confidence_scores.positive}")

# === Azure OpenAI ===

# Créer Azure OpenAI resource
az cognitiveservices account create \
    --name MyOpenAI \
    --resource-group MyResourceGroup \
    --kind OpenAI \
    --sku S0 \
    --location eastus

# Python
# pip install openai

import openai

openai.api_type = "azure"
openai.api_base = "https://myopenai.openai.azure.com/"
openai.api_version = "2023-05-15"
openai.api_key = "<your-key>"

response = openai.ChatCompletion.create(
    engine="gpt-35-turbo",  # deployment name
    messages=[
        {"role": "user", "content": "What is Azure?"}
    ]
)

print(response.choices[0].message.content)


[OK] AZURE BACKUP & SITE RECOVERY

# === Azure Backup ===

# Créer Recovery Services Vault
az backup vault create \
    --resource-group MyResourceGroup \
    --name MyBackupVault \
    --location eastus

# Backup VM
az backup protection enable-for-vm \
    --resource-group MyResourceGroup \
    --vault-name MyBackupVault \
    --vm MyVM \
    --policy-name DefaultPolicy

# Trigger backup immédiat
az backup protection backup-now \
    --resource-group MyResourceGroup \
    --vault-name MyBackupVault \
    --container-name MyVM \
    --item-name MyVM \
    --retain-until 30-12-2024

# Lister recovery points
az backup recoverypoint list \
    --resource-group MyResourceGroup \
    --vault-name MyBackupVault \
    --container-name MyVM \
    --item-name MyVM

# Restore VM
az backup restore restore-disks \
    --resource-group MyResourceGroup \
    --vault-name MyBackupVault \
    --container-name MyVM \
    --item-name MyVM \
    --rp-name <recovery-point-name> \
    --storage-account mystorageaccount

# === Azure Site Recovery (Disaster Recovery) ===

# Configuration via portail recommandée pour ASR
# Permet réplication VMs vers autre région Azure


[OK] COST MANAGEMENT & BILLING

# === Voir coûts ===

# Coûts actuels
az consumption usage list --output table

# Coûts par resource group
az consumption usage list \
    --resource-group MyResourceGroup \
    --output table

# === Budgets ===

# Créer budget
az consumption budget create \
    --budget-name MyBudget \
    --category cost \
    --amount 1000 \
    --time-grain monthly \
    --start-date 2024-01-01 \
    --end-date 2024-12-31

# === Cost Analysis ===

# Via portail: Cost Management + Billing > Cost Analysis
# Permet visualiser et analyser coûts par:
# - Resource group
# - Service
# - Location
# - Tags

# === Recommandations d'économies ===

# Obtenir recommandations via Azure Advisor
az advisor recommendation list

# Types de recommandations:
# - Arrêter VMs non utilisées
# - Redimensionner VMs sous-utilisées
# - Supprimer IP publiques non attachées
# - Utiliser Reserved Instances

# === Tags pour tracking coûts ===

# Appliquer tags aux ressources
az resource tag \
    --tags Environment=Production CostCenter=IT Project=WebApp \
    --ids /subscriptions/{subscription-id}/resourceGroups/MyResourceGroup/providers/Microsoft.Web/sites/mywebapp

# Lister ressources par tag
az resource list --tag Environment=Production

# === Calculateur de prix ===
# https://azure.microsoft.com/pricing/calculator/


[OK] AZURE CLI - COMMANDES AVANCÉES

# === Output formats ===
az vm list --output json          # JSON (défaut)
az vm list --output jsonc         # JSON coloré
az vm list --output table         # Tableau
az vm list --output yaml          # YAML
az vm list --output tsv           # Tab-separated (pour scripts)

# === Query avec JMESPath ===

# Obtenir seulement les noms
az vm list --query "[].name"

# Filtrer par location
az vm list --query "[?location=='eastus'].{Name:name, Size:hardwareProfile.vmSize}"

# Premier élément
az vm list --query "[0].name"

# Compter éléments
az vm list --query "length([])"

# === Variables et loops (Bash) ===

# Stocker dans variable
VM_NAME=$(az vm show --name MyVM --resource-group MyResourceGroup --query name -o tsv)
echo $VM_NAME

# Loop sur VMs
for vm in $(az vm list --query "[].name" -o tsv); do
    echo "Processing $vm"
    az vm stop --name $vm --resource-group MyResourceGroup --no-wait
done

# === Exécution parallèle ===

# Démarrer plusieurs VMs en parallèle
az vm start --name VM1 --resource-group MyResourceGroup --no-wait
az vm start --name VM2 --resource-group MyResourceGroup --no-wait
az vm start --name VM3 --resource-group MyResourceGroup --no-wait

# --no-wait: Ne pas attendre completion

# === REST API directement ===

# Obtenir access token
ACCESS_TOKEN=$(az account get-access-token --query accessToken -o tsv)

# Faire requête REST
curl -X GET \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    "https://management.azure.com/subscriptions/{subscription-id}/resourceGroups?api-version=2021-04-01"

# === Déploiement via ARM Templates ===

# Déployer template
az deployment group create \
    --resource-group MyResourceGroup \
    --template-file template.json \
    --parameters parameters.json

# Avec paramètres inline
az deployment group create \
    --resource-group MyResourceGroup \
    --template-file template.json \
    --parameters vmName=MyVM adminUsername=azureuser

# Valider template
az deployment group validate \
    --resource-group MyResourceGroup \
    --template-file template.json

# What-if (preview changes)
az deployment group what-if \
    --resource-group MyResourceGroup \
    --template-file template.json

# === Bicep (alternative moderne à ARM) ===

# Installer Bicep CLI
az bicep install

# Upgrade
az bicep upgrade

# Compiler Bicep vers ARM
az bicep build --file main.bicep

# Déployer Bicep
az deployment group create \
    --resource-group MyResourceGroup \
    --template-file main.bicep

# Exemple main.bicep
param location string = resourceGroup().location
param vmName string

resource vm 'Microsoft.Compute/virtualMachines@2023-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: 'Standard_B2s'
    }
    // ...
  }
}


[OK] TERRAFORM AVEC AZURE

# Infrastructure as Code avec Terraform

# === Installation Terraform ===

# Windows (Chocolatey)
choco install terraform

# macOS
brew install terraform

# Linux
wget https://releases.hashicorp.com/terraform/1.6.0/terraform_1.6.0_linux_amd64.zip
unzip terraform_1.6.0_linux_amd64.zip
sudo mv terraform /usr/local/bin/

# Vérifier installation
terraform version

# === Configuration Azure Provider ===

# main.tf
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0"
    }
  }
}

provider "azurerm" {
  features {}
}

# Resource group
resource "azurerm_resource_group" "example" {
  name     = "MyResourceGroup"
  location = "East US"
}

# Storage account
resource "azurerm_storage_account" "example" {
  name                     = "mystorageaccount123"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

# === Commandes Terraform ===

# Initialiser
terraform init

# Planifier changements
terraform plan

# Appliquer changements
terraform apply

# Appliquer sans confirmation
terraform apply -auto-approve

# Détruire infrastructure
terraform destroy

# Formater code
terraform fmt

# Valider configuration
terraform validate

# Voir state
terraform show

# === Authentification ===

# Via Azure CLI (recommandé pour dev)
az login

# Via Service Principal (pour CI/CD)
# Définir variables d'environnement:
export ARM_CLIENT_ID="<service-principal-app-id>"
export ARM_CLIENT_SECRET="<service-principal-password>"
export ARM_SUBSCRIPTION_ID="<subscription-id>"
export ARM_TENANT_ID="<tenant-id>"

# === Backend distant (state storage) ===

terraform {
  backend "azurerm" {
    resource_group_name  = "terraform-state-rg"
    storage_account_name = "tfstate"
    container_name       = "tfstate"
    key                  = "prod.terraform.tfstate"
  }
}


[OK] BONNES PRATIQUES

# === Organisation ===

# 1. Structure de resource groups
# - Par environnement: dev-rg, staging-rg, prod-rg
# - Par application: webapp-rg, database-rg, monitoring-rg
# - Par cycle de vie: permanent-rg, temporary-rg

# 2. Naming conventions
# Format: <resource-type>-<app-name>-<environment>-<region>-<instance>
# Exemples:
# - vm-webapp-prod-eastus-001
# - st-logs-dev-westeu-001  (storage)
# - sql-customerdb-prod-eastus-001

# 3. Tagging strategy
# Tags obligatoires:
Environment=Production|Staging|Development
CostCenter=Finance|IT|Marketing
Owner=team@company.com
Project=ProjectName
ExpirationDate=2024-12-31

# === Sécurité ===

# 1. Principe du moindre privilège (Least Privilege)
# - Utiliser RBAC avec rôles spécifiques
# - Éviter rôle Owner sauf nécessaire
# - Utiliser groupes pour assignments

# 2. Network security
# - Utiliser NSG pour contrôler trafic
# - Activer Azure Firewall pour protection avancée
# - Isoler ressources dans VNets
# - Utiliser Private Endpoints quand possible

# 3. Secrets management
# - JAMAIS mettre secrets dans code/repo
# - Utiliser Key Vault pour tous les secrets
# - Utiliser Managed Identities (pas de credentials)