Skip to content

[Resource] az bicep: Add snapshot and run subcommands#33398

Open
shenglol wants to merge 2 commits into
Azure:devfrom
shenglol:shenglol/bicep-cli-gaps
Open

[Resource] az bicep: Add snapshot and run subcommands#33398
shenglol wants to merge 2 commits into
Azure:devfrom
shenglol:shenglol/bicep-cli-gaps

Conversation

@shenglol
Copy link
Copy Markdown
Contributor

@shenglol shenglol commented May 19, 2026

Related command

  • az bicep snapshot
  • az bicep run

Description

  • az bicep snapshot: Wraps the Bicep CLI snapshot command (introduced in Bicep CLI 0.41.2) to capture or validate deployment snapshots from a .bicepparam file. Supports --mode, --tenant-id, --subscription-id, --management-group-id, --location, --resource-group, and --deployment-name.
  • az bicep run: Generic passthrough that forwards a quoted command string to the installed Bicep CLI, allowing use of CLI features that don't yet have a dedicated az bicep wrapper.
  • Uses shlex.split(..., posix=False) plus quote stripping so Windows paths with backslashes are preserved.
  • Adds unit tests (TestBicepSnapshot, TestBicepRun) and LiveScenarioTests (BicepSnapshotTest, BicepRunTest).

Closes Azure/bicep#19502.

Testing Guide

  • az bicep snapshot --file {file}
  • az bicep run --command "build {file}"

History Notes

  • [Resource] az bicep snapshot: New command to wrap the Bicep CLI snapshot command to capture or validate deployment snapshots from a .bicepparam file.
  • [Resource] az bicep run: New command that forwards a quoted command string to the Bicep CLI, allowing use of CLI features that don't yet have a dedicated az bicep wrapper.

This checklist is used to make sure that common guidelines for a pull request are followed.

- `az bicep snapshot`: Wraps the Bicep CLI `snapshot` command (introduced in Bicep CLI 0.41.2) to capture or validate deployment snapshots from a .bicepparam file. Supports `--mode`, `--tenant-id`, `--subscription-id`, `--management-group-id`, `--location`, `--resource-group`, and `--deployment-name`.
- `az bicep run`: Generic passthrough that forwards a quoted command string to the installed Bicep CLI, allowing use of CLI features that don't yet have a dedicated `az bicep` wrapper.
- Uses `shlex.split(..., posix=False)` plus quote stripping so Windows paths with backslashes are preserved.
- Adds unit tests (TestBicepSnapshot, TestBicepRun) and LiveScenarioTests (BicepSnapshotTest, BicepRunTest).
Copilot AI review requested due to automatic review settings May 19, 2026 22:17
@azure-client-tools-bot-prd
Copy link
Copy Markdown

azure-client-tools-bot-prd Bot commented May 19, 2026

️✔️AzureCLI-FullTest
️✔️acr
️✔️latest
️✔️3.12
️✔️3.13
️✔️acs
️✔️latest
️✔️3.12
️✔️3.13
️✔️advisor
️✔️latest
️✔️3.12
️✔️3.13
️✔️ams
️✔️latest
️✔️3.12
️✔️3.13
️✔️apim
️✔️latest
️✔️3.12
️✔️3.13
️✔️appconfig
️✔️latest
️✔️3.12
️✔️3.13
️✔️appservice
️✔️latest
️✔️3.12
️✔️3.13
️✔️aro
️✔️latest
️✔️3.12
️✔️3.13
️✔️backup
️✔️latest
️✔️3.12
️✔️3.13
️✔️batch
️✔️latest
️✔️3.12
️✔️3.13
️✔️batchai
️✔️latest
️✔️3.12
️✔️3.13
️✔️billing
️✔️latest
️✔️3.12
️✔️3.13
️✔️botservice
️✔️latest
️✔️3.12
️✔️3.13
️✔️cdn
️✔️latest
️✔️3.12
️✔️3.13
️✔️cloud
️✔️latest
️✔️3.12
️✔️3.13
️✔️cognitiveservices
️✔️latest
️✔️3.12
️✔️3.13
️✔️compute_recommender
️✔️latest
️✔️3.12
️✔️3.13
️✔️computefleet
️✔️latest
️✔️3.12
️✔️3.13
️✔️config
️✔️latest
️✔️3.12
️✔️3.13
️✔️configure
️✔️latest
️✔️3.12
️✔️3.13
️✔️consumption
️✔️latest
️✔️3.12
️✔️3.13
️✔️container
️✔️latest
️✔️3.12
️✔️3.13
️✔️containerapp
️✔️latest
️✔️3.12
️✔️3.13
️✔️core
️✔️latest
️✔️3.12
️✔️3.13
️✔️cosmosdb
️✔️latest
️✔️3.12
️✔️3.13
️✔️databoxedge
️✔️latest
️✔️3.12
️✔️3.13
️✔️dls
️✔️latest
️✔️3.12
️✔️3.13
️✔️dms
️✔️latest
️✔️3.12
️✔️3.13
️✔️eventgrid
️✔️latest
️✔️3.12
️✔️3.13
️✔️eventhubs
️✔️latest
️✔️3.12
️✔️3.13
️✔️feedback
️✔️latest
️✔️3.12
️✔️3.13
️✔️find
️✔️latest
️✔️3.12
️✔️3.13
️✔️hdinsight
️✔️latest
️✔️3.12
️✔️3.13
️✔️identity
️✔️latest
️✔️3.12
️✔️3.13
️✔️iot
️✔️latest
️✔️3.12
️✔️3.13
️✔️keyvault
️✔️latest
️✔️3.12
️✔️3.13
️✔️lab
️✔️latest
️✔️3.12
️✔️3.13
️✔️managedservices
️✔️latest
️✔️3.12
️✔️3.13
️✔️maps
️✔️latest
️✔️3.12
️✔️3.13
️✔️marketplaceordering
️✔️latest
️✔️3.12
️✔️3.13
️✔️monitor
️✔️latest
️✔️3.12
️✔️3.13
️✔️mysql
️✔️latest
️✔️3.12
️✔️3.13
️✔️netappfiles
️✔️latest
️✔️3.12
️✔️3.13
️✔️network
️✔️latest
️✔️3.12
️✔️3.13
️✔️policyinsights
️✔️latest
️✔️3.12
️✔️3.13
️✔️postgresql
️✔️latest
️✔️3.12
️✔️3.13
️✔️privatedns
️✔️latest
️✔️3.12
️✔️3.13
️✔️profile
️✔️latest
️✔️3.12
️✔️3.13
️✔️rdbms
️✔️latest
️✔️3.12
️✔️3.13
️✔️redis
️✔️latest
️✔️3.12
️✔️3.13
️✔️relay
️✔️latest
️✔️3.12
️✔️3.13
️✔️resource
️✔️latest
️✔️3.12
️✔️3.13
️✔️role
️✔️latest
️✔️3.12
️✔️3.13
️✔️search
️✔️latest
️✔️3.12
️✔️3.13
️✔️security
️✔️latest
️✔️3.12
️✔️3.13
️✔️servicebus
️✔️latest
️✔️3.12
️✔️3.13
️✔️serviceconnector
️✔️latest
️✔️3.12
️✔️3.13
️✔️servicefabric
️✔️latest
️✔️3.12
️✔️3.13
️✔️signalr
️✔️latest
️✔️3.12
️✔️3.13
️✔️sql
️✔️latest
️✔️3.12
️✔️3.13
️✔️sqlvm
️✔️latest
️✔️3.12
️✔️3.13
️✔️storage
️✔️latest
️✔️3.12
️✔️3.13
️✔️synapse
️✔️latest
️✔️3.12
️✔️3.13
️✔️telemetry
️✔️latest
️✔️3.12
️✔️3.13
️✔️util
️✔️latest
️✔️3.12
️✔️3.13
️✔️vm
️✔️latest
️✔️3.12
️✔️3.13

@azure-client-tools-bot-prd
Copy link
Copy Markdown

Hi @shenglol,
Since the current milestone time is less than 7 days, this pr will be reviewed in the next milestone.

@azure-client-tools-bot-prd
Copy link
Copy Markdown

azure-client-tools-bot-prd Bot commented May 19, 2026

⚠️AzureCLI-BreakingChangeTest
⚠️resource
rule cmd_name rule_message suggest_message
⚠️ 1001 - CmdAdd bicep run cmd bicep run added
⚠️ 1001 - CmdAdd bicep snapshot cmd bicep snapshot added

@microsoft-github-policy-service microsoft-github-policy-service Bot added the Auto-Assign Auto assign by bot label May 19, 2026
@microsoft-github-policy-service microsoft-github-policy-service Bot added ARM az resource/group/lock/tag/deployment/policy/managementapp/account management-group act-identity-squad labels May 19, 2026
@github-actions
Copy link
Copy Markdown

The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR.

Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions).
After that please run the following commands to enable git hooks:

pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds two new Bicep subcommands to the resource module: az bicep snapshot (wraps Bicep CLI's snapshot command, requires Bicep CLI v0.41.2+) and az bicep run (generic passthrough that forwards a quoted command string to the Bicep CLI, preserving Windows-style backslashes via shlex non-POSIX mode).

Changes:

  • Implements snapshot_bicep_file and run_bicep_cli_passthrough in custom.py, wired up via commands.py, _params.py, and _help.py.
  • Adds unit tests covering argument forwarding, version-gating, quote handling, and empty-command validation.
  • Adds LiveScenarioTest classes exercising the new commands end-to-end against the installed Bicep CLI.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/azure-cli/azure/cli/command_modules/resource/custom.py Adds snapshot_bicep_file and run_bicep_cli_passthrough implementations.
src/azure-cli/azure/cli/command_modules/resource/commands.py Registers the new snapshot and run commands under the bicep group.
src/azure-cli/azure/cli/command_modules/resource/_params.py Declares arguments for the new commands.
src/azure-cli/azure/cli/command_modules/resource/_help.py Adds help text and examples for bicep snapshot and bicep run.
src/azure-cli/azure/cli/command_modules/resource/tests/latest/test_resource_bicep.py Adds unit tests for the new custom functions.
src/azure-cli/azure/cli/command_modules/resource/tests/latest/test_resource.py Adds live scenario tests for bicep snapshot and bicep run.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +5673 to +5676
class BicepSnapshotTest(LiveScenarioTest):
def setup(self):
super().setup()
self.cmd('az bicep uninstall')
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d88079b — renamed both the method and the super() call to setUp in BicepSnapshotTest.

Comment on lines +5702 to +5705
class BicepRunTest(LiveScenarioTest):
def setup(self):
super().setup()
self.cmd('az bicep uninstall')
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d88079b — same correction applied to BicepRunTest.

Comment on lines +5683 to +5685
curr_dir = os.path.dirname(os.path.realpath(__file__))
params_file = os.path.join(curr_dir, 'sample_params.bicepparam').replace('\\', '\\\\')
snapshot_path = os.path.join(curr_dir, 'sample_params.snapshot.json')
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fixtures already exist in this directory and are reused by other Bicep tests (e.g. BicepBuildParamsTest). They were originally added in #26781. No new files are required for this PR.

Comment on lines +4614 to +4621
def run_bicep_cli_passthrough(cmd, command_string):
import shlex

# Use non-POSIX mode so that backslashes in Windows paths are preserved.
# In non-POSIX mode, shlex retains the surrounding quotes on quoted tokens,
# so strip them so the values are passed through cleanly to the Bicep CLI.
args = []
for token in shlex.split(command_string, posix=False):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d88079brun_bicep_cli_passthrough now calls ensure_bicep_installation(cmd.cli_ctx, stdout=False) at the start, matching the other az bicep wrappers, and the unit tests assert this. A fresh environment will now auto-install the Bicep CLI rather than failing with a confusing error.

Comment on lines +4610 to +4611
else:
logger.error("az bicep snapshot could not be executed with the current version of Bicep CLI. Please upgrade Bicep CLI to v%s or later.", minimum_supported_version)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d88079bsnapshot_bicep_file now raises ValidationError (from azure.cli.core.azclierror) when the installed Bicep CLI is older than the minimum supported version, so the command exits with a non-zero code and CI/scripts can detect the failure. test_snapshot_bicep_file_errors_when_bicep_too_old was updated to assert the raise.

c.argument('mode', arg_type=get_enum_type(['Overwrite', 'Validate']),
help="The snapshot mode. 'Overwrite' (default) writes the snapshot file. 'Validate' compares the existing snapshot against the current template and fails if differences are detected.")
c.argument('tenant_id', options_list=['--tenant-id'], help="The Azure tenant ID to use when capturing the snapshot.")
c.argument('subscription_id', options_list=['--subscription-id'], help="The Azure subscription ID to use when capturing the snapshot.")
Copy link
Copy Markdown
Contributor Author

@shenglol shenglol May 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarified in d88079b by expanding the --help text for --tenant-id, --subscription-id, --management-group-id, --location, --resource-group, and --deployment-name to call out that they are forwarded to the Bicep CLI as the deployment context used to resolve existing references in the snapshot, and are unrelated to Azure CLI authentication. The help for --subscription-id also explicitly points users to the global --subscription argument for switching the active subscription.

We intentionally kept the names aligned with bicep snapshot's native flags so that users coming from the Bicep CLI don't have to learn a new vocabulary. Happy to revisit (e.g. --snapshot-subscription-id) if you'd prefer the rename.

Comment on lines +767 to +768
c.argument('location', options_list=['--location'], help="The Azure location to use when capturing the snapshot.")
c.argument('resource_group', options_list=['--resource-group'], help="The Azure resource group name to use when capturing the snapshot.")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d88079b — switched --resource-group to resource_group_name_type and --location to get_location_type(self.cli_ctx), so users now get the standard -g / -l short flags, completion, and az configure --defaults integration consistent with the rest of the module.

Comment on lines +4614 to +4615
def run_bicep_cli_passthrough(cmd, command_string):
import shlex
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

az bicep run is intentionally a thin escape hatch for users to consume new Bicep CLI features (or one-off subcommands) without waiting for an az bicep wrapper to ship in azure-cli — so an allowlist of subcommands would defeat its purpose. The command runs the Bicep CLI as the same user, so it can't grant elevated privileges that the user wouldn't already have by invoking bicep directly, but the untrusted-input concern is fair: in d88079b the long-summary in --help now warns "Because the value is forwarded to the Bicep CLI without validation, do not pass strings derived from untrusted input." Wrappers for the most useful Bicep CLI subcommands continue to be added over time, and az bicep run is meant to bridge the gap in the meantime.

@yonzhan
Copy link
Copy Markdown
Collaborator

yonzhan commented May 19, 2026

Thank you for your contribution! We will review the pull request and get back to you soon.

@yonzhan yonzhan assigned isra-fel and unassigned zhoxing-ms May 20, 2026
@shenglol shenglol changed the title [Resource] az bicep: Add snapshot and run subcommands [Resource] az bicep: Add snapshot and run subcommands May 22, 2026
- Fix setup -> setUp typo in BicepSnapshotTest and BicepRunTest so the pre-test az bicep uninstall actually runs.
- Call ensure_bicep_installation at the start of run_bicep_cli_passthrough so a fresh environment auto-installs the Bicep CLI (matching the other az bicep wrappers).
- Raise ValidationError (instead of only logging) in snapshot_bicep_file when the installed Bicep CLI is older than the minimum supported version, so failures surface with a non-zero exit code.
- Use shared resource_group_name_type and get_location_type for az bicep snapshot's --resource-group/--location so users get the standard -g/-l short flags.
- Clarify in --help that --tenant-id/--subscription-id/--management-group-id/--location/--resource-group/--deployment-name on az bicep snapshot are forwarded to the Bicep CLI as deployment context (used to resolve existing references) and are unrelated to Azure CLI authentication.
- Add a security note to az bicep run --help warning against passing untrusted input.
@shenglol shenglol requested a review from MaddyMicrosoft as a code owner May 22, 2026 04:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

act-identity-squad ARM az resource/group/lock/tag/deployment/policy/managementapp/account management-group Auto-Assign Auto assign by bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

az bicep featurure parity

5 participants