diff --git a/docs/wiki/Debugging.md b/docs/wiki/Debugging.md index 1ac9edef..6a17f86b 100644 --- a/docs/wiki/Debugging.md +++ b/docs/wiki/Debugging.md @@ -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 @@ -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. @@ -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. @@ -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. diff --git a/src/AzOps.psd1 b/src/AzOps.psd1 index 6e61af2e..bae7ba66 100644 --- a/src/AzOps.psd1 +++ b/src/AzOps.psd1 @@ -3,7 +3,7 @@ # # Generated by: Customer Architecture Team (CAT) # -# Generated on: 08/27/2025 +# Generated on: 9/15/2025 # @{ @@ -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'; }) diff --git a/src/internal/functions/ConvertTo-AzOpsState.ps1 b/src/internal/functions/ConvertTo-AzOpsState.ps1 index e73a44e9..4d07213f 100644 --- a/src/internal/functions/ConvertTo-AzOpsState.ps1 +++ b/src/internal/functions/ConvertTo-AzOpsState.ps1 @@ -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 diff --git a/src/localized/en-us/Strings.psd1 b/src/localized/en-us/Strings.psd1 index b5e71307..4205cced 100644 --- a/src/localized/en-us/Strings.psd1 +++ b/src/localized/en-us/Strings.psd1 @@ -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