diff --git a/src/ALZ/Private/Shared/Get-GithubRelease.ps1 b/src/ALZ/Private/Shared/Get-GithubRelease.ps1 index 1447490..30da6de 100644 --- a/src/ALZ/Private/Shared/Get-GithubRelease.ps1 +++ b/src/ALZ/Private/Shared/Get-GithubRelease.ps1 @@ -81,73 +81,77 @@ function Get-GithubRelease { return $releaseTag } - # Check if directory exists - Write-Verbose "=====> Checking if directory for releases exists: $targetPath" - - if (!(Test-Path $targetPath)) { - Write-Verbose "Directory does not exist for releases, will now create: $targetPath" - New-Item -ItemType Directory -Path $targetPath | Out-String | Write-Verbose - } - - # Check the directory for this release + # Determine the target version path (do not create it yet - we only create it after a successful download/extract) $targetVersionPath = Join-Path $targetPath $releaseTag Write-Verbose "===> Checking if directory for release version exists: $targetVersionPath" - if (!(Test-Path $targetVersionPath)) { - Write-Verbose "Directory does not exist for release $releaseTag, will now create: $targetVersionPath" - New-Item -ItemType Directory -Path $targetVersionPath | Out-String | Write-Verbose + $contentTargetVersionPath = $null + if (Test-Path $targetVersionPath) { + $contentTargetVersionPath = Get-ChildItem -Path $targetVersionPath -Recurse -Force -ErrorAction SilentlyContinue } - Write-Verbose "===> Checking if any content exists inside of $targetVersionPath" - - $contentTargetVersionPath = Get-ChildItem -Path $targetVersionPath -Recurse -Force -ErrorAction SilentlyContinue - if ($null -eq $contentTargetVersionPath) { - Write-Verbose "===> Pulling and extracting release $releaseTag into $targetVersionPath" - New-Item -ItemType Directory -Path "$targetVersionPath/tmp" | Out-String | Write-Verbose - $targetPathForZip = "$targetVersionPath/tmp/$releaseTag.zip" - - # Get the artifact url - if($releaseArtifactName -ne "") { - $releaseArtifactUrl = $releaseData.assets | Where-Object { $_.name -eq $releaseArtifactName } | Select-Object -ExpandProperty browser_download_url - } else { - $releaseArtifactUrl = $releaseData.zipball_url - } - - Write-Verbose "===> Downloading the release artifact $releaseArtifactUrl from the GitHub repository $repoOrgPlusRepo" - - $downloadParams = @{ - Uri = $releaseArtifactUrl - OutputFile = $targetPathForZip - MaxRetryCount = $maxRetryCount - RetryIntervalSeconds = $retryIntervalSeconds - } - if ($PSBoundParameters.ContainsKey("httpRequestTimeoutSeconds")) { - $downloadParams["TimeoutSec"] = $httpRequestTimeoutSeconds + # Stage the download and extraction in a temp location under the outputs folder so a failure + # does not leave behind empty release/version folders. We always clean it up in `finally`. + $stagingRoot = Join-Path $targetDirectory "temp/downloads/$([System.Guid]::NewGuid().ToString("N"))" + New-Item -ItemType Directory -Path $stagingRoot -Force | Out-String | Write-Verbose + $targetPathForZip = Join-Path $stagingRoot "$releaseTag.zip" + $targetPathForExtractedZip = Join-Path $stagingRoot "extracted" + + try { + # Get the artifact url + if($releaseArtifactName -ne "") { + $releaseArtifactUrl = $releaseData.assets | Where-Object { $_.name -eq $releaseArtifactName } | Select-Object -ExpandProperty browser_download_url + } else { + $releaseArtifactUrl = $releaseData.zipball_url + } + + Write-Verbose "===> Downloading the release artifact $releaseArtifactUrl from the GitHub repository $repoOrgPlusRepo to staging location $targetPathForZip" + + $downloadParams = @{ + Uri = $releaseArtifactUrl + OutputFile = $targetPathForZip + MaxRetryCount = $maxRetryCount + RetryIntervalSeconds = $retryIntervalSeconds + } + if ($PSBoundParameters.ContainsKey("httpRequestTimeoutSeconds")) { + $downloadParams["TimeoutSec"] = $httpRequestTimeoutSeconds + } + Invoke-GitHubApiRequest @downloadParams + + if(!(Test-Path $targetPathForZip)) { + Write-ToConsoleLog "Failed to download the release $releaseTag from the GitHub repository $repoOrgPlusRepo" -IsError + throw "Failed to download the release $releaseTag from the GitHub repository $repoOrgPlusRepo" + } + + Expand-Archive -Path $targetPathForZip -DestinationPath $targetPathForExtractedZip | Out-String | Write-Verbose + + $extractedSubFolder = $targetPathForExtractedZip + if($releaseArtifactName -eq "") { + $extractedSubFolder = (Get-ChildItem -Path $targetPathForExtractedZip -Directory -Force).FullName + } + + # Only now (after a successful download and extract) do we create the target folders + # and copy the content in. + if (!(Test-Path $targetPath)) { + Write-Verbose "Directory does not exist for releases, will now create: $targetPath" + New-Item -ItemType Directory -Path $targetPath | Out-String | Write-Verbose + } + + Write-Verbose "Directory does not exist for release $releaseTag, will now create: $targetVersionPath" + New-Item -ItemType Directory -Path $targetVersionPath | Out-String | Write-Verbose + + Write-Verbose "===> Copying all extracted contents into $targetVersionPath from $($extractedSubFolder)/$moduleSourceFolder/*." + + Copy-Item -Path "$($extractedSubFolder)/$moduleSourceFolder/*" -Destination "$targetVersionPath" -Recurse -Force | Out-String | Write-Verbose + + Write-ToConsoleLog "The directory for $targetVersionPath has been created and populated." -IsSuccess + } finally { + if (Test-Path $stagingRoot) { + Remove-Item -Path $stagingRoot -Force -Recurse -ErrorAction SilentlyContinue + } } - Invoke-GitHubApiRequest @downloadParams - - if(!(Test-Path $targetPathForZip)) { - Write-ToConsoleLog "Failed to download the release $releaseTag from the GitHub repository $repoOrgPlusRepo" -IsError - throw - } - - $targetPathForExtractedZip = "$targetVersionPath/tmp/extracted" - - Expand-Archive -Path $targetPathForZip -DestinationPath $targetPathForExtractedZip | Out-String | Write-Verbose - - $extractedSubFolder = $targetPathForExtractedZip - if($releaseArtifactName -eq "") { - $extractedSubFolder = (Get-ChildItem -Path $targetPathForExtractedZip -Directory -Force).FullName - } - - Write-Verbose "===> Copying all extracted contents into $targetVersionPath from $($extractedSubFolder)/$moduleSourceFolder/*." - - Copy-Item -Path "$($extractedSubFolder)/$moduleSourceFolder/*" -Destination "$targetVersionPath" -Recurse -Force | Out-String | Write-Verbose - - Remove-Item -Path "$targetVersionPath/tmp" -Force -Recurse - Write-ToConsoleLog "The directory for $targetVersionPath has been created and populated." -IsSuccess } else { Write-ToConsoleLog "The directory for $targetVersionPath already exists and has content in it, so we are not overwriting it." -IsSuccess Write-Verbose "===> Content already exists in $releaseDirectory. Skipping" diff --git a/src/ALZ/Private/Tools/Get-TerraformTool.ps1 b/src/ALZ/Private/Tools/Get-TerraformTool.ps1 index df54920..c3102dc 100644 --- a/src/ALZ/Private/Tools/Get-TerraformTool.ps1 +++ b/src/ALZ/Private/Tools/Get-TerraformTool.ps1 @@ -47,7 +47,7 @@ function Get-TerraformTool { Write-ToConsoleLog "Unable to query Terraform version '$version' from HashiCorp API. HTTP status code: $($versionResponse.StatusCode)" -IsError throw "Unable to query Terraform version, please check the supplied version and try again..." } - $release = ($versionResponse).Content + $release = ($versionResponse).Content | ConvertFrom-Json } Write-Verbose "Required version of Terraform is $version" diff --git a/src/ALZ/Public/Deploy-Accelerator.ps1 b/src/ALZ/Public/Deploy-Accelerator.ps1 index b5c033f..3514e49 100644 --- a/src/ALZ/Public/Deploy-Accelerator.ps1 +++ b/src/ALZ/Public/Deploy-Accelerator.ps1 @@ -221,7 +221,15 @@ function Deploy-Accelerator { )] [Alias("hrts")] [Alias("httpRequestTimeoutSeconds")] - [int] $http_request_timeout_seconds + [int] $http_request_timeout_seconds, + + [Parameter( + Mandatory = $false, + HelpMessage = "[OPTIONAL] The version of Terraform to download and use. Defaults to '1.14.9'. Specify 'latest' to download the latest stable release. Environment variable: ALZ_terraform_version. Config file input: terraform_version." + )] + [Alias("tv")] + [Alias("terraformVersion")] + [string] $terraform_version = "1.14.9" ) $ProgressPreference = "SilentlyContinue" @@ -355,9 +363,9 @@ function Deploy-Accelerator { if ($skipInternetChecks) { Write-ToConsoleLog "Skipping Terraform tool check as you used the skipInternetCheck parameter. Please ensure you have the most recent version of Terraform installed" -IsWarning } else { - Write-ToConsoleLog "Checking you have the latest version of Terraform installed..." -IsSuccess + Write-ToConsoleLog "Checking you have the correct version of Terraform installed..." -IsSuccess $terraformToolParams = @{ - version = "latest" + version = $terraform_version toolsPath = $toolsPath maxRetryCount = $http_request_max_retry_count retryIntervalSeconds = $http_request_retry_interval_seconds