Bicep pipeline basics

Bicep pipeline basics

After the series of blog posts about Terraform and Azure DevOps, lets dive into Bicep and build a pipeline.

In this blog I shall highlight information about Bicep deployment modes, (Bicep) Linter, what-if operations with preflight validation and good practices.

Also I will refer to mainly Microsoft documentation. I find that the Microsoft documentation and learn sites are great and contain the information needed to learn. So, going into too much detail explaining what is already documented would be a waste of time 😉

In a previous post regarding IaC tool selection, Bicep is also mentioned:IaC Tool selection, where to start? – Cloudfive

New to Bicep? Watch this video:

Table of Contents

Bicep deployment modes

Bicep (Azure Resource Manager) supports two deployment modes:
 

Incremental mode

This is the default mode used by Azure Resource Manager. In this mode Resource Manager won’t delete anything. Bicep builds based on a template. With existing resources not specified in the template, these existing resources are left alone. Resources specified in the template are added if they don’t exist. Existing resources are updated based on the configuration in the template.

Complete mode

To run in complete mode, you must explicitly ask the deployment to run in this mode. Using this mode, Azure Resource Manager deletes resources that exist in the Resource Group but are not specified in the Bicep template.

Azure CLI example for setting deployment mode parameter:

				
					az deployment group create \
  --mode Complete \
  --name ExampleDeployment \
  --resource-group ExampleResourceGroup \
  --template-file storage.json
				
			

Caution: When applying complete mode, all resources not defined in the template file are removed!

Deployment scope

Complete mode is only available when deploying to a resource group. So, it is not available when deploying to a subscription, management group, or a tenant.

Example what-if output with “Complete” deployment mode:

What is a Linter?

A linter is a tool to help you improve your code. Linters can provide information to speed up debugging.

‘The Bicep linter checks Bicep files for syntax errors and best practice violations. The linter helps enforce coding standards by providing guidance during development. You can customize the best practices to use for checking the file.’

Use Bicep linter – Azure Resource Manager | Microsoft Docs

What is preflight validation?

A check for succesful deployment to Azure environment. Additional checks include:

  • Valid naming context for your Bicep resources valid;
  • Names already taken for Bicep resources;
  • Region checks for resource deployments.

Lint and validate your Bicep code – Training | Microsoft Docs

What-if operation

Preview the changes when deploying a Bicep file.

Overall Good practices

Working with environments

Using the environments feature in Azure Pipelines makes it possible to link deployments to an environment. An environment owner can define checks and approvals which are inherited by deployments. It is important to establish good practices to review your pipeline definitions. Your repository can be configured to require pull request reviews on any changes to your main branch by using branch protection policies (like explained in: Terraform and Azure DevOps | Part 3 – Cloudfive).

More about working with the environments feature with Azure pipelines: Create target environment – Azure Pipelines | Microsoft Docs

Additional check and approvals

Adding additional checks and approvals to service connections, ensures that approval is needed before deployment.

Separate service connection

In certain stages you could use an additional separate service connection (service principal), for example the what-if stage. It is possible to have a custom Azure role defined based on least privileges (minimum permissions needed for execution).

Example

Prerequisites

Project in Azure DevOps > https://dev.azure.com/ (First 5 users free)

Azure Subscription > https://portal.azure.com/ (Free Trial Azure subscription)

Demo code can be downloaded at: Git CloudFive the  repository consists of three files:

  • azure-pipelines.yml
  • bicepconfig.json > Linter configuration
  • main.bicep > Bicep template


If you don’t have your own test project available or you are to lazy 😉 It is also possible to run a template and set up your Azure DevOps project.
View steps @ Exercise – Set up your environment – Training | Microsoft Docs

The result

In this example an Azure pipeline is built which consists of three stages:

  • Lint > linting of Bicep file
  • Validate > Is the Bicep template likely to deploy? Are names for resources already taken? Are resources valid?
  • Deploy > Deploy resources
 
The stages are defined in the yml file below:
				
					stages:
  - stage: Lint
    jobs: 
    - job: LintCode
      displayName: Lint code
      steps:
        - script: |
            az bicep build --file deploy/main.bicep
          name: LintBicepCode
          displayName: Run Bicep linter
          
  - stage: Validate
    jobs: 
    - job: ValidateBicepCode
      displayName: Validate Bicep code
      steps:
        - task: AzureResourceManagerTemplateDeployment@3
          name: RunPreflightValidation
          displayName: Run preflight validation
          inputs:
            connectedServiceName: $(ServiceConnectionName)
            location: $(deploymentDefaultLocation)
            deploymentMode: Validation
            resourceGroupName: $(ResourceGroupName)
            csmFile: deploy/main.bicep
            overrideParameters: >
              -environmentType $(EnvironmentType)          

  - stage: Deploy
    jobs:
    - job: Deploy
      steps:
        - task: AzureResourceManagerTemplateDeployment@3
          name: Deploy
          displayName: Deploy to Azure
          inputs:
            connectedServiceName: $(ServiceConnectionName)
            deploymentName: $(Build.BuildNumber)
            location: $(DeploymentDefaultLocation)
            resourceGroupName: $(ResourceGroupName)
            csmFile: deploy/main.bicep
            overrideParameters: >
              -environmentType $(EnvironmentType)
				
			
Share:
LinkedIn
Robert Knoester

Written by:

Get in touch with us.

Interested in taking the next step for your career? Let’s get to know each other.