GitHub Copilot
ChatGPT
Claude
Codex CLI
Cursor
opencode
Skill
Text
azure-appconfiguration-ts
Build applications using Azure App Configuration SDK for JavaScript (@azure/app-configuration). Use when working with configuration settings, feature flags, Key Vault references, dynamic refresh, or centralized configuration management.
Virus-scanned
Reviewed automatically before listing.
Download
microsoft-skills-.github_plugins_azure-sdk-typescript_skills_azure-appconfiguration-ts-e58528d.zip · 2 KB
Install
skills CLI
npx skills add https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-typescript/skills/azure-appconfiguration-ts
Claude Code
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
Git
git clone https://github.com/microsoft/skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole microsoft/skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Azure App Configuration SDK for TypeScript
Centralized configuration management with feature flags and dynamic refresh.
Installation
# Low-level CRUD SDK
npm install @azure/app-configuration @azure/identity
# High-level provider (recommended for apps)
npm install @azure/app-configuration-provider @azure/identity
# Feature flag management
npm install @microsoft/feature-management
Environment Variables
AZURE_APPCONFIG_ENDPOINT=https://<your-resource>.azconfig.io
# OR
AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://...;Id=...;Secret=...
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production
Authentication
import { AppConfigurationClient } from "@azure/app-configuration";
import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity";
// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
const credential = new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]});
// Or use a specific credential directly in production:
// See 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
);
// Connection string
const client2 = new AppConfigurationClient(
process.env.AZURE_APPCONFIG_CONNECTION_STRING!
);
CRUD Operations
Create/Update Settings
// Add new (fails if exists)
await client.addConfigurationSetting({
key: "app:settings:message",
value: "Hello World",
label: "production",
contentType: "text/plain",
tags: { environment: "prod" },
});
// Set (create or update)
await client.setConfigurationSetting({
key: "app:settings:message",
value: "Updated value",
label: "production",
});
// Update with optimistic concurrency
const existing = await client.getConfigurationSetting({ key: "myKey" });
existing.value = "new value";
await client.setConfigurationSetting(existing, { onlyIfUnchanged: true });
Read Settings
// Get single setting
const setting = await client.getConfigurationSetting({
key: "app:settings:message",
label: "production", // optional
});
console.log(setting.value);
// List with filters
const settings = client.listConfigurationSettings({
keyFilter: "app:*",
labelFilter: "production",
});
for await (const setting of settings) {
console.log(`${setting.key}: ${setting.value}`);
}
Delete Settings
await client.deleteConfigurationSetting({
key: "app:settings:message",
label: "production",
});
Lock/Unlock (Read-Only)
// Lock
await client.setReadOnly({ key: "myKey", label: "prod" }, true);
// Unlock
await client.setReadOnly({ key: "myKey", label: "prod" }, false);
App Configuration Provider
Load 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:"],
}
);
// Map-style access
const value = appConfig.get("settings:message");
// Object-style access
const config = appConfig.constructConfigurationObject({ separator: ":" });
console.log(config.settings.message);
Dynamic Refresh
const appConfig = await load(endpoint, credential, {
selectors: [{ keyFilter: "app:*" }],
refreshOptions: {
enabled: true,
refreshIntervalInMs: 30_000, // 30 seconds
},
});
// Trigger refresh (non-blocking)
appConfig.refresh();
// Listen for refresh events
const disposer = appConfig.onRefresh(() => {
console.log("Configuration refreshed!");
});
// Express middleware pattern
app.use((req, res, next) => {
appConfig.refresh();
next();
});
Key Vault References
const appConfig = await load(endpoint, credential, {
selectors: [{ keyFilter: "app:*" }],
keyVaultOptions: {
credential: new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]}),
secretRefreshIntervalInMs: 7200_000, // 2 hours
},
});
// Secrets are automatically resolved
const dbPassword = appConfig.get("database:password");
Feature Flags
Create Feature Flag (Low-Level)
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);
Load and Evaluate Feature Flags
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);
// Simple check
const isEnabled = await featureManager.isEnabled("Beta");
// With targeting context
const isEnabledForUser = await featureManager.isEnabled("Beta", {
userId: "user@example.com",
groups: ["beta-testers"],
});
Snapshots
// Create snapshot
const snapshot = await client.beginCreateSnapshotAndWait({
name: "release-v1.0",
retentionPeriod: 2592000, // 30 days
filters: [{ keyFilter: "app:*", labelFilter: "production" }],
});
// Get snapshot
const snap = await client.getSnapshot("release-v1.0");
// List settings in snapshot
const settings = client.listConfigurationSettingsForSnapshot("release-v1.0");
for await (const setting of settings) {
console.log(`${setting.key}: ${setting.value}`);
}
// Archive/recover
await client.archiveSnapshot("release-v1.0");
await client.recoverSnapshot("release-v1.0");
// Load from snapshot (provider)
const config = await load(endpoint, credential, {
selectors: [{ snapshotName: "release-v1.0" }],
});
Labels
// Create settings with labels
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",
});
// Filter by label
const prodSettings = client.listConfigurationSettings({
keyFilter: "*",
labelFilter: "production",
});
// No label (null label)
const noLabelSettings = client.listConfigurationSettings({
labelFilter: "\0",
});
// List available labels
for await (const label of client.listLabels()) {
console.log(label.name);
}
Key Types
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";
Best Practices
- Use provider for apps -
@azure/app-configuration-providerfor runtime config - Use low-level for management -
@azure/app-configurationfor CRUD operations - Enable refresh - For dynamic configuration updates
- Use labels - Separate configurations by environment
- Use snapshots - For immutable release configurations
- Sentinel pattern - Use a sentinel key to trigger full refresh
- RBAC roles -
App Configuration Data Readerfor read-only access
Files (skills)
-
SKILL.md 8.7 KB
--- name: azure-appconfiguration-ts description: Build applications using Azure App Configuration SDK for JavaScript (@azure/app-configuration). Use when working with configuration settings, feature flags, Key Vault references, dynamic refresh, or centralized configuration management. license: MIT metadata: author: Microsoft version: "1.0.0" package: '@azure/app-configuration' --- # Azure App Configuration SDK for TypeScript Centralized configuration management with feature flags and dynamic refresh. ## Installation ```bash # Low-level CRUD SDK npm install @azure/app-configuration @azure/identity # High-level provider (recommended for apps) npm install @azure/app-configuration-provider @azure/identity # Feature flag management npm install @microsoft/feature-management ``` ## Environment Variables ```bash AZURE_APPCONFIG_ENDPOINT=https://<your-resource>.azconfig.io # OR AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://...;Id=...;Secret=... AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production ``` ## Authentication ```typescript import { AppConfigurationClient } from "@azure/app-configuration"; import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity"; // Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential> const credential = new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]}); // Or use a specific credential directly in production: // See 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 ); // Connection string const client2 = new AppConfigurationClient( process.env.AZURE_APPCONFIG_CONNECTION_STRING! ); ``` ## CRUD Operations ### Create/Update Settings ```typescript // Add new (fails if exists) await client.addConfigurationSetting({ key: "app:settings:message", value: "Hello World", label: "production", contentType: "text/plain", tags: { environment: "prod" }, }); // Set (create or update) await client.setConfigurationSetting({ key: "app:settings:message", value: "Updated value", label: "production", }); // Update with optimistic concurrency const existing = await client.getConfigurationSetting({ key: "myKey" }); existing.value = "new value"; await client.setConfigurationSetting(existing, { onlyIfUnchanged: true }); ``` ### Read Settings ```typescript // Get single setting const setting = await client.getConfigurationSetting({ key: "app:settings:message", label: "production", // optional }); console.log(setting.value); // List with filters const settings = client.listConfigurationSettings({ keyFilter: "app:*", labelFilter: "production", }); for await (const setting of settings) { console.log(`${setting.key}: ${setting.value}`); } ``` ### Delete Settings ```typescript await client.deleteConfigurationSetting({ key: "app:settings:message", label: "production", }); ``` ### Lock/Unlock (Read-Only) ```typescript // Lock await client.setReadOnly({ key: "myKey", label: "prod" }, true); // Unlock await client.setReadOnly({ key: "myKey", label: "prod" }, false); ``` ## App Configuration Provider ### Load Configuration ```typescript 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:"], } ); // Map-style access const value = appConfig.get("settings:message"); // Object-style access const config = appConfig.constructConfigurationObject({ separator: ":" }); console.log(config.settings.message); ``` ### Dynamic Refresh ```typescript const appConfig = await load(endpoint, credential, { selectors: [{ keyFilter: "app:*" }], refreshOptions: { enabled: true, refreshIntervalInMs: 30_000, // 30 seconds }, }); // Trigger refresh (non-blocking) appConfig.refresh(); // Listen for refresh events const disposer = appConfig.onRefresh(() => { console.log("Configuration refreshed!"); }); // Express middleware pattern app.use((req, res, next) => { appConfig.refresh(); next(); }); ``` ### Key Vault References ```typescript const appConfig = await load(endpoint, credential, { selectors: [{ keyFilter: "app:*" }], keyVaultOptions: { credential: new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]}), secretRefreshIntervalInMs: 7200_000, // 2 hours }, }); // Secrets are automatically resolved const dbPassword = appConfig.get("database:password"); ``` ## Feature Flags ### Create Feature Flag (Low-Level) ```typescript 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); ``` ### Load and Evaluate Feature Flags ```typescript 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); // Simple check const isEnabled = await featureManager.isEnabled("Beta"); // With targeting context const isEnabledForUser = await featureManager.isEnabled("Beta", { userId: "user@example.com", groups: ["beta-testers"], }); ``` ## Snapshots ```typescript // Create snapshot const snapshot = await client.beginCreateSnapshotAndWait({ name: "release-v1.0", retentionPeriod: 2592000, // 30 days filters: [{ keyFilter: "app:*", labelFilter: "production" }], }); // Get snapshot const snap = await client.getSnapshot("release-v1.0"); // List settings in snapshot const settings = client.listConfigurationSettingsForSnapshot("release-v1.0"); for await (const setting of settings) { console.log(`${setting.key}: ${setting.value}`); } // Archive/recover await client.archiveSnapshot("release-v1.0"); await client.recoverSnapshot("release-v1.0"); // Load from snapshot (provider) const config = await load(endpoint, credential, { selectors: [{ snapshotName: "release-v1.0" }], }); ``` ## Labels ```typescript // Create settings with labels 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", }); // Filter by label const prodSettings = client.listConfigurationSettings({ keyFilter: "*", labelFilter: "production", }); // No label (null label) const noLabelSettings = client.listConfigurationSettings({ labelFilter: "\0", }); // List available labels for await (const label of client.listLabels()) { console.log(label.name); } ``` ## Key Types ```typescript 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"; ``` ## Best Practices 1. **Use provider for apps** - `@azure/app-configuration-provider` for runtime config 2. **Use low-level for management** - `@azure/app-configuration` for CRUD operations 3. **Enable refresh** - For dynamic configuration updates 4. **Use labels** - Separate configurations by environment 5. **Use snapshots** - For immutable release configurations 6. **Sentinel pattern** - Use a sentinel key to trigger full refresh 7. **RBAC roles** - `App Configuration Data Reader` for read-only access
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.