From 44d658745e04c6084dbff4d55198d3ba6956fd1c Mon Sep 17 00:00:00 2001 From: Alexandros Kritikos Date: Sun, 1 Mar 2026 14:16:19 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Add=20bootstrap=20script=20for?= =?UTF-8?q?=20Azure=20state=20management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/bootstrap-az-state.ps1 | 78 ++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 scripts/bootstrap-az-state.ps1 diff --git a/scripts/bootstrap-az-state.ps1 b/scripts/bootstrap-az-state.ps1 new file mode 100644 index 0000000..2289d9d --- /dev/null +++ b/scripts/bootstrap-az-state.ps1 @@ -0,0 +1,78 @@ +Param( + [string]$Location = "westeurope", + [string]$ResourceGroup = "rg-tofu-state", + [string]$StorageAccountName = "", + [string]$ContainerName = "tfstate", + [string]$StateKey = "terraform.tfstate", + [switch]$UseAzureAdAuth = $true +) + +$ErrorActionPreference = "Stop" + +function Ensure-AzLogin { + try { az account show | Out-Null } + catch { az login | Out-Null } +} + +Ensure-AzLogin + +# Resource Group (idempotent) +az group create --name $ResourceGroup --location $Location | Out-Null + +# Storage Account name must be globally unique, 3-24 chars, lowercase letters/numbers +if ([string]::IsNullOrWhiteSpace($StorageAccountName)) { + $rand = Get-Random -Minimum 100000 -Maximum 999999 + $StorageAccountName = ("tofu" + $rand + "state").ToLower() + if ($StorageAccountName.Length -gt 24) { $StorageAccountName = $StorageAccountName.Substring(0, 24) } +} + +# Create SA if missing +$saExists = $true +try { az storage account show -g $ResourceGroup -n $StorageAccountName | Out-Null } +catch { $saExists = $false } + +if (-not $saExists) { + az storage account create ` + -g $ResourceGroup -n $StorageAccountName -l $Location ` + --sku Standard_LRS --kind StorageV2 ` + --https-only true --min-tls-version TLS1_2 ` + --allow-blob-public-access false | Out-Null +} + +# Enable blob versioning + soft delete (nice safety net for state) +az storage account blob-service-properties update ` + -g $ResourceGroup -n $StorageAccountName ` + --enable-versioning true ` + --enable-delete-retention true --delete-retention-days 14 | Out-Null + +# Create container (try Entra "login" auth first; fallback to account key if needed) +$containerCreated = $false +try { + az storage container create ` + --name $ContainerName --account-name $StorageAccountName ` + --auth-mode login | Out-Null + $containerCreated = $true +} +catch { + $key = az storage account keys list -g $ResourceGroup -n $StorageAccountName --query "[0].value" -o tsv + az storage container create ` + --name $ContainerName --account-name $StorageAccountName ` + --account-key $key | Out-Null + $containerCreated = $true +} + +# Write backend.hcl (NO secrets if you keep AzureAD auth + CLI) +$backend = @() +$backend += "resource_group_name = `"$ResourceGroup`"" +$backend += "storage_account_name = `"$StorageAccountName`"" +$backend += "container_name = `"$ContainerName`"" +$backend += "key = `"$StateKey`"" +if ($UseAzureAdAuth) { $backend += "use_azuread_auth = true" } # uses Entra ID :contentReference[oaicite:2]{index=2} +Set-Content -Path (Join-Path (Get-Location) "backend.hcl") -Value ($backend -join "`n") -Encoding UTF8 + +Write-Host "State backend ready:" +Write-Host " RG: $ResourceGroup" +Write-Host " SA: $StorageAccountName" +Write-Host " Container: $ContainerName" +Write-Host " Key: $StateKey" +Write-Host "Wrote backend.hcl"