Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
06f5f1e
Add stub code
Oct 27, 2025
74a3d0f
Fix parsing
Oct 29, 2025
b80cda8
Fix parsing
Oct 29, 2025
add68de
Fix displaying
Oct 29, 2025
1f12482
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Oct 30, 2025
aeb58e6
Fix commands
Oct 30, 2025
1636d5d
Add tests
Oct 30, 2025
b9696af
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Oct 30, 2025
b26a3b2
Fix style
Oct 30, 2025
1a9b886
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Oct 30, 2025
ea95cc0
Rename cli extension module name
Nov 3, 2025
6e4bdaa
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Nov 3, 2025
bdeffae
Fix linter
Nov 3, 2025
c50dfe8
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Nov 3, 2025
78286dd
Fix linter
Nov 3, 2025
421d339
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Nov 3, 2025
56b725b
Fix linter
Nov 3, 2025
d03e382
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Nov 3, 2025
964371c
Fix module name
Nov 3, 2025
34d2514
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Nov 3, 2025
3f5b4d7
add test scenarios
Nov 4, 2025
f0d9bdc
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Nov 4, 2025
1578369
Fix style
Nov 4, 2025
7274b10
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Nov 4, 2025
6c8d92c
Add service name
Nov 4, 2025
ee776c6
Add stageprogression and stagemap
Nov 25, 2025
aa3b9bd
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Dec 4, 2025
8dd8743
Update alias
Dec 11, 2025
d02017a
Update ChangeRecord name
Dec 11, 2025
871d9b4
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Dec 11, 2025
bf2565b
Address comments
Dec 19, 2025
e52f0b2
Merge remote-tracking branch 'other-repo/henrydai/ImplementCRUDforCha…
Dec 19, 2025
0201ab5
Update comments
Jan 26, 2026
74531c8
Update CLI to rename changeRecords for 2026-01-01-repview
Jan 30, 2026
094e6bf
Update CLI to rename changeRecords for 2026-01-01-repview
Jan 30, 2026
8abf613
Fix custom
Jan 31, 2026
e067473
Merge remote-tracking branch 'other-repo/feature/changesafety-api-202…
Jan 31, 2026
6dc6162
Fix issues
Jan 31, 2026
46f52a7
Merge remote-tracking branch 'other-repo/feature/changesafety-api-202…
Jan 31, 2026
2d96cae
fix stageMap parameters
Jan 31, 2026
0b2a75d
Merge remote-tracking branch 'other-repo/feature/changesafety-api-202…
Jan 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/azure-changesafety/HISTORY.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.. :changelog:

Release History
===============

1.0.0b1
++++++
* Initial release.
115 changes: 115 additions & 0 deletions src/azure-changesafety/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Azure CLI Change Safety Extension
Azure CLI extension for managing Change Safety resources. This includes `ChangeRecord`, `StageMap`, and `StageProgression` resources for coordinating, tracking, and safely deploying changes across your Azure environment.

## Installation
```bash
az extension add --source <path-to-extension-dist> --yes
# or install the latest published build
az extension add --name azure-changesafety
```

## Commands

### ChangeRecord
```bash
az changesafety changerecord create # Create a ChangeRecord for one or more targets.
az changesafety changerecord update # Update metadata, rollout configuration, or target definitions.
az changesafety changerecord delete # Delete a ChangeRecord resource.
az changesafety changerecord show # Display details for a ChangeRecord resource.
az changesafety changerecord list # List ChangeRecord resources.
```

### StageMap
```bash
az changesafety stagemap create # Create a StageMap defining rollout stages.
az changesafety stagemap update # Update StageMap stages.
az changesafety stagemap delete # Delete a StageMap resource.
az changesafety stagemap show # Display details for a StageMap resource.
az changesafety stagemap list # List StageMap resources.
```

### StageProgression
```bash
az changesafety stageprogression create # Create a StageProgression to track stage execution.
az changesafety stageprogression update # Update StageProgression status or comments.
az changesafety stageprogression delete # Delete a StageProgression resource.
az changesafety stageprogression show # Display details for a StageProgression resource.
az changesafety stageprogression list # List StageProgression resources for a ChangeRecord.
```

Run `az changesafety -h` to see full command groups and examples.

## Examples

### StageMap Examples
Create a two-stage StageMap for rollout:
```bash
az changesafety stagemap create \
--stage-map-name rolloutStageMap \
--stages "[{name:Canary,sequence:1},{name:Production,sequence:2}]"
```

Create a StageMap with configurable parameters:
```bash
# Parameters use AAZ shorthand: paramName.{string|number|array|object}.property=value
# Use --parameters paramName.string="??" to explore available properties
az changesafety stagemap create \
--stage-map-name parameterized-rollout \
--stages "[{name:Canary,sequence:1},{name:Production,sequence:2}]" \
--parameters region.string.default-value=westus batchSize.number.default-value=10
```

### ChangeRecord Examples
Create a ChangeRecord for a manual touch operation (e.g., delete a Traffic Manager profile):
```bash
az changesafety changerecord create \
-g MyResourceGroup \
-n changerecord-delete-tm \
--change-type ManualTouch \
--rollout-type Hotfix \
--targets "resourceId=/subscriptions/<subId>/resourceGroups/MyResourceGroup/providers/Microsoft.Network/trafficManagerProfiles/myProfile,operation=DELETE" \
--description "Delete Traffic Manager profile for maintenance"
```

Create a ChangeRecord for an app deployment with a StageMap reference:
```bash
az changesafety changerecord create \
-g MyResourceGroup \
-n changerecord-webapp-rollout \
--change-type AppDeployment \
--rollout-type Normal \
--targets "resourceId=/subscriptions/<subId>/resourceGroups/MyResourceGroup/providers/Microsoft.Web/sites/myApp,operation=PUT" \
--stagemap-name rolloutStageMap \
--links name=Runbook uri=https://contoso.com/runbook
```

Update the ChangeRecord and add a comment:
```bash
az changesafety changerecord update \
-g MyResourceGroup \
-n changerecord-webapp-rollout \
--comments "Deployment validated in canary region"
```

### StageProgression Examples
Create a StageProgression for the Canary stage:
```bash
az changesafety stageprogression create \
--change-record-name changerecord-webapp-rollout \
-n canary-progression \
--stage-reference Canary \
--status InProgress
```

Update StageProgression to mark stage as completed:
```bash
az changesafety stageprogression update \
--change-record-name changerecord-webapp-rollout \
-n canary-progression \
--status Completed \
--comments "Canary validation passed"
```

## Additional Information
- View command documentation: `az changesafety -h`
- Remove the extension when no longer needed: `az extension remove --name azure-changesafety`
44 changes: 44 additions & 0 deletions src/azure-changesafety/azext_changesafety/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
#
# Code generated by aaz-dev-tools
# --------------------------------------------------------------------------------------------

from azure.cli.core import AzCommandsLoader
from azext_changesafety._help import helps # pylint: disable=unused-import
# Import custom to apply AZ_HELP patches for StageMap commands
from azext_changesafety import custom as _custom # pylint: disable=unused-import


class ChangeRecordCommandsLoader(AzCommandsLoader):

def __init__(self, cli_ctx=None):
from azure.cli.core.commands import CliCommandType
custom_command_type = CliCommandType(
operations_tmpl='azext_changesafety.custom#{}')
super().__init__(cli_ctx=cli_ctx,
custom_command_type=custom_command_type)

def load_command_table(self, args):
from azext_changesafety.commands import load_command_table
from azure.cli.core.aaz import load_aaz_command_table
try:
from . import aaz
except ImportError:
aaz = None
if aaz:
load_aaz_command_table(
loader=self,
aaz_pkg_name=aaz.__name__,
args=args
)
load_command_table(self, args)
return self.command_table

def load_arguments(self, command):
from azext_changesafety._params import load_arguments
load_arguments(self, command)


COMMAND_LOADER_CLS = ChangeRecordCommandsLoader
199 changes: 199 additions & 0 deletions src/azure-changesafety/azext_changesafety/_help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
#
# Code generated by aaz-dev-tools
# --------------------------------------------------------------------------------------------

# pylint: disable=line-too-long
# pylint: disable=too-many-lines

from knack.help_files import helps # pylint: disable=unused-import

helps['changesafety'] = """
type: group
short-summary: Manage Change Safety resources.
"""

helps['changesafety changerecord'] = """
type: group
short-summary: Manage ChangeRecord resources that describe planned changes across targets.
"""

helps['changesafety changerecord create'] = """
type: command
short-summary: Create a ChangeRecord resource.
long-summary: >
Provide at least one target definition to describe which resources or operations the ChangeRecord
will affect. Targets are expressed as comma or semicolon separated key=value pairs such as
resourceId=RESOURCE_ID,operation=DELETE. The command is also available through the alias
`az changesafety changerecord`. If you omit scheduling flags, the anticipated start time
defaults to now and the anticipated end time defaults to eight hours later (UTC).
parameters:
- name: --targets
short-summary: >
One or more target definitions expressed as key=value pairs (for example
resourceId=RESOURCE_ID,operation=DELETE,resourceType=Microsoft.Compute/virtualMachines).
- name: --description
short-summary: A description of the change being performed.
- name: --anticipated-start-time
short-summary: Expected start time in ISO 8601 format. Defaults to current UTC time when omitted.
- name: --anticipated-end-time
short-summary: Expected completion time in ISO 8601 format. Defaults to eight hours after the anticipated start time when omitted.
- name: --change-type
short-summary: Classify the change such as AppDeployment, Config, ManualTouch, or PolicyDeployment.
- name: --rollout-type
short-summary: Specify the rollout type (Normal, Hotfix, or Emergency).
- name: --stage-map-name --stagemap-name
short-summary: StageMap name in the current subscription scope; the resource ID is built for you.
- name: --stage-map
short-summary: Reference an existing StageMap resource using resource-id=RESOURCE_ID and optional parameters key=value pairs.
- name: --links
short-summary: Add supporting links by repeating --links name=NAME uri=URL [description=TEXT].
examples:
- name: Create with StageMap reference and status link
text: |-
az changesafety changerecord create -g MyResourceGroup -n changerecord002 --change-type ManualTouch --rollout-type Normal --stage-map "{resource-id:/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.ChangeSafety/stageMaps/rolloutStageMap}" --targets "resourceId=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/myVm,operation=PATCH" --links "[{name:status,uri:'https://contoso.com/change/rollout-002'}]"
az changesafety changerecord delete -g MyResourceGroup -n changerecord002 --yes
- name: Create a ChangeRecord for a VM rollout
text: |-
az changesafety changerecord create -g MyResourceGroup -n changerecord001 --change-type AppDeployment --rollout-type Normal --targets "resourceId=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/myVm,operation=PUT"
- name: Create a ChangeRecord for deleting a Traffic Manager profile
text: |-
az changesafety changerecord create -g MyResourceGroup -n delete-trafficmanager --change-type ManualTouch --rollout-type Hotfix --targets "resourceId=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Network/trafficManagerProfiles/myProfile,operation=DELETE" --description "Delete Traffic Manager profile"
- name: Create with staging rollout configuration
text: |-
az changesafety changerecord create -g MyResourceGroup -n changerecord-ops01 --change-type AppDeployment --rollout-type Hotfix --targets "resourceId=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Web/sites/myApp,operation=POST"
- name: Reference a StageMap by name
text: |-
az changesafety changerecord create -g MyResourceGroup -n changerecord003 --change-type ManualTouch --rollout-type Normal --stagemap-name rolloutStageMap --targets "resourceId=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/myVm,operation=DELETE"
"""

helps['changesafety changerecord update'] = """
type: command
short-summary: Update an existing ChangeRecord resource.
long-summary: >
Use this command to modify descriptive metadata, rollout settings, or scheduling for an
existing ChangeRecord. Note: The changeDefinition (targets) cannot be modified after creation.
parameters:
- name: --stage-map-name --stagemap-name
short-summary: StageMap name in the current subscription scope; the resource ID is built for you.
- name: --stage-map
short-summary: Reference an existing StageMap resource using resource-id=RESOURCE_ID and optional parameters key=value pairs.
- name: --comments
short-summary: Provide notes about the latest update to the ChangeRecord.
- name: --description
short-summary: Update the description of the change.
- name: --anticipated-start-time
short-summary: Update the expected start time in ISO 8601 format. If omitted, the current value is preserved.
- name: --anticipated-end-time
short-summary: Update the expected completion time in ISO 8601 format. If omitted, the current value is preserved.
examples:
- name: Adjust rollout type and add a comment
text: |-
az changesafety changerecord update -g MyResourceGroup -n changerecord001 --rollout-type Emergency --comments "Escalated to emergency rollout"
- name: Update scheduling window
text: |-
az changesafety changerecord update -g MyResourceGroup -n changerecord001 --anticipated-start-time "2024-09-01T08:00:00Z" --anticipated-end-time "2024-09-01T12:00:00Z"
- name: Update description
text: |-
az changesafety changerecord update -g MyResourceGroup -n changerecord001 --description "Updated rollout for production deployment"
"""

helps['changesafety changerecord delete'] = """
type: command
short-summary: Delete a ChangeRecord resource.
examples:
- name: Delete a ChangeRecord without confirmation
text: |-
az changesafety changerecord delete -g MyResourceGroup -n changerecord001 --yes
"""

helps['changesafety changerecord show'] = """
type: command
short-summary: Show details for a ChangeRecord resource.
examples:
- name: Show a ChangeRecord
text: |-
az changesafety changerecord show -g MyResourceGroup -n changerecord001
"""

helps['changesafety stagemap'] = """
type: group
short-summary: Manage StageMap resources that define rollout stages for orchestrated changes.
"""

helps['changesafety stagemap create'] = """
type: command
short-summary: Create a StageMap resource.
long-summary: >
A StageMap defines the stages through which a change progresses during rollout.
Each stage has a name and sequence number. Stages are executed in order of their
sequence values. StageMap resources can be referenced by ChangeRecord resources
to enforce staged rollout patterns.
parameters:
- name: --stage-map-name
short-summary: The name of the StageMap resource to create.
- name: --stages
short-summary: >
Array of stage definitions. Each stage requires a name and sequence number.
Use shorthand syntax or JSON format.
- name: --parameters
short-summary: >
Optional parameters schema for the StageMap. Define parameters that can be
passed when referencing this StageMap from a ChangeRecord. Use AAZ shorthand
syntax: paramName.{string|number|array|object}.default-value=value.
Run with --parameters paramName.string="??" to see available properties.
examples:
- name: Create a simple two-stage StageMap
text: |-
az changesafety stagemap create --subscription 00000000-0000-0000-0000-000000000000 --stage-map-name rolloutStageMap --stages "[{name:Canary,sequence:1},{name:Production,sequence:2}]"
- name: Create a StageMap with three stages
text: |-
az changesafety stagemap create --subscription 00000000-0000-0000-0000-000000000000 --stage-map-name regional-rollout --stages "[{name:WestUS,sequence:1},{name:EastUS,sequence:2},{name:Global,sequence:3}]"
- name: Create a StageMap with parameters
text: |-
az changesafety stagemap create --subscription 00000000-0000-0000-0000-000000000000 --stage-map-name parameterized-rollout --stages "[{name:Canary,sequence:1},{name:Production,sequence:2}]" --parameters region.string.default-value=westus batchSize.number.default-value=10
"""

helps['changesafety stagemap update'] = """
type: command
short-summary: Update an existing StageMap resource.
long-summary: >
Modify the stages defined in a StageMap. When updating, provide the complete
list of stages as the update replaces the existing stages array.
examples:
- name: Add a new stage to an existing StageMap
text: |-
az changesafety stagemap update --subscription 00000000-0000-0000-0000-000000000000 --stage-map-name rolloutStageMap --stages "[{name:Canary,sequence:1},{name:Pilot,sequence:2},{name:Production,sequence:3}]"
"""

helps['changesafety stagemap show'] = """
type: command
short-summary: Get details for a StageMap resource.
examples:
- name: Show a StageMap
text: |-
az changesafety stagemap show --subscription 00000000-0000-0000-0000-000000000000 --stage-map-name rolloutStageMap
"""

helps['changesafety stagemap delete'] = """
type: command
short-summary: Delete a StageMap resource.
long-summary: >
Delete a StageMap that is no longer needed. Note that StageMap resources
that are currently referenced by active ChangeRecord resources cannot be deleted.
examples:
- name: Delete a StageMap
text: |-
az changesafety stagemap delete --subscription 00000000-0000-0000-0000-000000000000 --stage-map-name rolloutStageMap --yes
"""

helps['changesafety stagemap list'] = """
type: command
short-summary: List StageMap resources in a subscription.
examples:
- name: List all StageMaps in the subscription
text: |-
az changesafety stagemap list --subscription 00000000-0000-0000-0000-000000000000
"""
13 changes: 13 additions & 0 deletions src/azure-changesafety/azext_changesafety/_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
#
# Code generated by aaz-dev-tools
# --------------------------------------------------------------------------------------------

# pylint: disable=too-many-lines
# pylint: disable=too-many-statements


def load_arguments(self, _): # pylint: disable=unused-argument
pass
6 changes: 6 additions & 0 deletions src/azure-changesafety/azext_changesafety/aaz/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
#
# Code generated by aaz-dev-tools
# --------------------------------------------------------------------------------------------
Loading
Loading