Skip to content

Commit

Permalink
6.4.11
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianHayward committed Jul 15, 2024
1 parent 5fa4361 commit 97c78b6
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 65 deletions.
22 changes: 13 additions & 9 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
{
"name": "AzureGovernanceVisualizer",
"dockerFile": "Dockerfile",
"settings": {
"terminal.integrated.defaultProfile.linux": "pwsh"
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.defaultProfile.linux": "pwsh"
},
"extensions": [
"ms-vscode.powershell",
"analytic-signal.preview-html",
"bierner.markdown-mermaid",
"streetsidesoftware.code-spell-checker",
"yzhang.markdown-all-in-one"
]
}
},
"extensions": [
"ms-vscode.powershell",
"analytic-signal.preview-html",
"bierner.markdown-mermaid",
"streetsidesoftware.code-spell-checker",
"yzhang.markdown-all-in-one"
],
"forwardPorts": []
}
2 changes: 1 addition & 1 deletion .github/workflows/psScriptAnalyzer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
recurse: true
# Include your own basic security rules. Removing this option will run all the rules
# includeRule: '"PSAvoidGlobalAliases", "PSAvoidUsingConvertToSecureStringWithPlainText"'
excludeRule: '"PSAvoidUsingWriteHost", "PSUseDeclaredVarsMoreThanAssignments", "PSReviewUnusedParameter"'
excludeRule: '"PSAvoidUsingWriteHost", "PSUseDeclaredVarsMoreThanAssignments", "PSReviewUnusedParameter", "PSUseOutputTypeCorrectly"'
output: results.sarif

# Upload the SARIF file generated in the previous step
Expand Down
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,19 @@ Azure Governance Visualizer is intended to help you to get a holistic overview o
- Listed as [tool](https://learn.microsoft.com/azure/cloud-adoption-framework/resources/tools-templates#govern) for the Govern discipline in the Microsoft Cloud Adoption Framework.
- Included in the Cloud Adoption Framework's [Strategy-Plan-Ready-Governance](https://azuredevopsdemogenerator.azurewebsites.net/?name=strategyplan) Azure DevOps Demo Generator template.

### Azure Governance Visualizer accelerator

The [Azure Governance Visualizer accelerator](https://github.com/Azure/Azure-Governance-Visualizer-Accelerator) provides an easy and fast deployment process that automates the creation and publishing of AzGovViz to an Azure Web Application and provides automation to configuring the pre-requisites for AzGovViz.

## :rocket: Azure Governance Visualizer deployment guide

The instructions to deploy the Azure Governance Visualizer is found in the **[Azure Governance Visualizer (AzGovViz) deployment guide](setup.md)**. Follow those instructions to run AzGovViz from your terminal (console), GitHub Codepaces, Azure DevOps, or GitHub.

As an alternative, you can use the [Azure Governance Visualizer accelerator](https://github.com/Azure/Azure-Governance-Visualizer-Accelerator) to deploy the Azure Governance Visualizer per code.

### Azure Governance Visualizer accelerator

The [Azure Governance Visualizer accelerator](https://github.com/Azure/Azure-Governance-Visualizer-Accelerator) provides an easy and fast deployment process that automates the creation and publishing of AzGovViz to an Azure Web Application and provides automation to configuring the pre-requisites for AzGovViz.

## Release history

**Changes** (2024-June-18 / 6.4.10 Minor)
**Changes** (2024-July-15 / 6.4.11 Minor)

- ALZ policy refresh H2 FY24 (initiatives.json)
- [DevSkim](https://github.com/microsoft/DevSkim-Action), [PSScriptAnalyzer](https://github.com/microsoft/psscriptanalyzer-action) and [OpenSSF Scorecard](https://github.com/ossf/scorecard?tab=readme-ov-file#scorecard-github-action) integration
Expand All @@ -91,8 +91,9 @@ As an alternative, you can use the [Azure Governance Visualizer accelerator](htt
- update GitHub workflows to use azure/login@v2 (previous: azure/login@v1):
- [AzGovViz_OIDC.yml](/.github/workflows/AzGovViz_OIDC.yml)
- [AzGovViz.yml](/.github/workflows/AzGovViz.yml)
- update getConsumption (experimental for now): instead of full Management Group scope costmanagement data retrieval, batch by Subscription quotaId in batches of 100. Failing batches will fallback to get costmanagement data per Subscription. In order to use this you must update the AzGovVizParallel.ps1 file to use the function `getConsumptionv2` instead of `getConsumption`
- update getConsumption (experimental for now): instead of full Management Group scope costmanagement data retrieval, batch by Subscription quotaId in batches of 100. Failing batches and batches of Subscriptions of quotaId `CSP_2015-05-01` (see param block variable `SubscriptionQuotaIdsThatDoNotSupportCostManagementManagementGroupScopeQuery`) will fallback to get costmanagement data per Subscription. In order to use this you must update the AzGovVizParallel.ps1 file to use the function `getConsumptionv2` instead of `getConsumption`
- html; update jquery; source tablefilter js
- update `.devcontainer/devcontainer.json`

[Full release history](history.md)

Expand All @@ -109,6 +110,7 @@ More [demo output](https://github.com/JulianHayward/AzGovViz)
- Microsoft Tech Talks - Bevan Sinclair (Cloud Solution Architect Microsoft) [Automated Governance Reporting in Azure (MTT0AEDT)](https://mtt.eventbuilder.com/event/66431) (register to view)
- Microsoft Dev Radio (YouTube) [Get visibility into your environment with Azure Governance Visualizer](https://www.youtube.com/watch?v=hZXvF5oypLE)
- Jack Tracey (Cloud Solution Architect Microsoft) [Azure Governance Visualizer With Azure DevOps](https://jacktracey.co.uk/azgovviz-with-azure-devops/)
- SCHUTTEN.CLOUD [Automate Pertinent Governance Insight with Azure Governance Visualizer](https://schutten.cloud/post/azure-governance-visualizer/)

### Presentations

Expand Down
5 changes: 3 additions & 2 deletions history.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

### Azure Governance Visualizer version 6

**Changes** (2024-June-18 / 6.4.10 Minor)
**Changes** (2024-July-15 / 6.4.11 Minor)

- ALZ policy refresh H2 FY24 (initiatives.json)
- [DevSkim](https://github.com/microsoft/DevSkim-Action), [PSScriptAnalyzer](https://github.com/microsoft/psscriptanalyzer-action) and [OpenSSF Scorecard](https://github.com/ossf/scorecard?tab=readme-ov-file#scorecard-github-action) integration
Expand All @@ -13,8 +13,9 @@
- update GitHub workflows to use azure/login@v2 (previous: azure/login@v1):
- [AzGovViz_OIDC.yml](/.github/workflows/AzGovViz_OIDC.yml)
- [AzGovViz.yml](/.github/workflows/AzGovViz.yml)
- update getConsumption (experimental for now): instead of full Management Group scope costmanagement data retrieval, batch by Subscription quotaId in batches of 100. Failing batches will fallback to get costmanagement data per Subscription. In order to use this you must update the AzGovVizParallel.ps1 file to use the function `getConsumptionv2` instead of `getConsumption`
- update getConsumption (experimental for now): instead of full Management Group scope costmanagement data retrieval, batch by Subscription quotaId in batches of 100. Failing batches and batches of Subscriptions of quotaId `CSP_2015-05-01` (see param block variable `SubscriptionQuotaIdsThatDoNotSupportCostManagementManagementGroupScopeQuery`) will fallback to get costmanagement data per Subscription. In order to use this you must update the AzGovVizParallel.ps1 file to use the function `getConsumptionv2` instead of `getConsumption`
- html; update jquery; source tablefilter js
- update `.devcontainer/devcontainer.json`

**Changes** (2024-May-05 / 6.4.5 Minor)

Expand Down
68 changes: 45 additions & 23 deletions pwsh/AzGovVizParallel.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ Param
$Product = 'AzGovViz',

[string]
$ProductVersion = '6.4.10',
$ProductVersion = '6.4.11',

[string]
$GithubRepository = 'aka.ms/AzGovViz',
Expand Down Expand Up @@ -646,7 +646,10 @@ Param
AzureUSGovernment = '2023-01-01'
AzureChinaCloud = '2023-01-01'
}
}
},

[array]
$SubscriptionQuotaIdsThatDoNotSupportCostManagementManagementGroupScopeQuery = @('CSP_2015-05-01') #PayAsYouGo_2014-09-01
)

$Error.clear()
Expand Down Expand Up @@ -3374,13 +3377,10 @@ function getConsumptionv2 {
$startConsumptionData = Get-Date

if ($subsToProcessInCustomDataCollectionCount -gt 0) {

#$subscriptionIdsOptimizedForBody = '"{0}"' -f ($subsToProcessInCustomDataCollection.subscriptionId -join '","')
$currenttask = "Getting Consumption data (scope MG '$($ManagementGroupId)') for $($subsToProcessInCustomDataCollectionCount) Subscriptions for period $AzureConsumptionPeriod days ($azureConsumptionStartDate - $azureConsumptionEndDate)"
$currenttask = "Getting Consumption data scope MG (ManagementGroupId '$($ManagementGroupId)') for $($subsToProcessInCustomDataCollectionCount) Subscriptions for period $AzureConsumptionPeriod days ($azureConsumptionStartDate - $azureConsumptionEndDate)"
Write-Host "$currentTask"
#https://learn.microsoft.com/rest/api/cost-management/query/usage
$uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/providers/Microsoft.Management/managementGroups/$($ManagementGroupId)/providers/Microsoft.CostManagement/query?api-version=$($costManagementQueryAPIVersion)&`$top=100"
$method = 'POST'
$uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/providers/Microsoft.Management/managementGroups/$($ManagementGroupId)/providers/Microsoft.CostManagement/query?api-version=$($costManagementQueryAPIVersion)&`$top=5000"

$subsToProcessInCustomDataCollectionGroupedByQuotaId = $subsToProcessInCustomDataCollection | Group-Object -Property subscriptionQuotaId
$cnter = 0
Expand All @@ -3390,16 +3390,22 @@ function getConsumptionv2 {
$batchSize = 100
$subscriptionsBatch = ($quotaIdGroup.Group) | Group-Object -Property { [math]::Floor($counterBatch.Value++ / $batchSize) }
$batchCnt = 0
Write-Host " Processing $($quotaIdGroup.Count) Subscriptions with QuotaId $($quotaIdGroup.Name) in $(($subscriptionsBatch | Measure-Object).Count) batch(es) of max $batchSize Subscriptions"
Write-Host " Processing $($quotaIdGroup.Count) Subscriptions with QuotaId '$($quotaIdGroup.Name)' in $(($subscriptionsBatch | Measure-Object).Count) batch(es) of max $batchSize Subscriptions"

foreach ($batch in $subscriptionsBatch) {
$cnter++
$batchCnt++
$subscriptionIdsOptimizedForBody = '"{0}"' -f (($batch.Group).subscriptionId -join '","')
$currenttask = " Getting Consumption data quotaId:'$($quotaIdGroup.Name)' #batch$($batchCnt)/$(($subscriptionsBatch | Measure-Object).Count) (scope MG '$($ManagementGroupId)') for $(($batch.Group).Count) Subscriptions for period $AzureConsumptionPeriod days ($azureConsumptionStartDate - $azureConsumptionEndDate)"
Write-Host "$currentTask" -ForegroundColor Cyan
if ($quotaIdGroup.Name -in $SubscriptionQuotaIdsThatDoNotSupportCostManagementManagementGroupScopeQuery) {
Write-Host " Enforcing 'foreach Subscription' Subscription scope mode, due to QuotaId '$($quotaIdGroup.Name)' for $($batch.Group.Count) Subscriptions"
$mgConsumptionData = 'NoValidSubscriptions'
}
else {
$subscriptionIdsOptimizedForBody = '"{0}"' -f (($batch.Group).subscriptionId -join '","')
$currenttask = " Getting Consumption data QuotaId '$($quotaIdGroup.Name)' #batch$($batchCnt)/$(($subscriptionsBatch | Measure-Object).Count) (scope MG '$($ManagementGroupId)') for $(($batch.Group).Count) Subscriptions for period $AzureConsumptionPeriod days ($azureConsumptionStartDate - $azureConsumptionEndDate)"
Write-Host "$currentTask" -ForegroundColor Cyan

$body = @"

$bodyMGScope = @"
{
"type": "ActualCost",
"dataset": {
Expand Down Expand Up @@ -3450,7 +3456,17 @@ function getConsumptionv2 {
}
"@

$mgConsumptionData = AzAPICall -AzAPICallConfiguration $azAPICallConf -uri $uri -method $method -body $body -currentTask $currentTask -listenOn 'ContentProperties'
$mgConsumptionDataParametersSplat = @{
AzAPICallConfiguration = $azAPICallConf
uri = $uri
method = 'POST'
body = $bodyMGScope
currentTask = $currentTask
listenOn = 'ContentProperties'
}
$mgConsumptionData = AzAPICall @mgConsumptionDataParametersSplat

}

<#test
#$mgConsumptionData = "OfferNotSupported"
Expand All @@ -3471,8 +3487,8 @@ function getConsumptionv2 {
Subscriptions = ($batch.Group).subscriptionId
}

Write-Host " Switching to 'foreach Subscription' Subscription scope mode. Getting Consumption data #batch$($batchCnt) using Management Group scope failed."
$body = @"
Write-Host " Switching to 'foreach Subscription' Subscription scope mode. Getting Consumption data for $($batch.Group.Count) Subscriptions of QuotaId '$($quotaIdGroup.Name)' #batch$($batchCnt)/$(($subscriptionsBatch | Measure-Object).Count)"
$bodySubScope = @"
{
"type": "ActualCost",
"dataset": {
Expand Down Expand Up @@ -3519,7 +3535,7 @@ function getConsumptionv2 {
$subNameToProcess = $_.subscriptionName
$subQuotaId = $_.subscriptionQuotaId
#region UsingVARs
$body = $using:body
$bodySubScope = $using:bodySubScope
$azureConsumptionStartDate = $using:azureConsumptionStartDate
$azureConsumptionEndDate = $using:azureConsumptionEndDate
#fromOtherFunctions
Expand All @@ -3535,15 +3551,23 @@ function getConsumptionv2 {
$costManagementQueryAPIVersion = $using:costManagementQueryAPIVersion
#endregion UsingVARs

$currentTask = " Getting Consumption data (scope Sub $($subNameToProcess) '$($subIdToProcess)')"
$currentTask = " Getting Consumption data scope Sub (Subscription: $($subNameToProcess) '$($subIdToProcess)' QuotaId '$($subQuotaId)')"
#test
Write-Host $currentTask
#https://learn.microsoft.com/rest/api/cost-management/query/usage
$uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/subscriptions/$($subIdToProcess)/providers/Microsoft.CostManagement/query?api-version=$($costManagementQueryAPIVersion)&`$top=5000"
$method = 'POST'
$subConsumptionData = AzAPICall -AzAPICallConfiguration $azAPICallConf -uri $uri -method $method -body $body -currentTask $currentTask -listenOn 'ContentProperties'
$subConsumptionDataParametersSplat = @{
AzAPICallConfiguration = $azAPICallConf
uri = $uri
method = 'POST'
body = $bodySubScope
currentTask = $currentTask
listenOn = 'ContentProperties'
}
$subConsumptionData = AzAPICall @subConsumptionDataParametersSplat

if ($subConsumptionData -eq 'Unauthorized' -or $subConsumptionData -eq 'OfferNotSupported' -or $subConsumptionData -eq 'InvalidQueryDefinition' -or $subConsumptionData -eq 'NonValidWebDirectAIRSOfferType' -or $subConsumptionData -eq 'NotFoundNotSupported' -or $subConsumptionData -eq 'IndirectCostDisabled') {
Write-Host " Failed ($subConsumptionData) - Getting Consumption data (scope Sub $($subNameToProcess) '$($subIdToProcess)')"
Write-Host " Failed ($subConsumptionData) - Getting Consumption data scope Sub (Subscription: $($subNameToProcess) '$($subIdToProcess)' QuotaId '$($subQuotaId)')"
$hlper = $htAllSubscriptionsFromAPI.($subIdToProcess).subDetails
$hlper2 = $htSubscriptionsMgPath.($subIdToProcess)
$script:htConsumptionExceptionLog.Sub.($subIdToProcess) = @{
Expand All @@ -3566,14 +3590,13 @@ function getConsumptionv2 {
} -ThrottleLimit $ThrottleLimit
}
else {
Write-Host " #batch$($batchCnt)/$(($subscriptionsBatch | Measure-Object).Count) returned $($mgConsumptionData.properties.rows.Count) Consumption data entries"
Write-Host " #batch$($batchCnt)/$(($subscriptionsBatch | Measure-Object).Count) for $($batch.Group.Count) Subscriptions of QuotaId '$($quotaIdGroup.Name)' returned $($mgConsumptionData.properties.rows.Count) Consumption data entries"
if ($mgConsumptionData.Count -gt 0) {
addToAllConsumptionData -consumptiondataFromAPI $mgConsumptionData -subscriptionQuotaId $quotaIdGroup.Name
}
}
}
}

}
else {
$detailShowStopperResult = 'NoSubscriptionsPresent'
Expand Down Expand Up @@ -30423,7 +30446,6 @@ function verifyModules3rd {
if (-not $installAzAPICallModuleSuccess) {
throw " Installing '$($module.ModuleName)' module ($($moduleVersion)) failed"
}

}
else {
do {
Expand Down
7 changes: 5 additions & 2 deletions pwsh/dev/devAzGovVizParallel.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ Param
$Product = 'AzGovViz',

[string]
$ProductVersion = '6.4.10',
$ProductVersion = '6.4.11',

[string]
$GithubRepository = 'aka.ms/AzGovViz',
Expand Down Expand Up @@ -646,7 +646,10 @@ Param
AzureUSGovernment = '2023-01-01'
AzureChinaCloud = '2023-01-01'
}
}
},

[array]
$SubscriptionQuotaIdsThatDoNotSupportCostManagementManagementGroupScopeQuery = @('CSP_2015-05-01') #PayAsYouGo_2014-09-01
)

$Error.clear()
Expand Down
Loading

0 comments on commit 97c78b6

Please sign in to comment.