Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tnc1997/azure-app-configuration-emulator
Please note that Emulator for Azure App Configuration is unofficial and not endorsed by Microsoft.
https://github.com/tnc1997/azure-app-configuration-emulator
azure-app-configuration emulator
Last synced: 4 days ago
JSON representation
Please note that Emulator for Azure App Configuration is unofficial and not endorsed by Microsoft.
- Host: GitHub
- URL: https://github.com/tnc1997/azure-app-configuration-emulator
- Owner: tnc1997
- License: mit
- Created: 2023-10-01T07:17:53.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-06-15T20:40:26.000Z (5 months ago)
- Last Synced: 2024-06-15T21:40:31.963Z (5 months ago)
- Topics: azure-app-configuration, emulator
- Language: C#
- Homepage:
- Size: 197 KB
- Stars: 3
- Watchers: 1
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Emulator for Azure App Configuration
![Docker Pulls](https://img.shields.io/docker/pulls/tnc1997/azure-app-configuration-emulator?link=https%3A%2F%2Fhub.docker.com%2Fr%2Ftnc1997%2Fazure-app-configuration-emulator) ![Docker Stars](https://img.shields.io/docker/stars/tnc1997/azure-app-configuration-emulator?link=https%3A%2F%2Fhub.docker.com%2Fr%2Ftnc1997%2Fazure-app-configuration-emulator)
Please note that Emulator for Azure App Configuration is unofficial and not endorsed by Microsoft.
## Getting Started
```shell
docker pull tnc1997/azure-app-configuration-emulator
docker run -p 8080:8080 tnc1997/azure-app-configuration-emulator
```## Authentication
The emulator supports HMAC authentication and Microsoft Entra ID authentication.
### HMAC
The credential and secret may be overridden using the environment variables `Authentication__Schemes__Hmac__Credential` and `Authentication__Schemes__Hmac__Secret` respectively.
```yaml
services:
azure-app-configuration-emulator:
environment:
- Authentication__Schemes__Hmac__Credential=xyz
- Authentication__Schemes__Hmac__Secret=c2VjcmV0
image: tnc1997/azure-app-configuration-emulator
```#### .NET
The client may authenticate requests using the connection string for the emulator.
```csharp
using Azure.Data.AppConfiguration;var connectionString = Environment.GetEnvironmentVariable("ConnectionStrings__AzureAppConfiguration");
var client = new ConfigurationClient(connectionString);var setting = new ConfigurationSetting("AzureAppConfigurationEmulator", "Hello World");
await client.SetConfigurationSettingAsync(setting);
``````yaml
services:
azure-app-configuration-emulator:
image: tnc1997/azure-app-configuration-emulator
console-application:
build:
context: .
dockerfile: ./ConsoleApplication/Dockerfile
depends_on:
- azure-app-configuration-emulator
environment:
- ConnectionStrings__AzureAppConfiguration=Endpoint=http://azure-app-configuration-emulator:8080;Id=abcd;Secret=c2VjcmV0;
```#### Postman
The authentication related headers may be generated using the following script:
```javascript
const credential = "abcd";
const secret = "c2VjcmV0";const date = new Date().toUTCString();
const contentHash = CryptoJS.SHA256(CryptoJS.enc.Utf8.parse(pm.request.body.toString())).toString(CryptoJS.enc.Base64);const signedHeaders = "x-ms-date;Host;x-ms-content-sha256";
const stringToSign = `${pm.request.method}\n${pm.request.url.getPathWithQuery()}\n${date};${pm.request.url.getRemote()};${contentHash}`;
const signature = CryptoJS.HmacSHA256(CryptoJS.enc.Utf8.parse(stringToSign), CryptoJS.enc.Base64.parse(secret)).toString(CryptoJS.enc.Base64);pm.request.headers.upsert(`x-ms-date: ${date}`);
pm.request.headers.upsert(`x-ms-content-sha256: ${contentHash}`);
pm.request.headers.upsert(`Authorization: HMAC-SHA256 Credential=${credential}&SignedHeaders=${signedHeaders}&Signature=${signature}`);
```### Microsoft Entra ID
HMAC authentication is recommended because it does not require a Microsoft Entra tenant and an Azure App Configuration resource.
1. [Register an application](https://learn.microsoft.com/entra/identity-platform/quickstart-register-app) within the Microsoft Entra tenant.
1. On the Overview page, in the Essentials accordion, copy the following values:
* Application (client) ID
* Directory (tenant) ID
2. On the Certificates & secrets page, in the Client secrets tab, add a client secret.
2. [Create an Azure App Configuration resource](https://learn.microsoft.com/azure/azure-app-configuration/quickstart-azure-app-configuration-create) to be emulated.
1. On the Overview page, in the Essentials accordion, copy the following values:
* Endpoint
2. On the Access control (IAM) page, add a role assignment.
1. In the Role tab, select the App Configuration Data Owner role.
2. In the Members tab, assign access to the registered application.
3. [Generate a self-signed certificate](#ssl--tls) with the `` as the [Subject Alternative Name](https://wikipedia.org/wiki/Subject_Alternative_Name).The metadata address must be set using the environment variable `Authentication__Schemes__MicrosoftEntraId__MetadataAddress`.
```yaml
services:
azure-app-configuration-emulator:
environment:
- ASPNETCORE_HTTP_PORTS=80
- ASPNETCORE_HTTPS_PORTS=443
- Authentication__Schemes__MicrosoftEntraId__MetadataAddress=https://login.microsoftonline.com//v2.0/.well-known/openid-configuration
image: tnc1997/azure-app-configuration-emulator
networks:
default:
aliases:
-
volumes:
- ./emulator.crt:/usr/local/share/azureappconfigurationemulator/emulator.crt:ro
- ./emulator.key:/usr/local/share/azureappconfigurationemulator/emulator.key:ro
```The valid audience should be overriden using the environment variable `Authentication__Schemes__MicrosoftEntraId__ValidAudience`.
```yaml
services:
azure-app-configuration-emulator:
environment:
- ASPNETCORE_HTTP_PORTS=80
- ASPNETCORE_HTTPS_PORTS=443
- Authentication__Schemes__MicrosoftEntraId__MetadataAddress=https://login.microsoftonline.com//.well-known/openid-configuration
- Authentication__Schemes__MicrosoftEntraId__ValidAudience=https://
image: tnc1997/azure-app-configuration-emulator
networks:
default:
aliases:
-
volumes:
- ./emulator.crt:/usr/local/share/azureappconfigurationemulator/emulator.crt:ro
- ./emulator.key:/usr/local/share/azureappconfigurationemulator/emulator.key:ro
```#### .NET
The client may authenticate requests using the Microsoft Entra tenant.
```csharp
using Azure.Data.AppConfiguration;
using Azure.Identity;var tenantId = Environment.GetEnvironmentVariable("Authentication__Schemes__MicrosoftEntraId__TenantId");
var clientId = Environment.GetEnvironmentVariable("Authentication__Schemes__MicrosoftEntraId__ClientId");
var clientSecret = Environment.GetEnvironmentVariable("Authentication__Schemes__MicrosoftEntraId__ClientSecret");
var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);var endpoint = Environment.GetEnvironmentVariable("Endpoints__AzureAppConfiguration");
var client = new ConfigurationClient(new Uri(endpoint), credential);var setting = new ConfigurationSetting("AzureAppConfigurationEmulator", "Hello World");
await client.SetConfigurationSettingAsync(setting);
``````yaml
services:
azure-app-configuration-emulator:
environment:
- ASPNETCORE_HTTP_PORTS=80
- ASPNETCORE_HTTPS_PORTS=443
- Authentication__Schemes__MicrosoftEntraId__MetadataAddress=https://login.microsoftonline.com//.well-known/openid-configuration
- Authentication__Schemes__MicrosoftEntraId__ValidAudience=https://
image: tnc1997/azure-app-configuration-emulator
networks:
default:
aliases:
-
volumes:
- ./emulator.crt:/usr/local/share/azureappconfigurationemulator/emulator.crt:ro
- ./emulator.key:/usr/local/share/azureappconfigurationemulator/emulator.key:ro
console-application:
build:
context: .
dockerfile: ./ConsoleApplication/Dockerfile
depends_on:
- azure-app-configuration-emulator
entrypoint: /bin/sh -c "update-ca-certificates && dotnet ConsoleApplication.dll"
environment:
- Authentication__Schemes__MicrosoftEntraId__ClientId=
- Authentication__Schemes__MicrosoftEntraId__ClientSecret=
- Authentication__Schemes__MicrosoftEntraId__TenantId=
- Endpoints__AzureAppConfiguration=https://
volumes:
- ./emulator.crt:/usr/local/share/ca-certificates/emulator.crt:ro
```#### Postman
The access token may be obtained using the following configuration:
| Configuration | |
|------------------|-------------------------------------------------------------------|
| Auth Type | OAuth 2.0 |
| Grant Type | Client Credentials |
| Access Token URL | `https://login.microsoftonline.com//oauth2/v2.0/token` |
| Client ID | `` |
| Client Secret | `` |
| Scope | `https:///.default` |## Compatibility
The emulator is compatible with the following operations:
### Key Values
| Operation | |
|--------------------------|-----|
| Get | ✔️ |
| Get (Conditionally) | ✔️ |
| Get (Select Fields) | ✔️ |
| Get (Time-Based Access) | ✔️ |
| List | ✔️ |
| List (Pagination) | ❌ |
| List (Filtering) | ✔️ |
| List (Select Fields) | ✔️ |
| List (Time-Based Access) | ✔️ |
| Set | ✔️ |
| Set (Conditionally) | ✔️ |
| Delete | ✔️ |
| Delete (Conditionally) | ✔️ |### Keys
| Operation | |
|--------------------------|----|
| List | ✔️ |
| List (Pagination) | ❌ |
| List (Filtering) | ✔️ |
| List (Select Fields) | ✔️ |
| List (Time-Based Access) | ✔️ |### Labels
| Operation | |
|--------------------------|----|
| List | ✔️ |
| List (Pagination) | ❌ |
| List (Filtering) | ✔️ |
| List (Select Fields) | ✔️ |
| List (Time-Based Access) | ✔️ |### Locks
| Operation | |
|------------------------|----|
| Lock | ✔️ |
| Lock (Conditionally) | ✔️ |
| Unlock | ✔️ |
| Unlock (Conditionally) | ✔️ |### Revisions
| Operation | |
|--------------------------|---|
| List | ❌ |
| List (Pagination) | ❌ |
| List (Range) | ❌ |
| List (Filtering) | ❌ |
| List (Select Fields) | ❌ |
| List (Time-Based Access) | ❌ |## Data
The emulator stores configuration settings in a [SQLite](https://sqlite.org) database.
The data that is generated by the emulator during a session may be persisted between sessions using a [volume](https://docs.docker.com/storage/volumes).
```yaml
services:
azure-app-configuration-emulator:
image: tnc1997/azure-app-configuration-emulator
volumes:
- azure-app-configuration-emulator:/var/lib/azureappconfigurationemulator
volumes:
azure-app-configuration-emulator:
```The connection string for the database may be overridden using the environment variable `ConnectionStrings__DefaultConnection`.
```yaml
services:
azure-app-configuration-emulator:
environment:
- ConnectionStrings__DefaultConnection=Data Source=/var/lib/azureappconfigurationemulator/emulator.db
image: tnc1997/azure-app-configuration-emulator
```The database may be seeded with data and mounted into the container however care should be taken to ensure that the database has the required schema.
```yaml
services:
azure-app-configuration-emulator:
image: tnc1997/azure-app-configuration-emulator
volumes:
- ./emulator.db:/var/lib/azureappconfigurationemulator/emulator.db
```## Messaging
The emulator integrates with Azure Event Grid to publish events using the [Event Grid event schema](https://learn.microsoft.com/en-us/azure/event-grid/custom-topics#event-grid-event-schema) when configuration settings are deleted or modified.
The endpoint and key for the [Event Grid Topic](https://learn.microsoft.com/en-us/azure/event-grid/custom-topics) may be set using the environment variables `Messaging__EventGridTopics__xyz__Endpoint` and `Messaging__EventGridTopics__xyz__Credential__Key` respectively where `xyz` is an arbitrary name.
```yaml
services:
azure-app-configuration-emulator:
environment:
- Messaging__EventGridTopics__Contoso__Credential__Key=a2V5
- Messaging__EventGridTopics__Contoso__Endpoint=https://contoso.uksouth-1.eventgrid.azure.net/api/events
image: tnc1997/azure-app-configuration-emulator
```## Observability
The emulator integrates with OpenTelemetry to provide metrics and traces.
The endpoint for the [OpenTelemetry Protocol (OTLP) Exporter](https://opentelemetry.io/docs/specs/otel/protocol/exporter) may be overridden using the environment variable `OTEL_EXPORTER_OTLP_ENDPOINT`.
```yaml
services:
azure-app-configuration-emulator:
depends_on:
- opentelemetry-collector
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=http://opentelemetry-collector:4317
image: tnc1997/azure-app-configuration-emulator
opentelemetry-collector:
image: otel/opentelemetry-collector-contrib
```## SSL / TLS
The emulator may be configured to serve requests over HTTPS using a [self-signed certificate](https://wikipedia.org/wiki/self-signed_certificate).
```shell
openssl req -x509 -out ./emulator.crt -keyout ./emulator.key -newkey rsa:2048 -nodes -sha256 -subj '/CN=azure-app-configuration-emulator' -addext 'subjectAltName=DNS:azure-app-configuration-emulator'
```The port for HTTPS must be set using the environment variable [`ASPNETCORE_HTTPS_PORTS`](https://learn.microsoft.com/aspnet/core/security/enforcing-ssl#port-configuration).
The paths for the certificate and key must be set using the environment variables `Kestrel__Certificates__Default__Path` and `Kestrel__Certificates__Default__KeyPath` respectively.
The certificate and key must be [mounted](https://docs.docker.com/storage/bind-mounts) into the container at the paths that are set above.
```yaml
services:
azure-app-configuration-emulator:
environment:
- ASPNETCORE_HTTP_PORTS=8080
- ASPNETCORE_HTTPS_PORTS=8081
- Kestrel__Certificates__Default__Path=/usr/local/share/azureappconfigurationemulator/emulator.crt
- Kestrel__Certificates__Default__KeyPath=/usr/local/share/azureappconfigurationemulator/emulator.key
image: tnc1997/azure-app-configuration-emulator
volumes:
- ./emulator.crt:/usr/local/share/azureappconfigurationemulator/emulator.crt:ro
- ./emulator.key:/usr/local/share/azureappconfigurationemulator/emulator.key:ro
```## Testcontainers
The emulator integrates with [Testcontainers](https://testcontainers.org) to ease the integration testing of applications that use Azure App Configuration.
```csharp
var container = new ContainerBuilder()
.WithImage("tnc1997/azure-app-configuration-emulator:1.0")
.WithPortBinding(8080, true)
.WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged("Now listening on"))
.Build();await container.StartAsync();
var client = new ConfigurationClient($"Endpoint={new UriBuilder(Uri.UriSchemeHttp, container.Hostname, container.GetMappedPublicPort(8080))};Id=abcd;Secret=c2VjcmV0");
await client.SetConfigurationSettingAsync(nameof(ConfigurationSetting.Key), nameof(ConfigurationSetting.Value));
var response = await client.GetConfigurationSettingAsync(nameof(ConfigurationSetting.Key));
```**Coming Soon** [testcontainers/testcontainers-dotnet#1198](https://github.com/testcontainers/testcontainers-dotnet/issues/1198)
```csharp
var container = new AzureAppConfigurationBuilder().Build();await container.StartAsync();
var client = new ConfigurationClient(container.GetConnectionString());
await client.SetConfigurationSettingAsync(nameof(ConfigurationSetting.Key), nameof(ConfigurationSetting.Value));
var response = await client.GetConfigurationSettingAsync(nameof(ConfigurationSetting.Key));
```