deploy/scripts/pwsh/SAPDeploymentUtilities/Internal/new_sapdeployer.ps1 (197 lines of code) (raw):
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
function New-SAPDeployer {
<#
.SYNOPSIS
Bootstrap a new deployer
.DESCRIPTION
Bootstrap a new deployer
.PARAMETER Parameterfile
This is the parameter file for the deployer
.EXAMPLE
#
#
# Import the module
Import-Module "SAPDeploymentUtilities.psd1"
New-SAPDeployer -Parameterfile .\PROD-WEEU-MGMT00-INFRASTRUCTURE.json
.LINK
https://github.com/Azure/sap-automation
.NOTES
v0.1 - Initial version
.
#>
<#
Copyright (c) Microsoft Corporation.
Licensed under the MIT license.
#>
[cmdletbinding(SupportsShouldProcess)]
param(
#Parameter file
[Parameter(Mandatory = $true)][string]$Parameterfile,
[Parameter(Mandatory = $false)][Switch]$Silent
)
Write-Host -ForegroundColor green ""
Write-Host -ForegroundColor green "Bootstrap the deployer"
$curDir = Get-Location
$autoApprove=""
if($Silent) {
$autoApprove=" --auto-approve "
}
$fInfo = Get-ItemProperty -Path $Parameterfile
if (!$fInfo.Exists ) {
Write-Error ("File " + $Parameterfile + " does not exist")
return
}
$CachePath = (Join-Path -Path $Env:APPDATA -ChildPath "terraform.d\plugin-cache")
if ( -not (Test-Path -Path $CachePath)) {
New-Item -Path $CachePath -ItemType Directory
}
$env:TF_PLUGIN_CACHE_DIR = $CachePath
$ParamFullFile = (Get-ItemProperty -Path $Parameterfile -Name Fullname).Fullname
Add-Content -Path "deployment.log" -Value "Bootstrap the deployer"
Add-Content -Path "deployment.log" -Value (Get-Date -Format "yyyy-MM-dd HH:mm")
$mydocuments = [environment]::getfolderpath("mydocuments")
$fileINIPath = $mydocuments + "\sap_deployment_automation.ini"
$iniContent = Get-IniContent -Path $fileINIPath
$Environment = ""
$region = ""
$KeyValuePairs = @{}
if ($fInfo.Extension -eq ".tfvars") {
$paramContent = Get-Content -Path $Parameterfile
foreach ($param in $paramContent) {
if ($param.Contains("=")) {
$KeyValuePairs.Add($param.Split("=")[0].ToLower(), $param.Split("=")[1].Replace("""", ""))
}
}
$Environment = $KeyValuePairs["environment"]
$region = $KeyValuePairs["location"]
}
else {
$jsonData = Get-Content -Path $Parameterfile | ConvertFrom-Json
$Environment = $jsonData.infrastructure.environment
$region = $jsonData.infrastructure.region
}
Write-Host "Region:"$region
Write-Host "Environment:"$Environment
$combined = $Environment + $region
if ($null -ne $iniContent[$combined] ) {
$sub = $iniContent[$combined]["STATE_SUBSCRIPTION"]
}
else {
$Category1 = @{"subscription" = "" }
$iniContent += @{$combined = $Category1 }
Out-IniFile -InputObject $iniContent -Path $fileINIPath
}
# Subscription & repo path
$sub = $iniContent[$combined]["STATE_SUBSCRIPTION"]
$repo = $iniContent["Common"]["repo"]
$changed = $false
if ($null -eq $sub -or "" -eq $sub) {
if ($null -ne $env:ARM_SUBSCRIPTION_ID) {
$sub = $env:ARM_SUBSCRIPTION_ID
}
else {
$sub = Read-Host -Prompt "Please enter the subscription"
}
$iniContent[$combined]["subscription"] = $sub
$changed = $true
}
$Cmd = "az account set --sub $sub"
Add-Content -Path "deployment.log" -Value $Cmd
& ([ScriptBlock]::Create($Cmd))
if ($null -eq $repo -or "" -eq $repo) {
$repo = Read-Host -Prompt "Please enter the path to the repository"
$iniContent["Common"]["repo"] = $repo
$changed = $true
}
if ($changed) {
Out-IniFile -InputObject $iniContent -Path $fileINIPath
}
$terraform_module_directory = Join-Path -Path $repo -ChildPath "\deploy\terraform\bootstrap\sap_deployer"
if (-not (Test-Path $terraform_module_directory) ) {
Write-Host -ForegroundColor Red "The repository path: $repo is incorrect!"
$iniContent["Common"]["repo"] = ""
Out-IniFile -InputObject $iniContent -Path $fileINIPath
throw "The repository path: $repo is incorrect!"
return
}
$Env:TF_DATA_DIR = (Join-Path -Path $curDir -ChildPath ".terraform")
Write-Host -ForegroundColor green "Initializing Terraform"
$statefile = (Join-Path -Path $curDir -ChildPath "terraform.tfstate")
$Command = " init -upgrade=true -backend-config ""path=$statefile"""
if (Test-Path ".terraform" -PathType Container) {
$jsonData = Get-Content -Path .\.terraform\terraform.tfstate | ConvertFrom-Json
if ("azurerm" -eq $jsonData.backend.type) {
Write-Host -ForegroundColor green "State file already migrated to Azure!"
$ans = Read-Host -Prompt "State is already migrated to Azure. Do you want to re-initialize the deployer Y/N?"
if ("Y" -ne $ans) {
$Env:TF_DATA_DIR = $null
return
}
else {
$Command = " init -upgrade=true -reconfigure "
}
}
else {
$ans = Read-Host -Prompt "The system has already been deployed, do you want to redeploy Y/N?"
if ("Y" -ne $ans) {
$Env:TF_DATA_DIR = $null
return
}
}
}
$Cmd = "terraform -chdir=$terraform_module_directory $Command"
Add-Content -Path "deployment.log" -Value $Cmd
& ([ScriptBlock]::Create($Cmd))
if ($LASTEXITCODE -ne 0) {
$Env:TF_DATA_DIR = $null
throw "Error executing command: $Cmd"
}
Write-Host -ForegroundColor green "Running plan"
$Command = " plan -var-file " + $ParamFullFile
$Cmd = "terraform -chdir=$terraform_module_directory $Command"
Add-Content -Path "deployment.log" -Value $Cmd
$planResults = & ([ScriptBlock]::Create($Cmd)) | Out-String
if ($LASTEXITCODE -ne 0) {
$Env:TF_DATA_DIR = $null
throw "Error executing command: $Cmd"
}
$planResultsPlain = $planResults -replace '\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]', ''
if ( $planResultsPlain.Contains('Infrastructure is up-to-date')) {
Write-Host ""
Write-Host -ForegroundColor Green "Infrastructure is up to date"
Write-Host ""
$Env:TF_DATA_DIR = $null
return;
}
if ( $planResultsPlain.Contains('Plan: 0 to add, 0 to change, 0 to destroy')) {
Write-Host ""
Write-Host -ForegroundColor Green "Infrastructure is up to date"
Write-Host ""
$Env:TF_DATA_DIR = $null
return;
}
Write-Host $planResults
if ($PSCmdlet.ShouldProcess($Parameterfile)) {
Write-Host -ForegroundColor green "Running apply"
$Command = " apply " +$autoApprove +" -var-file " + $ParamFullFile
$Cmd = "terraform -chdir=$terraform_module_directory $Command"
Add-Content -Path "deployment.log" -Value $Cmd
& ([ScriptBlock]::Create($Cmd))
if ($LASTEXITCODE -ne 0) {
$Env:TF_DATA_DIR = $null
throw "Error executing command: $Cmd"
}
$Command = " output deployer_kv_user_name"
$Cmd = "terraform -chdir=$terraform_module_directory $Command"
$kvName = & ([ScriptBlock]::Create($Cmd)) | Out-String
Write-Host ("SPN Keyvault: " + $kvName)
$iniContent[$combined]["Vault"] = $kvName.Replace("""", "")
Out-IniFile -InputObject $iniContent -Path $fileINIPath
if ($LASTEXITCODE -ne 0) {
$Env:TF_DATA_DIR = $null
throw "Error executing command: $Cmd"
}
}
$Env:TF_DATA_DIR = $null
}