Creating ARM template or Bicep for Azure with C# Code

Writing ARM templates or Bicep code for Azure deployments is always difficult for me, even though the Visual Studio Code extensions for ARM templates and Bicep are great tools and help a lot. I’d always like to have such a tool with which I can simply say what I want to deploy, and it will automatically generate an ARM template or Bicep code for me. I even created such a tool for the virtual network previously. It is very simple and specific, and only works for virtual networks. I want a more generic tool which could work for almost everything on Azure. I cannot seem to find such a tool, so I decided to roll my own in the last winter holidays, and I named it Azure Design Studio.

As I’m using Blazor WebAssembly as the core stack, one of the challenges Azure Design Studio was facing is how to translate user inputs from UI to the Json of ARM templates. In vnet planner, I leveraged the dynamic of C#. It works fine for limited number of resources, but it is not scalable when I want to cover all Azure resources in Azure Design Studio. Also Azure ARM APIs and schemas are updated frequently. It’s impossible to catch up with the updates if the attributes and properties have to be verified manually. I need a set of POCO classes which provide the strong type in C#, can be serialized to Json easily, and are up to date with the latest ARM schemas.

The packages of Azure SDK for .NET have model classes for Azure resources that can be used for my purpose. But there are two problems with it: 1) The Json tooling used by Azure SDK is based on Newtonsoft.Json. I’d prefer to use System.Text.Json as much as possible as it is the recommended option from the Blazor team. 2) The package size of Azure SDK is huge. For example, the size of Microsoft.Azure.Management.Network is about 4.72MB which makes it not suitable for Blazor WASM.

So as a side project, I created AzureDesignStudio.AzureResources which includes a set of packages for Azure resources. In these packages, there are only POCO classes, so the size is minimal compared to Azure SDK. For example, the size of AzureDesignStudio.AzureResources.Network is only 94.09KB. The classes are decorated with System.Text.Json attributes, so there is no dependency on Newtonsoft.Json. All classes are generated automatically from the latest ARM schemas with a tool. So I hope it can catch up with the updates.

As a pilot, I’m using it in vnet planner and Azure Design Studio now. The following is an example of how you can use the package to create an ARM template easily.

VirtualNetworks vnet = new()
{
    Name = "Hello-vnet",
    Location = "eastus",
    Properties = new()
    {
        AddressSpace = new()
        {
            AddressPrefixes = new List<string> { "10.0.0.0/16" }
        }
    }
};

VirtualNetworksSubnets subnet = new()
{
    Name = $"{vnet.Name}/subnet1",
    Properties = new()
    {
        AddressPrefix = "10.0.0.0/24"
    },
};

DeploymentTemplate deploymentTemplate = new()
{
    Schema = "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    ContentVersion = "1.0.0.0",
    Resources = new List<ResourceBase> { vnet, subnet }
};

var template = JsonSerializer.Serialize(deploymentTemplate,
    new JsonSerializerOptions(JsonSerializerDefaults.Web)
    {
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
        Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
        WriteIndented = true,
        Converters = { new ResourceBaseJsonConverter() }
    });

Console.Write(template);

For more info and examples, please check out its GitHub repo. Again, this is a very opinionated personal project without any warranty. Use it at your own risk.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.