Publish Bicep code from a deployment pipeline
When you automate the publishing process for a template spec or a Bicep module, you need to ensure that everything you normally do manually can be automated and run within the pipeline. In this unit, you apply principles you previously learned to publish template specs and Bicep modules from a deployment pipeline.
Template specs and modules
Bicep enables you to easily reuse your code. Two common approaches for reusing your Bicep code across deployments are:
- Template specs, which are optimized for the deployment of complete solutions. For example, suppose you've defined a set of security-hardened resources to deploy a complete virtual machine according to your company's specifications. You could publish this code as a template spec. Your colleagues could then use your template spec to deploy a complete virtual machine, even from the Azure portal.
- Modules, which are designed to be components of other deployments. For example, suppose you've created a Bicep file that creates a storage account. You're likely to need storage accounts in many other deployments, so you could publish the Bicep file to a registry and use it as a module throughout your organization's deployments.
When you're deciding between template specs and Bicep modules, a good rule of thumb is: if the template is going to be deployed as is throughout your organization, template specs are probably a good fit. But if you're likely to reuse this template within multiple parent templates, Bicep modules might serve your needs better.
Validate reusable code in a pipeline
Unlike regular Bicep deployments, when you create a template spec or a module, you don't deploy the resources directly to Azure. Instead, you publish the template spec or module. Then you can use the template spec or module in another deployment. That deployment then deploys the resources you've defined. Consequently, the ways that you validate and test your template specs and Bicep modules can differ from the process that you use for regular Bicep deployments.
Linting your Bicep code is good practice. The linter detects syntactical problems, and it warns you if you're not following the recommended practices.
Beyond linting, you might want to consider testing your template specs and modules by using preflight validation. You might even consider deploying your template specs and modules to Azure and testing that the resources they create behave as you expect. However, it can be challenging to run these types of tests from a deployment pipeline for two reasons:
- Preflight validation and deployments require an Azure environment to deploy the resources to. You might need to maintain a dedicated Azure subscription or resource group to use for deploying and testing your modules.
- Many template specs and modules require you to specify a set of parameters. You might need to create a test set of parameters for your template specs or modules to use when they're deployed.
You'll need to decide whether to include pipeline steps that deploy and test your template specs and modules. In this Microsoft Learn module, we lint the Bicep code but don't include other forms of testing. If you want to test your template specs and modules, consider how you deploy them to Azure. Also consider whether to use dedicated subscriptions or resource groups to deploy the resources.
Tip
We recommend that you review Test your Bicep code by using Azure Pipelines for more information on how to test your Bicep files in an automated pipeline.
Authentication and authorization
When you publish template specs to Azure yourself, your Microsoft Entra user needs to be granted access to the resource group that contains the template spec resource. Likewise, when you publish a Bicep module to a registry, your Microsoft Entra user needs to have permission to write to the Azure Container Registry instance that your organization uses for its Bicep modules.
When you work with an automated deployment pipeline, the same principles apply. However, because you aren't the person running the deployment, you need to ensure that your pipeline's service principal is given the appropriate access to the resource group for publishing the template spec, or to the container registry for publishing modules.
Tip
When you publish a module to a registry, the service principal running the deployment probably doesn't need a lot of permission. When your registry uses Microsoft Entra authorization, the service principal needs only the AcrPush permission on the registry.
Consider using the security principle of least privilege. Provide the pipeline's service principal with access only to the container registry, and not to a resource group or subscription.
Publish template specs and modules from a pipeline
When you publish a template spec from your own computer by using the Azure CLI, you use a command like the following one:
az ts create \
--name StorageWithoutSAS \
--resource-group MyResourceGroup \
--location westus3 \
--display-name "Storage account with SAS disabled" \
--description "This template spec creates a storage account, which is preconfigured to disable SAS authentication." \
--version 1 \
--template-file main.bicep
You can convert this Azure CLI command to a pipeline step:
- task: AzureCLI@2
name: Publish
displayName: Publish template spec
inputs:
azureSubscription: $(ServiceConnectionName)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az ts create \
--name StorageWithoutSAS \
--resource-group MyResourceGroup \
--location westus3 \
--display-name "Storage account with SAS disabled" \
--description "This template spec creates a storage account, which is preconfigured to disable SAS authentication." \
--version 1 \
--template-file main.bicep
The pipeline uses the same process to publish the template spec that you would use yourself.
Similarly, when you publish a Bicep module from your own computer by using the Azure CLI, you use a command like the following one:
az bicep publish \
--file module.bicep \
--target 'br:toycompany.azurecr.io/mymodules/myqueue:2'
You can convert this Azure CLI command to a pipeline step, too:
- task: AzureCLI@2
name: Publish
displayName: Publish Bicep module
inputs:
azureSubscription: $(ServiceConnectionName)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az bicep publish \
--file module.bicep \
--target 'br:toycompany.azurecr.io/mymodules/myqueue:2'
Tip
In this example, the Bicep registry's host name (toycompany.azurecr.io
) is embedded in the pipeline step definition. This isn't a good practice. You can use environment variables to set configuration settings like this. You'll see how this works later in this Microsoft Learn module.
How to publish a template spec from a pipeline is described in this unit.
Use a module or template spec
In previous Microsoft Learn training modules, you learned how to deploy the resources defined in template specs, and how to use Bicep modules stored in registries. Whether you publish your template specs and modules manually or from a deployment pipeline, you use and deploy them in the same way.
For example, you deploy a template spec or Bicep file to a resource group by using the az deployment group create
Azure CLI command, or the New-AzResourceGroupDeployment
cmdlet with Azure PowerShell.