Tuesday, February 11, 2025
HomePowershellPowerShell based mostly Terraform Bootstrap Script

PowerShell based mostly Terraform Bootstrap Script


At present, we are going to implement a Terraform bootstrap script that may set up Terraform and create directories the place we will place our Terraform venture, which can then run a plan towards and deploy. This script will likely be written in PowerShell to bootstrap a brand new Terraform venture.

“Bootstrapping normally refers to a self-starting course of that’s speculated to proceed or develop with out exterior enter. Many analytical methods are sometimes known as bootstrap strategies in reference to their self-starting or self-supporting implementation” ~ Wikipedia.

📜 Script Overview

Impressed by the ALZ Accelerator bootstrap script, this script will:

  1. Set up-Terraform
  • Downloads and installs Terraform if not current
  • Handles model administration
  • Helps Home windows/Mac/Linux detection
  • Provides Terraform to PATH
  1. Creates required directories (config and output)
  • Copies *.tf and *.tfvars information from config to output
  • Validate file contents and paths
  1. Invoke-Terraform
  • Initializes Terraform
  • Creates execution plan
  • Handles apply/destroy with non-compulsory auto-approve
  • Manages working listing context

And I’ve examined it on my Home windows 11 machine and a Linux Codespace. In my examples, I’m utilizing it to run some base Terraform to deploy a brand new Useful resource Group and Storage Account within the New Zealand North Azure area.

Run Terraform Bootstrap

You might additionally have a look at turning it into an executable utilizing one thing like PS2EXE, after which you possibly can run it like some other executable, as beneath:

Run Terraform Bootstrap Executable

📋 Stipulations

  • PowerShell 5.1 or PowerShell Core 6.0+
  • Web connectivity for downloading Terraform
  • Azure CLI is put in and logged in (az login). It is just required if deploying to Microsoft Azure.
  • Write permissions to the listing the place you may run the script

🎯 Utilization Examples

Primary utilization with default parameters:

.Terraform-Bootstrap.ps1

Customized paths and auto-approved apply:

.Terraform-Bootstrap.ps1 -terraformPath "C:terraform" -configPath "C:tf-configs" -outputPath "C:tf-output" -autoApprove

Utilizing a particular Terraform model:

.Terraform-Bootstrap.ps1 -terraformPath "C:terraform" -configPath "C:tf-configs" -outputPath "C:tf-output"

💻 PowerShell Script

Terraform-Bootstrap.ps1




































[CmdletBinding()]
param (
[Parameter(Mandatory = $false)]
[string]$terraformPath = ".terraform",

[Parameter(Mandatory = $false)]
[string]$terraformVersion = "newest",

[Parameter(Mandatory = $false)]
[string]$configPath = ".config",

[Parameter(Mandatory = $false)]
[string]$outputPath = ".output",

[Parameter(Mandatory = $false)]
[switch]$autoApprove
)


perform Set up-Terraform {
param (
[string]$model,
[string]$path
)


if ($model -eq "newest") ConvertFrom-Json


$tfCommand = Get-Command -Title terraform -ErrorAction SilentlyContinue
if ($tfCommand) {
Write-Verbose "Terraform already put in at $($tfCommand.Path)"
return
}


if (!(Take a look at-Path $path)) Out-Null



$os = if ($IsWindows) { "home windows" } else { if ($IsMacOS) { "darwin" } else { "linux" } }
$arch = if ([System.Environment]::Is64BitOperatingSystem) { "amd64" } else { "386" }

$url = "https://releases.hashicorp.com/terraform/$($model)/terraform_$($model)_${os}_${arch}.zip"
$zipFile = Be a part of-Path $path "terraform.zip"
$extractPath = Be a part of-Path $path "terraform_$model"

Write-Verbose "Downloading Terraform from $url"
Invoke-WebRequest -Uri $url -OutFile $zipFile

Write-Verbose "Extracting Terraform to $extractPath"
Increase-Archive -Path $zipFile -DestinationPath $extractPath -Drive
Take away-Merchandise $zipFile


$env:PATH = "$extractPath;$env:PATH"
}


perform Invoke-Terraform {
param (
[string]$workingDirectory,
[string]$command,
[switch]$autoApprove
)

Push-Location $workingDirectory
strive {

Write-Host "Initializing Terraform..." -ForegroundColor Inexperienced
terraform init


Write-Host "Operating terraform $command..." -ForegroundColor Inexperienced
if ($command -eq "apply" -or $command -eq "destroy") {
terraform plan -out=tfplan

if (!$autoApprove) {
$affirmation = Learn-Host "Do you need to proceed with terraform $command? (y/n)"
if ($affirmation -ne 'y') {
Write-Host "Operation cancelled" -ForegroundColor Yellow
return
}
}

if ($command -eq "apply") {
terraform apply -auto-approve tfplan
}
else {
terraform destroy -auto-approve
}
}
else {
terraform $command
}
}
lastly {
Pop-Location
}
}


strive {

if (!(Take a look at-Path $configPath)) Out-Null
Write-Host "Config listing created at $configPath. Please place Terraform information into this listing and press any key to proceed..." -ForegroundColor Yellow
Learn-Host

if (!(Take a look at-Path $outputPath)) Out-Null



Write-Host "Making certain Terraform is put in..." -ForegroundColor Inexperienced
Set up-Terraform -model $terraformVersion -path $terraformPath


Write-Host "Establishing Terraform workspace..." -ForegroundColor Inexperienced


$configPathFull = Resolve-Path $configPath -ErrorAction Cease
$outputPathFull = Resolve-Path $outputPath -ErrorAction Cease

Write-Verbose "Config Path: $configPathFull"
Write-Verbose "Output Path: $outputPathFull"

$configFiles = Get-ChildItem -Path $configPathFull -Recurse -File -Filter "*.tf" -ErrorAction Cease
$varFiles = Get-ChildItem -Path $configPathFull -Recurse -File -Filter "*.tfvars" -ErrorAction Cease

Write-Verbose "Discovered $($configFiles.Rely) .tf information"

foreach ($file in $configFiles) {
Write-Verbose "Processing file: $($file.FullName)"


if (!(Take a look at-Path $file.FullName)) {
Write-Error "Supply file not discovered: $($file.FullName)"
proceed
}


$content material = Get-Content material $file.FullName -Uncooked
if ([string]::IsNullOrWhiteSpace($content material)) {
Write-Warning "File is empty: $($file.FullName)"
proceed
}

Write-Host "Copying $($file.Title) to $outputPathFull" -ForegroundColor Inexperienced
Copy-Merchandise -Path $file.FullName -Vacation spot $outputPathFull -Drive


$destFile = Be a part of-Path $outputPathFull $file.Title
if (!(Take a look at-Path $destFile)) {
Write-Error "Failed to repeat file to: $destFile"
}
}

foreach ($file in $varFiles) {
Write-Verbose "Processing var file: $($file.FullName)"
Write-Host "Copying $($file.Title) to $outputPathFull" -ForegroundColor Inexperienced
Copy-Merchandise -Path $file.FullName -Vacation spot $outputPathFull -Drive
}



Write-Host "Operating Terraform..." -ForegroundColor Inexperienced
Invoke-Terraform -workingDirectory $outputPath -command "apply" -autoApprove:$autoApprove

}
catch {
Write-Error "Error occurred: $_"
exit 1
}

This script may also be discovered on GitHub right here, in the event you wished to fork, or open up a Pull Request with modifications.

Hopefully that is helpful for you, having a script like this implies I can shortly deploy assets which might be coded in Terraform (HCL).

📂 Instance Terraform Recordsdata

For these , right here is the bottom Terraform code I’m utilizing in my instance:

config/principal.tf

useful resource "azurerm_resource_group" "instance" {
title = "example-stgaccount-rg"
location = "New Zealand North"
}

useful resource "azurerm_storage_account" "instance" {
title = "stgacctfboot1"
resource_group_name = azurerm_resource_group.instance.title
location = azurerm_resource_group.instance.location
account_tier = "Commonplace"
account_replication_type = "LRS"

tags = {
atmosphere = "staging"
}
}

config/suppliers.tf

terraform {
required_providers {
azurerm = {
supply = "hashicorp/azurerm"
model = "4.15.0"
}
}
}

supplier "azurerm" {
subscription_id = "9dc6cc8c-5b10-403b-9a2f-5192497ca1ed"

options {}

}
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments