Variables d'environnement
Notions théoriques
Pourquoi les variables d'environnement ?
Les variables d'environnement permettent de séparer la configuration du code. On ne met jamais de mots de passe, d'URL de base de données ou de clés API directement dans le code source.
// MAUVAIS — mot de passe dans le code !
string mdp = "MonMotDePasse123";
// BON — mot de passe dans l'environnement
string? mdp = Environment.GetEnvironmentVariable("DB_PASSWORD");
Définir des variables d'environnement
Sur Windows (PowerShell) :
# Temporaire (session courante uniquement)
$env:DB_HOST = "localhost"
$env:DB_PASSWORD = "secret"
# Permanent (utilisateur courant)
[System.Environment]::SetEnvironmentVariable("DB_HOST", "localhost", "User")
Sur Linux (Bash) :
# Temporaire (session courante)
export DB_HOST="localhost"
export DB_PASSWORD="secret"
# Permanent (ajouter dans ~/.bashrc ou ~/.zshrc)
echo 'export DB_HOST="localhost"' >> ~/.bashrc
Lire les variables d'environnement en C#
// Lecture simple (retourne null si non définie)
string? host = Environment.GetEnvironmentVariable("DB_HOST");
// Avec valeur par défaut grâce à ?? (null-coalescing)
string host = Environment.GetEnvironmentVariable("DB_HOST") ?? "localhost";
int port = int.Parse(Environment.GetEnvironmentVariable("DB_PORT") ?? "3306");
// Vérifier qu'une variable critique est définie
string? mdp = Environment.GetEnvironmentVariable("DB_PASSWORD");
if (string.IsNullOrEmpty(mdp))
{
Console.Error.WriteLine("ERREUR : DB_PASSWORD non définie !");
Environment.Exit(1);
}
appsettings.json — configuration .NET standard
Le fichier appsettings.json est l'approche standard pour la configuration non sensible :
{
"Database": {
"Host": "localhost",
"Port": 3306,
"Name": "ma_base"
},
"AppName": "MonApplication"
}
appsettings.json est committé dans git. Ne l'utilisez que pour des valeurs non sensibles (host, port, nom de base). Les mots de passe restent dans des variables d'environnement ou dans appsettings.Development.json (exclu du git via .gitignore).
Paquet DotNetEnv — fichier .env
Le paquet DotNetEnv permet de charger des variables depuis un fichier .env (pratique en développement) :
dotnet add package DotNetEnv
// Charger le fichier .env au démarrage
DotNetEnv.Env.Load();
string host = Environment.GetEnvironmentVariable("DB_HOST") ?? "localhost";
Fichier .env (à ne jamais committer — ajoutez-le au .gitignore) :
DB_HOST=localhost
DB_PORT=3306
DB_NAME=mabase
DB_PASSWORD=secret
Ajoutez toujours .env à votre .gitignore. Ce fichier contient des secrets et ne doit jamais être poussé sur le dépôt distant. Committez à la place un fichier .env.example avec des valeurs fictives pour documenter les variables attendues.
L'opérateur ?? — valeur par défaut
string? valeur = null;
string resultat = valeur ?? "défaut"; // "défaut" car valeur est null
// Enchaînable
string config = Environment.GetEnvironmentVariable("HOST")
?? Environment.GetEnvironmentVariable("HOSTNAME")
?? "localhost";
Exemple pratique
// Lecture de la configuration depuis l'environnement
string dbHost = Environment.GetEnvironmentVariable("DB_HOST") ?? "localhost";
string dbPort = Environment.GetEnvironmentVariable("DB_PORT") ?? "3306";
string dbName = Environment.GetEnvironmentVariable("DB_NAME") ?? "mabase";
string? dbPass = Environment.GetEnvironmentVariable("DB_PASSWORD");
string appEnv = Environment.GetEnvironmentVariable("APP_ENV") ?? "development";
// Vérification de la variable critique
if (string.IsNullOrEmpty(dbPass))
{
Console.Error.WriteLine("⚠ DB_PASSWORD non définie. Utilisation de la valeur par défaut (DANGEREUX en production !)");
dbPass = "changeme";
}
// Masquage du mot de passe pour l'affichage
string masque = dbPass.Length > 2
? new string('*', dbPass.Length - 2) + dbPass[^2..]
: "****";
Console.WriteLine("=== Configuration de l'application ===");
Console.WriteLine($"Environnement : {appEnv.ToUpper()}");
Console.WriteLine($"Base de données :");
Console.WriteLine($" Host : {dbHost}");
Console.WriteLine($" Port : {dbPort}");
Console.WriteLine($" Nom : {dbName}");
Console.WriteLine($" Password : {masque}");
// Construire la chaîne de connexion
string connexion = $"Server={dbHost};Port={dbPort};Database={dbName};Uid=root;Pwd={dbPass};";
Console.WriteLine($"\nChaîne de connexion :");
Console.WriteLine($" {connexion.Replace(dbPass, masque)}");
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Vous allez créer un programme qui lit sa configuration depuis les variables d'environnement.
Étape 1 — Définir les variables (Windows et Linux)
Définissez les variables d'environnement pour le projet.
Les variables définies avec $env: (PowerShell) ou export (Bash) sont temporaires : elles disparaissent à la fermeture du terminal. Pour le développement, utilisez un fichier .env avec le paquet DotNetEnv. Pour la production (serveur, Docker), définissez les variables de façon permanente dans le système ou le conteneur.
Étape 2 — Lire la configuration en C#
Lisez les variables et fournissez des valeurs par défaut.
Utilisez ?? "valeur_par_defaut" pour les variables optionnelles. Pour les variables obligatoires (mot de passe, clé API), vérifiez qu'elles sont définies et quittez proprement si ce n'est pas le cas, plutôt que de continuer avec une valeur nulle.
Étape 3 — Masquer le secret et sauvegarder la config
Masquez la valeur sensible et sauvegardez la configuration dans un fichier.
Masquez toujours les valeurs sensibles avant de les afficher dans les logs ou la console. L'opérateur [^2..] (range depuis la fin) extrait les 2 derniers caractères, suffisant pour confirmer que la variable est définie sans révéler sa valeur.