[ARM] Fix bicep template size inflation with differential template handling#32169
[ARM] Fix bicep template size inflation with differential template handling#32169
Conversation
- Bicep files now use JSON objects directly to prevent Azure SDK string escaping size inflation - ARM template files continue using string content with JsonCTemplatePolicy for JSONC compatibility - URI-based deployments use template_link without local processing - Conditional JsonCTemplatePolicy application only for ARM template files - Fixes false '4MB template too large' errors for bicep templates under the actual limit This implements a bicep-specific solution rather than modifying JsonCTemplatePolicy globally, ensuring ~20% size reduction for bicep templates while maintaining full ARM template compatibility.
- Extract _process_template_file helper function to handle bicep/ARM template processing - Reduces branches in _prepare_deployment_properties_unmodified - Maintains all existing functionality while improving code organization
- Extract _get_template_for_deployment helper function - Fix trailing whitespace issue - Reduces branch count in main function for pylint compliance
- Replace elif statements with separate if statements after return - Improves code clarity and follows pylint best practices
- Remove trailing whitespace from blank lines - Final style cleanup for CI compliance
…ts string content, not JSON objects
…e_file for consistency and DRY principle
The condition 'and not (template_file and is_bicep_file(template_file))' is no longer needed because: - JsonCTemplatePolicy only affects string content, not JSON objects - Bicep files use JSON objects (template_obj) directly - ARM templates use string content (template_content) where policy applies - Therefore, JsonCTemplatePolicy can always be applied safely
Clarifies that _deploy_arm_template_core_unmodified is resource-group-specific, so the hardcoded 'resourceGroup' scope is intentional and correct.
- Added TestTemplateSizeOptimization class with 8 focused unit tests - Tests validate differential handling between bicep and ARM templates - Bicep templates use template objects (size optimized) - ARM templates use template content (backward compatible) - URI deployments use template links (unchanged behavior) - All tests pass and existing functionality preserved - Validates size optimization benefits while maintaining compatibility
- Add @live_only() decorator to BicepTemplateSizeOptimizationScenarioTest methods - Aligns with existing bicep test patterns (test_bicep_generate_params_*, test_bicep_lint_*, etc.) - Prevents Bicep CLI dependency issues in CI/CD playback mode - Removes redundant import statements (tempfile, os already imported at module level) - Unit tests continue to run in CI/CD ensuring core functionality validation
|
Validation for Azure CLI Full Test Starting...
Thanks for your contribution! |
|
Hi @vhvb1989, |
|
Validation for Breaking Change Starting...
Thanks for your contribution! |
|
Thank you for your contribution! We will review the pull request and get back to you soon. |
|
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). pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>
|
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a critical issue where bicep templates experience significant size inflation during Azure CLI deployment processing, causing deployments to fail when templates approach the 4MB ARM template size limit. The fix implements differential template handling: bicep templates use compact JSON strings to avoid size inflation, while ARM templates maintain existing logic for JsonC compatibility.
Key changes:
- Optimized bicep template processing to prevent size inflation caused by string representation overhead
- Added comprehensive test coverage with 8 unit tests and 2 scenario tests
- Fixed CI/CD compatibility by adding appropriate
@live_only()decorators to scenario tests
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
src/azure-cli/azure/cli/command_modules/resource/custom.py |
Core optimization logic implementing differential bicep vs ARM template handling |
src/azure-cli/azure/cli/command_modules/resource/tests/latest/test_resource_custom.py |
Comprehensive test suite with unit tests and scenario tests using proper @live_only() decorators |
src/azure-cli/azure/cli/command_modules/resource/tests/latest/recordings/*.yaml |
VCR recordings for automated CI/CD testing |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| with tempfile.NamedTemporaryFile(mode='w', suffix='.bicep', delete=False) as f: | ||
| f.write(bicep_content) | ||
| bicep_file_path = f.name |
There was a problem hiding this comment.
The test is missing the import for tempfile module. Add import tempfile to the imports section at the top of the file.
| if os.path.exists(bicep_file_path): | ||
| os.unlink(bicep_file_path) |
There was a problem hiding this comment.
The test is missing the import for os module. Add import os to the imports section at the top of the file.
| mock_validate.return_value = None # No validation errors | ||
|
|
||
| # Act | ||
| template_content, template_obj = _process_template_file(cmd, "test.bicep", "resourceGroup") |
There was a problem hiding this comment.
The test is using an undefined variable cmd. Add a mock or fixture for the cmd parameter to prevent test failures.
| mock_remove_comments.return_value = mock_template_obj | ||
|
|
||
| # Act | ||
| template_content, template_obj = _process_template_file(cmd, "test.json", "resourceGroup") |
There was a problem hiding this comment.
The test is using an undefined variable cmd. Add a mock or fixture for the cmd parameter to prevent test failures.
| mock_get_template.return_value = compact_json # This is the key - bicep uses compact JSON string | ||
|
|
||
| # Act | ||
| properties = _prepare_deployment_properties_unmodified(cmd, "resourceGroup", "test.bicep", None, None, None, None) |
There was a problem hiding this comment.
The test is using an undefined variable cmd. Add a mock or fixture for the cmd parameter to prevent test failures.
| mock_get_template.return_value = mock_template_content # ARM uses template_content | ||
|
|
||
| # Act | ||
| properties = _prepare_deployment_properties_unmodified(cmd, "resourceGroup", "test.json", None, None, None, None) |
There was a problem hiding this comment.
The test is using an undefined variable cmd. Add a mock or fixture for the cmd parameter to prevent test failures.
| mock_urlretrieve.return_value = b'{"resources": []}' | ||
|
|
||
| # Act | ||
| properties = _prepare_deployment_properties_unmodified(cmd, "resourceGroup", None, "https://example.com/template.json", None, None, None) |
There was a problem hiding this comment.
The test is using an undefined variable cmd. Add a mock or fixture for the cmd parameter to prevent test failures.
…cep-template-size-inflation-clean
Summary
This PR fixes a critical issue where bicep templates experience significant size inflation during Azure CLI deployment processing, causing deployments to fail when templates approach or exceed the 4MB ARM template size limit.
Problem
When deploying bicep templates through Azure CLI, the templates undergo unnecessary size inflation due to:
Solution
Core Fix
_get_template_for_deploymentincustom.pyto return compact JSON strings for bicep templates usingjson.dumps(template_obj, separators=(',', ':'))Test Coverage
@live_only()decoratorsCI/CD Test Fix
Fixed CI/CD test failures by aligning bicep scenario tests with existing patterns:
Problem in CI/CD
The scenario tests were failing in CI/CD with .NET dependency errors:
This occurred because scenario tests were trying to execute Bicep CLI in CI/CD playback mode where:
Solution Applied
Added
@live_only()decorators to scenario tests, following the established pattern used by ALL existing bicep tests:Examples of Existing Bicep Tests Using
@live_only():Our Tests Now Follow Same Pattern:
Why This Approach Works
Testing
Unit Tests (Run in CI/CD)
pytest test_resource_custom.py::TestTemplateSizeOptimization -v # 8/8 tests passingScenario Tests (Live Testing Only)
# Requires live Azure connection pytest test_resource_custom.py::BicepTemplateSizeOptimizationScenarioTest -vReal-World Validation
Tested with 128KB bicep template (AI Landing Zone) that compiles to 5.8MB ARM JSON:
Impact
Files Changed
src/azure-cli/azure/cli/command_modules/resource/custom.py: Core optimization logicsrc/azure-cli/azure/cli/command_modules/resource/tests/latest/test_resource_custom.py: Comprehensive test suite with proper@live_only()decorators