Skip to content

Bicep Best Practices

Azure Bicep is a Domain Specific Language (DSL) for deploying Azure resources declaratively. It is a language that is designed to be a more readable and maintainable way to define Azure resources.

Bicep comes with a linter that detects various faults, but also comes with online best practices which are not completely covered by the linter.

Web App Basic Linux

The following is a Bicep file that deploys a web app with a Linux app service plan. It is the microsoft.web/webapp-basic-linux/main.bicep sample template in the bicep playground.

web-app-basic-linux.bicep
@description('Base name of the resource such as web app name and app service plan ')
@minLength(2)
param webAppName string = 'AzureLinuxApp'
@description('The SKU of App Service Plan ')
param sku string = 'S1'
@description('The Runtime stack of current web app')
param linuxFxVersion string = 'php|7.4'
@description('Location for all resources.')
param location string = resourceGroup().location
var webAppPortalName = '${webAppName}-webapp'
#disable-next-line genaiscript
var appServicePlanName = 'AppServicePlan-${webAppName}'
resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
name: appServicePlanName
location: location
sku: {
name: sku
}
kind: 'linux'
properties: {
reserved: true
}
}
resource webAppPortal 'Microsoft.Web/sites@2022-03-01' = {
name: webAppPortalName
location: location
kind: 'app'
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
linuxFxVersion: linuxFxVersion
ftpsState: 'FtpsOnly'
}
httpsOnly: true
}
identity: {
type: 'SystemAssigned'
}
}

Script

The file is linter clean, but some improvements could be made with best practices. The following script will apply best practices to the Bicep file.

bicep-best-practices.genai.mjs
script({
title: "Bicep Best Practices",
temperature: 0,
system: ["system", "system.annotations"]
})
def("FILE", env.files, { endsWith: ".bicep" })
$`You are an expert at Azure Bicep.
Review the bicep in FILE and generate errors to enhance the script base on best practices
(https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/best-practices).
- Generate the top 3 most important annotations.
- Limit range to a single line.
- Do NOT generate notes.
- If a line starts with "#disable-next-line genaiscript", ignore the next line.
`
  • line numbers are added to the file content to help the LLM precisely locate the issues.
def("FILE", env.files, { endsWith: ".bicep", lineNumbers: true })
  • the script uses a builtin support for annotations to generate parseable warnings and errors. Annotations are automatically integrated as problems in VSCode or as build errors in the CI/CD pipeline.
$`... and generate annotations ...`
  • added support to ignore false positives using the #disable-next-line genaiscript comment
$`- If a line starts with "#disable-next-line genaiscript", ignore the next line.`
  • GPT-4 already knows about the best practices for Bicep, no need to repeat them!

Results

The LLM generates 3 annotations for the Bicep file. The annotations are surfaced as squiggly lines in VSCode.

Screenshot of a code editor displaying a Bicep file with parameters for an Azure web app. The parameters include webAppName, sku, linuxFxVersion, and location. There are warnings at the bottom suggesting to use a secure and unique default value for 'webAppName', specify the runtime stack more dynamically, and consider adding a 'reserved' property within 'siteConfig'.