Skip to content

Commit

Permalink
feat: Implemented post-deployment validation (Azure#668)
Browse files Browse the repository at this point in the history
## Description

- Implemented post-deployment validation
- Improved robustness of `diff` logic

| Pipeline | 
| - |
|
https://github.com/AlexanderSehr/bicep-registry-modules/actions/runs/6982605270/job/19002095467#step:4:165
|

## Example Output
```
VERBOSE: Invoke function with
  VERBOSE: {
    "Version": "0.3",
    "ModulePath": "avm/res/key-vault/vault"
  }
  
  VERBOSE: Requested HTTP/1.1 GET with 0-byte payload
  VERBOSE: Received HTTP/1.1 71191-byte response of content type application/json
  VERBOSE: Bicep modules found in MCR catalog:
  
  bicep/samples/hello-world
  bicep/samples/array-loop
  bicep/ai/bing-resource
  bicep/ai/cognitiveservices
  bicep/app/app-configuration
  bicep/app/dapr-containerapp
  bicep/app/dapr-containerapps-environment
  bicep/authorization/resource-scope-role-assignment
  bicep/azure-gaming/game-dev-vm
  bicep/azure-gaming/game-dev-vmss
  bicep/compute/availability-set
  bicep/compute/container-registry
  bicep/compute/custom-image-vmss
  bicep/compute/event-hub
  bicep/compute/function-app
  bicep/cost/resourcegroup-scheduled-action
  bicep/cost/subscription-scheduled-action
  bicep/deployment-scripts/aks-run-command
  bicep/deployment-scripts/aks-run-helm
  bicep/deployment-scripts/build-acr
  bicep/deployment-scripts/create-kv-certificate
  bicep/deployment-scripts/create-kv-sshkeypair
  bicep/deployment-scripts/import-acr
  bicep/deployment-scripts/wait
  bicep/lz/sub-vending
  bicep/identity/user-assigned-identity
  bicep/network/virtual-network
  bicep/network/traffic-manager
  bicep/network/nat-gateway
  bicep/network/dns-zone
  bicep/network/public-ip-address
  bicep/network/public-ip-prefix
  bicep/network/private-dns-zone
  bicep/observability/grafana
  bicep/search/search-service
  bicep/security/keyvault
  bicep/storage/cosmos-db
  bicep/storage/data-explorer
  bicep/storage/storage-account
  bicep/storage/log-analytics-workspace
  bicep/storage/postgresql-single-server
  bicep/storage/redis-cache
  bicep/storage/mysql-single-server
  bicep/avm/res/batch/batch-account
  bicep/avm/res/cognitive-services/account
  bicep/avm/res/compute/ssh-public-key
  bicep/avm/res/event-grid/domain
  bicep/avm/res/event-grid/system-topic
  bicep/avm/res/insights/action-group
  bicep/avm/res/insights/component
  bicep/avm/res/insights/diagnostic-setting
  bicep/avm/res/key-vault/vault
  bicep/avm/res/kubernetes-configuration/extension
  bicep/avm/res/kubernetes-configuration/flux-configuration
  bicep/avm/res/logic/workflow
  bicep/avm/res/network/dns-forwarding-ruleset
  bicep/avm/res/network/dns-resolver
  bicep/avm/res/network/dns-zone
  bicep/avm/res/network/express-route-circuit
  bicep/avm/res/network/express-route-gateway
  bicep/avm/res/network/load-balancer
  bicep/avm/res/network/network-interface
  bicep/avm/res/network/private-dns-zone
  bicep/avm/res/network/private-endpoint
  bicep/avm/res/network/public-ip-address
  bicep/avm/res/operational-insights/workspace
  bicep/avm/res/operations-management/solution
  bicep/avm/res/power-bi-dedicated/capacity
  bicep/avm/res/resource-graph/query
  bicep/avm/res/search/search-service
  bicep/avm/res/sql/server
  
  
  VERBOSE: Passed: Found module [avm/res/key-vault/vault] in the MCR catalog
  VERBOSE: Requested HTTP/1.1 GET with 0-byte payload
  VERBOSE: Received HTTP/1.1 87-byte response of content type application/json
  VERBOSE: Tags for module in path [avm/res/key-vault/vault] found in MCR catalog:
  0.2.0
  0.3.0
  
  Passed: Found new tag [0.3] for published module
```

---------

Co-authored-by: Erika Gressi <[email protected]>
Co-authored-by: ChrisSidebotham-MSFT <[email protected]>
  • Loading branch information
3 people authored Dec 3, 2023
1 parent bd9ef71 commit 4ae6c8f
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 3 deletions.
30 changes: 28 additions & 2 deletions .github/actions/templates/avm-publishModule/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ runs:
bicep --version
- name: "Publish module to public bicep registry"
id: publish_step
uses: azure/powershell@v1
with:
azPSVersion: "latest"
Expand All @@ -68,8 +69,33 @@ runs:
Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
# Get the modified child resources
Publish-ModuleFromPathToPBR @functionInput -Verbose
if($publishOutputs = Publish-ModuleFromPathToPBR @functionInput -Verbose) {
Write-Output ('{0}={1}' -f 'version', $publishOutputs.version) >> $env:GITHUB_OUTPUT
Write-Output ('{0}={1}' -f 'publishedModuleName', $publishOutputs.publishedModuleName) >> $env:GITHUB_OUTPUT
}
Write-Output '::endgroup::'
# TODO Add publish validation (as per PBR pipeline template 'publish-module.yml')
- name: "Validate publish"
uses: azure/powershell@v1
if: ${{ steps.publish_step.outputs.version != '' && steps.publish_step.outputs.publishedModuleName != '' }}
with:
azPSVersion: "latest"
inlineScript: |
# Grouping task logs
Write-Output '::group::Validate publish'
# Load used functions
. (Join-Path $env:GITHUB_WORKSPACE 'avm' 'utilities' 'pipelines' 'publish' 'Confirm-ModuleIsPublished.ps1')
$functionInput = @{
Version = "${{ steps.publish_step.outputs.version }}"
PublishedModuleName = "${{ steps.publish_step.outputs.publishedModuleName }}"
}
Write-Verbose "Invoke function with" -Verbose
Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
Confirm-ModuleIsPublished @functionInput -Verbose
Write-Output '::endgroup::'
81 changes: 81 additions & 0 deletions avm/utilities/pipelines/publish/Confirm-ModuleIsPublished.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<#
.SYNOPSIS
Check if a module in a given path is published in a given version
.DESCRIPTION
Check if a module in a given path is published in a given version. Tries to find the module & version for a maximum of 60 minutes.
.PARAMETER Version
Mandatory. The version of the module to check for. For example: '0.2.0'
.PARAMETER PublishedModuleName
Mandatory. The path of the module to check for. For example: 'avm/res/key-vault/vault'
.EXAMPLE
Confirm-ModuleIsPublished -Version '0.2.0' -PublishedModuleName 'avm/res/key-vault/vault' -Verbose
Check if module 'key-vault/vault' has been published with version '0.2.0
#>
function Confirm-ModuleIsPublished {

[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string] $Version,

[Parameter(Mandatory)]
[string] $PublishedModuleName
)

$baseUrl = 'https://mcr.microsoft.com/v2'
$catalogUrl = "$baseUrl/_catalog"
$moduleVersionsUrl = "$baseUrl/bicep/$PublishedModuleName/tags/list"

$time_limit_seconds = 3600 # 1h
$end_time = (Get-Date).AddSeconds($time_limit_seconds)
$retry_seconds = 5

#####################################
## Confirm module is published ##
#####################################
while ($true) {
$catalogContentRaw = (Invoke-WebRequest -Uri $catalogUrl -UseBasicParsing).Content
$bicepCatalogContent = ($catalogContentRaw | ConvertFrom-Json).repositories | Select-String 'bicep/'
Write-Verbose ("Bicep modules found in MCR catalog:`n{0}" -f ($bicepCatalogContent | Out-String))

if ($bicepCatalogContent -match "bicep/$PublishedModuleName") {
Write-Verbose "Passed: Found module [$PublishedModuleName] in the MCR catalog" -Verbose
break
} else {
Write-Error "Error: Module [$PublishedModuleName] is not in the MCR catalog. Retrying in [$retry_seconds] seconds"
Start-Sleep -Seconds $retry_seconds
}

if ((Get-Date) -ge $end_time) {
throw "Time limit reached. Failed to validate publish of module in path [$PublishedModuleName] within the specified time."
}
}

#############################################
## Confirm module version is published ##
#############################################
while ($true) {
$tagsContentRaw = (Invoke-WebRequest -Uri $moduleVersionsUrl -UseBasicParsing).Content
$tagsContent = ($tagsContentRaw | ConvertFrom-Json).tags

Write-Verbose ("Tags for module in path [$PublishedModuleName] found in MCR catalog:`n{0}" -f ($tagsContent | Out-String))

if ($tagsContent -match $Version) {
Write-Host "Passed: Found new tag [$Version] for published module"
break
} else {
Write-Host "Error: Could not find new tag [$Version] for published module. Retrying in [$retry_seconds] seconds"
Start-Sleep -Seconds $retry_seconds
}

if ((Get-Date) -ge $end_time) {
Write-Host 'Time limit reached. Failed to validate publish within the specified time.'
exit 1
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,9 @@ function Publish-ModuleFromPathToPBR {
Write-Verbose "Publish Input:`n $($publishInput | ConvertTo-Json -Depth 10)" -Verbose

bicep publish @publishInput

return @{
version = $targetVersion
publishedModuleName = $publishedModuleName
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function Get-ModifiedFileList {
Write-Verbose 'Gathering modified files from the previous head' -Verbose
$Diff = git diff --name-only --diff-filter=AM HEAD^ HEAD
}
$ModifiedFiles = $Diff | Get-Item -Force
$ModifiedFiles = $Diff ? ($Diff | Get-Item -Force) : @()

return $ModifiedFiles
}
Expand Down

0 comments on commit 4ae6c8f

Please sign in to comment.