Skip to content
Back to main site

Azure App Configuration

Create a local configuration store, then write and read labeled key-values, with ETag checks and locks.

Plan: Pro50 of 50 operations implemented across 2 APIs

Only key-values, labels, ETag checks and locks were tested. Snapshots, feature flags, revision history and configuration refresh in the SDKs weren't.

Example checked on Vera 1.2.2, 8 November 2026. Each coverage note names its own evidence and date.

Start Vera as in Get started, with your license key activated and the emulator started by the Vera launcher (Activate Pro). Then open Bash in a terminal of its own (on macOS, whose terminal starts zsh, type bash first), go to an empty scratch directory and run this; it needs curl and Python 3, and jq. It fetches the emulator's own certificate, so every request checks TLS, and defines data_request and data_arm, which this page's commands use. The bearer token vera-local is a dummy local credential, not your license key.

Terminal window
export VERA_CA_CERT="$PWD/vera-ca.pem"
curl --fail --silent --show-error --noproxy '*' --insecure \
https://localhost:8543/_vera/ca.pem --output "$VERA_CA_CERT"
curl --fail --silent --show-error --noproxy '*' \
--cacert "$VERA_CA_CERT" https://localhost:8543/_vera/health; echo
export VERA_CA="$VERA_CA_CERT"
export ARM='https://localhost:8543'
export SUB='00000000-0000-0000-0000-000000000001'
export TENANT='00000000-0000-0000-0000-0000000000a1'
export RG='azdata-rg'
export ROOT="/subscriptions/$SUB/resourceGroups/$RG"
export AUDIT_TMP="$(mktemp -d)"
56 more lines: show the full setup
# Every .localhost host name is connected to loopback, and TLS is verified.
# DATA_RESPONSE is replaced after each call: copy any IDs before the next one.
data_request() {
local method="$1" url="$2" host status
shift 2
case "$url" in
https://localhost:8543/*|https://*.localhost:8543/*) ;;
*) printf 'Refusing non-local URL: %s\n' "$url" >&2; return 1 ;;
esac
host="${url#https://}"
host="${host%%/*}"
host="${host%:8543}"
status=$(curl --noproxy '*' --silent --show-error \
--cacert "$VERA_CA" --resolve "$host:8543:127.0.0.1" \
-H 'Authorization: Bearer vera-local' \
-X "$method" "$url" "$@" \
-D "$AUDIT_TMP/headers" -o "$AUDIT_TMP/body" -w '%{http_code}') || return
DATA_RESPONSE=$(cat "$AUDIT_TMP/body")
printf 'HTTP %s\n%s\n' "$status" "$DATA_RESPONSE"
case "$status" in 2??) ;; *) return 1 ;; esac
}
# Polls the operation URL from the last successful management change, even
# after HTTP 200 or 201. Don't replace it with a fixed sleep.
data_wait_arm() {
local operation attempt status state delay
operation=$(awk 'BEGIN {IGNORECASE=1} tolower($1)=="azure-asyncoperation:" {gsub("\r", "", $2); print $2; exit}' "$AUDIT_TMP/headers")
if [ -z "$operation" ]; then
operation=$(awk 'tolower($1)=="location:" {gsub("\r", "", $2); print $2; exit}' "$AUDIT_TMP/headers")
fi
[ -z "$operation" ] && return 0
case "$operation" in "$ARM"/_vera/operations/*) ;; *) printf 'Inspect unexpected operation URL: %s\n' "$operation" >&2; return 1 ;; esac
for attempt in $(seq 1 60); do
data_request GET "$operation" || return
status=$(awk '/^HTTP\// {code=$2} END {print code}' "$AUDIT_TMP/headers")
state=$(printf '%s' "$DATA_RESPONSE" | jq -r '.status // empty' 2>/dev/null) || state=''
case "$state" in
Failed|Canceled|Cancelled) return 1 ;;
Succeeded) return 0 ;;
InProgress|Running|Accepted) ;;
*) [ "$status" != '202' ] && return 0 ;;
esac
delay=$(awk 'tolower($1)=="retry-after:" {gsub("\r", "", $2); print $2; exit}' "$AUDIT_TMP/headers")
case "$delay" in ''|*[!0-9]*) delay=1 ;; esac
sleep "$delay"
done
printf 'Operation did not finish within the polling limit\n' >&2
return 1
}
data_arm() {
local method="$1" path="$2"
shift 2
data_request "$method" "$ARM$path" "$@" || return
case "$method" in PUT|PATCH|POST|DELETE) data_wait_arm ;; esac
}

The health check answers {"cloud": "azure", "generation_status": "generated", "status": "ok"}. Requests go only to the emulator at https://localhost:8543: the helper refuses any other address, including the Azure-looking URLs some responses hold. When you've finished, close the terminal and delete the scratch directory; that removes only these local files, not what you created in the emulator.

The examples use the App Configuration management API at 2024-06-01, its data API at 2026-04-01 and resource groups at 2025-04-01, the versions tested with this build: keep them as shown. Each goes in an api-version parameter.

Store management goes to https://localhost:8543. Key-values go to the store’s own host name, azdataconfig.azconfig.localhost, on the same port. The emulator finds the store by that name, so keep it in the URL. data_request gives curl a --resolve for it, which connects to 127.0.0.1 while keeping the name for routing and TLS, so the name doesn’t need to resolve on your machine. See data host names.

The store’s Azure SKU, free, is an Azure pricing tier the emulator records. It doesn’t change Vera’s plan: App Configuration needs Pro.

Create a store, write a key-value, then write the same key under the dev label and read both. ETag checks and locks uses the same key, and Clean up deletes the store at the end.

Create the resource group the examples share, then the store, and read the store. The create answers HTTP 201 with an operation, and data_arm prints each response, then polls the operation until it has succeeded (long-running operations). The create’s own response has a null endpoint, so read the store afterwards: the GET answers HTTP 200 with the store’s local endpoint.

Terminal window
data_arm PUT "$ROOT?api-version=2025-04-01" \
-H 'Content-Type: application/json' --data '{"location":"eastus"}'
CONFIG="$ROOT/providers/Microsoft.AppConfiguration/configurationStores/azdataconfig"
CFG='https://azdataconfig.azconfig.localhost:8543'
data_arm PUT "$CONFIG?api-version=2024-06-01" -H 'Content-Type: application/json' \
--data '{"location":"eastus","sku":{"name":"free"}}'
data_arm GET "$CONFIG?api-version=2024-06-01"

Write azdata.message, read it, write it again under the dev label, then read the labeled and unlabeled values:

Terminal window
data_request PUT "$CFG/kv/azdata.message?api-version=2026-04-01" \
-H 'Content-Type: application/json' --data '{"value":"hello vera","content_type":"text/plain"}'
data_request GET "$CFG/kv/azdata.message?api-version=2026-04-01"
data_request PUT "$CFG/kv/azdata.message?api-version=2026-04-01&label=dev" \
-H 'Content-Type: application/json' --data '{"value":"dev value"}'
data_request GET "$CFG/kv/azdata.message?api-version=2026-04-01&label=dev"
data_request GET "$CFG/kv/azdata.message?api-version=2026-04-01"

Each request answers HTTP 200 with the key-value’s etag, key, value, label and last_modified. The dev label holds dev value, and the unlabeled key keeps hello vera. These are selected fields of the last read:

Output (selected fields)
{
"key": "azdata.message",
"value": "hello vera"
}

Two writes here are meant to fail, so data_request returns non-zero for them; || true marks those two lines only. First a write with an ETag that doesn’t match, then a lock, a write to the locked key, the unlock and a read:

Terminal window
# Stale ETag: expected HTTP 412.
data_request PUT "$CFG/kv/azdata.message?api-version=2026-04-01" \
-H 'Content-Type: application/json' -H 'If-Match: "does-not-match"' \
--data '{"value":"wrong"}' || true
data_request PUT "$CFG/locks/azdata.message?api-version=2026-04-01"
# Write to the locked key: expected HTTP 409, and the value stays unchanged.
data_request PUT "$CFG/kv/azdata.message?api-version=2026-04-01" \
-H 'Content-Type: application/json' --data '{"value":"wrong"}' || true
data_request DELETE "$CFG/locks/azdata.message?api-version=2026-04-01"
data_request GET "$CFG/kv/azdata.message?api-version=2026-04-01"

The stale ETag answers HTTP 412, Precondition Failed. The lock answers HTTP 200 with locked set to true, and the write to the locked key answers HTTP 409, The key-value is locked. The unlock answers HTTP 200 with locked set to false, and the read still returns hello vera.

Delete the labeled and unlabeled key-values, then the store:

Terminal window
data_request DELETE "$CFG/kv/azdata.message?api-version=2026-04-01&label=dev"
data_request DELETE "$CFG/kv/azdata.message?api-version=2026-04-01"
data_arm DELETE "$CONFIG?api-version=2024-06-01"

The key-value deletes answer HTTP 200. The store’s delete answers HTTP 202 and its operation succeeds; a GET of the store then answers HTTP 404. The resource group azdata-rg stays, since deleting a group fails in Vera 1.2.2: see deleting resource groups. Other pages’ examples reuse it. To remove it and anything else left over, start a fresh emulator: see Stop and start again.

  • Stores: a store created, read back with its local endpoint once its operation has finished, listed in its resource group and deleted. A missing store answers HTTP 404.
  • Key-values and labels: a key-value written with a content type and read back with its ETag and last-modified time, and the same key kept separately under a label. Labeled and unlabeled values are deleted separately.
  • ETag checks: a write with an If-Match ETag that doesn’t match answers HTTP 412.
  • Locks: a locked key-value refuses writes with HTTP 409 and keeps its value. Locking and unlocking return the key-value with locked set to true or false.
  • Not run as examples: listing keys, labels and key-values, revisions, snapshots, feature flags, replicas, access keys and key-values through the management API. The API coverage marks these from a review of Vera 1.2.0’s source, with their limits in the notes.

The main limits are below. A few more apply to every service, and the API coverage notes cover smaller differences.

  • Only the requests shown were run. Snapshots, feature-flag evaluation, revision history, paging through labels and key-values, and configuration refresh in the App Configuration SDKs weren’t. Don’t infer them from the key-value examples.
  • Replicas are records. Replica resources are local metadata: replication across regions isn’t established. Sync tokens give strong consistency within the local store.
  • A write with a matching ETag wasn’t tested. The ETag check was shown to refuse a stale ETag, not to accept the current one.
  • Wait for the store. The create’s response has a null endpoint; read the store once its operation has finished, as data_arm does.

Every operation of the APIs on this page, from their pinned public definitions, and whether Vera 1.2.0 implements it. Only the API surfaces in this release are listed, and each operation once. Implementation availability was reviewed against the Vera 1.2.0 source on 6 November 2026. Source inspection identifies a local implementation and its known limits; it doesn't mean every operation or API version was tested with a request. Each note names its evidence: a Local observation without a build or date is from Vera 1.2.0 preview, on 5 November 2026, and one from a later build, such as Vera 1.2.0-rc.3 or Vera 1.2.2, names that build and its date. No response was compared with Azure's. What the statuses mean

App Configuration management 2024-06-01Plan: Pro

29 of 29 implemented

Version 2024-06-01, from the Azure REST API specifications at commit 21bbf1b.

ConfigurationStores

11 of 11 implemented
OperationStatusNotes
ConfigurationStores_CreateImplementedLocal observation: Created a store (HTTP 201) with an operation that reached Succeeded. The create response's endpoint was null; a GET afterwards returned it.
ConfigurationStores_DeleteImplementedLocal observation: Deleted the store (HTTP 202); its operation reached Succeeded, and a GET then answered HTTP 404.
ConfigurationStores_GetImplementedLocal observation: Returned the store (HTTP 200), with its local endpoint once its create operation had finished. A missing store, and the store after deletion, answered HTTP 404.
ConfigurationStores_GetDeletedImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
ConfigurationStores_ListImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
ConfigurationStores_ListByResourceGroupImplementedLocal observation: Listed the resource group's stores (HTTP 200).
ConfigurationStores_ListDeletedImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
ConfigurationStores_ListKeysImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
ConfigurationStores_PurgeDeletedImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
ConfigurationStores_RegenerateKeyImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
ConfigurationStores_UpdateImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.

KeyValues

3 of 3 implemented
OperationStatusNotes
KeyValues_CreateOrUpdateImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
KeyValues_DeleteImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
KeyValues_GetImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.

Operations

3 of 3 implemented
OperationStatusNotes
Operations_CheckNameAvailabilityImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
Operations_ListImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
Operations_RegionalCheckNameAvailabilityImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.

PrivateEndpointConnections

4 of 4 implemented
OperationStatusNotes
PrivateEndpointConnections_CreateOrUpdateImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
PrivateEndpointConnections_DeleteImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
PrivateEndpointConnections_GetImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
PrivateEndpointConnections_ListByConfigurationStoreImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.

PrivateLinkResources

2 of 2 implemented
OperationStatusNotes
PrivateLinkResources_GetImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
PrivateLinkResources_ListByConfigurationStoreImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.

Replicas

4 of 4 implemented
OperationStatusNotes
Replicas_CreateImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
Replicas_DeleteImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
Replicas_GetImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
Replicas_ListByConfigurationStoreImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.

Snapshots

2 of 2 implemented
OperationStatusNotes
Snapshots_CreateImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
Snapshots_GetImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.

App Configuration data 2026-04-01Plan: Pro

21 of 21 implemented

Version 2026-04-01, from the Azure REST API specifications at commit 21bbf1b.

appconfiguration_data

21 of 21 implemented
OperationStatusNotes
CheckKeyValueImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
CheckKeyValuesImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
CheckKeysImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
CheckLabelsImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
CheckRevisionsImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
CheckSnapshotImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
CheckSnapshotsImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
CreateSnapshotImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
DeleteKeyValueImplementedLocal observation: Deleted an unlabeled and a labeled key-value (HTTP 200 each).
DeleteLockImplementedLocal observation: Unlocked a key-value, returning it with locked false (HTTP 200).
GetKeyValueImplementedLocal observation: Returned key-values with etag, key, value, label and last_modified (HTTP 200): the labeled value with label=dev, and the unlabeled one without.
GetKeyValuesImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
GetKeysImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
GetLabelsImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
GetOperationDetailsImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
GetRevisionsImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
GetSnapshotImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
GetSnapshotsImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.
PutKeyValueImplementedLocal observation: Stored an unlabeled and a dev-labeled value (HTTP 200). A stale If-Match ETag answered HTTP 412, and a write to a locked key-value answered HTTP 409, leaving the value unchanged.
PutLockImplementedLocal observation: Locked a key-value, returning it with locked true (HTTP 200).
UpdateSnapshotImplementedSource inspection: Local configuration state; replicas and sync tokens are a local consistency model, not cross-region replication.