Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support tfvars for inputs and lib for vnext #251

Merged
merged 6 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ function Convert-ParametersToInputConfig {
if($inputConfig.PsObject.Properties.Name -contains $parameterAlias) {
Write-Verbose "Alias $parameterAlias exists in input config, renaming..."
$configItem = $inputConfig.PSObject.Properties | Where-Object { $_.Name -eq $parameterAlias }
$inputConfig | Add-Member -NotePropertyName $parameterKey -NotePropertyValue $configItem.Value
$inputConfig | Add-Member -NotePropertyName $parameterKey -NotePropertyValue @{
Value = $configItem.Value.Value
Source = $configItem.Value.Source
}
$inputConfig.PSObject.Properties.Remove($configItem.Name)
continue
}
Expand All @@ -34,7 +37,10 @@ function Convert-ParametersToInputConfig {
$variableValue = [bool]::Parse($variableValue)
}
Write-Verbose "Adding parameter $parameterKey with value $variableValue"
$inputConfig | Add-Member -NotePropertyName $parameterKey -NotePropertyValue $variableValue
$inputConfig | Add-Member -NotePropertyName $parameterKey -NotePropertyValue @{
Value = $variableValue
Source = "parameter"
}
}
}

Expand Down
19 changes: 16 additions & 3 deletions src/ALZ/Private/Config-Helpers/Get-ALZConfig.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ function Get-ALZConfig {
[Parameter(Mandatory = $false)]
[string] $configFilePath = "",
[Parameter(Mandatory = $false)]
[PSCustomObject] $inputConfig = $null
[PSCustomObject] $inputConfig = $null,
[Parameter(Mandatory = $false)]
[string] $hclParserToolPath = ""
)

if(!(Test-Path $configFilePath)) {
Expand Down Expand Up @@ -39,14 +41,25 @@ function Get-ALZConfig {
Write-Error $errorMessage
throw $errorMessage
}
} elseif($extension -eq ".tfvars") {
try {
$config = [PSCustomObject](& $hclParserToolPath $configFilePath | ConvertFrom-Json)
} catch {
$errorMessage = "Failed to parse HCL inputs. Please check the HCL file for errors and try again. $_"
Write-Error $errorMessage
throw $errorMessage
}
} else {
throw "The config file must be a json or yaml/yml file"
throw "The config file must be a json, yaml/yml or tfvars file"
}

Write-Verbose "Config file loaded from $configFilePath with $($config.PSObject.Properties.Name.Count) properties."

foreach($property in $config.PSObject.Properties) {
$inputConfig | Add-Member -NotePropertyName $property.Name -NotePropertyValue $property.Value
$inputConfig | Add-Member -NotePropertyName $property.Name -NotePropertyValue @{
Value = $property.Value
Source = $extension
}
}

return $inputConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ function Remove-TerraformMetaFileSet {
"terraform.tfvars",
".terraform.lock.hcl",
"examples",
"yaml.tf"
"yaml.tf",
".alzlib"
),
[Parameter(Mandatory = $false)]
[switch]$writeVerboseLogs
Expand Down
2 changes: 1 addition & 1 deletion src/ALZ/Private/Config-Helpers/Request-SpecialInput.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function Request-SpecialInput {
}

if($type -eq "starter") {
foreach($starter in $starterConfig.starter_modules.PsObject.Properties) {
foreach($starter in $starterConfig.starter_modules.Value.PsObject.Properties) {
if($starter.Name -eq $starterPipelineFolder) {
continue
}
Expand Down
2 changes: 1 addition & 1 deletion src/ALZ/Private/Config-Helpers/Set-Config.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function Set-Config {
# Look for input config match
$inputConfigItem = $inputConfig.PsObject.Properties | Where-Object { $_.Name -eq $inputConfigName }
if($null -ne $inputConfigItem) {
$configurationValue.Value.Value = $inputConfigItem.Value
$configurationValue.Value.Value = $inputConfigItem.Value.Value
continue
}

Expand Down
10 changes: 9 additions & 1 deletion src/ALZ/Private/Config-Helpers/Write-TfvarsJsonFile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ function Write-TfvarsJsonFile {
[string] $tfvarsFilePath,

[Parameter(Mandatory = $false)]
[PSObject] $configuration
[PSObject] $configuration,

[Parameter(Mandatory = $false)]
[string[]] $skipItems = @()
)

if ($PSCmdlet.ShouldProcess("Download Terraform Tools", "modify")) {
Expand All @@ -17,6 +20,11 @@ function Write-TfvarsJsonFile {
$jsonObject = [ordered]@{}

foreach($configurationProperty in $configuration.PSObject.Properties | Sort-Object Name) {
if($skipItems -contains $configurationProperty.Name) {
Write-Verbose "Skipping configuration property: $($configurationProperty.Name)"
continue
}

$configurationValue = $configurationProperty.Value.Value

if($null -ne $configurationValue -and $configurationValue.ToString() -eq "sourced-from-env") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ function Get-BootstrapAndStarterConfig {
[Parameter(Mandatory = $false)]
[string]$bootstrapConfigPath,
[Parameter(Mandatory = $false)]
[PSCustomObject]$inputConfig,
[Parameter(Mandatory = $false)]
[string]$toolsPath
)

Expand All @@ -31,7 +29,7 @@ function Get-BootstrapAndStarterConfig {
$bootstrapConfigFullPath = Join-Path $bootstrapPath $bootstrapConfigPath
Write-Verbose "Bootstrap config path $bootstrapConfigFullPath"
$bootstrapConfig = Get-ALZConfig -configFilePath $bootstrapConfigFullPath
$validationConfig = $bootstrapConfig.validators
$validationConfig = $bootstrapConfig.validators.Value

# Get the supported regions and availability zones
Write-Verbose "Getting Supported Regions and Availability Zones with Terraform"
Expand All @@ -42,7 +40,7 @@ function Get-BootstrapAndStarterConfig {
$azureLocationValidator.AllowedValues.Values = $regionsAndZones.supportedRegions

# Get the available bootstrap modules
$bootstrapModules = $bootstrapConfig.bootstrap_modules
$bootstrapModules = $bootstrapConfig.bootstrap_modules.Value

# Get the bootstrap details and validate it exists (use alias for legacy values)
$bootstrapDetails = $bootstrapModules.PsObject.Properties | Where-Object { $_.Name -eq $bootstrap -or $bootstrap -in $_.Value.aliases }
Expand All @@ -57,9 +55,9 @@ function Get-BootstrapAndStarterConfig {
if($null -ne $bootstrapStarterModule) {
# If the bootstrap has starter modules, get the details and url
$hasStarterModule = $true
$starterModules = $bootstrapConfig.PSObject.Properties | Where-Object { $_.Name -eq "starter_modules" }
$starterModules = $bootstrapConfig.starter_modules.Value
$starterModuleType = $bootstrapStarterModule.Value
$starterModuleDetails = $starterModules.Value.PSObject.Properties | Where-Object { $_.Name -eq $starterModuleType }
$starterModuleDetails = $starterModules.PSObject.Properties | Where-Object { $_.Name -eq $starterModuleType }
if($null -eq $starterModuleDetails) {
Write-InformationColored "The starter modules '$($starterModuleType)' for the bootstrap type '$bootstrap' that you have selected does not exist. This could be an issue with your custom configuration, please check and try again..." -ForegroundColor Red -InformationAction Continue
throw
Expand Down
93 changes: 75 additions & 18 deletions src/ALZ/Private/Deploy-Accelerator-Helpers/New-Bootstrap.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,19 @@ function New-Bootstrap {

[Parameter(Mandatory = $false)]
[string]
$hclParserToolPath
$hclParserToolPath,

[Parameter(Mandatory = $false)]
[switch]
$convertTfvarsToJson,

[Parameter(Mandatory = $false)]
[string[]]
$inputConfigFilePaths = @(),

[Parameter(Mandatory = $false)]
[string[]]
$starterAdditionalFiles = @()
)

if ($PSCmdlet.ShouldProcess("ALZ-Terraform module configuration", "modify")) {
Expand All @@ -71,13 +83,16 @@ function New-Bootstrap {
$starterFoldersToRetain = @()

if($hasStarter) {
if($inputConfig.starter_module_name -eq "") {
$inputConfig.starter_module_name = Request-SpecialInput -type "starter" -starterConfig $starterConfig
if($inputConfig.starter_module_name.Value -eq "") {
$inputConfig.starter_module_name = @{
Value = Request-SpecialInput -type "starter" -starterConfig $starterConfig
Source = "user"
}
}

$chosenStarterConfig = $starterConfig.starter_modules.$($inputConfig.starter_module_name)
$chosenStarterConfig = $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value)

Write-Verbose "Selected Starter: $($inputConfig.starter_module_name))"
Write-Verbose "Selected Starter: $($inputConfig.starter_module_name.Value))"
$starterModulePath = (Resolve-Path (Join-Path -Path $starterPath -ChildPath $chosenStarterConfig.location)).Path
$starterRootModuleFolderPath = $starterModulePath
Write-Verbose "Starter Module Path: $starterModulePath"
Expand All @@ -94,7 +109,10 @@ function New-Bootstrap {
$starterFoldersToRetain += $starterRootModuleFolder

# Add the root module folder to bootstrap input config
$inputConfig | Add-Member -NotePropertyName "root_module_folder_relative_path" -NotePropertyValue $starterRootModuleFolder
$inputConfig | Add-Member -NotePropertyName "root_module_folder_relative_path" -NotePropertyValue @{
Value = $starterRootModuleFolder
Source = "caluated"
}

# Set the starter root module folder full path
$starterRootModuleFolderPath = Join-Path -Path $starterModulePath -ChildPath $starterRootModuleFolder
Expand Down Expand Up @@ -126,25 +144,37 @@ function New-Bootstrap {
}

if($iac -eq "bicep") {
$starterParameters = Convert-BicepConfigToInputConfig -bicepConfig $starterConfig.starter_modules.$($inputConfig.starter_module_name) -validators $validationConfig
$starterParameters = Convert-BicepConfigToInputConfig -bicepConfig $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value) -validators $validationConfig
}
}

# Set computed inputs
$inputConfig | Add-Member -NotePropertyName "module_folder_path" -NotePropertyValue $starterModulePath
$inputConfig | Add-Member -NotePropertyName "availability_zones_bootstrap" -NotePropertyValue @(Get-AvailabilityZonesSupport -region $inputConfig.bootstrap_location -zonesSupport $zonesSupport)
$inputConfig | Add-Member -NotePropertyName "module_folder_path" -NotePropertyValue @{
Value = $starterModulePath
Source = "calculated"
}
$inputConfig | Add-Member -NotePropertyName "availability_zones_bootstrap" -NotePropertyValue @{
Value = @(Get-AvailabilityZonesSupport -region $inputConfig.bootstrap_location.Value -zonesSupport $zonesSupport)
Source = "calculated"
}

if($inputConfig.PSObject.Properties.Name -contains "starter_location" -and $inputConfig.PSObject.Properties.Name -notcontains "starter_locations") {
Write-Verbose "Converting starter_location $($inputConfig.starter_location) to starter_locations..."
$inputConfig | Add-Member -NotePropertyName "starter_locations" -NotePropertyValue @($inputConfig.starter_location)
Write-Verbose "Converting starter_location $($inputConfig.starter_location.Value) to starter_locations..."
$inputConfig | Add-Member -NotePropertyName "starter_locations" -NotePropertyValue @{
Value = @($inputConfig.starter_location.Value)
Source = "calculated"
}
}

if($inputConfig.PSObject.Properties.Name -contains "starter_locations") {
$availabilityZonesStarter = @()
foreach($region in $inputConfig.starter_locations) {
foreach($region in $inputConfig.starter_locations.Value) {
$availabilityZonesStarter += , @(Get-AvailabilityZonesSupport -region $region -zonesSupport $zonesSupport)
}
$inputConfig | Add-Member -NotePropertyName "availability_zones_starter" -NotePropertyValue $availabilityZonesStarter
$inputConfig | Add-Member -NotePropertyName "availability_zones_starter" -NotePropertyValue @{
Value = $availabilityZonesStarter
Source = "calculated"
}
}

Write-Verbose "Final Input config: $(ConvertTo-Json $inputConfig -Depth 100)"
Expand Down Expand Up @@ -188,26 +218,53 @@ function New-Bootstrap {
}
}
Remove-TerraformMetaFileSet -path $starterModulePath -writeVerboseLogs:$writeVerboseLogs.IsPresent
Write-TfvarsJsonFile -tfvarsFilePath $starterTfvarsPath -configuration $starterConfiguration
if($convertTfvarsToJson) {
Write-TfvarsJsonFile -tfvarsFilePath $starterTfvarsPath -configuration $starterConfiguration
} else {
$inputsFromTfvars = $inputConfig.PSObject.Properties | Where-Object { $_.Value.Source -eq ".tfvars" } | Select-Object -ExpandProperty Name
Write-TfvarsJsonFile -tfvarsFilePath $starterTfvarsPath -configuration $starterConfiguration -skipItems $inputsFromTfvars
foreach($inputConfigFilePath in $inputConfigFilePaths | Where-Object { $_ -like "*.tfvars" }) {
$fileName = [System.IO.Path]::GetFileName($inputConfigFilePath)
$fileName = $fileName.Replace(".tfvars", ".auto.tfvars")
$destination = Join-Path -Path $starterRootModuleFolderPath -ChildPath $fileName
Write-Verbose "Copying tfvars file $inputConfigFilePath to $destination"
Copy-Item -Path $inputConfigFilePath -Destination $destination -Force
}
}

# Copy additional files
foreach($additionalFile in $starterAdditionalFiles) {
if(Test-Path $additionalFile -PathType Container) {
$folderName = ([System.IO.DirectoryInfo]::new($additionalFile)).Name
$destination = Join-Path -Path $starterRootModuleFolderPath -ChildPath $folderName
Write-Verbose "Copying folder $additionalFile to $destination"
Copy-Item -Path "$additionalFile/*" -Destination $destination -Recurse -Force
} else {
$fileName = [System.IO.Path]::GetFileName($inputConfigFilePath)
$destination = Join-Path -Path $starterRootModuleFolderPath -ChildPath $fileName
Write-Verbose "Copying file $additionalFile to $destination"
Copy-Item -Path $additionalFile -Destination $destination -Force
}
}
}

if($iac -eq "bicep") {
Copy-ParametersFileCollection -starterPath $starterModulePath -configFiles $starterConfig.starter_modules.$($inputConfig.starter_module_name).deployment_files
Copy-ParametersFileCollection -starterPath $starterModulePath -configFiles $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value).deployment_files
Set-ComputedConfiguration -configuration $starterConfiguration
Edit-ALZConfigurationFilesInPlace -alzEnvironmentDestination $starterModulePath -configuration $starterConfiguration
Write-JsonFile -jsonFilePath $starterBicepVarsPath -configuration $starterConfiguration

# Remove unrequired files
$foldersOrFilesToRetain = $starterConfig.starter_modules.$($inputConfig.starter_module_name).folders_or_files_to_retain
$foldersOrFilesToRetain = $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value).folders_or_files_to_retain
$foldersOrFilesToRetain += "parameters.json"
$foldersOrFilesToRetain += "config"
$foldersOrFilesToRetain += "starter-cache.json"

foreach($deployment_file in $starterConfig.starter_modules.$($inputConfig.starter_module_name).deployment_files) {
foreach($deployment_file in $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value).deployment_files) {
$foldersOrFilesToRetain += $deployment_file.templateParametersSourceFilePath
}

$subFoldersOrFilesToRemove = $starterConfig.starter_modules.$($inputConfig.starter_module_name).subfolders_or_files_to_remove
$subFoldersOrFilesToRemove = $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value).subfolders_or_files_to_remove

Remove-UnrequiredFileSet -path $starterModulePath -foldersOrFilesToRetain $foldersOrFilesToRetain -subFoldersOrFilesToRemove $subFoldersOrFilesToRemove -writeVerboseLogs:$writeVerboseLogs.IsPresent
}
Expand Down
Loading
Loading