Skip to main content
Kamil Mrzygłód
Topaz maintainer & contributor
View all authors

Debugging Application Insights without a cloud subscription

· 7 min read
Kamil Mrzygłód
Topaz maintainer & contributor

Application Insights bugs tend to fall into one of two categories. Either the SDK sends something and you never see it in the portal - wrong connection string, wrong environment variable, telemetry initializer stripping the data - or it sends something you did not intend, and you only find out a week later when billing shows an unexpected spike. Both categories share one root cause: there is no fast, local feedback loop.

The standard debugging advice is to enable DiagnosticsTelemetryModule, or to tail the Fiddler capture, or to deploy to a dev environment and wait for the portal to ingest the data. All of those paths are slow. Some require a cloud subscription you might not have access to from the machine you are debugging on.

Topaz emulates the Application Insights ingestion API (/v2/track) and the query API (/v1/apps/{ikey}/query) locally. The SDK points at localhost, sends telemetry as it normally would, and you can query the ingested data immediately - from code, from the Topaz Portal, or from a KQL query in your terminal.

15 months of building OSS software - with and without AI

· 10 min read
Kamil Mrzygłód
Topaz maintainer & contributor

When I started working on Topaz 15 months ago (I pushed the first commit in the middle of April 2025), I had no idea how the landscape of software engineering would change by the time I wrote this. I wanted to summarize the whole journey and describe how AI changed the way I design, develop and test Topaz — a local Azure emulator I've been building in the open.

Testing Azure retry logic locally: why I stopped mocking 429s and started injecting them

· 9 min read
Kamil Mrzygłód
Topaz maintainer & contributor

There is a certain category of test that feels good to write but does not actually test what you think it does. Retry logic sits squarely in that category.

The usual pattern is this: inject a fake HttpMessageHandler, make it return a 429 or 503 on the first N calls, assert that the code retried and eventually succeeded. The test passes. You ship with confidence. Then, in production, a real throttling event triggers a path through the Azure SDK that your mock never covered, and the retry policy does not behave the way the test implied.

The issue is not that the mock is wrong. It is that the mock bypasses the entire SDK transport layer. When you return a 429 from a fake handler, you are testing whether your own retry wrapper handles it correctly. You are not testing whether Azure.Core's built-in retry pipeline fires, whether the Retry-After header is respected, or whether the SDK's own exception hierarchy propagates through your application code the way you assumed. That is a different bar entirely.

I replaced three Azure emulators with one binary, added Key Vault and ACR, and cut our CI setup to a single step

· 8 min read
Kamil Mrzygłód
Topaz maintainer & contributor

For a while, local Azure development in my projects looked like this: Azurite for Blob and Queue Storage, the Microsoft Service Bus Emulator for messaging, the Cosmos DB Emulator for document storage, and nothing at all for Key Vault, Container Registry, or Entra. The last three were either skipped in local runs, mocked, or simply hit against a real Azure subscription when I needed them.

That worked, to a point. But the setup cost was real. Each emulator has its own Docker image, its own port range, its own quirks, and its own certificate story. Compose files grew. CI pipelines grew to match. And the services that had no emulator at all stayed untested locally, which is exactly the category where surprises tend to show up in production.

I wanted to see whether a single tool could cover the whole stack without making too many compromises.

Running Azure integration tests in CI without a subscription, credentials, or cloud costs

· 9 min read
Kamil Mrzygłód
Topaz maintainer & contributor

Every team that tests against real Azure services in CI eventually hits the same four problems. You need credentials for the pipeline. Those credentials need to be stored somewhere, rotated, and audited, and if they leak they affect a real environment. The tests themselves become flaky because Azure provisioning has variable latency and your Service Bus namespace occasionally takes three minutes to appear. And if you run on private agents, you need to add networking complexity on top of all of that.

These are not Azure-specific problems. They show up in any pipeline that depends on external cloud services. But the fix for them often is Azure-specific, and the usual answers (use a dedicated test subscription, use Managed Identity, sanitize your test fixtures) treat the symptoms without changing the fundamental structure of the problem.

I wanted to see whether running tests against a local Azure emulator in CI could close those gaps cleanly. The short version is: it can, and the job runs in 38 seconds.

How Topaz enables az login without root: MSAL, port 443, and a built-in CONNECT proxy

· 10 min read
Kamil Mrzygłód
Topaz maintainer & contributor

One of the fundamental rules of Topaz is that it must not require sudo or admin rights. There is nothing more frustrating than having to request elevated permissions on your machine just to run a dev tool.

For most Azure CLI operations this is not a problem. You point the CLI at https://topaz.local.dev:8899, it talks to port 8899, done. ROPC login is the exception - az login --username --password triggers a user-realm discovery pre-flight inside MSAL that always targets port 443, regardless of what port you configured in the authority URL. On a non-Docker Topaz install, nothing is listening on port 443, because binding that port requires root. The result is a connection timeout that surfaces as an opaque account-not-found error with no indication that port 443 is involved at all.

This post explains the MSAL assumption behind that behavior, why the straightforward fixes do not work without elevated permissions, and how a built-in HTTP CONNECT proxy on port 44380 closes the gap cleanly.

Local Azure development with Docker Compose: a copy-paste starting point

· 14 min read
Kamil Mrzygłód
Topaz maintainer & contributor

I had a simple target in mind: open a project, run docker compose up, and have a working local Azure environment — Key Vault, Blob Storage, ARM API. No manual steps on the host machine, no az login, no cloud subscription. Additionally, I wanted to avoid those pesky manual changes in the hosts file like echo 127.0.0.1 topaz.local.dev >> /etc/hosts, that someone will inevitably skip.

It sounds like a two-hour job. It took longer because three things that should be straightforward each had a non-obvious edge case.

What AMQP compatibility means for a local Azure emulator (.NET / MassTransit)

· 9 min read
Kamil Mrzygłód
Topaz maintainer & contributor

I wanted to see whether Topaz could run a real PeekLock consumer, not just accept AMQP frames and pass a basic SDK smoke test. The first MassTransit run failed in two different ways. CompleteAsync waited 60 seconds for a management response that never arrived, and after fixing that, the consumer still stalled after a single message.

That was the point where "supports AMQP" stopped being a useful statement. This post explains what MassTransit was actually doing on the wire, which parts of the protocol Topaz was still missing, and which traces made the root causes obvious.

The concrete examples use MassTransit and the Azure Service Bus SDK for .NET. The AMQP behaviour described applies to any framework driving PeekLock, but the code is C#. If you are not working in .NET, the protocol sections may still be useful context for evaluating any AMQP emulator.

Topaz Weekly Pulse #5: Azure App Service, Virtual Machines, Storage SAS security, Key Vault AES keys, and a live Portal terminal

· 6 min read
Kamil Mrzygłód
Topaz maintainer & contributor

This week in Topaz: Azure App Service lands as a first-class service with Plans and Sites. Virtual Machines gain full CLI coverage. Storage gets end-to-end SAS and stored-access-policy enforcement. Key Vault now handles symmetric AES keys. The Portal grows a live CLI terminal and universal tag editing.

Using Topaz with GitHub Copilot via MCP Server

· 12 min read
Kamil Mrzygłód
Topaz maintainer & contributor

I wanted GitHub Copilot to do more than generate a bash script that calls az group create. I wanted to describe the local Azure stack in natural language and have the assistant provision it while I worked on the application code. Instead of tab-switching to a terminal, remembering the right parameter names, and sequencing five CLI commands in the right order, I wanted the infrastructure to be created directly from the chat, with connection strings returned in a form I could paste into the application configuration.

Topaz ships a Model Context Protocol (MCP) server that makes this possible against the local emulator. The interesting part was not the tool call itself, but getting the container networking, DNS, and certificate setup right so those tool calls returned endpoints that were actually usable. This post covers how the MCP server works, why the Docker networking setup is non-trivial, and what the full setup looks like end to end.

Star on GitHub