diff --git a/README.md b/README.md index 2ec95ee8..efcc7aad 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,21 @@ ## Synopsis -This is a PowerShell module that provides a set of cmdlets to manage Azure Landing Zones. +This is a PowerShell module that provides a set of cmdlets to create and manage Azure Landing Zones. ## Description -This module provides a set of cmdlets to manage Azure Landing Zones. +This module provides a set of cmdlets to create and manage Azure Landing Zones. ## Why -The goal of this project it is to make easy to get started with Azure Landing Zones and to speed up some basic tasks that you would be using while managing your Azure Landing Zones. +The goal of this project it is to make easy to get started with Azure Landing Zones and to speed up some basic tasks that you would need to perform whilst managing your Azure Landing Zones. ## Getting Started ### Prerequisites -In order to use this module you will need powershell 7.1 or higher. +In order to use this module you will need PowerShell 7.1 or higher. ### Installation @@ -32,24 +32,31 @@ Install-Module -Name ALZ ### Quick start -Before start o utilize the functionality of the module you can verify if you have all the prerequisites installed, with the built in command: +Before you start you can utilize the functionality of the module to verify if you have all the prerequisites installed with the built in command: ```powershell -Test-ALZPrerequisites +Test-ALZRequirement ``` -#### Create a new Azure Landing Zone Environment +Currently this tests for: -```powershell +* Supported minimum PowerShell version +* Azure PowerShell Module +* Git +* Azure CLI +* Bicep +#### Create a new Azure Landing Zone Environment +```powershell +New-ALZEnvironment -o ``` ## Development -### Prerequisites +### Development Prerequisites -In order to develop this module you will need powershell 7.1 or higher. +In order to develop this module you will need PowerShell 7.1 or higher. ### Commands to install a build locally @@ -61,22 +68,16 @@ Import-Module .\src\Artifacts\ALZ.psd1 -Force ## Contributing -This project welcomes contributions and suggestions. Most contributions require you to agree to a -Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. -When you submit a pull request, a CLA bot will automatically determine whether you need to provide -a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions -provided by the bot. You will only need to do this once across all repos using our CLA. +When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. ## Trademarks -This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft -trademarks or logos is subject to and must follow -[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. -Any use of third-party trademarks or logos are subject to those third-party's policies. \ No newline at end of file +Any use of third-party trademarks or logos are subject to those third-party's policies. diff --git a/src/ALZ/Assets/alz-bicep-config/v0.14.1-pre.config.json b/src/ALZ/Assets/alz-bicep-config/v0.14.1-pre.config.json index e30460a4..feb58ad0 100644 --- a/src/ALZ/Assets/alz-bicep-config/v0.14.1-pre.config.json +++ b/src/ALZ/Assets/alz-bicep-config/v0.14.1-pre.config.json @@ -340,7 +340,7 @@ }, "AllSubscriptionIds": { "Type": "Computed", - "Process": "@($args | Select-Object -Unique)", + "Process": "@($args | ForEach-Object { $_.ToLower() } | Select-Object -Unique)", "Value": [ "{%ManagementSubscriptionId%}", "{%ConnectivitySubscriptionId%}", diff --git a/src/ALZ/Private/Edit-ALZConfigurationFilesInPlace.ps1 b/src/ALZ/Private/Edit-ALZConfigurationFilesInPlace.ps1 index 1c371165..1912a2e3 100644 --- a/src/ALZ/Private/Edit-ALZConfigurationFilesInPlace.ps1 +++ b/src/ALZ/Private/Edit-ALZConfigurationFilesInPlace.ps1 @@ -71,6 +71,7 @@ function Edit-ALZConfigurationFilesInPlace { if ($null -ne $configKey.Value.Process) { $scriptBlock = [ScriptBlock]::Create($configKey.Value.Process) $formattedValues = Invoke-Command -ScriptBlock $scriptBlock -ArgumentList $formattedValues + $formattedValues = @($formattedValues) } $bicepConfigNode[$leafPropertyName] = $formattedValues diff --git a/src/Tests/Unit/Private/Edit-ALZConfigurationFilesInPlace.Tests.ps1 b/src/Tests/Unit/Private/Edit-ALZConfigurationFilesInPlace.Tests.ps1 index 7bab2ac8..2c9ccee9 100644 --- a/src/Tests/Unit/Private/Edit-ALZConfigurationFilesInPlace.Tests.ps1 +++ b/src/Tests/Unit/Private/Edit-ALZConfigurationFilesInPlace.Tests.ps1 @@ -531,6 +531,103 @@ InModuleScope 'ALZ' { -Scope It } + It 'Computed, Processed array values replace values correctly in a case insensitive deduplication.' { + $config = [pscustomobject]@{ + Nested = [pscustomobject]@{ + Type = "Computed" + Description = "A Test Value" + Process = '@($args | ForEach-Object { $_.ToLower() } | Select-Object -Unique)' + Value = @( + "A", + "a", + "A", + "a" + ) + Targets = @( + [pscustomobject]@{ + Name = "parValue.value" + Destination = "Parameters" + }) + } + } + + $fileContent = '{ + "parameters": { + "parValue": { + "value": [] + } + } + }' + + $expectedContent = '{ + "parameters": { + "parValue": { + "value": [ "a" ] + } + } + }' + + Mock -CommandName Get-Content -ParameterFilter { $Path -eq $testFile1Name } -MockWith { + $fileContent + } + + $expectedContent = Format-ExpectedResult -expectedJson $expectedContent + + Edit-ALZConfigurationFilesInPlace -alzEnvironmentDestination '.' -configuration $config + + Should -Invoke -CommandName Out-File ` + -ParameterFilter { $FilePath -eq $testFile1Name -and $InputObject -eq $expectedContent } ` + -Scope It + } + + It 'Computed, Processed array values replace values correctly and keep array type when only one item remains.' { + $config = [pscustomobject]@{ + Nested = [pscustomobject]@{ + Type = "Computed" + Description = "A Test Value" + Process = '@($args | Select-Object -Unique)' + Value = @( + "1", + "1", + "1" + ) + Targets = @( + [pscustomobject]@{ + Name = "parValue.value" + Destination = "Parameters" + }) + } + } + + $fileContent = '{ + "parameters": { + "parValue": { + "value": [] + } + } + }' + + $expectedContent = '{ + "parameters": { + "parValue": { + "value": [ "1" ] + } + } + }' + + Mock -CommandName Get-Content -ParameterFilter { $Path -eq $testFile1Name } -MockWith { + $fileContent + } + + $expectedContent = Format-ExpectedResult -expectedJson $expectedContent + + Edit-ALZConfigurationFilesInPlace -alzEnvironmentDestination '.' -configuration $config + + Should -Invoke -CommandName Out-File ` + -ParameterFilter { $FilePath -eq $testFile1Name -and $InputObject -eq $expectedContent } ` + -Scope It + } + It 'Computed, Processed values replace values correctly' { $config = [pscustomobject]@{ Nested = [pscustomobject]@{