Public/Terraform/Invoke-TerraformPlan.ps1
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 |
function Invoke-TerraformPlan { [CmdletBinding()] param ( # The path to the terraform configuration to plan against [Parameter( Mandatory = $false, Position = 0, ValueFromPipelineByPropertyName = $true )] [ValidateNotNullOrEmpty()] [string] $TerraformConfigPath = $PWD, # The Path to the Terraform executable to use [Parameter( Mandatory = $false, ValueFromPipelineByPropertyName = $true )] [ValidateNotNullOrEmpty()] [string] $TerraformPath = 'terraform', # The path to store the output of the Terraform plan [Parameter( Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 1 )] [string] $OutputPath, # A resource to target (useful in testing) [Parameter( Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 2 )] [string] $Target, # Whether or not to refresh resources [Parameter( Mandatory = $false, ValueFromPipelineByPropertyName = $true )] [bool] $Refresh = $true, # Whether or not to use detailed exit codes [Parameter( Mandatory = $false )] [bool] $DetailedExitCodes = $false, # Limit the number of concurrent operation as Terraform walks the graph. [Parameter( Mandatory = $false )] [int] $Parallelism, # Whether or not to enable color output, defaults to false so as not to break CI/CD tools [Parameter( Mandatory = $false, ValueFromPipelineByPropertyName = $true )] [bool] $EnableColor = $false ) $ValidExitCodes = @(0) $PlanArgs = @('plan') if ($EnableColor -eq $false) { Write-Verbose "Disabling color output" $PlanArgs += @("-no-color") } if ($OutputPath) { Write-Verbose "Setting output path to $OutputPath" $PlanArgs += "-out=$OutputPath" } if ($Target) { Write-Verbose "Targetting $target" $PlanArgs += "-target='$Target'" } if ($Refresh -eq $false) { Write-Verbose "Disabling refresh" $PlanArgs += "-refresh=false" } if ($DetailedExitCodes -eq $true) { Write-Verbose "Using detailed exit codes" # terraform plan may actually return a non-zero exit code when detailed exit codes are used https://www.terraform.io/docs/cli/commands/plan.html#detailed-exitcode $ValidExitCodes += 2 $PlanArgs += "-detailed-exitcode" } if ($Parallelism) { Write-Verbose "Setting Parallelism to $Parallelism" $PlanArgs += "-parallelism=$Parallelism" } try { $TerraformParams = @{ FilePath = $TerraformPath ArgumentList = $PlanArgs ExitCodes = $ValidExitCodes WorkingDirectory = $TerraformConfigPath PassThru = $true SuppressOutput = $true } if ($VerbosePreference -eq 'Continue') { $TerraformParams.Remove('SuppressOutput') } $TerraformPlan = Invoke-NativeCommand @TerraformParams | Select-Object -ExpandProperty OutputContent # We want to extract the plan results for later consumption } catch { Write-Error "Terraform plan has failed.`n$($_.Exception.Message)" } $TerraformResult = @{ PlanOutput = $TerraformPlan } if ($OutputPath) { try { $AbsoluteOutputPath = Get-Item $OutputPath | Convert-Path } catch { Write-Error "Failed to find Terraform plan output at $OutputPath.`n$($_.Exception.Message)" } # Add the path to the Terraform plan output to the returned object so it can be piped into Invoke-Terraform show if desired $TerraformResult.Add('TerraformPlanPath', $AbsoluteOutputPath) } Return [pscustomobject]$TerraformResult } |