With Bicep going full production since version 0.3, more and more companies have opened up to the use of it. Because Bicep is a lot easier to understand and maintain than ARM but still outputs ARM as the immutable artifact. It is a relatively small step to start using Bicep, but how to use your blessed templates you already invested so much time, effort, and money.
Yes. As of v0.3, Bicep is now supported by Microsoft Support Plans and Bicep has 100% parity with what can be accomplished with ARM Templates. As of this writing, there are no breaking changes currently planned, but it is still possible they will need to be made in the future.
GitHub readme
Examples used in this blog are simplified and not actually blessed templates, they should not be used as such in an production environment
Tl;Dr
You can use your existing Template Specs deployed in Azure tenant by referencing them as linked templates.
resource templatespec 'Microsoft.Resources/deployments@2021-01-01' = {
name: 'blessed-sa'
properties:{
templateLink:{
id : '/subscriptions/xxxx-xxxxx-xxxx-xxxx-xxxxxxx/resourceGroups/module-templates/providers/Microsoft.Resources/templateSpecs/StorageAccount/versions/0.2'
}
mode: 'Incremental'
parameters:{
name: {
value:'mystorageaccountname214'
}
}
}
}
Creating a simple blessed template
If you don’t already have some blessed templates or you are using some pipeline or GitOps strategy to enable reuse of these templates, your might want to take a look into the benefits of using Azure Template Specs:
- You use standard ARM templates for your template spec.
- You manage access through Azure RBAC, rather than SAS tokens.
- Users can deploy the template spec without having write access to the template
- You can integrate the template spec into existing deployment process, such as PowerShell script or Devops pipeline.
Even though it is no Bicep (yet), it doesn’t mean you cannot use these Template Specs. Let’s try it out by creating a simple Bicep (StorageAccount. Bicep) for the storage account, build it, and deploy it as a template spec.
param name string
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-04-01' = {
name: name
location: resourceGroup().location
properties: {
minimumTlsVersion: 'TLS1_2'
supportsHttpsTrafficOnly: true
encryption: {
services: {
file: {
keyType: 'Account'
enabled: true
}
blob: {
keyType: 'Account'
enabled: true
}
}
keySource: 'Microsoft.Storage'
}
}
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
tags: {}
}
resource blobservices 'Microsoft.Storage/storageAccounts/blobServices@2021-04-01' = {
name: 'default'
parent: storageAccount
}
output blobserviceId string = blobservices.id
az bicep build --file .\StorageAccount.bicep
az ts create `
-g module-templates `
--name StorageAccount `
-v 0.2 `
-l westeurope `
--template-file .\StorageAccount.json `
--display-name StorageAccount `
--description 'Blessed template for StorageAccount' `
--version-description "Simplified blessed template"
Consuming the blessed template with Bicep
To consume the deployed template, you can use the ‘Microsoft.Resource/deployments@2021-01-01’ resource and reference the blessed template and its explicit version using the ‘templateLink’. Pass the parameters for the template using the parameters: { <parametername>: { value: ''} }
.
targetScope = 'resourceGroup'
resource templatespec 'Microsoft.Resources/deployments@2021-01-01' = {
name: 'blessed-sa'
properties:{
templateLink:{
id : '/subscriptions/XXXX-XXXX-XXXX-XXXX-XXXXXX/resourceGroups/module-templates/providers/Microsoft.Resources/templateSpecs/StorageAccount/versions/0.2'
}
mode: 'Incremental'
parameters:{
name: {
value:'mystorageaccountname214'
}
}
}
}
Next, build and deploy your resource based on the blessed template.
az bicep build --file .\main.bicep
az deployment group create `
--template-file .\main.json `
--resource-group demo-blessed-bicep `
--output tsv
Use the outputs of your blessed templates
In some of the blessed templates, you want the consumer to continue with some values set by your templates. Usually, this is relatively easy to achieve by directly referring to the output of your modules and let IntelliSense help you do the rest. However, when you are using linked templates, you need to use the reference() function. Let’s see how that works.
Create the following as a deployment script. Bicep, this will just run a PowerShell script writing a message used to show the passed in value coming from the blessed template
param timestamp string = utcNow()
param dsName string = 'ds${uniqueString(resourceGroup().name)}'
param message string
resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
kind: 'AzurePowerShell'
name: dsName
location: resourceGroup().location
// identity property no longer required
properties: {
azPowerShellVersion: '3.0'
arguments: '-message \'${message}\''
scriptContent: '''
param([string] $message)
$DeploymentScriptOutputs["test"] = "test this output: [$message]"
'''
forceUpdateTag: timestamp // script will run every time
retentionInterval: 'PT1H' // deploymentScript resource will delete itself in 1 hour
}
}
output scriptOutput string = deploymentScript.properties.outputs.test
Next, reference to the module by adding the following to the main. Bicep. The first line references the newly added deploymentScript resource, and the 4th line references the output coming from our template spec. Using the reference(templatespec.name)
to get a link to the blessed template and the .outputs.blobserviceId
to the value outputted by the last line of the blessed template.
module runScript 'DeploymentScript/deployment-script.bicep' = {
name: 'runCustomScript'
params: {
message: string(reference(templatespec.name).outputs.blobserviceId)
}
}
Build and deploy.
az bicep build --file .\main.bicep
az deployment group create `
--template-file .\main.json `
--resource-group demo-blessed-bicep `
--output tsv
Conclusion
You can keep using or start creating your template specs with Bicep. By doing so, you are using Microsoft’s recommended way of sharing your infrastructure deployments templates with other teams in your organization. The only downside I see here is that only during runtime can you be sure that the Bicep script is correct because, at design time, it does not actively reach out to the template spec and retrieve the parameter values. This, by the way, is also an issue when you use ARM instead of Bicep, so it is no breaker for me. Let’s hope that it will be possible when Microsoft adds support for Bicep modules to be used as template specs.
Special thanks to Erwin Staal. He helped me understand that you can still use your template specs even when writing your Bicep.
Have Fun,
Erick
You must be logged in to post a comment.