-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathRequest-AcceleratorConfigurationInput.ps1
More file actions
314 lines (266 loc) · 15.2 KB
/
Request-AcceleratorConfigurationInput.ps1
File metadata and controls
314 lines (266 loc) · 15.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
function Request-AcceleratorConfigurationInput {
<#
.SYNOPSIS
Prompts the user for accelerator configuration input and creates the folder structure.
.DESCRIPTION
This function interactively prompts the user for the inputs needed to set up the accelerator folder structure,
calls New-AcceleratorFolderStructure to create the folders and configuration files, and returns the paths
needed for Deploy-Accelerator to continue.
.PARAMETER Destroy
When set, only prompts for the target folder path and validates the existing folder structure exists.
.OUTPUTS
Returns a hashtable with the following keys:
- Continue: Boolean indicating whether to continue with deployment
- InputConfigFilePaths: Array of input configuration file paths
- StarterAdditionalFiles: Array of additional files/folders for the starter module
- OutputFolderPath: Path to the output folder
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param(
[Parameter(Mandatory = $false)]
[switch] $Destroy,
[Parameter(Mandatory = $false)]
[switch] $ClearCache,
[Parameter(Mandatory = $false)]
[string] $OutputFolderName = "output"
)
if ($PSCmdlet.ShouldProcess("Accelerator folder structure setup", "prompt and create")) {
# Display appropriate header message
if ($Destroy.IsPresent) {
Write-ToConsoleLog "Running in destroy mode. Please provide the path to your existing accelerator folder." -IsWarning
} else {
Write-ToConsoleLog "No input configuration files provided. Let's set up the accelerator folder structure first..." -IsSuccess
Write-ToConsoleLog "For more information, see: https://aka.ms/alz/acc/phase2"
}
# Prompt for target folder path (first prompt for both modes)
$targetFolderPathInput = Read-MenuSelection `
-Title "Enter the target folder path for the accelerator files:" `
-DefaultValue "~/accelerator" `
-AllowManualEntry `
-ManualEntryPrompt "Target folder path"
# Normalize the path
$normalizedTargetPath = Get-NormalizedPath -Path $targetFolderPathInput
# Analyze existing folder configuration
$folderConfig = Get-AcceleratorFolderConfiguration -FolderPath $normalizedTargetPath
$useExistingFolder = $false
$forceFlag = $false
# If folder exists, ask about overwriting before other prompts
if ($folderConfig.FolderExists) {
# Ask about overwriting the folder
Write-ToConsoleLog "Target folder '$normalizedTargetPath' already exists." -IsWarning
$forceResponse = Read-MenuSelection `
-Title "Do you want to overwrite the existing folder structure? This will replace existing configuration files." `
-DefaultValue "no" `
-Type "boolean" `
-AllowManualEntry `
-ManualEntryPrompt "Enter '[y]es' to overwrite or '[n]o' to keep existing"
Write-Verbose "User overwrite response: $forceResponse"
Write-Verbose $forceResponse.GetType().FullName
if ($forceResponse) {
$forceFlag = $true
} else {
# User wants to keep existing folder
$useExistingFolder = $true
# Validate config files exist
if (-not $folderConfig.IsValid) {
if (-not (Test-Path -Path $folderConfig.ConfigFolderPath)) {
Write-ToConsoleLog "ERROR: Config folder not found at '$($folderConfig.ConfigFolderPath)'" -IsError
} elseif (-not (Test-Path -Path $folderConfig.InputsYamlPath)) {
Write-ToConsoleLog "ERROR: Required configuration file not found: inputs.yaml" -IsError
}
Write-ToConsoleLog "Please overwrite the folder structure by choosing 'y', or run New-AcceleratorFolderStructure manually." -IsWarning
return ConvertTo-AcceleratorResult -Continue $false
}
}
}
# Handle destroy mode - validate existing folder and return early
if ($Destroy.IsPresent) {
if (-not $folderConfig.FolderExists) {
Write-ToConsoleLog "ERROR: Target folder '$normalizedTargetPath' does not exist." -IsError
Write-ToConsoleLog "Cannot destroy a deployment that doesn't exist. Please check the path and try again." -IsWarning
return ConvertTo-AcceleratorResult -Continue $false
}
if (-not (Test-Path -Path $folderConfig.ConfigFolderPath)) {
Write-ToConsoleLog "ERROR: Config folder not found at '$($folderConfig.ConfigFolderPath)'" -IsError
Write-ToConsoleLog "Cannot destroy a deployment without configuration files." -IsWarning
return ConvertTo-AcceleratorResult -Continue $false
}
if (-not (Test-Path -Path $folderConfig.InputsYamlPath)) {
Write-ToConsoleLog "ERROR: Required configuration file not found: inputs.yaml" -IsError
Write-ToConsoleLog "Cannot destroy a deployment without inputs.yaml." -IsWarning
return ConvertTo-AcceleratorResult -Continue $false
}
# Build input config file paths based on detected IaC type
$configPaths = Get-AcceleratorConfigPath -IacType $folderConfig.IacType -ConfigFolderPath $folderConfig.ConfigFolderPath
$resolvedTargetPath = (Resolve-Path -Path $normalizedTargetPath).Path
Write-ToConsoleLog "Using existing folder: $resolvedTargetPath" -IsSuccess
# Prompt for sensitive inputs that are not already set (e.g., PATs)
Write-ToConsoleLog "Checking for sensitive inputs that need to be provided..." -IsWarning
Request-ALZConfigurationValue `
-ConfigFolderPath $folderConfig.ConfigFolderPath `
-IacType $folderConfig.IacType `
-VersionControl $folderConfig.VersionControl `
-AzureContextOutputDirectory $folderConfig.OutputFolderPath `
-AzureContextClearCache:$ClearCache.IsPresent `
-SensitiveOnly
Write-ToConsoleLog "Proceeding with destroy..." -IsWarning
return ConvertTo-AcceleratorResult -Continue $true `
-InputConfigFilePaths $configPaths.InputConfigFilePaths `
-StarterAdditionalFiles $configPaths.StarterAdditionalFiles `
-OutputFolderPath $folderConfig.OutputFolderPath
}
# Set selected values from detected values (for use existing folder case)
$selectedIacType = $folderConfig.IacType
$selectedVersionControl = $folderConfig.VersionControl
$selectedScenarioNumber = 1
# Only prompt for IaC type, version control, and scenario if creating new folder or overwriting
if (-not $useExistingFolder) {
# Prompt for IaC type with detected value as default
$iacTypeOptions = @("terraform", "bicep")
$defaultIacTypeIndex = if ($null -ne $folderConfig.IacType) {
[Math]::Max(0, $iacTypeOptions.IndexOf($folderConfig.IacType))
} else { 0 }
$selectedIacType = Read-MenuSelection `
-Title "Select the Infrastructure as Code (IaC) type:" `
-Options $iacTypeOptions `
-DefaultIndex $defaultIacTypeIndex
# Prompt for version control with detected value as default
$versionControlOptions = @("github", "azure-devops", "local")
$defaultVcsIndex = if ($null -ne $folderConfig.VersionControl) {
[Math]::Max(0, $versionControlOptions.IndexOf($folderConfig.VersionControl))
} else { 0 }
$selectedVersionControl = Read-MenuSelection `
-Title "Select the Version Control System:" `
-Options $versionControlOptions `
-DefaultIndex $defaultVcsIndex
# Prompt for scenario number (Terraform only)
if ($selectedIacType -eq "terraform") {
$scenariosJsonPath = Join-Path $PSScriptRoot "TerraformScenarios.json"
$scenarioOptions = Get-Content -Path $scenariosJsonPath -Raw | ConvertFrom-Json
$selectedScenarioNumber = Read-MenuSelection `
-Title "Select the Terraform scenario (see https://aka.ms/alz/acc/scenarios):" `
-Options $scenarioOptions `
-DefaultIndex 0
}
}
# Create folder structure if needed
if (-not $folderConfig.FolderExists -or $forceFlag) {
New-AcceleratorFolderStructure `
-iacType $selectedIacType `
-versionControl $selectedVersionControl `
-scenarioNumber $selectedScenarioNumber `
-targetFolderPath $targetFolderPathInput `
-outputFolderName $OutputFolderName `
-force:$forceFlag
Write-ToConsoleLog "Folder structure created at: $normalizedTargetPath" -IsSuccess
}
# Resolve the path after folder creation or validation
$resolvedTargetPath = (Resolve-Path -Path $normalizedTargetPath).Path
$outputFolderPath = Join-Path $resolvedTargetPath $OutputFolderName
$configFolderPath = if ($useExistingFolder) {
$folderConfig.ConfigFolderPath
} else {
Join-Path $resolvedTargetPath "config"
}
if ($useExistingFolder) {
Write-ToConsoleLog "Using existing folder structure at: $resolvedTargetPath" -IsSuccess
}
Write-ToConsoleLog "Config folder: $configFolderPath"
# Offer to configure inputs interactively (default is Yes)
$configureNowResponse = Read-MenuSelection `
-Title "Would you like to configure the input values interactively now?" `
-DefaultValue "yes" `
-Type "boolean" `
-AllowManualEntry `
-ManualEntryPrompt "Enter '[y]es' for interactive mode or '[n]o' to update the file manually later"
if ($configureNowResponse) {
Request-ALZConfigurationValue `
-ConfigFolderPath $configFolderPath `
-IacType $selectedIacType `
-VersionControl $selectedVersionControl `
-AzureContextOutputDirectory $outputFolderPath `
-AzureContextClearCache:$ClearCache.IsPresent
} else {
Write-ToConsoleLog "Checking for sensitive inputs that need to be provided..." -IsWarning
Request-ALZConfigurationValue `
-ConfigFolderPath $configFolderPath `
-IacType $selectedIacType `
-VersionControl $selectedVersionControl `
-AzureContextOutputDirectory $outputFolderPath `
-AzureContextClearCache:$ClearCache.IsPresent `
-SensitiveOnly
}
# Check for VS Code or VS Code Insiders and offer to open the config folder
$vsCodeCommand = $null
$vsCodeName = $null
if (Get-Command "code-insiders" -ErrorAction SilentlyContinue) {
$vsCodeCommand = "code-insiders"
$vsCodeName = "VS Code Insiders"
} elseif (Get-Command "code" -ErrorAction SilentlyContinue) {
$vsCodeCommand = "code"
$vsCodeName = "VS Code"
}
if ($null -ne $vsCodeCommand) {
$openInVsCodeResponse = Read-MenuSelection `
-Title "Would you like to open the config folder in $($vsCodeName)?" `
-DefaultValue "yes" `
-Type "boolean" `
-AllowManualEntry `
-ManualEntryPrompt "Enter '[y]es' to open or '[n]o' to continue without opening"
if ($openInVsCodeResponse) {
Write-ToConsoleLog "Opening config folder in $vsCodeName..." -IsSuccess
& $vsCodeCommand $configFolderPath
}
}
Write-ToConsoleLog "Please check and update the configuration files in the config folder before continuing:" -IsWarning
Write-ToConsoleLog " - inputs.yaml: Bootstrap configuration (required)" -IsSelection
if ($selectedIacType -eq "terraform") {
Write-ToConsoleLog " - platform-landing-zone.tfvars: Platform configuration (required)" -IsSelection
Write-ToConsoleLog " - starter_locations: Enter the regions for you platform landing zone (required)" -IsSelection
Write-ToConsoleLog " - defender_email_security_contact: Enter the email security contact for Microsoft Defender for Cloud (required)" -IsSelection
Write-ToConsoleLog " - lib/: Library customizations (optional)" -IsSelection
} elseif ($selectedIacType -eq "bicep") {
Write-ToConsoleLog " - platform-landing-zone.yaml: Platform configuration (required)" -IsSelection
Write-ToConsoleLog " - starter_locations: Enter the regions for you platform landing zone (required)" -IsSelection
}
Write-ToConsoleLog "For more details, see: https://azure.github.io/Azure-Landing-Zones/accelerator/configuration-files/"
# Prompt to continue or exit
$continueResponse = Read-MenuSelection `
-Title "Have you checked and updated the configuration files? Ready to continue with deployment?" `
-DefaultValue "yes" `
-Type "boolean" `
-AllowManualEntry `
-ManualEntryPrompt "Enter '[y]es' to continue or '[n]o' to exit"
if (!$continueResponse) {
Write-ToConsoleLog "To continue later, run Deploy-Accelerator with the following parameters:" -IsSuccess
if ($selectedIacType -eq "terraform") {
Write-ToConsoleLog @"
Deploy-Accelerator ``
-inputs "$configFolderPath/inputs.yaml", "$configFolderPath/platform-landing-zone.tfvars" ``
-starterAdditionalFiles "$configFolderPath/lib" ``
-output "$outputFolderPath"
"@ -Color Cyan
} elseif ($selectedIacType -eq "bicep") {
Write-ToConsoleLog @"
Deploy-Accelerator ``
-inputs "$configFolderPath/inputs.yaml", "$configFolderPath/platform-landing-zone.yaml" ``
-output "$outputFolderPath"
"@ -Color Cyan
} else {
Write-ToConsoleLog @"
Deploy-Accelerator ``
-inputs "$configFolderPath/inputs.yaml" ``
-output "$outputFolderPath"
"@ -Color Cyan
}
return ConvertTo-AcceleratorResult -Continue $false
}
# Build the result for continuing with deployment
$configPaths = Get-AcceleratorConfigPath -IacType $selectedIacType -ConfigFolderPath $configFolderPath
Write-ToConsoleLog "Continuing with deployment..." -IsSuccess
return ConvertTo-AcceleratorResult -Continue $true `
-InputConfigFilePaths $configPaths.InputConfigFilePaths `
-StarterAdditionalFiles $configPaths.StarterAdditionalFiles `
-OutputFolderPath $outputFolderPath
}
}