Kit de développement Azure App Configuration pour TypeScript
Gestion centralisée de la configuration avec des drapeaux de fonctionnalité et actualisation dynamique.
Installation
# SDK CRUD bas niveau
npm install @azure/app-configuration @azure/identity
# Fournisseur haut niveau (recommandé pour les applications)
npm install @azure/app-configuration-provider @azure/identity
# Gestion des drapeaux de fonctionnalité
npm install @microsoft/feature-management
Variables d'environnement
AZURE_APPCONFIG_ENDPOINT=https://<votre-ressource>.azconfig.io
# OU
AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://...;Id=...;Secret=...
AZURE_TOKEN_CREDENTIALS=prod # Requis uniquement si DefaultAzureCredential est utilisé en production
Authentification
import { AppConfigurationClient } from "@azure/app-configuration";
import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity";
// Dev local : DefaultAzureCredential. Production : définir AZURE_TOKEN_CREDENTIALS=prod ou AZURE_TOKEN_CREDENTIALS=<credential_spécifique>
const credential = new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]});
// Ou utiliser une credential spécifique directement en production :
// Voir https://learn.microsoft.com/javascript/api/overview/azure/identity-readme?view=azure-node-latest#credential-classes
// const credential = new ManagedIdentityCredential();
const client = new AppConfigurationClient(
process.env.AZURE_APPCONFIG_ENDPOINT!,
credential
);
// Chaîne de connexion
const client2 = new AppConfigurationClient(
process.env.AZURE_APPCONFIG_CONNECTION_STRING!
);
Opérations CRUD
Créer/Mettre à jour des paramètres
// Ajouter nouveau (échoue s'il existe)
await client.addConfigurationSetting({
key: "app:settings:message",
value: "Hello World",
label: "production",
contentType: "text/plain",
tags: { environment: "prod" },
});
// Définir (créer ou mettre à jour)
await client.setConfigurationSetting({
key: "app:settings:message",
value: "Updated value",
label: "production",
});
// Mettre à jour avec concurrence optimiste
const existing = await client.getConfigurationSetting({ key: "myKey" });
existing.value = "new value";
await client.setConfigurationSetting(existing, { onlyIfUnchanged: true });
Lire les paramètres
// Récupérer un paramètre unique
const setting = await client.getConfigurationSetting({
key: "app:settings:message",
label: "production", // optionnel
});
console.log(setting.value);
// Lister avec filtres
const settings = client.listConfigurationSettings({
keyFilter: "app:*",
labelFilter: "production",
});
for await (const setting of settings) {
console.log(`${setting.key}: ${setting.value}`);
}
Supprimer les paramètres
await client.deleteConfigurationSetting({
key: "app:settings:message",
label: "production",
});
Verrouiller/Déverrouiller (Lecture seule)
// Verrouiller
await client.setReadOnly({ key: "myKey", label: "prod" }, true);
// Déverrouiller
await client.setReadOnly({ key: "myKey", label: "prod" }, false);
Fournisseur App Configuration
Charger la configuration
import { load } from "@azure/app-configuration-provider";
import { DefaultAzureCredential } from "@azure/identity";
const appConfig = await load(
process.env.AZURE_APPCONFIG_ENDPOINT!,
new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]}),
{
selectors: [
{ keyFilter: "app:*", labelFilter: "production" },
],
trimKeyPrefixes: ["app:"],
}
);
// Accès de style map
const value = appConfig.get("settings:message");
// Accès de style objet
const config = appConfig.constructConfigurationObject({ separator: ":" });
console.log(config.settings.message);
Actualisation dynamique
const appConfig = await load(endpoint, credential, {
selectors: [{ keyFilter: "app:*" }],
refreshOptions: {
enabled: true,
refreshIntervalInMs: 30_000, // 30 secondes
},
});
// Déclencher l'actualisation (non-bloquant)
appConfig.refresh();
// Écouter les événements d'actualisation
const disposer = appConfig.onRefresh(() => {
console.log("Configuration actualisée !");
});
// Motif de middleware Express
app.use((req, res, next) => {
appConfig.refresh();
next();
});
Références Key Vault
const appConfig = await load(endpoint, credential, {
selectors: [{ keyFilter: "app:*" }],
keyVaultOptions: {
credential: new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]}),
secretRefreshIntervalInMs: 7200_000, // 2 heures
},
});
// Les secrets sont résolus automatiquement
const dbPassword = appConfig.get("database:password");
Drapeaux de fonctionnalité
Créer un drapeau de fonctionnalité (bas niveau)
import {
featureFlagPrefix,
featureFlagContentType,
FeatureFlagValue,
ConfigurationSetting,
} from "@azure/app-configuration";
const flag: ConfigurationSetting<FeatureFlagValue> = {
key: `${featureFlagPrefix}Beta`,
contentType: featureFlagContentType,
value: {
id: "Beta",
enabled: true,
description: "Beta feature",
conditions: {
clientFilters: [
{
name: "Microsoft.Targeting",
parameters: {
Audience: {
Users: ["user@example.com"],
Groups: [{ Name: "beta-testers", RolloutPercentage: 50 }],
DefaultRolloutPercentage: 0,
},
},
},
],
},
},
};
await client.addConfigurationSetting(flag);
Charger et évaluer les drapeaux de fonctionnalité
import { load } from "@azure/app-configuration-provider";
import {
ConfigurationMapFeatureFlagProvider,
FeatureManager,
} from "@microsoft/feature-management";
const appConfig = await load(endpoint, credential, {
featureFlagOptions: {
enabled: true,
selectors: [{ keyFilter: "*" }],
refresh: {
enabled: true,
refreshIntervalInMs: 30_000,
},
},
});
const featureProvider = new ConfigurationMapFeatureFlagProvider(appConfig);
const featureManager = new FeatureManager(featureProvider);
// Vérification simple
const isEnabled = await featureManager.isEnabled("Beta");
// Avec contexte de ciblage
const isEnabledForUser = await featureManager.isEnabled("Beta", {
userId: "user@example.com",
groups: ["beta-testers"],
});
Snapshots
// Créer un snapshot
const snapshot = await client.beginCreateSnapshotAndWait({
name: "release-v1.0",
retentionPeriod: 2592000, // 30 jours
filters: [{ keyFilter: "app:*", labelFilter: "production" }],
});
// Récupérer un snapshot
const snap = await client.getSnapshot("release-v1.0");
// Lister les paramètres dans un snapshot
const settings = client.listConfigurationSettingsForSnapshot("release-v1.0");
for await (const setting of settings) {
console.log(`${setting.key}: ${setting.value}`);
}
// Archiver/Récupérer
await client.archiveSnapshot("release-v1.0");
await client.recoverSnapshot("release-v1.0");
// Charger à partir d'un snapshot (fournisseur)
const config = await load(endpoint, credential, {
selectors: [{ snapshotName: "release-v1.0" }],
});
Étiquettes
// Créer des paramètres avec des étiquettes
await client.setConfigurationSetting({
key: "database:host",
value: "dev-db.example.com",
label: "development",
});
await client.setConfigurationSetting({
key: "database:host",
value: "prod-db.example.com",
label: "production",
});
// Filtrer par étiquette
const prodSettings = client.listConfigurationSettings({
keyFilter: "*",
labelFilter: "production",
});
// Aucune étiquette (étiquette null)
const noLabelSettings = client.listConfigurationSettings({
labelFilter: "\0",
});
// Lister les étiquettes disponibles
for await (const label of client.listLabels()) {
console.log(label.name);
}
Types de clés
import {
AppConfigurationClient,
ConfigurationSetting,
FeatureFlagValue,
SecretReferenceValue,
featureFlagPrefix,
featureFlagContentType,
secretReferenceContentType,
ListConfigurationSettingsOptions,
} from "@azure/app-configuration";
import { load } from "@azure/app-configuration-provider";
import {
FeatureManager,
ConfigurationMapFeatureFlagProvider,
} from "@microsoft/feature-management";
Bonnes pratiques
- Utiliser le fournisseur pour les applications -
@azure/app-configuration-providerpour la configuration à l'exécution - Utiliser le bas niveau pour la gestion -
@azure/app-configurationpour les opérations CRUD - Activer l'actualisation - Pour les mises à jour de configuration dynamique
- Utiliser les étiquettes - Séparer les configurations par environnement
- Utiliser les snapshots - Pour les configurations de version immuables
- Motif sentinel - Utiliser une clé sentinel pour déclencher une actualisation complète
- Rôles RBAC -
App Configuration Data Readerpour l'accès en lecture seule