Azure Appconfiguration Java
MicrosoftOfficialCreated by Microsoft
- Skill
- Tool integration
- Cloud and DevOps
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The Azure App Configuration SDK for Java provides a robust client library for centralizing application configuration management. It enables developers to store and retrieve key-value settings, manage feature flags for gradual rollouts, and create immutable snapshots of configuration states. The library supports both synchronous and asynchronous operations, integrates with Azure Identity for secure authentication, and provides advanced features like conditional updates, secret references to Key Vault, and read-only protection for critical settings.
What it does
- Provides a ConfigurationClient for CRUD operations on application settings.
- Supports feature flag management with client-side filtering.
- Enables point-in-time configuration snapshots for release management.
- Integrates with Azure Key Vault for secure secret referencing.
- Offers asynchronous client support for high-throughput applications.
- Implements optimistic concurrency control using ETags.
When to use it
- When centralizing configuration across multiple microservices or environments.
- When implementing feature flags for A/B testing or gradual feature rollouts.
- When requiring immutable configuration states for specific application releases.
- When managing sensitive configuration data via Azure Key Vault integration.
- When needing to separate configuration by environment using labels.
Advantages
- Centralized management reduces configuration drift across environments.
- Supports secure authentication via Entra ID (formerly Azure AD).
- Optimistic concurrency prevents accidental overwrites of shared settings.
- Flexible filtering allows for complex environment-based configuration strategies.
- Native support for both sync and async programming models.
Usage examples
- “How do I create a ConfigurationClient in Java using Entra ID?”
- The agent provides a code snippet using DefaultAzureCredentialBuilder and the ConfigurationClientBuilder to securely connect to the App Configuration endpoint.
- “Show me how to list all settings with the label 'Production'.”
- The agent demonstrates using a SettingSelector with a label filter to retrieve and iterate through the relevant configuration settings.
- “How can I implement a feature flag with a percentage filter?”
- The agent provides an example of creating a FeatureFlagConfigurationSetting with a Microsoft.Percentage filter parameter.
- “How do I perform a conditional update to a setting?”
- The agent explains using setConfigurationSettingWithResponse with the ifUnchanged flag to ensure the update only occurs if the ETag matches.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/microsoft/azure-appconfiguration-java/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip azure-appconfiguration-java.zip -d .agents/skills
Documentation by Microsoft
Azure App Configuration SDK for Java
Client library for Azure App Configuration, a managed service for centralizing application configurations.
Installation
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-appconfiguration</artifactId>
<version>1.8.0</version>
</dependency>Or use Azure SDK BOM:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-sdk-bom</artifactId>
<version>{bom_version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-appconfiguration</artifactId>
</dependency>
</dependencies>Prerequisites
Azure App Configuration store
Connection string or Entra ID credentials
Environment Variables
AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://<store>.azconfig.io;Id=<id>;Secret=<secret> # Alternative to Entra ID auth
AZURE_APPCONFIG_ENDPOINT=https://<store>.azconfig.io # Required for all auth methods
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in productionClient Creation
With Connection String
import com.azure.data.appconfiguration.ConfigurationClient;
import com.azure.data.appconfiguration.ConfigurationClientBuilder;
ConfigurationClient configClient = new ConfigurationClientBuilder()
.connectionString(System.getenv("AZURE_APPCONFIG_CONNECTION_STRING"))
.buildClient();Async Client
import com.azure.data.appconfiguration.ConfigurationAsyncClient;
ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
.connectionString(connectionString)
.buildAsyncClient();With Entra ID (Recommended)
import com.azure.core.credential.TokenCredential;
import com.azure.identity.AzureIdentityEnvVars;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.ManagedIdentityCredentialBuilder;
// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
TokenCredential credential = new DefaultAzureCredentialBuilder()
.requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS)
.build();
// Or use a specific credential directly in production:
// See https://learn.microsoft.com/java/api/overview/azure/identity-readme?view=azure-java-stable#credential-classes
// TokenCredential credential = new ManagedIdentityCredentialBuilder().build();
ConfigurationClient configClient = new ConfigurationClientBuilder()
.credential(credential)
.endpoint(System.getenv("AZURE_APPCONFIG_ENDPOINT"))
.buildClient();Key Concepts
| Concept | Description |
|---|---|
| Configuration Setting | Key-value pair with optional label |
| Label | Dimension for separating settings (e.g., environments) |
| Feature Flag | Special setting for feature management |
| Secret Reference | Setting pointing to Key Vault secret |
| Snapshot | Point-in-time immutable view of settings |
Configuration Setting Operations
Create Setting (Add)
Creates only if setting doesn't exist:
import com.azure.data.appconfiguration.models.ConfigurationSetting;
ConfigurationSetting setting = configClient.addConfigurationSetting(
"app/database/connection",
"Production",
"Server=prod.db.com;Database=myapp"
);Create or Update Setting (Set)
Creates or overwrites:
ConfigurationSetting setting = configClient.setConfigurationSetting(
"app/cache/enabled",
"Production",
"true"
);Get Setting
ConfigurationSetting setting = configClient.getConfigurationSetting(
"app/database/connection",
"Production"
);
System.out.println("Value: " + setting.getValue());
System.out.println("Content-Type: " + setting.getContentType());
System.out.println("Last Modified: " + setting.getLastModified());Conditional Get (If Changed)
import com.azure.core.http.rest.Response;
import com.azure.core.util.Context;
Response<ConfigurationSetting> response = configClient.getConfigurationSettingWithResponse(
setting, // Setting with ETag
null, // Accept datetime
true, // ifChanged - only fetch if modified
Context.NONE
);
if (response.getStatusCode() == 304) {
System.out.println("Setting not modified");
} else {
ConfigurationSetting updated = response.getValue();
}Update Setting
ConfigurationSetting updated = configClient.setConfigurationSetting(
"app/cache/enabled",
"Production",
"false"
);Conditional Update (If Unchanged)
// Only update if ETag matches (no concurrent modifications)
Response<ConfigurationSetting> response = configClient.setConfigurationSettingWithResponse(
setting, // Setting with current ETag
true, // ifUnchanged
Context.NONE
);Delete Setting
ConfigurationSetting deleted = configClient.deleteConfigurationSetting(
"app/cache/enabled",
"Production"
);Conditional Delete
Response<ConfigurationSetting> response = configClient.deleteConfigurationSettingWithResponse(
setting, // Setting with ETag
true, // ifUnchanged
Context.NONE
);List and Filter Settings
List by Key Pattern
import com.azure.data.appconfiguration.models.SettingSelector;
import com.azure.core.http.rest.PagedIterable;
SettingSelector selector = new SettingSelector()
.setKeyFilter("app/*");
PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);
for (ConfigurationSetting s : settings) {
System.out.println(s.getKey() + " = " + s.getValue());
}List by Label
SettingSelector selector = new SettingSelector()
.setKeyFilter("*")
.setLabelFilter("Production");
PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);List by Multiple Keys
SettingSelector selector = new SettingSelector()
.setKeyFilter("app/database/*,app/cache/*");
PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);List Revisions
SettingSelector selector = new SettingSelector()
.setKeyFilter("app/database/connection");
PagedIterable<ConfigurationSetting> revisions = configClient.listRevisions(selector);
for (ConfigurationSetting revision : revisions) {
System.out.println("Value: " + revision.getValue() + ", Modified: " + revision.getLastModified());
}Feature Flags
Create Feature Flag
import com.azure.data.appconfiguration.models.FeatureFlagConfigurationSetting;
import com.azure.data.appconfiguration.models.FeatureFlagFilter;
import java.util.Arrays;
FeatureFlagFilter percentageFilter = new FeatureFlagFilter("Microsoft.Percentage")
.addParameter("Value", 50);
FeatureFlagConfigurationSetting featureFlag = new FeatureFlagConfigurationSetting("beta-feature", true)
.setDescription("Beta feature rollout")
.setClientFilters(Arrays.asList(percentageFilter));
FeatureFlagConfigurationSetting created = (FeatureFlagConfigurationSetting)
configClient.addConfigurationSetting(featureFlag);Get Feature Flag
FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting)
configClient.getConfigurationSetting(featureFlag);
System.out.println("Feature: " + flag.getFeatureId());
System.out.println("Enabled: " + flag.isEnabled());
System.out.println("Filters: " + flag.getClientFilters());Update Feature Flag
featureFlag.setEnabled(false);
FeatureFlagConfigurationSetting updated = (FeatureFlagConfigurationSetting)
configClient.setConfigurationSetting(featureFlag);Secret References
Create Secret Reference
import com.azure.data.appconfiguration.models.SecretReferenceConfigurationSetting;
SecretReferenceConfigurationSetting secretRef = new SecretReferenceConfigurationSetting(
"app/secrets/api-key",
"https://myvault.vault.azure.net/secrets/api-key"
);
SecretReferenceConfigurationSetting created = (SecretReferenceConfigurationSetting)
configClient.addConfigurationSetting(secretRef);Get Secret Reference
SecretReferenceConfigurationSetting ref = (SecretReferenceConfigurationSetting)
configClient.getConfigurationSetting(secretRef);
System.out.println("Secret URI: " + ref.getSecretId());Read-Only Settings
Set Read-Only
ConfigurationSetting readOnly = configClient.setReadOnly(
"app/critical/setting",
"Production",
true
);Clear Read-Only
ConfigurationSetting writable = configClient.setReadOnly(
"app/critical/setting",
"Production",
false
);Snapshots
Create Snapshot
import com.azure.data.appconfiguration.models.ConfigurationSnapshot;
import com.azure.data.appconfiguration.models.ConfigurationSettingsFilter;
import com.azure.core.util.polling.SyncPoller;
import com.azure.core.util.polling.PollOperationDetails;
List<ConfigurationSettingsFilter> filters = new ArrayList<>();
filters.add(new ConfigurationSettingsFilter("app/*"));
SyncPoller<PollOperationDetails, ConfigurationSnapshot> poller = configClient.beginCreateSnapshot(
"release-v1.0",
new ConfigurationSnapshot(filters),
Context.NONE
);
poller.setPollInterval(Duration.ofSeconds(10));
poller.waitForCompletion();
ConfigurationSnapshot snapshot = poller.getFinalResult();
System.out.println("Snapshot: " + snapshot.getName() + ", Status: " + snapshot.getStatus());Get Snapshot
ConfigurationSnapshot snapshot = configClient.getSnapshot("release-v1.0");
System.out.println("Created: " + snapshot.getCreatedAt());
System.out.println("Items: " + snapshot.getItemCount());List Settings in Snapshot
PagedIterable<ConfigurationSetting> settings =
configClient.listConfigurationSettingsForSnapshot("release-v1.0");
for (ConfigurationSetting setting : settings) {
System.out.println(setting.getKey() + " = " + setting.getValue());
}Archive Snapshot
ConfigurationSnapshot archived = configClient.archiveSnapshot("release-v1.0");
System.out.println("Status: " + archived.getStatus()); // archivedRecover Snapshot
ConfigurationSnapshot recovered = configClient.recoverSnapshot("release-v1.0");
System.out.println("Status: " + recovered.getStatus()); // readyList All Snapshots
import com.azure.data.appconfiguration.models.SnapshotSelector;
SnapshotSelector selector = new SnapshotSelector().setNameFilter("release-*");
PagedIterable<ConfigurationSnapshot> snapshots = configClient.listSnapshots(selector);
for (ConfigurationSnapshot snap : snapshots) {
System.out.println(snap.getName() + " - " + snap.getStatus());
}Labels
List Labels
import com.azure.data.appconfiguration.models.SettingLabelSelector;
configClient.listLabels(new SettingLabelSelector().setNameFilter("*"))
.forEach(label -> System.out.println("Label: " + label.getName()));Async Operations
ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
.connectionString(connectionString)
.buildAsyncClient();
// Async list with reactive streams
asyncClient.listConfigurationSettings(new SettingSelector().setLabelFilter("Production"))
.subscribe(
setting -> System.out.println(setting.getKey() + " = " + setting.getValue()),
error -> System.err.println("Error: " + error.getMessage()),
() -> System.out.println("Completed")
);Error Handling
import com.azure.core.exception.HttpResponseException;
try {
configClient.getConfigurationSetting("nonexistent", null);
} catch (HttpResponseException e) {
if (e.getResponse().getStatusCode() == 404) {
System.err.println("Setting not found");
} else {
System.err.println("Error: " + e.getMessage());
}
}Best Practices
Use labels — Separate configurations by environment (Dev, Staging, Production)
Use snapshots — Create immutable snapshots for releases
Feature flags — Use for gradual rollouts and A/B testing
Secret references — Store sensitive values in Key Vault
Conditional requests — Use ETags for optimistic concurrency
Read-only protection — Lock critical production settings
Use Entra ID — Preferred over connection strings
Async client — Use for high-throughput scenarios
Reference Links
Files
- ATTRIBUTION.mdAdded by AutoGineer988 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md13.6 KiB
- references/examples.md25.2 KiB
references/examples.md
Azure App Configuration Java SDK - Examples
Comprehensive code examples for the Azure App Configuration SDK for Java.
Table of Contents
Maven Dependency
Client Creation
Configuration Settings CRUD
List and Filter Settings
Feature Flags
Secret References
Read-Only Settings
Snapshots
Labels
Async Operations
Error Handling
Complete Application Example
Maven Dependency
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-appconfiguration</artifactId>
<version>1.8.0</version>
</dependency>
<!-- For DefaultAzureCredential -->
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.14.2</version>
</dependency>Or use Azure SDK BOM:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-sdk-bom</artifactId>
<version>1.2.28</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-appconfiguration</artifactId>
</dependency>
</dependencies>Client Creation
With Connection String
import com.azure.data.appconfiguration.ConfigurationClient;
import com.azure.data.appconfiguration.ConfigurationClientBuilder;
String connectionString = System.getenv("AZURE_APPCONFIG_CONNECTION_STRING");
ConfigurationClient client = new ConfigurationClientBuilder()
.connectionString(connectionString)
.buildClient();With Entra ID (Recommended)
import com.azure.identity.DefaultAzureCredentialBuilder;
String endpoint = System.getenv("AZURE_APPCONFIG_ENDPOINT");
ConfigurationClient client = new ConfigurationClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(endpoint)
.buildClient();Async Client
import com.azure.data.appconfiguration.ConfigurationAsyncClient;
ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(endpoint)
.buildAsyncClient();Configuration Settings CRUD
Create Setting (Add)
Creates only if setting doesn't exist:
import com.azure.data.appconfiguration.models.ConfigurationSetting;
// Add with key, label, and value
ConfigurationSetting setting = client.addConfigurationSetting(
"app/database/connection", // key
"Production", // label (can be null)
"Server=prod.db.com;Database=myapp" // value
);
System.out.println("Setting created:");
System.out.println(" Key: " + setting.getKey());
System.out.println(" Label: " + setting.getLabel());
System.out.println(" Value: " + setting.getValue());
System.out.println(" ETag: " + setting.getETag());Create or Update Setting (Set)
Creates or overwrites:
ConfigurationSetting setting = client.setConfigurationSetting(
"app/cache/enabled",
"Production",
"true"
);
System.out.println("Setting set: " + setting.getKey() + " = " + setting.getValue());Create with ConfigurationSetting Object
ConfigurationSetting newSetting = new ConfigurationSetting()
.setKey("app/feature/timeout")
.setLabel("Production")
.setValue("30000")
.setContentType("application/json");
ConfigurationSetting created = client.addConfigurationSetting(newSetting);Get Setting
ConfigurationSetting setting = client.getConfigurationSetting(
"app/database/connection",
"Production"
);
System.out.println("=== Setting Details ===");
System.out.println("Key: " + setting.getKey());
System.out.println("Label: " + setting.getLabel());
System.out.println("Value: " + setting.getValue());
System.out.println("Content-Type: " + setting.getContentType());
System.out.println("Last Modified: " + setting.getLastModified());
System.out.println("ETag: " + setting.getETag());
System.out.println("Read-Only: " + setting.isReadOnly());Conditional Get (If Changed)
Only fetch if modified since last retrieval:
import com.azure.core.http.rest.Response;
import com.azure.core.util.Context;
// First, get the setting with its ETag
ConfigurationSetting setting = client.getConfigurationSetting("app/cache/enabled", "Production");
// Later, check if it changed
Response<ConfigurationSetting> response = client.getConfigurationSettingWithResponse(
setting, // Setting with ETag
null, // Accept datetime
true, // ifChanged - only fetch if modified
Context.NONE
);
if (response.getStatusCode() == 304) {
System.out.println("Setting not modified since last fetch");
} else {
ConfigurationSetting updated = response.getValue();
System.out.println("Setting was modified: " + updated.getValue());
}Update Setting
// Simple update
ConfigurationSetting updated = client.setConfigurationSetting(
"app/cache/enabled",
"Production",
"false"
);
System.out.println("Updated value: " + updated.getValue());Conditional Update (If Unchanged)
Only update if no concurrent modifications:
// Get current setting with ETag
ConfigurationSetting current = client.getConfigurationSetting("app/timeout", "Production");
// Modify the value
current.setValue("60000");
// Update only if ETag matches (optimistic concurrency)
Response<ConfigurationSetting> response = client.setConfigurationSettingWithResponse(
current, // Setting with current ETag
true, // ifUnchanged - only update if ETag matches
Context.NONE
);
if (response.getStatusCode() == 200) {
System.out.println("Update successful");
} else {
System.out.println("Conflict - setting was modified by another process");
}Delete Setting
ConfigurationSetting deleted = client.deleteConfigurationSetting(
"app/cache/enabled",
"Production"
);
if (deleted != null) {
System.out.println("Deleted setting: " + deleted.getKey());
}Conditional Delete
Response<ConfigurationSetting> response = client.deleteConfigurationSettingWithResponse(
setting, // Setting with ETag
true, // ifUnchanged
Context.NONE
);
if (response.getStatusCode() == 200) {
System.out.println("Setting deleted");
}List and Filter Settings
List All Settings
import com.azure.data.appconfiguration.models.SettingSelector;
import com.azure.core.http.rest.PagedIterable;
PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(
new SettingSelector()
);
System.out.println("=== All Settings ===");
for (ConfigurationSetting s : settings) {
System.out.printf("%s [%s] = %s%n", s.getKey(), s.getLabel(), s.getValue());
}List by Key Pattern
SettingSelector selector = new SettingSelector()
.setKeyFilter("app/*"); // Wildcard pattern
PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);
for (ConfigurationSetting s : settings) {
System.out.println(s.getKey() + " = " + s.getValue());
}List by Label
SettingSelector selector = new SettingSelector()
.setKeyFilter("*")
.setLabelFilter("Production");
PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);List by Multiple Keys
SettingSelector selector = new SettingSelector()
.setKeyFilter("app/database/*,app/cache/*"); // Comma-separated patterns
PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);List Null Labels Only
SettingSelector selector = new SettingSelector()
.setKeyFilter("*")
.setLabelFilter("\0"); // Null label filter
PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);Select Specific Fields
import com.azure.data.appconfiguration.models.SettingFields;
import java.util.EnumSet;
SettingSelector selector = new SettingSelector()
.setKeyFilter("*")
.setFields(EnumSet.of(SettingFields.KEY, SettingFields.VALUE, SettingFields.LAST_MODIFIED));
PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);List Revisions
View history of changes:
SettingSelector selector = new SettingSelector()
.setKeyFilter("app/database/connection");
PagedIterable<ConfigurationSetting> revisions = client.listRevisions(selector);
System.out.println("=== Setting Revisions ===");
for (ConfigurationSetting revision : revisions) {
System.out.printf("Value: %s, Modified: %s%n",
revision.getValue(),
revision.getLastModified());
}Feature Flags
Create Feature Flag
import com.azure.data.appconfiguration.models.FeatureFlagConfigurationSetting;
import com.azure.data.appconfiguration.models.FeatureFlagFilter;
import java.util.Arrays;
// Simple feature flag
FeatureFlagConfigurationSetting simpleFlag = new FeatureFlagConfigurationSetting("dark-mode", true)
.setDescription("Enable dark mode theme");
client.addConfigurationSetting(simpleFlag);
// Feature flag with percentage filter
FeatureFlagFilter percentageFilter = new FeatureFlagFilter("Microsoft.Percentage")
.addParameter("Value", 50); // 50% rollout
FeatureFlagConfigurationSetting betaFlag = new FeatureFlagConfigurationSetting("beta-feature", true)
.setDescription("Beta feature with gradual rollout")
.setClientFilters(Arrays.asList(percentageFilter));
FeatureFlagConfigurationSetting created = (FeatureFlagConfigurationSetting)
client.addConfigurationSetting(betaFlag);
System.out.println("Feature flag created: " + created.getFeatureId());Create Feature Flag with Targeting Filter
import java.util.HashMap;
import java.util.Map;
Map<String, Object> targetingParams = new HashMap<>();
targetingParams.put("Audience", Map.of(
"Users", Arrays.asList("[email protected]", "[email protected]"),
"Groups", Arrays.asList(
Map.of("Name", "beta-testers", "RolloutPercentage", 100),
Map.of("Name", "employees", "RolloutPercentage", 50)
),
"DefaultRolloutPercentage", 10
));
FeatureFlagFilter targetingFilter = new FeatureFlagFilter("Microsoft.Targeting")
.setParameters(targetingParams);
FeatureFlagConfigurationSetting targetedFlag = new FeatureFlagConfigurationSetting("new-dashboard", true)
.setDescription("New dashboard with targeted rollout")
.setClientFilters(Arrays.asList(targetingFilter));
client.addConfigurationSetting(targetedFlag);Get Feature Flag
FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting)
client.getConfigurationSetting(
".appconfig.featureflag/beta-feature", // Key format for feature flags
null
);
System.out.println("=== Feature Flag ===");
System.out.println("Feature ID: " + flag.getFeatureId());
System.out.println("Enabled: " + flag.isEnabled());
System.out.println("Description: " + flag.getDescription());
System.out.println("Filters: " + flag.getClientFilters());Update Feature Flag
FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting)
client.getConfigurationSetting(".appconfig.featureflag/beta-feature", null);
// Disable the feature
flag.setEnabled(false);
FeatureFlagConfigurationSetting updated = (FeatureFlagConfigurationSetting)
client.setConfigurationSetting(flag);
System.out.println("Feature flag updated. Enabled: " + updated.isEnabled());List Feature Flags
SettingSelector selector = new SettingSelector()
.setKeyFilter(".appconfig.featureflag/*");
PagedIterable<ConfigurationSetting> flags = client.listConfigurationSettings(selector);
System.out.println("=== Feature Flags ===");
for (ConfigurationSetting setting : flags) {
if (setting instanceof FeatureFlagConfigurationSetting) {
FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting) setting;
System.out.printf("%s: %s%n", flag.getFeatureId(), flag.isEnabled() ? "ON" : "OFF");
}
}Secret References
Create Secret Reference
import com.azure.data.appconfiguration.models.SecretReferenceConfigurationSetting;
SecretReferenceConfigurationSetting secretRef = new SecretReferenceConfigurationSetting(
"app/secrets/api-key", // Key
"https://myvault.vault.azure.net/secrets/api-key" // Key Vault secret URI
);
SecretReferenceConfigurationSetting created = (SecretReferenceConfigurationSetting)
client.addConfigurationSetting(secretRef);
System.out.println("Secret reference created: " + created.getKey());
System.out.println("Points to: " + created.getSecretId());Get Secret Reference
SecretReferenceConfigurationSetting ref = (SecretReferenceConfigurationSetting)
client.getConfigurationSetting("app/secrets/api-key", null);
System.out.println("Secret URI: " + ref.getSecretId());
// To get the actual secret value, use Key Vault SDK
// SecretClient kvClient = new SecretClientBuilder()...
// KeyVaultSecret secret = kvClient.getSecret("api-key");Update Secret Reference
SecretReferenceConfigurationSetting ref = (SecretReferenceConfigurationSetting)
client.getConfigurationSetting("app/secrets/api-key", null);
// Point to a different secret version
ref.setSecretId("https://myvault.vault.azure.net/secrets/api-key/abc123");
client.setConfigurationSetting(ref);Read-Only Settings
Set Read-Only
ConfigurationSetting readOnly = client.setReadOnly(
"app/critical/setting",
"Production",
true // isReadOnly
);
System.out.println("Setting is now read-only: " + readOnly.isReadOnly());Clear Read-Only
ConfigurationSetting writable = client.setReadOnly(
"app/critical/setting",
"Production",
false // make writable
);
System.out.println("Setting is writable: " + !writable.isReadOnly());Snapshots
Create Snapshot
import com.azure.data.appconfiguration.models.ConfigurationSnapshot;
import com.azure.data.appconfiguration.models.ConfigurationSettingsFilter;
import com.azure.core.util.polling.SyncPoller;
import com.azure.core.util.polling.PollOperationDetails;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
List<ConfigurationSettingsFilter> filters = new ArrayList<>();
filters.add(new ConfigurationSettingsFilter("app/*")); // Include all app/* keys
SyncPoller<PollOperationDetails, ConfigurationSnapshot> poller = client.beginCreateSnapshot(
"release-v1.0",
new ConfigurationSnapshot(filters),
Context.NONE
);
poller.setPollInterval(Duration.ofSeconds(10));
poller.waitForCompletion();
ConfigurationSnapshot snapshot = poller.getFinalResult();
System.out.println("=== Snapshot Created ===");
System.out.println("Name: " + snapshot.getName());
System.out.println("Status: " + snapshot.getStatus());
System.out.println("Item Count: " + snapshot.getItemCount());
System.out.println("Size: " + snapshot.getSizeInBytes() + " bytes");
System.out.println("Created: " + snapshot.getCreatedAt());Get Snapshot
ConfigurationSnapshot snapshot = client.getSnapshot("release-v1.0");
System.out.println("Snapshot: " + snapshot.getName());
System.out.println("Status: " + snapshot.getStatus());
System.out.println("Items: " + snapshot.getItemCount());
System.out.println("Retention: " + snapshot.getRetentionPeriod());List Settings in Snapshot
PagedIterable<ConfigurationSetting> settings =
client.listConfigurationSettingsForSnapshot("release-v1.0");
System.out.println("=== Settings in Snapshot ===");
for (ConfigurationSetting setting : settings) {
System.out.printf("%s = %s%n", setting.getKey(), setting.getValue());
}Archive Snapshot
ConfigurationSnapshot archived = client.archiveSnapshot("release-v1.0");
System.out.println("Status: " + archived.getStatus()); // archivedRecover Snapshot
ConfigurationSnapshot recovered = client.recoverSnapshot("release-v1.0");
System.out.println("Status: " + recovered.getStatus()); // readyList All Snapshots
import com.azure.data.appconfiguration.models.SnapshotSelector;
SnapshotSelector selector = new SnapshotSelector()
.setNameFilter("release-*");
PagedIterable<ConfigurationSnapshot> snapshots = client.listSnapshots(selector);
System.out.println("=== Snapshots ===");
for (ConfigurationSnapshot snap : snapshots) {
System.out.printf("%s - %s (%d items)%n",
snap.getName(),
snap.getStatus(),
snap.getItemCount());
}Labels
List Labels
import com.azure.data.appconfiguration.models.SettingLabelSelector;
PagedIterable<SettingLabel> labels = client.listLabels(
new SettingLabelSelector().setNameFilter("*")
);
System.out.println("=== Labels ===");
for (SettingLabel label : labels) {
System.out.println("Label: " + (label.getName() == null ? "(null)" : label.getName()));
}Async Operations
Async List with Reactive Streams
ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(endpoint)
.buildAsyncClient();
asyncClient.listConfigurationSettings(new SettingSelector().setLabelFilter("Production"))
.subscribe(
setting -> System.out.println(setting.getKey() + " = " + setting.getValue()),
error -> System.err.println("Error: " + error.getMessage()),
() -> System.out.println("Completed listing")
);
// Keep application running for async operations
Thread.sleep(5000);Async Get and Set
asyncClient.getConfigurationSetting("app/timeout", "Production")
.flatMap(setting -> {
setting.setValue("45000");
return asyncClient.setConfigurationSetting(setting);
})
.subscribe(
updated -> System.out.println("Updated: " + updated.getValue()),
error -> System.err.println("Error: " + error.getMessage())
);Error Handling
import com.azure.core.exception.HttpResponseException;
import com.azure.core.exception.ResourceNotFoundException;
try {
ConfigurationSetting setting = client.getConfigurationSetting("nonexistent", null);
} catch (ResourceNotFoundException e) {
System.err.println("Setting not found");
} catch (HttpResponseException e) {
int statusCode = e.getResponse().getStatusCode();
switch (statusCode) {
case 401:
System.err.println("Unauthorized - check credentials");
break;
case 403:
System.err.println("Forbidden - check permissions");
break;
case 409:
System.err.println("Conflict - setting already exists or ETag mismatch");
break;
case 412:
System.err.println("Precondition failed - setting was modified");
break;
case 429:
System.err.println("Rate limited - retry with backoff");
break;
default:
System.err.println("Error: " + e.getMessage());
}
}Complete Application Example
import com.azure.data.appconfiguration.ConfigurationClient;
import com.azure.data.appconfiguration.ConfigurationClientBuilder;
import com.azure.data.appconfiguration.models.*;
import com.azure.core.http.rest.PagedIterable;
import com.azure.identity.DefaultAzureCredentialBuilder;
import java.util.*;
public class AppConfigurationManager {
private final ConfigurationClient client;
private final String environment;
public AppConfigurationManager(String environment) {
this.client = new ConfigurationClientBuilder()
.endpoint(System.getenv("AZURE_APPCONFIG_ENDPOINT"))
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
this.environment = environment;
}
public String getSetting(String key) {
try {
ConfigurationSetting setting = client.getConfigurationSetting(key, environment);
return setting.getValue();
} catch (Exception e) {
// Try without label
try {
ConfigurationSetting setting = client.getConfigurationSetting(key, null);
return setting.getValue();
} catch (Exception ex) {
return null;
}
}
}
public void setSetting(String key, String value) {
client.setConfigurationSetting(key, environment, value);
}
public boolean isFeatureEnabled(String featureId) {
try {
String key = ".appconfig.featureflag/" + featureId;
ConfigurationSetting setting = client.getConfigurationSetting(key, environment);
if (setting instanceof FeatureFlagConfigurationSetting) {
return ((FeatureFlagConfigurationSetting) setting).isEnabled();
}
// Try without label
setting = client.getConfigurationSetting(key, null);
if (setting instanceof FeatureFlagConfigurationSetting) {
return ((FeatureFlagConfigurationSetting) setting).isEnabled();
}
} catch (Exception e) {
// Feature flag doesn't exist - default to disabled
}
return false;
}
public void setFeatureEnabled(String featureId, boolean enabled) {
String key = ".appconfig.featureflag/" + featureId;
try {
FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting)
client.getConfigurationSetting(key, environment);
flag.setEnabled(enabled);
client.setConfigurationSetting(flag);
} catch (Exception e) {
// Create new feature flag
FeatureFlagConfigurationSetting newFlag = new FeatureFlagConfigurationSetting(featureId, enabled);
newFlag.setLabel(environment);
client.addConfigurationSetting(newFlag);
}
}
public Map<String, String> getAllSettings(String prefix) {
Map<String, String> result = new HashMap<>();
SettingSelector selector = new SettingSelector()
.setKeyFilter(prefix + "*")
.setLabelFilter(environment);
PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);
for (ConfigurationSetting setting : settings) {
if (!(setting instanceof FeatureFlagConfigurationSetting)
&& !(setting instanceof SecretReferenceConfigurationSetting)) {
result.put(setting.getKey(), setting.getValue());
}
}
return result;
}
public void createSnapshot(String snapshotName, String keyPrefix) {
List<ConfigurationSettingsFilter> filters = new ArrayList<>();
filters.add(new ConfigurationSettingsFilter(keyPrefix + "*")
.setLabel(environment));
var poller = client.beginCreateSnapshot(snapshotName, new ConfigurationSnapshot(filters), null);
poller.waitForCompletion();
ConfigurationSnapshot snapshot = poller.getFinalResult();
System.out.printf("Snapshot '%s' created with %d items%n",
snapshot.getName(), snapshot.getItemCount());
}
public static void main(String[] args) {
AppConfigurationManager config = new AppConfigurationManager("Production");
// Set some configuration
config.setSetting("app/database/timeout", "30000");
config.setSetting("app/cache/ttl", "3600");
// Get configuration
String timeout = config.getSetting("app/database/timeout");
System.out.println("Database timeout: " + timeout);
// Feature flags
config.setFeatureEnabled("dark-mode", true);
if (config.isFeatureEnabled("dark-mode")) {
System.out.println("Dark mode is enabled");
}
// Get all app settings
Map<String, String> appSettings = config.getAllSettings("app/");
System.out.println("\n=== All App Settings ===");
appSettings.forEach((key, value) ->
System.out.printf("%s = %s%n", key, value));
// Create a snapshot for release
config.createSnapshot("release-" + System.currentTimeMillis(), "app/");
}
}Environment Variables
AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://<store>.azconfig.io;Id=<id>;Secret=<secret>
AZURE_APPCONFIG_ENDPOINT=https://<store>.azconfig.io
# For DefaultAzureCredential
AZURE_CLIENT_ID=<service-principal-client-id>
AZURE_CLIENT_SECRET=<service-principal-secret>
AZURE_TENANT_ID=<tenant-id>Best Practices
Use labels — Separate configurations by environment (Dev, Staging, Production)
Use snapshots — Create immutable snapshots for releases
Feature flags — Use for gradual rollouts and A/B testing
Secret references — Store sensitive values in Key Vault, not App Configuration
Conditional requests — Use ETags for optimistic concurrency
Read-only protection — Lock critical production settings
Use Entra ID — Preferred over connection strings for security
Async client — Use for high-throughput scenarios
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Microsoft
- Publisher
- Microsoft (Official)
- Source
- microsoft/skills · .github/plugins/azure-sdk-java/skills/azure-appconfiguration-java · commit 0696600
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Microsoft.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download azure-appconfiguration-java.zip