diff --git a/.github/workflows/platform.linkcheck.yml b/.github/workflows/platform.linkcheck.yml new file mode 100644 index 0000000000..9a0e8ac807 --- /dev/null +++ b/.github/workflows/platform.linkcheck.yml @@ -0,0 +1,33 @@ +name: '.Platform: Broken Links Check' + +on: + workflow_dispatch: + pull_request: + branches: + - main + paths: + - '**/*.md' + +jobs: + build: + name: Broken Links Check + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v2 + with: + # Full git history is needed to get a proper list of changed files within `super-linter` + fetch-depth: 0 + + - name: Check Broken Links + if: always() + id: checker + uses: lycheeverse/lychee-action@v1.1.1 + with: + args: --verbose --no-progress **/*.md --accept 200,201,403,429,401 --exclude-file .lycheeignore + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + - name: Publish Results + if: always() + run: exit ${{ steps.checker.outputs.exit_code }} diff --git a/.lycheeignore b/.lycheeignore new file mode 100644 index 0000000000..cb8f72b8ec --- /dev/null +++ b/.lycheeignore @@ -0,0 +1,9 @@ +https://foo.psd1/ +file:///github +https://mystorageaccount.blob.core.windows.net +https://mykeyvault.vault.azure.net +https://www.powershellgallery.com +https://github.com/myProject +http://validurltoconfiglocation/ +https://mycustomdependencylocation/ +http://tools.ietf.org/html/rfc6749#section-3.2 diff --git a/arm/Microsoft.ApiManagement/service/portalsettings/readme.md b/arm/Microsoft.ApiManagement/service/portalsettings/readme.md index fe3e8f578d..f6fb9eb86e 100644 --- a/arm/Microsoft.ApiManagement/service/portalsettings/readme.md +++ b/arm/Microsoft.ApiManagement/service/portalsettings/readme.md @@ -27,4 +27,4 @@ This module deploys API Management Service Portal Setting. ## Template references -- [Service/Portalsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2019-12-01/service/portalsettings) +- ['service/portalsettings' Parent Documentation](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/service) diff --git a/arm/Microsoft.ApiManagement/service/readme.md b/arm/Microsoft.ApiManagement/service/readme.md index f8ccc6a603..36768ae46d 100644 --- a/arm/Microsoft.ApiManagement/service/readme.md +++ b/arm/Microsoft.ApiManagement/service/readme.md @@ -151,6 +151,10 @@ You can specify multiple user assigned identities to a resource by providing add ## Template references +- ['service/portalsettings' Parent Documentation](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/service) +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) +- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) +- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Service](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-12-01/service) - [Service/Apis](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/apis) - [Service/Apis/Policies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/apis/policies) @@ -161,11 +165,7 @@ You can specify multiple user assigned identities to a resource by providing add - [Service/Identityproviders](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/identityProviders) - [Service/Namedvalues](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/namedValues) - [Service/Policies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/policies) -- [Service/Portalsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2019-12-01/service/portalsettings) - [Service/Products](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/products) - [Service/Products/Apis](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/products/apis) - [Service/Products/Groups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/products/groups) - [Service/Subscriptions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/subscriptions) -- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) -- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) diff --git a/arm/Microsoft.Automanage/accounts/readme.md b/arm/Microsoft.Automanage/accounts/readme.md index 8260e8b2fa..c6f108b5cf 100644 --- a/arm/Microsoft.Automanage/accounts/readme.md +++ b/arm/Microsoft.Automanage/accounts/readme.md @@ -32,5 +32,4 @@ This module deploys an Automanage account and associates VM with it. ## Template references -- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Accounts](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automanage/2020-06-30-preview/accounts) +- [Define resources with Bicep and ARM templates](https://docs.microsoft.com/en-us/azure/templates) diff --git a/arm/Microsoft.CognitiveServices/accounts/readme.md b/arm/Microsoft.CognitiveServices/accounts/readme.md index af27e495d6..39266f085c 100644 --- a/arm/Microsoft.CognitiveServices/accounts/readme.md +++ b/arm/Microsoft.CognitiveServices/accounts/readme.md @@ -200,9 +200,9 @@ You can specify multiple user assigned identities to a resource by providing add ## Template references -- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) -- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Accounts](https://docs.microsoft.com/en-us/azure/templates/Microsoft.CognitiveServices/2017-04-18/accounts) - [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) -- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/privateEndpoints) +- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) +- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/privateEndpoints) - [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/privateEndpoints/privateDnsZoneGroups) +- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) diff --git a/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md b/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md index 4f1e419349..b6c47d8e92 100644 --- a/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md +++ b/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md @@ -197,25 +197,16 @@ The following resources are required to be able to deploy this resource. ```json -"extensionDomainJoinConfig": { - "value": { - "settings": { - "Name": ".onmicrosoft.com", - "User": "domainJoinUser02@.onmicrosoft.com", - "OUPath": "OU=Template-Test; DC=; DC=onmicrosoft; DC=com", - "Restart": true, - "Options": "" - } - } -} -``` - -Should be configured alongside: -```json -"extensionDomainJoinPassword": { - "reference": { - "keyVault": { - "id": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/" +"windowsScriptExtensionFileData": { + "value": [ + //storage accounts with SAS token requirement + { + "uri": "https://mystorageAccount.blob.core.windows.net/avdscripts/File1.ps1", + "storageAccountId": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName" + }, + { + "uri": "https://mystorageAccount.blob.core.windows.net/avdscripts/File2.ps1", + "storageAccountId": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName" }, "secretName": "domainJoinUser-Password" } @@ -267,9 +258,9 @@ Only for OSType Windows "enabled": true, "settings": { "EncryptionOperation": "EnableEncryption", - "KeyVaultURL": "https://devopsbaseline.vault.azure.net/", + "KeyVaultURL": "https://mykeyvault.vault.azure.net/", "KeyVaultResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001", - "KeyEncryptionKeyURL": "https://devopsbaseline.vault.azure.net/keys/keyEncryptionKey/3e13110def0d4a26ac38341c73c059bb", + "KeyEncryptionKeyURL": "https://mykeyvault.vault.azure.net/keys/keyEncryptionKey/3e13110def0d4a26ac38341c73c059bb", "KekVaultResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001", "KeyEncryptionAlgorithm": "RSA-OAEP", "VolumeType": "All", diff --git a/arm/Microsoft.Compute/virtualMachines/readme.md b/arm/Microsoft.Compute/virtualMachines/readme.md index 125f6fd3dd..3cd8f2bc6f 100644 --- a/arm/Microsoft.Compute/virtualMachines/readme.md +++ b/arm/Microsoft.Compute/virtualMachines/readme.md @@ -293,7 +293,7 @@ The field `nicSuffix` and `subnetId` are mandatory. If `enablePublicIP` is set t "domainJoinSettings": { "value": { "domainName": "contoso.com", - "domainJoinUser": "domainJoinUser@contoso.com", + "domainJoinUser": "test.user@testcompany.com", "domainJoinOU": "OU=testOU; DC=contoso; DC=com", "domainJoinRestart": true, "domainJoinOptions": 3 @@ -343,9 +343,9 @@ Only for OSType Windows "diskEncryptionSettings": { "value": { "EncryptionOperation": "EnableEncryption", - "KeyVaultURL": "https://adp-sxx-az-kv-x-001.vault.azure.net/", + "KeyVaultURL": "https://mykeyvault.vault.azure.net/", "KeyVaultResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001", - "KeyEncryptionKeyURL": "https://adp-sxx-az-kv-x-001.vault.azure.net/keys/keyEncryptionKey/685153483a1140e3856f004a753e1ab4", + "KeyEncryptionKeyURL": "https://mykeyvault.vault.azure.net/keys/keyEncryptionKey/685153483a1140e3856f004a753e1ab4", "KekVaultResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001", "KeyEncryptionAlgorithm": "RSA-OAEP", //'RSA-OAEP'/'RSA-OAEP-256'/'RSA1_5' "VolumeType": "All", //'OS'/'Data'/'All' @@ -409,11 +409,11 @@ Only for OSType Windows "value": [ //storage accounts with SAS token requirement { - "uri": "https://storageAccount.blob.core.windows.net/avdscripts/File1.ps1", + "uri": "https://mystorageaccount.blob.core.windows.net/avdscripts/File1.ps1", "storageAccountId": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName" }, { - "uri": "https://storageAccount.blob.core.windows.net/avdscripts/File2.ps1", + "uri": "https://mystorageaccount.blob.core.windows.net/avdscripts/File2.ps1", "storageAccountId": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName" }, //storage account with public container (no SAS token is required) OR other public URL (not a storage account) @@ -512,7 +512,7 @@ You can specify multiple user assigned identities to a resource by providing add ## Template references -- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2017-04-01/locks) +- [Locks ](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2017-04-01/locks) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Virtualmachines](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2021-07-01/virtualMachines) - [Virtualmachines/Extensions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2021-07-01/virtualMachines/extensions) diff --git a/arm/Microsoft.ContainerService/managedClusters/agentPools/readme.md b/arm/Microsoft.ContainerService/managedClusters/agentPools/readme.md index 929311fc88..fa853264e1 100644 --- a/arm/Microsoft.ContainerService/managedClusters/agentPools/readme.md +++ b/arm/Microsoft.ContainerService/managedClusters/agentPools/readme.md @@ -48,7 +48,7 @@ For available properties check -Please make sure to set your environment up and also consult the ['Pipeline Design'](./PipelinesDesign) and ['Pipeline Usage'](.\PipelinesUsage) sections. +Please make sure to set your environment up and also consult the ['Pipeline Design'](./PipelinesDesign) and ['Pipeline Usage'](./PipelinesUsage) sections. diff --git a/docs/wiki/ModulesDesign.md b/docs/wiki/ModulesDesign.md index c2954e6d6a..76671eb299 100644 --- a/docs/wiki/ModulesDesign.md +++ b/docs/wiki/ModulesDesign.md @@ -78,7 +78,7 @@ Microsoft.Sql In this folder we recommend to place the child-resource-template alongside a ReadMe (that can be generated via the `.github\workflows\scripts\Set-ModuleReadMe.ps1` script) and optionally further nest additional folders for it's child-resources. -The parent template should reference all it's direct child-templates to allow for an end to end deployment experience while allowing any user to also reference 'just' the child-resource itself. In the case of the SQL-server example the server template would reference the database module and encapsulate it it in a loop to allow for the deployment of n-amount of databases. For example +The parent template should reference all it's direct child-templates to allow for an end-to-end deployment experience while allowing any user to also reference 'just' the child-resource itself. In the case of the SQL-server example the server template would reference the database module and encapsulate it it in a loop to allow for the deployment of n-amount of databases. For example ```Bicep @description('Optional. The databases to create in the server') diff --git a/docs/wiki/ModulesUsage.md b/docs/wiki/ModulesUsage.md index ce425ceda3..726dad6f29 100644 --- a/docs/wiki/ModulesUsage.md +++ b/docs/wiki/ModulesUsage.md @@ -70,7 +70,7 @@ New-AzResourceGroup -Name 'ExampleGroup' -Location "Central US" $inputObject = @{ DeploymentName = 'ExampleDeployment' ResourceGroupName = 'ExampleGroup' - TemplateUri = 'https://raw.githubusercontent.com/arm/ResourceModules/main/arm/Microsoft.KeyVault/vaults/deploy.json' + TemplateUri = 'https://raw.githubusercontent.com/Azure/ResourceModules/main/arm/Microsoft.KeyVault/vaults/deploy.bicep' } New-AzResourceGroupDeployment @inputObject ``` @@ -83,7 +83,7 @@ az group create --name 'ExampleGroup' --location "Central US" $inputObject = @( '--name', 'ExampleDeployment', '--resource-group', 'ExampleGroup', - '--template-uri', 'https://raw.githubusercontent.com/arm/ResourceModules/main/arm/Microsoft.KeyVault/vaults/deploy.json', + '--template-uri', 'https://raw.githubusercontent.com/Azure/ResourceModules/main/arm/Microsoft.KeyVault/vaults/deploy.bicep', '--parameters', 'storageAccountType=Standard_GRS', ) az deployment group create @inputObject diff --git a/docs/wiki/PipelinesDesign.md b/docs/wiki/PipelinesDesign.md index 617d437f5a..bb38d4b378 100644 --- a/docs/wiki/PipelinesDesign.md +++ b/docs/wiki/PipelinesDesign.md @@ -188,7 +188,7 @@ Outside of the previously described platform pipelines we implemented several ad ## Dependencies pipeline -As the modules we test often times have dependencies to other services, we created a pipeline to deploys several standard services like VirtualNetworks and KeyVaults (alongside dummy secrets) for the modules to use. This _dependency_ pipeline should be prepared and executed before you start running any pipelines on your own. In case you need to rename any services there (for example because a certain globally unique resource name was already taken) make sure to update any references to this name in the module parameter files. You can find further details about this pipeline [here](.\TestingDesign#Module-Dependencies). +As the modules we test often times have dependencies to other services, we created a pipeline to deploys several standard services like VirtualNetworks and KeyVaults (alongside dummy secrets) for the modules to use. This _dependency_ pipeline should be prepared and executed before you start running any pipelines on your own. In case you need to rename any services there (for example because a certain globally unique resource name was already taken) make sure to update any references to this name in the module parameter files. You can find further details about this pipeline [here](./TestingDesign#Module-Dependencies). ### Dependencies pipeline inputs @@ -229,7 +229,7 @@ In the following sub-sections we will take a deeper look into each element. ### **GitHub Component:** GitHub secrets -The GitHub repository secrets can be set up in the repositories _'Settings'_ as described [here](https://docs.github.com/en/actions/security-guides/encrypted-secret). +The GitHub repository secrets can be set up in the repositories _'Settings'_ as described [here](https://docs.github.com/en/actions/security-guides/encrypted-secrets). For _GitHub_ in particular we need the following secrets in addition to those described in the shared [pipeline secrets](#pipeline-secrets) section: diff --git a/docs/wiki/TestingDesign.md b/docs/wiki/TestingDesign.md index 097c9a35a9..a64209ab7e 100644 --- a/docs/wiki/TestingDesign.md +++ b/docs/wiki/TestingDesign.md @@ -63,7 +63,7 @@ The following activities are run executing the `arm/.global/global.module.tests. - [Pester Wiki](https://github.com/pester/Pester/wiki) - [Pester on GitHub](https://github.com/pester/Pester) -- [Pester Setup and Commands](https://pester.dev/docs/commands/Setup) +- [Pester Installation and Update](https://pester.dev/docs/introduction/installation) --- @@ -81,7 +81,7 @@ The template validation tests execute a dry-run with each parameter file provide # Deployment validation -If all other tests passed, the deployment tests are the ultimate module validation. Using the available & configured parameter files for a module, each is deployed to Azure (in parallel) and verifies if the deployment works end to end. +If all other tests passed, the deployment tests are the ultimate module validation. Using the available & configured parameter files for a module, each is deployed to Azure (in parallel) and verifies if the deployment works end-to-end. Most of the resources are deleted by default after their deployment, to keep costs down and to be able to retest resource modules from scratch in the next run. However, the removal step can be skipped in case further investigation on the deployed resource is needed. For further details, please refer to the (./PipelinesUsage) section. diff --git a/utilities/tools/Set-ModuleReadMe.ps1 b/utilities/tools/Set-ModuleReadMe.ps1 index 2ab6f52a55..5fe4e41b37 100644 --- a/utilities/tools/Set-ModuleReadMe.ps1 +++ b/utilities/tools/Set-ModuleReadMe.ps1 @@ -86,22 +86,22 @@ function Set-ResourceTypesSection { ) # Process content - $sectionContent = [System.Collections.ArrayList]@( + $SectionContent = [System.Collections.ArrayList]@( '| Resource Type | API Version |', '| :-- | :-- |' ) - $relevantResourceTypes = Get-NestedResourceList $TemplateFileContent | Where-Object { + $RelevantResourceTypes = Get-NestedResourceList $TemplateFileContent | Where-Object { $_.type -notin $ResourceTypesToExclude -and $_ } | Select-Object 'Type', 'ApiVersion' -Unique | Sort-Object Type -Culture en-US - foreach ($resourceType in $relevantResourceTypes) { - $sectionContent += ('| `{0}` | {1} |' -f $resourceType.type, $resourceType.apiVersion) + foreach ($resourceType in $RelevantResourceTypes) { + $SectionContent += ('| `{0}` | {1} |' -f $resourceType.type, $resourceType.apiVersion) } # Build result if ($PSCmdlet.ShouldProcess('Original file with new resource type content', 'Merge')) { - $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $sectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' + $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $SectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' } return $updatedFileContent } @@ -149,7 +149,7 @@ function Set-ParametersSection { ) # Process content - $sectionContent = [System.Collections.ArrayList]@( + $SectionContent = [System.Collections.ArrayList]@( '| Parameter Name | Type | Default Value | Possible Values | Description |', '| :-- | :-- | :-- | :-- | :-- |' ) @@ -176,12 +176,12 @@ function Set-ParametersSection { $defaultValue = ($param.defaultValue -is [array]) ? ('[{0}]' -f ($param.defaultValue -join ', ')) : (($param.defaultValue -is [hashtable]) ? '{object}' : $param.defaultValue) $allowed = ($param.allowedValues -is [array]) ? ('[{0}]' -f ($param.allowedValues -join ', ')) : (($param.allowedValues -is [hashtable]) ? '{object}' : $param.allowedValues) $description = $param.metadata.description - $sectionContent += ('| `{0}` | {1} | {2} | {3} | {4} |' -f $paramName, $type, (($defaultValue) ? "``$defaultValue``" : ''), (($allowed) ? "``$allowed``" : ''), $description) + $SectionContent += ('| `{0}` | {1} | {2} | {3} | {4} |' -f $paramName, $type, (($defaultValue) ? "``$defaultValue``" : ''), (($allowed) ? "``$allowed``" : ''), $description) } # Build result if ($PSCmdlet.ShouldProcess('Original file with new parameters content', 'Merge')) { - $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $sectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' + $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $SectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' } # Build sub-section 'ParameterUsage' @@ -251,28 +251,28 @@ function Set-OutputsSection { # Process content if ($TemplateFileContent.outputs.Values.metadata) { # Template has output descriptions - $sectionContent = [System.Collections.ArrayList]@( + $SectionContent = [System.Collections.ArrayList]@( '| Output Name | Type | Description |', '| :-- | :-- | :-- |' ) foreach ($outputName in ($templateFileContent.outputs.Keys | Sort-Object -Culture en-US)) { $output = $TemplateFileContent.outputs[$outputName] - $sectionContent += ("| ``{0}`` | {1} | {2} |" -f $outputName, $output.type, $output.metadata.description) + $SectionContent += ("| ``{0}`` | {1} | {2} |" -f $outputName, $output.type, $output.metadata.description) } } else { - $sectionContent = [System.Collections.ArrayList]@( + $SectionContent = [System.Collections.ArrayList]@( '| Output Name | Type |', '| :-- | :-- |' ) foreach ($outputName in ($templateFileContent.outputs.Keys | Sort-Object -Culture en-US)) { $output = $TemplateFileContent.outputs[$outputName] - $sectionContent += ("| ``{0}`` | {1} |" -f $outputName, $output.type) + $SectionContent += ("| ``{0}`` | {1} |" -f $outputName, $output.type) } } # Build result if ($PSCmdlet.ShouldProcess('Original file with new output content', 'Merge')) { - $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $sectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' + $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $SectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' } return $updatedFileContent } @@ -321,21 +321,44 @@ function Set-TemplateReferencesSection { ) # Process content - $sectionContent = [System.Collections.ArrayList]@() + $SectionContent = [System.Collections.ArrayList]@() - $relevantResourceTypes = Get-NestedResourceList $TemplateFileContent | Where-Object { + $RelevantResourceTypes = Get-NestedResourceList $TemplateFileContent | Where-Object { $_.type -notin $ResourceTypesToExclude -and $_ -and $_.type -notlike '*/providers/*' } | Select-Object 'Type', 'ApiVersion' -Unique | Sort-Object Type -Culture en-US $TextInfo = (Get-Culture).TextInfo - foreach ($resourceType in $relevantResourceTypes) { - $Type, $Resource = $resourceType.Type -split '/', 2 - $sectionContent += ('- [{0}](https://docs.microsoft.com/en-us/azure/templates/{1}/{2}/{3})' -f $TextInfo.ToTitleCase($Resource), $Type, $resourceType.ApiVersion, $Resource) + foreach ($RelevantResourceType in $RelevantResourceTypes) { + $ProviderNamespace, $ResourceType = $RelevantResourceType.Type -split '/', 2 + $ResourceReferenceTitle = $TextInfo.ToTitleCase($ResourceType) + # Validate if Reference URL Is working + $TemplatesBaseUrl = 'https://docs.microsoft.com/en-us/azure/templates' + try { + $ResourceReferenceUrl = '{0}/{1}/{2}/{3}' -f $TemplatesBaseUrl, $ProviderNamespace, $RelevantResourceType.ApiVersion, $ResourceType + $null = Invoke-WebRequest -Uri $ResourceReferenceUrl + } catch { + # Validate if Reference URL is working using the latest documented API version (with no API version in the URL) + try { + $ResourceReferenceUrl = '{0}/{1}/{2}' -f $TemplatesBaseUrl, $ProviderNamespace, $ResourceType + $null = Invoke-WebRequest -Uri $ResourceReferenceUrl + } catch { + # Check if the resource is a child resource + if ($ResourceType.Split('/').length -gt 1) { + $ResourceReferenceUrl = '{0}/{1}/{2}' -f $TemplatesBaseUrl, $ProviderNamespace, $ResourceType.Split('/')[0] + $ResourceReferenceTitle = "'$ResourceType' Parent Documentation" + } else { + # Use the default Templates URL (Last resort) + $ResourceReferenceUrl = '{0}' -f $TemplatesBaseUrl + $ResourceReferenceTitle = 'Define resources with Bicep and ARM templates' + } + } + } + $SectionContent += ('- [{0}]({1})' -f $ResourceReferenceTitle, $ResourceReferenceUrl) } - + $SectionContent = $SectionContent | Sort-Object -Unique # Build result if ($PSCmdlet.ShouldProcess('Original file with new template references content', 'Merge')) { - $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $sectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'list' + $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $SectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'list' } return $updatedFileContent }