Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 9 additions & 9 deletions docs/wiki/Debugging.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
## Debugging AzOps Locally - Walkthrough
# Debugging AzOps Locally - Walkthrough

If you're having issues with AzOps in your CI/CD system, it can be helpful to troubleshoot locally. For this example, we're going to use VS Code as the IDE (in a Windows 10 environment).
If you're having issues with AzOps in your CI/CD system, it can be helpful to troubleshoot locally. For this example, we're going to use VS Code as the IDE (in a Windows environment).

### Prerequisites
## Prerequisites

1. [Visual Studio Code](https://code.visualstudio.com/)
1. The [PowerShell Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)
1. JQ (Installing JQ from [Choco](https://community.chocolatey.org/packages/jq) using `choco install jq --verbose -y` and then add its directory (C:\ProgramData\chocolatey\lib\jq\tools) to the PATH env variable)

### Getting started
## Getting started

1. Clone the [project](https://github.com/Azure/AzOps) from GitHub and open with Visual Studio Code
1. Run `Dependencies.ps1` from the scripts directory to install the dependant PoSH modules`
1. Run `Dependencies.ps1` from the scripts directory to install the dependent PoSH modules
1. Login with the correct service principal that has Management Group scope access

```powershell
Expand All @@ -24,12 +24,12 @@ Connect-AzAccount -Credential $Credential -Tenant xxxx-xxx-xxxx-xxxx-xxx -Servic
1. Run `Debug.ps1`
1. Let the process finish, and observe the new file structure in the repository root. If this completes without error, then the `Pull` operation should operate without issue in your CI/CD system.

### Making a change
## Making a change

Running `Debug.ps1` in the last step leaves us on a [nested prompt](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshost.enternestedprompt). We're now able to feed in new Powershell commands at the command prompt to run in the correct context.

In this example, we're going to provide a new ARM template at a specific scope. The Arm template is the [Create New Subscription](https://github.com/Azure/Enterprise-Scale/blob/main/examples/landing-zones/empty-subscription/emptySubscription.json)
template from the Enterprise Scale repo, it has had default values provided for each of the parameters. The file is being dropped it inside the file structure that was created in the last step, inside the `Sandboxes` directory; `root\myorg (myorg)\myorg-sandboxes (myorg-sandboxes`).
template from the Enterprise Scale repository, it has had default values provided for each of the parameters. The file is being dropped it inside the file structure that was created in the last step, inside the `Sandboxes` directory; `root\myorg (myorg)\myorg-sandboxes (myorg-sandboxes`).

At the command prompt we'll provide it the json file path (wrapped as a changeset object), and then run the cmdlet to Invoke the AzOps Change process.

Expand All @@ -42,7 +42,7 @@ You can then monitor the PowerShell terminal in VS Code to see the Deployment co

## Additional Notes

### PowerShell Settings
## PowerShell Settings

Modify the default output state path generated by the module.

Expand All @@ -62,7 +62,7 @@ Increase the max retention count of log messages.
Set-PSFConfig PSFramework.Logging.MaxMessageCount 1MB
```

### VS Code Settings
## VS Code Settings

By default, setting breakpoints on AzOps in VS Code will not work.
This is due to the files being invoked as scriptblock by default, rather than as file, for performance reasons.
Expand Down
6 changes: 3 additions & 3 deletions src/AzOps.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# Generated by: Customer Architecture Team (CAT)
#
# Generated on: 08/27/2025
# Generated on: 9/15/2025
#

@{
Expand Down Expand Up @@ -51,8 +51,8 @@ PowerShellVersion = '7.2'
# ProcessorArchitecture = ''

# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @(@{ModuleName = 'PSFramework'; RequiredVersion = '1.12.346'; },
@{ModuleName = 'Az.Accounts'; RequiredVersion = '5.2.0'; },
RequiredModules = @(@{ModuleName = 'PSFramework'; RequiredVersion = '1.13.406'; },
@{ModuleName = 'Az.Accounts'; RequiredVersion = '5.3.0'; },
@{ModuleName = 'Az.Billing'; RequiredVersion = '2.2.0'; },
@{ModuleName = 'Az.ResourceGraph'; RequiredVersion = '1.2.1'; },
@{ModuleName = 'Az.Resources'; RequiredVersion = '8.1.0'; })
Expand Down
2 changes: 1 addition & 1 deletion src/internal/functions/ConvertTo-AzOpsState.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
The cmdlet converts Azure resources (Resources/ResourceGroups/Policy/PolicySet/PolicyAssignments/RoleAssignment/Definition) to the AzOps state format and exports them to the file structure.
.DESCRIPTION
The cmdlet converts Azure resources (Resources/ResourceGroups/Policy/PolicySet/PolicyAssignments/RoleAssignment/Definition) to the AzOps state format and exports them to the file structure.
It is normally executed and orchestrated through the Invoke-AzOpsPull cmdlet. As most of the AzOps-cmdlets, it is dependant on the AzOpsAzManagementGroup and AzOpsSubscriptions variables.
It is normally executed and orchestrated through the Invoke-AzOpsPull cmdlet. As most of the AzOps-cmdlets, it is dependent on the AzOpsAzManagementGroup and AzOpsSubscriptions variables.
Cmdlet will look into jq filter is template directory for the specific one before using the generic one at the root of the module
.PARAMETER Resource
Object with resource as input
Expand Down
28 changes: 14 additions & 14 deletions src/localized/en-us/Strings.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -314,23 +314,23 @@
'Remove-AzOpsDeployment.Scope.Failed' = 'Failed to resolve the scope for template {0}' # $TemplateFilePath
'Remove-AzOpsDeployment.Scope.Empty' = 'Unable to determine the scope of template {0}' # $TemplateFilePath
'Remove-AzOpsDeployment.SkipDueToWhatIf' = 'Skipping removal of resource due to WhatIf' #
'Remove-AzOpsDeployment.ResourceDependencyNested' = 'resource dependency {0} for complete deletion of {1} is outside of supported AzOps scope. Please remove this dependency in Azure without AzOps.'# $roleAssignmentId, $policyAssignment.ResourceId
'Remove-AzOpsDeployment.ResourceDependencyNotFound' = 'Missing resource dependency {0} for successful deletion of {1}. Please add missing resource and retry.'# $resource.Id, $scopeObject.Scope
'Remove-AzOpsDeployment.Resource.RetryCount' = 'Retry deletion of {0} resources in different order'# $retry.Count
'Remove-AzOpsDeployment.ResourceNotFound' = 'Unable to find resource of type {0} with id {1}.'# $scopeObject.Resource, $scopeObject.Scope, $resultsError
'Remove-AzOpsDeployment.SkipUnsupportedResource' = 'Deletion of AzOps generated file resources is only supported for locks, policyAssignments, policyDefinitions, policyExemptions, policySetDefinitions and roleAssignments. Will NOT proceed with deletion of resource in file {0}'# $TemplateFilePath

'Remove-AzResourceRaw.Resource.Recursive.Missing' = 'Missing required parameter InputObject, when running Recursive'#
'Remove-AzResourceRaw.Resource.Missing' = 'Missing required parameter ScopeObject'#
'Remove-AzResourceRaw.Resource.CheckExistence' = 'Checking existence after deletion of: [{0}]'# $FullyQualifiedResourceId
'Remove-AzOpsDeployment.ResourceDependencyNested' = 'resource dependency {0} for complete deletion of {1} is outside of supported AzOps scope. Please remove this dependency in Azure without AzOps.' # $roleAssignmentId, $policyAssignment.ResourceId
'Remove-AzOpsDeployment.ResourceDependencyNotFound' = 'Missing resource dependency {0} for successful deletion of {1}. Please add missing resource and retry.' # $resource.Id, $scopeObject.Scope
'Remove-AzOpsDeployment.Resource.RetryCount' = 'Retry deletion of {0} resources in different order' # $retry.Count
'Remove-AzOpsDeployment.ResourceNotFound' = 'Unable to find resource of type {0} with id {1}.' # $scopeObject.Resource, $scopeObject.Scope, $resultsError
'Remove-AzOpsDeployment.SkipUnsupportedResource' = 'Deletion of AzOps generated file resources is only supported for locks, policyAssignments, policyDefinitions, policyExemptions, policySetDefinitions and roleAssignments. Will NOT proceed with deletion of resource in file {0}' # $TemplateFilePath

'Remove-AzResourceRaw.Resource.Recursive.Missing' = 'Missing required parameter InputObject, when running Recursive' #
'Remove-AzResourceRaw.Resource.Missing' = 'Missing required parameter ScopeObject' #
'Remove-AzResourceRaw.Resource.CheckExistence' = 'Checking existence after deletion of: [{0}]' # $FullyQualifiedResourceId
'Remove-AzResourceRaw.Resource.StackCommand' = 'Running deletion command: [{0}] for resource: [{1}] with ActionOnUnmanage: [{2}]' # $removeCommand, $ScopeObject.Scope, $actionOnUnmanage
'Remove-AzResourceRaw.Resource.Command' = 'Running deletion command: [{0}] for resource: [{1}]' # 'Remove-AzResource', $ScopeObject.Scope
'Remove-AzResourceRaw.Resource.Failed' = 'Unable to delete resource of type {0} with id {1}'# $ScopeObject.Resource, $ScopeObject.Scope
'Remove-AzResourceRawRecursive.Processing' = 'Recursive retry processing to delete resource of type {0} with id {1}'# $item.ScopeObject.Resource, $item.ScopeObject.Scope
'Remove-AzResourceRaw.Resource.Failed' = 'Unable to delete resource of type {0} with id {1}' # $ScopeObject.Resource, $ScopeObject.Scope
'Remove-AzResourceRawRecursive.Processing' = 'Recursive retry processing to delete resource of type {0} with id {1}' # $item.ScopeObject.Resource, $item.ScopeObject.Scope

'Remove-AzOpsInvalidCharacter.Completed' = 'Valid string: {0}'# $String
'Remove-AzOpsInvalidCharacter.Invalid' = 'Invalid character detected in string: {0}, further processing initiated'# $String
'Remove-AzOpsInvalidCharacter.Removal' = 'Removed invalid character: {0} from string: {1}'# $character, $String
'Remove-AzOpsInvalidCharacter.Completed' = 'Valid string: {0}' # $String
'Remove-AzOpsInvalidCharacter.Invalid' = 'Invalid character detected in string: {0}, further processing initiated' # $String
'Remove-AzOpsInvalidCharacter.Removal' = 'Removed invalid character: {0} from string: {1}' # $character, $String

'Save-AzOpsManagementGroupChild.Creating.Scope' = 'Creating scope object' #
'Save-AzOpsManagementGroupChild.Data.Directory' = 'Resolved state path directory: {0}' # $statepathDirectory
Expand Down