Terrafrom Pre-Requisite - Azure PowerShell - PowerShell
- Purpose:
- You want to use Terraform in Azure
- You have read the official documentation
- You want to get running quickly
- You want to do things securely
- This script is an example of how to get going!
- It solves the “Chicken and the Egg” as this script will come first before Terraform can be started
- May also work on Linux.
- Pre-Requisites:
- You need to be have permissions similar to
Owner
andGlobal Administrator
for this to work - You will need access PowerShell (ideally
pwsh
or PowerShell 7), with some utilities installed:- Azure-PowerShell
- OpenSSH (default on Windows 11/Server 2022)
- You need to be have permissions similar to
- Why?
- You can’t use Terraform without some things, this script creates them.
- “Management” Resource group -
rg-${ShorthandName}-${ShorthandLocation}-${ShorthandEnv}-mgt
- Service Principal, assigned as Owner to subscription specified in
${SubscriptionId}
-svp-${SHORTHAND_NAME}-${ShorthandLocation}-${ShorthandEnv}-mgt-01
- You may want to change this based on IAM design - User-Assigned Managed Identity, assigned as Owner to subscription specified in
${SubscriptionId}
-id-${ShorthandName}-${ShorthandLocation}-${ShorthandEnv}-mgt-01
- You may want to change this based on IAM design - SSH Key -
ssh-${ShorthandName}-${ShorthandLocation}-${ShorthandEnv}-pub-mgt
- Storage Account -
sa${ShorthandName}${ShorthandLocation}${ShorthandEnv}mgt01
- Blob Container -
blob${ShorthandName}${ShorthandLocation}${ShorthandEnv}mgt01
- Sets Key Vault Managed Storage account to regenerate Primary Access Key in 90-day period
- Stores all information such as client secrets, client IDs etc. within Azure Keyvault
- Does some basic smoke testing on naming length, case sensitivity etc
- This is just an example, you should read this in entirety before running it
- “Management” Resource group -
- You can’t use Terraform without some things, this script creates them.
#!/usr/bin/env pwsh
[Diagnostics.CodeAnalysis.SuppressMessage("PSAvoidUsingInvokeExpression","")]
[CmdletBinding()]
[OutputType([System.Object[]])]
param(
[switch]$Help
)
Set-StrictMode -Version Latest
########### Edit the below variables to use script ############
$SubscriptionId = "libredevops-sub"
$ShorthandName = "ldo"
$ShorthandEnv = "ppd3"
$ShorthandLocation = "uks"
########## Do not edit anything below unless you know what you are doing ############
if ($ShorthandLocation = "uks")
{
$LonghandLocation = "uksouth"
}
elseif ($ShorthandLocation = "ukw")
{
$LonghandLocation = "ukwest"
}
elseif ($ShorthandLocation = "euw")
{
$LonghandLocation = "westeurope"
}
elseif ($ShorthandLocation = "eun")
{
$LonghandLocation = "northeurope"
}
elseif ($ShorthandLocation = "use")
{
$LonghandLocation = "eastus"
}
elseif ($ShorthandLocation = "use2")
{
$LonghandLocation = "eastus2"
}
# Set-PSDebug -Trace 1 // Basically the same as set -x in Bash
$lowerConvertedShorthandName = $ShorthandName.ToLower()
$lowerConvertedShorthandEnv = $ShorthandEnv.ToLower()
$lowerConvertedShorthandLocation = $ShorthandLocation.ToLower()
$upperConvertedShorthandName = $ShorthandName.ToUpper()
$upperConvertedShorthandEnv = $ShorthandEnv.ToUpper()
$upperConvertedShorthandLocation = $ShorthandLocation.ToUpper()
$TextInfo = (Get-Culture).TextInfo
$titleConvertedShorthandName = $TextInfo.ToTitleCase($ShorthandName)
$titleConvertedShorthandEnv = $TextInfo.ToTitleCase($ShorthandEnv)
$titleConvertedShorthandLocation = $TextInfo.ToTitleCase($ShorthandLocation)
$ResourceGroupName = "rg-${lowerConvertedShorthandName}-${lowerConvertedShorthandLocation}-${lowerConvertedShorthandEnv}-mgt"
$KeyvaultName = "kv-${lowerConvertedShorthandName}-${lowerConvertedShorthandLocation}-${lowerConvertedShorthandEnv}-mgt-01"
$ServicePrincipalName = "svp-${lowerConvertedShorthandName}-${lowerConvertedShorthandLocation}-${lowerConvertedShorthandEnv}-mgt-01"
$ManagedIdentityName = "id-${lowerConvertedShorthandName}-${lowerConvertedShorthandLocation}-${lowerConvertedShorthandEnv}-mgt-01"
$PublicSshKeyName = "ssh-${lowerConvertedShorthandName}-${lowerConvertedShorthandLocation}-${lowerConvertedShorthandEnv}-pub-mgt"
$PrivateSshKeyName = "Ssh${titleConvertedShorthandName}${titleConvertedShorthandLocation}${titleConvertedShorthandEnv}Key"
$StorageAccountName = "sa${lowerConvertedShorthandName}${lowerConvertedShorthandLocation}${lowerConvertedShorthandEnv}mgt01"
$BlobContainerName = "blob${lowerConvertedShorthandName}${lowerConvertedShorthandLocation}${lowerConvertedShorthandEnv}mgt01"
Write-Host "This script is intended to be ran in the Cloud Shell in Azure to setup your pre-requisite items in a fresh tenant, to setup management resources for terraform. This is just an example!" -ForegroundColor Black -BackgroundColor Yellow; Start-Sleep -Seconds 3
$TestCommands = @(
'Get-AzContext',
'Set-AzContext',
'New-AzResourceGroup',
'New-AzKeyVault',
'Get-AzKeyvault',
'Set-AzKeyVaultAccessPolicy',
'Set-AzKeyVaultSecret',
'Get-AzADUser',
'Get-AzADServicePrincipal',
'New-AzADServicePrincipal',
'Get-AzUserAssignedIdentity',
'New-AzSshKey',
'New-AzStorageAccount',
'New-AzStorageContainer',
'Add-AzKeyVaultManagedStorageAccount'
)
foreach ($command in $TestCommands)
{
# Sets up command testing as Az modules seem to be inconsitently installed
if (-not (Get-Command $command))
{
Write-Host "${command} doesn't exist, it requires to be installed for this script to continue, try - Install-Module -Name Az.Accounts -AllowClobber or pwsh -Command Install-Module -Name Az -Force -AllowClobber -Scope AllUsers -Repository PSGallery or something similar. - Exit Code - AZ_CMDS_NOT_INSTALLED" -ForegroundColor Black -BackgroundColor Yellow; exit 1
}
}
# Checks for logged in data, if the API responds with Null, you aren't logged in
$LoggedIn = Get-AzContext
if ($null -eq $LoggedIn)
{
Write-Host "You need to login to Azure to run this script" -ForegroundColor Black -BackgroundColor Red; exit 1
}
elseif ($null -ne $LoggedIn)
{
Write-Host "Already logged in, continuing..." -ForegroundColor Black -BackgroundColor Green
}
if (-not ($ShorthandName.Length -le 5 -and $ShorthandName.Length -ge 1))
{
Write-Host "You can't have a shorthand greater than 5, edit the variables and retry" -ForegroundColor Black -BackgroundColor Red; exit 1
}
else
{
Write-Host "${lowerConvertedShorthandName} shorthand name is less than 5 and greater than 1, thus is permissible, continuing" -ForegroundColor Black -BackgroundColor Green
}
# Set subscription
Set-AzContext -Subscription $SubscriptionId
$SubId = $(Get-AzContext | Select-Object -ExpandProperty Subscription)
$spokeSubId = ConvertTo-SecureString "$SubId" -AsPlainText -Force
$signedInUserUpn = $(Get-AzADUser -SignedIn | Select-Object -ExpandProperty Id)
# Create Resource Group
$spokeMgmtRgName = $(New-AzResourceGroup `
-Name $ResourceGroupName `
-Location $LonghandLocation -Force | Select-Object -ExpandProperty ResourceGroupName)
Write-Host "Resource Group created!" -ForegroundColor Black -BackgroundColor Green
# Create Keyvault
$KeyvaultExists = $(Get-AzKeyVault -VaultName $KeyvaultName)
if ($null -eq $KeyvaultExists)
{
Write-Host "Keyvault doesn't exist, creating it" -ForegroundColor Black -BackgroundColor Yellow
New-AzKeyVault `
-Name $KeyvaultName `
-ResourceGroupName $spokeMgmtRgName `
-Location $LonghandLocation
}
elseif ($null -ne $KeyvaultExists)
{
Write-Host "Keyvault already exists, fetching info" -ForegroundColor Black -BackgroundColor Yellow
}
$KvOutput = $(Get-AzKeyVault -VaultName $KeyvaultName)
$spokeKvId = $($KvOutput | Select-Object -ExpandProperty ResourceId)
$spokeKvName = ConvertTo-SecureString "$KeyvaultName" -AsPlainText -Force
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "SpokeKvname" `
-SecretValue $spokeKvName
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "SpokeSubId" `
-SecretValue $spokeSubId
Write-Host "Keyvault Setup Complete" -ForegroundColor Black -BackgroundColor Green
Write-Host "Creating new service principal now, be advised, this script will generate a new client secret if the service principal exists, you have 5 seconds to cancel the script now." -ForegroundColor Black -BackgroundColor Yellow; Start-Sleep -Seconds 5
$SubId = $(Get-AzSubscription -SubscriptionName $SubscriptionId | Select-Object -ExpandProperty SubscriptionId)
$AzSvpExistsOutput = $(Get-AzADServicePrincipal `
-DisplayName $ServicePrincipalName)
if ($null -eq $AzSvpExistsOutput)
{
Write-Host "Service Principal does not yet exist, creating now" -ForegroundColor Black -BackgroundColor Yellow;
$AzSvpExistsOutput = $null
$AzSvpExistsOutput = $(New-AzADServicePrincipal `
-DisplayName $ServicePrincipalName)
$spokeSvpClientId = $null
$spokeSvpId = $null
$spokeTenantId = $null
$SvpClientId = $null
$SvpId = $null
$SvpTenantId = $null
$SvpClientId = $AzSvpExistsOutput | Select-Object -ExpandProperty AppId
$SvpClientSecret = $AzSvpExistsOutput | Select-Object -ExpandProperty PasswordCredentials | Select-Object -First 1 | Select-Object -ExpandProperty SecretText
$SvpId = $AzSvpExistsOutput | Select-Object -ExpandProperty Id
$SvpTenantId = $AzSvpExistsOutput | Select-Object -ExpandProperty AppOwnerOrganizationId
$spokeSvpClientId = ConvertTo-SecureString "$SvpClientId" -AsPlainText -Force
$spokeSvpClientSecret = ConvertTo-SecureString "$SvpClientSecret" -AsPlainText -Force
$spokeSvpId = ConvertTo-SecureString "$SvpId" -AsPlainText -Force
$spokeTenantId = ConvertTo-SecureString "$SvpTenantId" -AsPlainText -Force
Write-Host "New Service Principal Created!" -ForegroundColor Black -BackgroundColor Green
}
elseif ($null -ne $AzSvpExistsOutput)
{
# Set conditional output so variables are the same between both conditions
$AzSvpExistsOutput = $null
$AzSvpExistsOutput = $(Get-AzADServicePrincipal -DisplayName $ServicePrincipalName)
Write-Host "Service Principal exists, fetching output and generating new secret" -ForegroundColor Black -BackgroundColor Green; `
$spokeSvpClientId = $null
$spokeSvpId = $null
$spokeTenantId = $null
$SvpClientId = $null
$SvpId = $null
$SvpTenantId = $null
$SvpClientId = $AzSvpExistsOutput | Select-Object -ExpandProperty AppId
$SvpClientSecret = $AzSvpExistsOutput | New-AzADSpCredential | Select-Object -ExpandProperty SecretText
$SvpId = $AzSvpExistsOutput | Select-Object -ExpandProperty Id
$SvpTenantId = $AzSvpExistsOutput | Select-Object -ExpandProperty AppOwnerOrganizationId
$spokeSvpClientId = ConvertTo-SecureString "$SvpClientId" -AsPlainText -Force
$spokeSvpClientSecret = ConvertTo-SecureString "$SvpClientSecret" -AsPlainText -Force
$spokeSvpId = ConvertTo-SecureString "$SvpId" -AsPlainText -Force
$spokeTenantId = ConvertTo-SecureString "$SvpTenantId" -AsPlainText -Force
Write-Host "Existing Service Principal updated!" -ForegroundColor Black -BackgroundColor Green
}
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "SpokeSvpClientId" `
-SecretValue $spokeSvpClientId
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "SpokeSvpObjectId" `
-SecretValue $spokeSvpId
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "SpokeSvpClientSecret" `
-SecretValue $spokeSvpClientSecret
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "SpokeTenantId" `
-SecretValue $spokeTenantId
$SvpRoleAssignmentExists = $(Get-AzRoleAssignment -Scope "/subscriptions/${SubId}" | Where-Object { $_.RoleDefinitionName -eq 'Owner' } | Select-Object -Property DisplayName | Where-Object { $_.DisplayName -eq $ServicePrincipalName })
if ($null -ne $SvpRoleAssignmentExists)
{
Write-Host "Service Principal Owner Role exists, skipping" -ForegroundColor Black -BackgroundColor Yellow
}
elseif ($null -eq $SvpRoleAssignmentExists)
{
Write-Host "Managed Identity Owner Role does not exist, creating now" -ForegroundColor Black -BackgroundColor Yellow
New-AzRoleAssignment `
-ApplicationId $SvpClientId `
-RoleDefinitionName "Owner" `
-Scope "/subscriptions/${SubId}"
Write-Host "Owner Role Assigned to Svp" -ForegroundColor Black -BackgroundColor Green
}
if (-not (Get-AzUserAssignedIdentity -ResourceGroup $ResourceGroupName -Name $ManagedIdentityName -ErrorAction SilentlyContinue))
{
Write-Host "Managed Identity does not exist, creating it" -ForegroundColor Black -BackgroundColor Yellow
$AzManagedIdOutput = $null
$AzManagedIdOutput = $(New-AzUserAssignedIdentity `
-ResourceGroupName $ResourceGroupName `
-Name $ManagedIdentityName)
Write-Host "Managed Identity Created, Sleeping 30s while we await API catching up" -ForegroundColor Black -BackgroundColor Yellow; Start-Sleep -Seconds 30
$spokeManagedIdentityId = $null
$spokeManagedIdentityClientId = $null
$spokeManagedIdentityPrincipalId = $null
$SpokeMiId = $($AzManagedIdOutput | Select-Object -ExpandProperty Id)
$SpokeMiClientId = $(Get-AzUserAssignedIdentity -ResourceGroup $ResourceGroupName -Name $ManagedIdentityName | Select-Object -ExpandProperty ClientId)
$spokeManagedIdentityPrincipalId = $($AzManagedIdOutput | Select-Object -ExpandProperty PrincipalId)
Set-AzKeyVaultAccessPolicy `
-VaultName $KeyvaultName `
-ResourceGroupName $ResourceGroupName `
-ServicePrincipalName $SpokeMiClientId `
-PermissionsToSecrets get,list,set,recover,backup,restore `
-PermissionsToCertificates get,list,update,create,import,delete,recover,backup,restore `
-PermissionsToKeys get,list,update,create,import,delete,recover,backup,restore,decrypt,encrypt,verify,sign
}
else
{
Write-Host "Managed Identity already exists, Exporting values" -ForegroundColor Black -BackgroundColor Yellow
$AzManagedIdOutput = $null
$AzManagedIdOutput = $(Get-AzUserAssignedIdentity `
-ResourceGroup $ResourceGroupName `
-Name $ManagedIdentityName)
$spokeManagedIdentityId = $null
$spokeManagedIdentityClientId = $null
$spokeManagedIdentityPrincipalId = $null
$SpokeMiId = $($AzManagedIdOutput | Select-Object -ExpandProperty Id)
$SpokeMiClientId = $(Get-AzUserAssignedIdentity -ResourceGroup $ResourceGroupName -Name $ManagedIdentityName | Select-Object -ExpandProperty ClientId)
$spokeManagedIdentityPrincipalId = $($AzManagedIdOutput | Select-Object -ExpandProperty PrincipalId)
Set-AzKeyVaultAccessPolicy `
-VaultName $KeyvaultName `
-ResourceGroupName $ResourceGroupName `
-ServicePrincipalName $SpokeMiClientId `
-PermissionsToSecrets get,list,set,recover,backup,restore `
-PermissionsToCertificates get,list,update,create,import,delete,recover,backup,restore `
-PermissionsToKeys get,list,update,create,import,delete,recover,backup,restore,decrypt,encrypt,verify,sign
}
$spokeManagedIdentityClientId = ConvertTo-SecureString "$SpokeMiClientId" -AsPlainText -Force
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "SpokeManagedIdentityClientId" `
-SecretValue $spokeManagedIdentityClientId
Write-Host "Managed Identity Created! and given rights to keyvault and subscription!" -ForegroundColor Black -BackgroundColor Green
$MiRoleAssignmentExists = $(Get-AzRoleAssignment -Scope "/subscriptions/$SubId" | Where-Object { $_.RoleDefinitionName -eq 'Owner' } | Select-Object -Property DisplayName | Where-Object { $_.DisplayName -eq $ManagedIdentityName})
if ($null -ne $MiRoleAssignmentExists)
{
Write-Host "Managed Identity Owner Role exists already, skipping" -ForegroundColor Black -BackgroundColor Yellow
}
elseif ($null -eq $MiRoleAssignmentExists)
{
Write-Host "Managed Identity Owner Role does not exist, creating now" -ForegroundColor Black -BackgroundColor Yellow
New-AzRoleAssignment `
-ApplicationId $SpokeMiClientId `
-RoleDefinitionName "Owner" `
-Scope "/subscriptions/$SubId"
Write-Host "Managed Identity Role Assignment Done!" -ForegroundColor Black -BackgroundColor Green
}
$PasswordGenerator = $(-join (((48..57) + (65..90) + (97..122)) * 80 | Get-Random -Count 25 | ForEach-Object { [char]$_ }))
$spokeAdminSecret = ConvertTo-SecureString "$PasswordGenerator" -AsPlainText -Force
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "Local${titleConvertedShorthandName}Admin${titleConvertedShorthandEnv}Pwd" `
-SecretValue $spokeAdminSecret
Write-Host "Admin Secret made in keyvault" -ForegroundColor Black -BackgroundColor Green
if (Get-Command ssh-keygen -ErrorAction SilentlyContinue)
{
Write-Host "ssh-keygen exists! Attempting to generate SSH key now" -ForegroundColor Black -BackgroundColor Green
#Gets current time tag in fractions of seconds to ensure running the same script twice is unlikely to exit with residue fodler
ssh-keygen -b 4096 -t rsa -f "${lowerConvertedShorthandName}-${lowerConvertedShorthandEnv}-ssh-azureid_rsa.key" -q -N '""'
$PublicKey = Get-Content "${lowerConvertedShorthandName}-${lowerConvertedShorthandEnv}-ssh-azureid_rsa.key.pub" -Raw
$RawPrivateKey = Get-Content "${lowerConvertedShorthandName}-${lowerConvertedShorthandEnv}-ssh-azureid_rsa.key" -Raw
$PrivateKey = ConvertTo-SecureString -String $RawPrivateKey -AsPlainText -Force
New-AzSshKey `
-ResourceGroupName $ResourceGroupName `
-Name $PublicSshKeyName `
-PublicKey $PublicKey
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name $PrivateSshKeyName `
-SecretValue $PrivateKey
Remove-Item -Force "${lowerConvertedShorthandName}-${lowerConvertedShorthandEnv}-ssh-azureid_rsa.key.pub"
Remove-Item -Force "${lowerConvertedShorthandName}-${lowerConvertedShorthandEnv}-ssh-azureid_rsa.key"
}
else
{
Write-Host "SSH Keygen does not exist, skipping SSH key generation" -ForegroundColor Black -BackgroundColor Yellow
}
# Creates storage account and blob container for terraform
if (-not (Get-AzStorageAccount -ResourceGroupName $ResourceGroupName -Name $StorageAccountName -ErrorAction SilentlyContinue))
{
Write-Host "Storage account doesn't exist, creating it" -ForegroundColor Black -BackgroundColor Yellow
$StorageAccountOutput = $null
$StorageAccountOutput = $(New-AzStorageAccount `
-ResourceGroupName $ResourceGroupName `
-AccountName $StorageAccountName `
-Location $LonghandLocation `
-SkuName "Standard_LRS" `
-AccessTier "Hot")
if (-not ($StorageAccountOutput | Get-AzStorageContainer -Name $BlobContainerName -ErrorAction SilentlyContinue))
{
Write-Host "Storage Container doesn't exist" -ForegroundColor Black -BackgroundColor Yellow
$BlobContainerOutput = $null
$BlobContainerOutput = $($StorageAccountOutput | New-AzStorageContainer -Name $BlobContainerName -Permission "off")
}
elseif ($StorageAccountOutput | Get-AzStorageContainer -Name $BlobContainerName)
{
Write-Host "Storage Container Created!" -ForegroundColor Black -BackgroundColor Green
$BlobContainerOutput = $null
$BlobContainerOutput = $($StorageAccountOutput | Get-AzStorageContainer -Name $BlobContainerName)
}
Write-Host "New Storage Account and Blob Created" -ForegroundColor Black -BackgroundColor Green
}
else
{
Write-Host "Storage Account already exists" -ForegroundColor Black -BackgroundColor Yellow
$StorageAccountOutput = $null
$StorageAccountOutput = $(Get-AzStorageAccount `
-ResourceGroupName $ResourceGroupName `
-Name $StorageAccountName)
if (-not ($StorageAccountOutput | Get-AzStorageContainer -Name $BlobContainerName))
{
Write-Host "Storage Container doesn't exist" -ForegroundColor Black -BackgroundColor Yellow
$BlobContainerOutput = $null
$BlobContainerOutput = $($StorageAccountOutput | New-AzStorageContainer -Name $BlobContainerName -Permission "off")
}
elseif ($StorageAccountOutput | Get-AzStorageContainer -Name $BlobContainerName)
{
Write-Host "Storage Container already exists" -ForegroundColor Black -BackgroundColor Yellow
$BlobContainerOutput = $null
$BlobContainerOutput = $($StorageAccountOutput | Get-AzStorageContainer -Name $BlobContainerName)
}
Write-Host "New Storage Account and Blob setup correctly!" -ForegroundColor Black -BackgroundColor Green
}
$SaRgName = $($StorageAccountOutput | Select-Object -ExpandProperty ResourceGroupName)
$StorageKey1 = $(Get-AzStorageAccountKey -ResourceGroupName $ResourceGroupName -AccountName $StorageAccountName | Select-Object -ExpandProperty Value | Select-Object -First 1)
$StorageKey2 = $(Get-AzStorageAccountKey -ResourceGroupName $ResourceGroupName -AccountName $StorageAccountName | Select-Object -ExpandProperty Value | Select-Object -Last 1)
$spokeSaId = $($StorageAccountOutput | Select-Object -ExpandProperty Id)
$spokeSaRgName = ConvertTo-SecureString "$SaRgName" -AsPlainText -Force
$spokeSaName = ConvertTo-SecureString "$StorageAccountName" -AsPlainText -Force
$spokeSaPrimaryKey = ConvertTo-SecureString "$StorageKey1" -AsPlainText -Force
$spokeSaSecondarykey = ConvertTo-SecureString "$StorageKey2" -AsPlainText -Force
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "SpokeSaRgName" `
-SecretValue $spokeSaRgName
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "SpokeSaName" `
-SecretValue $spokeSaName
$KeyExpiryDate = (Get-Date).AddMonths(3).ToUniversalTime()
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "SpokeSaPrimaryKey" `
-SecretValue $spokeSaPrimaryKey `
-Expires $KeyExpiryDate
Set-AzKeyVaultSecret `
-VaultName $KeyvaultName `
-Name "SpokeSaSecondaryKey" `
-SecretValue $spokeSaSecondarykey
Write-Host "Various Keyvault secrets have been set!" -ForegroundColor Black -BackgroundColor Green
# This value is set and managed by Azure, do not change
$AzureKeyvaultObjectId = "cfa8b339-82a2-471a-a3c9-0fc0be7a4093"
$SaRoleAssignmentExists = $(Get-AzRoleAssignment -Scope $spokeSaId | Where-Object { $_.RoleDefinitionName -eq 'Storage Account Key Operator Service Role'})
if ($null -ne $SaRoleAssignmentExists)
{
Write-Host "Managed Keyvault Assignment already exists, skipping" -ForegroundColor Black -BackgroundColor Yellow
}
elseif ($null -eq $SaRoleAssignmentExists)
{
Write-Host "Managed Keyvault Assignment does not exist, creating now" -ForegroundColor Black -BackgroundColor Yellow
# Sets up Keyvault to managed regen of Storage key1 every 90 days
New-AzRoleAssignment `
-ApplicationId $AzureKeyvaultObjectId `
-RoleDefinitionName "Storage Account Key Operator Service Role" `
-Scope $spokeSaId
Write-Host "Managed keyvault role created!, sleeping for 30 seconds to allow API to catchup" -ForegroundColor Black -BackgroundColor Green; Start-Sleep -Seconds 30
}
Set-AzKeyVaultAccessPolicy `
-VaultName $KeyvaultName `
-UserPrincipalName $signedInUserUpn `
-PermissionsToStorage get,list,delete,set,update,regeneratekey,getsas,listsas,deletesas,setsas,recover,backup,restore,purge
$RegenerationPeriod = [System.TimeSpan]::FromDays(90)
Add-AzKeyVaultManagedStorageAccount `
-VaultName $keyVaultName `
-AccountName $StorageAccountName `
-AccountResourceId $spokeSaId `
-ActiveKeyName "key1" `
-RegenerationPeriod $RegenerationPeriod
Write-Host "Storage Account is now being managed by keyvault" -ForegroundColor Black -BackgroundColor Green
Source: docs/quickstart/utils/azure-tf-pre-req-azpwsh-pwsh.md