azure-appconfiguration-ts

Créez des applications à l'aide du SDK Azure App Configuration pour JavaScript (`@azure/app-configuration`). À utiliser pour travailler avec des paramètres de configuration, des feature flags, des références Key Vault, le rafraîchissement dynamique ou la gestion centralisée de la configuration.

npx skills add https://github.com/microsoft/skills --skill azure-appconfiguration-ts

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

  1. Utiliser le fournisseur pour les applications - @azure/app-configuration-provider pour la configuration à l'exécution
  2. Utiliser le bas niveau pour la gestion - @azure/app-configuration pour les opérations CRUD
  3. Activer l'actualisation - Pour les mises à jour de configuration dynamique
  4. Utiliser les étiquettes - Séparer les configurations par environnement
  5. Utiliser les snapshots - Pour les configurations de version immuables
  6. Motif sentinel - Utiliser une clé sentinel pour déclencher une actualisation complète
  7. Rôles RBAC - App Configuration Data Reader pour l'accès en lecture seule

Skills similaires