Exporting Deployments as ARM Templates
Exporting from Existing Resources
Azure Resource Manager (ARM) templates are JSON files that use declarative syntax to define Azure infrastructure. You can export a template from a deployment that already exists using the Azure portal, PowerShell, or Azure CLI. In the portal, navigate to the resource group, select a deployment from the history, and choose the Template option to view and download the exact template used. With PowerShell, run Export-AzResourceGroup to export all resources in a group, or pass individual resource IDs. With Azure CLI, run az group export for the same result. The exported template captures the current state of the resource group, including any manual changes made after the original deployment.
Export Options and Their Tradeoffs
There are two paths to export a template. Export from a resource group or resource creates a snapshot of the live state, meaning it includes post-deployment modifications and can be used to recreate the environment as it is now. Save from history retrieves the exact template that was submitted during the original deployment, which is parameterized and ready to reuse without capturing manual changes. Choosing the right method depends on whether you need to preserve later tweaks or want a clean, repeatable starting point. Be aware that exporting is not guaranteed to succeed for every resource—some services, such as Azure Data Factory and certain Virtual Machine extensions, are not supported. Additionally, the resource group must contain 200 or fewer resources for the export to work, and sensitive information like passwords is stripped out of the exported file for security.
Converting ARM Templates to Bicep
Bicep is a domain-specific language that provides the same capabilities as ARM templates but with a simpler, more readable syntax. To convert an existing JSON template to a Bicep file, use the bicep decompile command or the Azure CLI equivalent az bicep decompile --file . In Visual Studio Code, you can paste JSON as Bicep or use the Decompile into Bicep command directly. The Bicep Playground lets you view both formats side by side. The decompilation process is a best-effort translation; not all ARM template features map perfectly to Bicep, so you must review the output for correctness. After conversion, the Bicep file takes advantage of symbolic resource names, string interpolation, and natural comments, which improve readability and maintainability compared to the verbose JSON syntax.
Best Practices and Limitations in Template Export and Conversion
Choosing the Right Export Method
The two export methods serve different goals. Export from a resource is best when you want to capture manual changes or resources that were never created through a template; it gives you a snapshot of the live environment. Save from history is best when you need a deployment-ready, parameterized template that matches the original plan. Understanding this tradeoff helps you avoid generating templates that contain unintended modifications or that are missing the parameters you need.
Limitations of Template Export
Template export is not a foolproof way to produce production-ready code. Certain resources, including Azure Data Factory and specific Virtual Machine extensions, cannot be exported and must be recreated manually. The export is limited to resource groups with 200 or fewer resources. Exported templates may also use older API versions that do not support the latest features. Because sensitive information like passwords is excluded, you must plan to supply those values separately when deploying. These limitations mean that for complex or security-sensitive environments, hand-written Bicep files, ARM templates, or Terraform are often a better starting point.
Refactoring After Conversion
After exporting or converting a template, the Refactor phase is essential. Review the API versions used in the generated file and update them to the latest supported versions. Simplify complex expressions and use Bicep features such as string interpolation to make the code clearer. Run the Bicep linter to catch potential errors, and standardize naming conventions. Modularizing large templates into smaller, reusable components improves long-term maintainability. Finally, use the what-if operation to preview the exact changes that the template will make before deploying. This tool compares the desired state in the template with the current environment so you can prevent accidental deletions or misconfigurations. Always test in a non-production environment first and have a documented rollback plan ready.
Conversion of ARM Templates to Bicep Files
The primary tools for converting ARM templates to Bicep are the Bicep CLI and the Bicep extension for Visual Studio Code. The command bicep decompile or az bicep decompile --file attempts a best-effort translation of the JSON template into an equivalent Bicep file. In Visual Studio Code, you can also use the Paste JSON as Bicep feature or the Decompile into Bicep command. The Bicep Playground allows you to view both formats side by side for learning and comparison. While the decompiler handles most common patterns, it may not use the latest API versions or take full advantage of Bicep features such as string interpolation and symbolic resource names. Always review the generated Bicep file for correctness before using it in production.
Structure and Syntax Differences
Bicep syntax is far more concise than ARM JSON. It eliminates the need for bracketed expressions like [ ... ] and allows direct function calls and property access. Resource declarations use symbolic names, making the template easier to read and manage. Parameters, variables, and outputs can be declared anywhere in the file, unlike ARM templates which require specific sections. Modularity is improved through Bicep modules, which let you break a large template into reusable, linked files. Comments and descriptions are naturally supported, aiding documentation and collaboration within a team.
Migration Workflow
Migrating from ARM templates to Bicep follows a structured five-phase workflow. First, Convert: capture the ARM template and decompile it to Bicep using the CLI or Visual Studio Code. Second, Migrate: create a new Bicep file, copy over the resources, and manually add any elements that were missing from the decompiled output. Third, Refactor: update API versions, revise names, simplify expressions, modularize the code, and add comments. Fourth, Test: use the what-if operation to preview changes and perform test deployments to validate the template. Fifth, Deploy: roll out the Bicep template to production, ensuring a rollback plan and post-deployment validation are in place. This workflow ensures that the conversion is safe and that the resulting Bicep file is production-ready.