Bicep never left: The peaceful return of Microsoft DSC support
Why Bicep support never truly disappeared
Many were shocked to see Steve Lee drop the support for Bicep in Microsoft DSC in his pull request on GitHub:

But was it actually fully gone?
Looking at the details of the pull request, both the extension manifests (bicep.dsc.extension.json and bicepparams.dsc.extension.json) that shipped with dsc.exe got deleted from the packaging. These were mainly responsible for compiling Bicep using the extensibility model of DSC to JSON that was consumable by DSC's engine.
But it couldn't cope for long. Bicep features evolved faster than DSC could, so there was a good reason why it was removed.
That said, the removal wasn't an actual rejection of Bicep. Better yet, it was an acknowledgement that the architecture no longer fit. So, while the extension was removed from the shipping itself, work behind the scenes was still going on. And that work came in the form of gRPC.
In this blog post, we'll look at what was actually removed and why it hit the limit. Then, we take a look at how a new gRPC-based JSON-RPC approach keeps Bicep support alive in Microsoft DSC today.
The origin of DSC's Bicep extension
Microsoft DSC got a pretty neat extensibility model that PowerShell DSC didn't have. It allows you to hook in three types: discover, import, and secret.
The Bicep's part fell under the import one, allowing you as a user to directly feed a .bicep or .bicepparam to dsc.exe without actually doing anything. DSC's engine would notice this file extension and call all extension manifests to see if it can do something with it. In this case, behind the scenes, it was calling bicep build with the stdout option to get raw JSON. Precisely what the DSC's engine could handle.
To give it a bit more context, this is the old bicep.dsc.extension.json manifest content:
{
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/extension/manifest.json",
"type": "Microsoft.DSC.Extension/Bicep",
"version": "0.1.0",
"description": "Enable passing Bicep file directly to DSC, but requires bicep executable to be available.",
"condition": "[not(equals(tryWhich('bicep'), null()))]",
"import": {
"fileExtensions": ["bicep"],
"executable": "bicep",
"args": [
"build",
{
"fileArg": ""
},
"--stdout"
]
}
}If the Bicep executable wasn't installed on your system, it wasn't able to do it. That's what the condition part is telling.
But here you can already see the limitations. This tight coupling of Bicep to DSC. Any features that Bicep developed, whether it was just the output or changes in the language, could break the extension.
This growing mismatch between both velocities and release cadencies exposed these limitations of an extension-based approach (from the DSC side). It started to set the stage for something different.
Bicep DSC via JSON-RPC and gRPC
The replacement approach lives in the bicep-types-dsc repository In this repository, the focus area centres around Bicep's experimental localDeploy feature. Instead of shelling out directly through Bicep's CLI and piping the raw JSON to DSC's engine, Bicep now acts as a higher-order tool (HOT). All of this is done through a gRPC contract.
The architecture, therefore, has two moving parts (currently). The first one is the type generation. It's a small TypeScript CLI that collects every available DSC resource and its embedded JSON Schema. It converts those schemas into Bicep's type format and emits an index.json file:

With the index.json together with a compiled binary, can be packaged into a so-called OCI artifact via Bicep's publish-extension command. The result is a Bicep extension hosted on a demo Azure Container Registry (bicepconfig.json):
{
"experimentalFeaturesEnabled": {
"localDeploy": true
},
"extensions": {
"dsc": "br:contosobicepdsc1.azurecr.io/extensions/dsc:latest"
}
}
Its second part sits in a gRPC proxy. Whenever bicep local-deploy runs, it starts a .NET facade binary (bicep-ext-dsc). That facade hosts a hosted gRPC service, immediately spawning the real Rust gRPC server. This gRPC server is built inside the DSC repository. To better illustrate it, check out the following image:

The outcome is that the coupling that existed in the old manifest approach is totally gone. In this manner, Bicep can evolve at its own pace, and so does DSC. The gRPC contact is the only shared boundary between them.
Why this architecture change matters
Originally, Bicep was never intended to be a HOT in this story. With the extension-based approach, users weren't really using Bicep at all. Yes, it had to be installed on the system, but they were invoked directly to the engine with Bicep acting behind the scenes. From the user's perspective, DSC was still the main entry point.
That distinction now clearly matters. The model is flipped around, and so is the flow. Bicep becomes the orchestrator. DSC is just the capability that's been called into. This means that users who want to take advantage of Bicep-driven DSC scenarios must now explicitly install Bicep as well (even though they had to with the extension-based model). But this is an intentional shift that reflects Bicep's new role: a HOT in the pipeline.
So, compared to the extension-based model, what are the benefits of this clear shift? Here are some key points:
- Full access to Bicep's language features
By making Bicep the HOT, DSC scenarios can now take advantage of newer language features such as strong typing, rich expressions, loops, and more. - Clear separation of concerns
Microsed Desired State Configuration will still focus on enforcing state, whereas Bicep owns authoring, validation, and now acts as an orchestrator. - Explicit and predictable user experience
Bicep is now the entry point, and there aren't any hidden compilation steps anymore - Future-proof foundation
As long as the gRPC contracts stay stable, internal changes on either side remain isolated. This reduces the risk of breaking changes compared to the old approach.
Summary
A big relief on what initially looked like that Bicep support was totally gone, has now become an architectural correction. The old extension-based model is gone after the 3.2.0-preview.11 release.
By repositioning Bicep as a HOT and introducing a gRPC-based JSON-RPC boundary, the integration becomes more explicit. Users gain the richness of Bicep's language features, while DSC always does what it does best: enforcing the desired state.
If you want to see a cool demo, Andy Lee Jordan demoed it during the DSC community call and it is available on YouTube!