Bicep has been introduced some time ago as a more human friendly language to create ARM templates. Azure Arc opens up a lot of possibilities to consume cloud resources on hardware close to the edge. With Bicep it’s easier then ever to write templates to deploy your resources to Azure and Azure Stack HCI.
Still a lot of companies are working on or figuring out their cloud journey. Being able to use Bicep and ARM in developer tools is often a requirement. Azure Arc provides new options and possibilities for IT organizations and developers to run applications and resources. In this blog we talk about deploying resources with Bicep templates through Azure Arc on an Azure Stack HCI cluster.
Biceps was pretty new to me until some weeks ago. I have heard about it for some time, but never took the effort to learn it and use it. I am not a Bicep guru at all, but I have to say it’s a lot easier then writing ARM Templates. With Azure Resource Manager as single pane of management for cloud resources, you could off course use the Bicep templates to deploy resources to Azure. But with all the new capabilities being added to Azure Stack HCI with Azure Arc, I thought lets deploy some resources with Bicep to the Edge. It could even perform beter on your own cluster closer to your users.
To create the templates you can used Visual Studio Code with the Bicep extension. There is plenty of info available on how to get started, so we will not go in to how to set it up. When starting with VM templates for Azure Stack HCI you must use the resource types ”Microsoft.AzureStackHCI”. Below an example to deploy a VM. I removed the more sensitive info and resource group data. Also pay attention to the custom location name.
param name string param vnicname string = 'Vnic-01' param vmvnicname string = '${name}${vnicname}' param location string = 'westeurope' param customlocation string = '/subscriptions/xxxxxx/resourceGroups/SB-WE-RG-HCIResourceBridge/providers/Microsoft.ExtendedLocation/customLocations/Splitbrain-Datacenter-HPELab' param memoryGB int = 4 param processors int = 2 param imagename string = 'WinServer2022STD' param adminusername string @secure() param adminpassword string resource azhcivnic 'Microsoft.AzureStackHCI/networkinterfaces@2021-09-01-preview' = { name: vmvnicname location: location tags: {} extendedLocation: { name: customlocation type: 'CustomLocation' } properties: { resourceName: vnicname dnsSettings: {} ipConfigurations: [ { name: vmvnicname properties: { privateIPAllocationMethod: 'Dynamic' subnet: { id : '/subscriptions/xxxxx/resourcegroups/sb-we-rg-hciresourcebridge/providers/microsoft.azurestackhci/virtualnetworks/vswitch' } } } ] } } resource azhcivm 'Microsoft.AzureStackHCI/virtualmachines@2021-09-01-preview' = { name: name location: location tags:{} extendedLocation: { name: customlocation type: 'CustomLocation' } properties: { guestAgentProfile: {} hardwareProfile: { memoryGB: memoryGB processors: processors vmSize: 'Custom' } networkProfile: { networkInterfaces: [ { id: azhcivnic.id } ] } osProfile: { adminPassword: adminpassword adminUsername: adminusername computerName: name osType: 'Windows' } resourceName: name securityProfile: { uefiSettings: { secureBootEnabled: true } } storageProfile: { dataDisks: [ ] imageReference: { name: imagename } } } }
After the template is done you can deploy it with the tool that you want to use. That can be Powershell, Azure CLI, Azure DevOps and so on. Let’s give it a try!
I used Azure CLI to deploy the template. First login with ‘az login’ and then set the subscription context if you have more than one with ‘az account set –subscription id’. Then you can deploy it with ‘az deployment group create’.
After providing the requested parameters the deployment kicks off. After 5 to 10 minutes (depending on the performance of your cluster) we have a new VM running on Azure Stack HCI. And fully deployed via a Bicep template through the Azure Resource Manager via Azure Arc. Cool stuff right?
Now why stop at the deployment of a VM? Lets deploy an AKS cluster while we are at it. As of writing I could not find any documentation on Hybrid AKS yet so I used an ARM template and converted it to a Bicep template. For Hybrid AKS we need to use the resource type “Microsoft.HybridContainerService”. Here I did some altering to suite the deployment. The SSH Key was a bit of a pain because the feature is currently still in preview. The portal does a trick that I cannot do with Bicep so I had to create the SSH Key first and provide the public key as parameter, but the template looks like below. Again some info is removed for security reasons.
param provisionedClustersName string param customLocation string ='/subscriptions/xxxxx/resourceGroups/SB-WE-RG-HCIResourceBridge/providers/Microsoft.ExtendedLocation/customLocations/SB-DCHPELAB-AKS' param adminGroupObjectIDs array = [] @secure() param sshkey string param location string = 'westeurope' param resourceTags object = { } param controlPlaneNodeCount int param controlPlaneNodesize string = 'Standard_A4_v2' param controlPlaneOsType string = 'Linux' param kubernetesVersion string = 'v1.22.11' param loadBalancerNodeSize string = 'Standard_A4_v2' param loadBalancerNodeCount int param loadBalancerSku string = 'unstacked-haproxy' param loadBalancerOsType string = 'Linux' param podCidr string = '10.244.0.0/16' param networkPolicy string = 'calico' param vnetSubnetIds array = ['/subscriptions/xxxxx/resourceGroups/SB-WE-RG-HCIResourceBridge/providers/Microsoft.HybridContainerService/virtualNetworks/sb-dchpelab-aksvnet101'] param agentpoolname string = '${provisionedClustersName}-nodepool1' param agentpoolCount int param agentpoolVMsize string = 'Standard_A4_v2' param agentpoolOsType string = 'Linux' resource provisionedClustersName_resource 'Microsoft.HybridContainerService/ProvisionedClusters@2022-05-01-preview' = { name: provisionedClustersName location: location extendedLocation: { type: 'customLocation' name: customLocation } tags: resourceTags identity: { type: 'SystemAssigned' } properties: { aadProfile: { adminGroupObjectIDs: adminGroupObjectIDs } linuxProfile: { ssh: { publicKeys: [ { keyData: sshkey } ] } } controlPlane: { count: controlPlaneNodeCount osType: controlPlaneOsType vmSize: controlPlaneNodesize } kubernetesVersion: kubernetesVersion networkProfile: { loadBalancerProfile: { count: loadBalancerNodeCount osType: loadBalancerOsType vmSize: loadBalancerNodeSize } loadBalancerSku: loadBalancerSku networkPolicy: networkPolicy podCidr: podCidr } agentPoolProfiles: [ { name: agentpoolname count: agentpoolCount vmSize: agentpoolVMsize osType: agentpoolOsType } ] cloudProviderProfile: { infraNetworkProfile: { vnetSubnetIds: vnetSubnetIds } } } }
Now that the template is done, we can deploy it.
Like with the VM deployment we use Azure CLI again to deploy the template. But this time because of the SSH Key preview limitation i create an SSH key first through Azure CLI and used the key as input for the SSHKey parameter. And because this is just a lab environment i only deployed single instance AKS Management, Load Balancer and Worker nodes.
After exactly 3 minutes and 24 seconds the deployment is done and the Hybrid AKS cluster is deployed. Ready for Developers to deploy applications to.
There were times that I need to go to the gym to work on my Bicep, it turns out I can work on my Bicep from the office at my laptop. All cheesy jokes aside, I still go to the gym, but that’s not where this is all about. The ability to use Bicep and ARM templates with Azure Arc and Azure Stack HCI is exactly what cloud is all about. Being able to consume and use resources everywhere you need. Whether it is in public cloud, your own datacenter, industrial buildings or retail store you can use it everywhere. Use existing code with minimal change to deploy it were your users need it.
If you need any help or want to try it yourself in the Technology Experience Center.. get in touch!