Azure Resource Manager supports declarative infrastructure deployment through ARM templates and Bicep.
Both ultimately deploy through Azure Resource Manager.
The difference is primarily the authoring experience.
ARM templates use JSON.
Bicep provides a more concise Azure-specific language that compiles into an ARM template for deployment.
ARM JSON and Bicep both express desired Azure resource state; Bicep can make the same deployment intent easier to maintain through typed parameters and modules. Test the workflow rather than the syntax preference: run a what-if preview, inspect replacements or deletions, identify inherited policy constraints, and verify the resources after deployment. A Bicep file that compiles successfully can still attempt an unauthorized or destructive change. In independent AZ-104 infrastructure-as-code practice cases, distinguish a template that passes syntax validation from a deployment blocked by policy, insufficient authorization or an unsafe resource-property change. Neither compilation nor third-party practice material establishes that the actual Azure deployment is safe.
Both are declarative
Declarative infrastructure code describes the desired resource state.
Instead of writing an imperative script that says:
- create a virtual network
- create a subnet
- create a NIC
- create a VM
the template defines the resources and their properties.
Azure Resource Manager determines the dependency and deployment behavior from the declarations and explicit relationships.
This makes deployments repeatable.
The same template can be applied to development, test, and production with different parameter values.
Azure Resource Manager deployments can target more than one scope. Resource-group deployments are common, but supported templates and Bicep files can also operate at subscription, management-group, or tenant scope when the resource types and permissions fit that level. The deployment scope influences which resources can be declared directly and how cross-scope modules are structured.
This matters operationally because infrastructure code should match the ownership boundary. A subscription-level governance deployment should not be hidden inside a resource-group module, while an application module usually should not need tenant-wide privileges. Scope is therefore part of the template’s security and lifecycle design, not merely the place where the deployment command is executed.
ARM templates are JSON
An ARM template is a JSON document.
It can define:
- parameters
- variables
- functions
- resources
- outputs
ARM templates are powerful and have direct access to the Azure resource model.
The tradeoff is verbosity.
Large nested JSON structures can be difficult to read and edit manually.
Expressions can also become visually complex.
That is the problem Bicep was designed to improve.
Declarative deployment changes the operator’s question from “which CLI commands do I run?” to “what state should exist?” Azure Resource Manager performs the supported create or update operations for declared resources. Its default incremental deployment mode normally leaves entirely omitted resources in place, but redeploying a declared resource can reset omitted properties to their defaults; do not mistake incremental mode for a safe partial-property patch or an automatic cleanup of resources absent from the template.
That model makes repeatability possible, but it does not mean every deployment is automatically harmless. Changing an immutable property can require replacement, dependencies can fail, and a logically valid template can still describe the wrong architecture. Infrastructure as code needs review and testing just like application code.
Bicep is a higher-level authoring language
Bicep provides the same Azure Resource Manager deployment capabilities with more concise syntax.
Microsoft describes Bicep as easier to use and notes that a Bicep file is converted to an ARM template during deployment.
That means Bicep is not a separate Azure deployment engine.
Azure Resource Manager is still the deployment platform.
Bicep is the source language engineers write.
The compiled ARM representation is what Resource Manager consumes.
Bicep keeps the Azure Resource Manager deployment engine while removing much of the JSON ceremony. Symbolic resource names, concise expressions, loops, conditions, and modules make relationships easier to see in code review. Tooling can use the resource type definitions to surface property errors and completions before a deployment is submitted.
Bicep is transpiled into an ARM template for deployment, so adopting it does not create a second Azure control plane. The deployment history and resulting resources still belong to Azure Resource Manager. That is why teams can migrate authoring incrementally instead of replacing their deployment platform.
Bicep improves readability and type awareness
Bicep removes much of the JSON punctuation and repetitive structure.
It also provides language tooling such as type validation, resource-property awareness, and editor support.
That can catch some errors earlier in the authoring process.
For administrators, the practical advantage is maintainability.
A resource definition that is difficult to review is more likely to accumulate mistakes.
Infrastructure as Code is valuable partly because teams can review the proposed state before deployment.
Bicep makes that review easier for many Azure-native environments.
Existing ARM templates remain valid.
Bicep did not make ARM JSON obsolete.
Organizations may already have mature ARM templates, deployment systems, template specs, and tooling.
Those assets continue to work.
The decision to migrate should consider maintenance cost, team skills, and how actively the template is changing.
For a stable template that rarely changes, rewriting may provide little value.
For a large codebase under frequent development, Bicep’s readability and module system can improve long-term maintenance.
Existing ARM JSON remains supported, and Microsoft provides tooling to decompile many templates into Bicep as a migration starting point. Decompilation should be treated as refactoring assistance rather than as proof that the generated Bicep is the best maintainable design. Generated symbolic names, duplicated expressions, and nested structures often deserve cleanup before the code becomes the new source of truth.
A mixed environment is therefore normal during transition. Mature JSON templates can continue to deploy while new modules are authored in Bicep, provided the team keeps clear ownership of which file is authoritative for each resource set.
Parameters separate code from environment values
Both ARM templates and Bicep support parameters.
Parameters allow one infrastructure definition to be reused with environment-specific values such as:
- region
- naming prefix
- SKU
- instance count
- address space
- feature flags
Avoid hardcoding production-specific values into the main template when they logically vary between deployments.
That makes the code easier to promote across environments and reduces copy-paste variants.
Parameters should carry values that genuinely vary by environment: location, SKU, instance count, naming inputs, network ranges, or identifiers supplied by another deployment. Secrets should not be hard-coded into the template. Use secure parameter handling and a secret store or deployment pattern that avoids placing credentials in source control or ordinary deployment logs.
Outputs can expose values that another deployment or pipeline needs, but they should also avoid returning secrets. A clean parameter-and-output contract makes a reusable module easier to test and prevents environment-specific values from leaking into otherwise reusable infrastructure code.
Dependencies should express real resource relationships
Azure can infer many dependencies when one resource references another.
Explicit dependencies are still available where needed.
Do not add unnecessary dependencies “just to be safe.”
Over-constraining the graph can reduce deployment parallelism and make the template harder to understand.
A clean IaC definition describes actual relationships.
That is especially useful during updates because Resource Manager can evaluate which resources need to change and which do not.
Modules help keep Bicep maintainable
Bicep modules let a large deployment be divided into reusable units.
For example:
- networking module
- monitoring module
- VM module
- storage module
- identity module
The main deployment can then compose those units.
This is better than putting every resource in one giant file.
Modules also make ownership clearer when different platform teams maintain different layers.
Dependencies should usually be derived from actual resource references rather than manually declared everywhere. When one resource property references another resource’s symbolic name or ID, Bicep and ARM can infer the dependency in many cases. Explicit dependencies remain available for relationships the deployment engine cannot infer, but unnecessary dependsOn chains reduce parallelism and make the template harder to reason about.
Modules provide a second form of structure. A networking module can own the virtual network and subnets while a compute module consumes the relevant outputs. The boundary should reflect a meaningful lifecycle or ownership unit, not merely split a file after an arbitrary number of lines.
What-if reduces deployment surprises
Azure Resource Manager supports what-if analysis for supported deployments.
What-if compares the desired template state with the current environment and reports predicted changes.
That is especially useful before a production deployment.
The team can review whether the template will:
- create
- modify
- delete
- or leave resources unchanged
What-if is not a substitute for testing, but it gives administrators a valuable preview of resource-manager changes.
The what-if operation previews the resource changes Azure Resource Manager expects from a Bicep file or ARM template before deployment. It is particularly useful in production pipelines because reviewers can see proposed creates, deletes, and modifications using the same environment-specific parameter values that will be deployed.
What-if reduces deployment surprises, but it is not a guarantee. Microsoft documents expansion limits that can cause unevaluated resources to appear as Ignore, and nested linked templates or unresolved expressions can prevent full analysis. Review diagnostic messages and unexpected replacements or deletions before release; validation, a controlled deployment and post-deployment verification are still required.
Bicep is still code and needs DevOps discipline
A concise language does not automatically make the infrastructure safe.
Bicep files should still use:
- source control
- code review
- automated validation
- linting
- deployment testing
- environment separation
- least-privilege deployment identities
- secure secret handling
The broader DevOps practices associated with Azure administration matter just as much as syntax.
Actual operational skill comes from treating infrastructure definitions as production code rather than as one-off deployment snippets.
Which should you choose?
Choose Bicep when:
- the environment is Azure-focused
- the team wants concise syntax
- strong editor/type support is valuable
- reusable modules are important
- new IaC is being created
Use or retain ARM JSON when:
- existing mature templates already work
- another system generates ARM templates
- direct JSON representation is operationally useful
- migration cost is not justified
The important architectural point is that both deploy through Azure Resource Manager.
Bicep improves authoring.
ARM templates remain the underlying declarative deployment model.
For AZ-104, the practical workflow matters more than the syntax comparison alone: declare the desired resource state, keep environment values in parameters, express real dependencies, use modules for reusable boundaries, preview the deployment with what-if, deploy through Azure Resource Manager, and validate the resulting service. Bicep usually makes that workflow easier to author, while ARM JSON remains the deployment representation Azure understands.