Azure Bicep: Extension and local deploy


Bicep was created with a single goal: to simplify Azure resource deployment. Instead of writing verbose JSON, Bicep gives us a cleaner, more concise way to define infrastructure.

But here’s the catch: like most Infrastructure as Code (IaC) tools, Bicep traditionally only deploys Azure resources. Modern deployments often require more than that; they need configuration tasks, data plane actions, or external integrations. The result? You end up gluing together multiple scripts in your pipeline, breaking the IaC promise of having a single source of truth.

This is the purpose of Extension in Bicep. Extension is about doing things beyond the Azure Resource Manager.

How does it work? When a Bicep template is published, the Azure Resource Manager API determines if a resource coded in the template should be deployed (like a storage account) or if another API should be used (like the Graph API for Entra resource).

I already talked about the Azure Graph API for Bicep extension. This extension is generally available.

For an extension to work, the Azure Resource Manager API needs to be able to contact an external API. This is a huge limitation. Extensions must live inside the Azure ecosystem. This is the case for the Microsoft Graph and the Kubernetes extensions. Anything else was impossible.

But with the Bicep Local deploy, experimental feature deployment occurs on the local devices without interacting with the Azure Resource Manager API.
Local Deploy is a new experimental feature; you need to update your Bicep CLI (at least v0.30) to use it.

There are already several extensions available; you can use them to make HTTP calls, manage GitHub or Azure DevOps, create passwords, execute scripts locally, and other things.

You can get more information on these GitHub pages bicep-extensions and Bicep GitHub Doc.

You can also create your own extension (but it is beyond the subject of this post), check this and this post

For this post, I will use two extensions, [bicep-ext-local}(https://github.com/anthony-c-martin/bicep-ext-local) to run scripts and bicep-ext-PassWordGenerator (https://github.com/anthony-c-martin/bicep-ext-local) to generate random passwords.

Keep in mind that local extensions run on the device where the Bicep code is executed. You need to check if the extension is compatible with your OS (Windows and Linux ARM may not be available).

To use these extensions and the local deploy feature, the Bicep configuration must be updated. A bicepconfig.json file needs to be created in the same folder (or a parent folder) of the bicep files. You can check the documentation on this page.

We need to indicate Bicep to use the experimental local deploy feature and which extension to use. But also, as we need to manipulate passwords and want to print them for the demonstration, Bicep will return a warning (outputs-should-not-contain-secrets). The linter should be modified to avoid this warning.

the bicepconfig.json file

{
  "experimentalFeaturesEnabled": {
    "localDeploy": true
  },
  "extensions": {
    "PassWordGenerator": "br:bicepextsys4opsacr.azurecr.io/extensions/passwordgenerator:0.1.0",
    "local": "br:bicepextdemo.azurecr.io/extensions/local:0.1.3"
  },
  "analyzers": {
    "core": {
      "rules": {
        "outputs-should-not-contain-secrets": {
          "level": "off"
        }
      }
    }
  }
}
Enter fullscreen mode

Exit fullscreen mode

The BicepConfig file allows to use of the experimental feature, use the two extensions (passwordgenerator and local), and change the linter to not show a warning when a password is used in the output.

The Bicep code used (main.bicep)

targetScope="local"

extension PassWordGenerator
extension local

resource password 'GeneratedPassword'  = {
  name: 'pass'
  properties: {
    includeLower: true
    includeUpper: false
    includeDigits: true
    includeSpecial: false
    passwordLength: 20
  }
}

resource sayHelloWithPowerShell 'Script' = {
  type: 'powershell'
  script: replace(loadTextContent('./pwshscript.ps1'), '$input', 'dev.to')
}

output sayHelloWithPowerShell string = sayHelloWithPowerShell.stdout
output password string = password.output 
Enter fullscreen mode

Exit fullscreen mode

The first thing to notice is the TargetScope statement. The value, local, indicates that local deploy will be used. Without enabling it in the bicepconfig file, it will generate an error.

As you can only have one TargetScope statement in a deployment, including linked modules, you can only deploy locally.

The two extension statements import the extension defined in the bicepconfig file.

Then we have the two resources, the password and the script.
The first one generates a random 20-character string in lowercase, the second one executes a script, pwshscript.ps1, in the same folder.

Write-Host "Hello from Bicep $($input)"

If you try to deploy the template, like any other template using Azure CLI or Azure PowerShell, you will get an “InvalidTemplateDeployment “error.

"details": [ 
{ 
"code": "UnknownExtension", 
"message": "Unknown extension 'PassWordGenerator'.", 
"target": "/resources/password" 
}, 
{ 
"code": "UnknownExtension", 
"message": "Unknown extension 'Local'.", 
"target": "/resources/sayHelloWithPowerShell" 
} 
] 
Enter fullscreen mode

Exit fullscreen mode

To use local deploy, the latest version of Bicep CLI is needed. The command to use is:

bicep local-deploy <PathToBicepParamFile>

You need to provide a bicep parameter file and not the path to the bicep template.
In the same directory as the Bicep template, main.bicep, and the PowerShell script pwshscript.ps1, we need a main.bicepparam file.

A bicepparam file defines values of parameters, but the template doesn’t have any parameters; it only needs to have a using close referencing the main.bicep.

using 'main.bicep'

Running bicep local-deploy produces this output

password │ 5gmj6e7qrxktvxsuzakr
sayHelloWithPowerShell │ Hello from Bicep

Local Deploy is still experimental and limited, but it’s a big step forward. Combined with extensions like Microsoft Graph, it reduces the need for configuring resources or managing data plane and makes Bicep a true central point for both infrastructure and configuration.



Source link