Public/Deploy/PaaS/sql/New-CmAzPaasSql.ps1
function New-CmAzPaasSql { <# .Synopsis Create SQL databases .Description Completes following: * Creates SQL Server. * Creates databases. * Configures firewall (for postgres | mariaDB | mysql) * Enable log analytics (Optional) .Parameter SettingsFile File path for the settings file to be converted into a settings object. .Parameter SettingsObject Object containing the configuration values required to run this cmdlet. .Parameter TagSettingsFile File path for the tag settings file to be converted into a tag settings object. .Component PaaS .Example New-CmAzPaasSql -SettingsFile ./sql.yml .Example New-CmAzPaasSql -SettingsObject $settings #> [OutputType([System.Collections.ArrayList])] [CmdletBinding(SupportsShouldProcess, ConfirmImpact = "Medium")] param( [parameter(Mandatory = $true, ParameterSetName = "Settings File")] [String]$SettingsFile, [parameter(Mandatory = $true, ParameterSetName = "Settings Object")] [Object]$SettingsObject, [String]$TagSettingsFile ) $ErrorActionPreference = "Stop" try { $commandName = $MyInvocation.MyCommand.Name Write-CommandStatus -CommandName $commandName $SettingsObject = Get-Settings -SettingsFile $SettingsFile -SettingsObject $SettingsObject -CmdletName $commandName if ($PSCmdlet.ShouldProcess((Get-CmAzSubscriptionName), "Deploy SQL database")) { $resourceGroup = Get-CmAzService -Service $SettingsObject.service.dependencies.resourceGroup -IsResourceGroup -ThrowIfUnavailable -ThrowIfMultiple if (!$SettingsObject.service.dependencies.workspace) { $workspace = @{ name = $null; resourceId = $null; location = $null } } else { Write-Verbose "Fetching workspace.." $workspace = Get-CmAzService -Service $SettingsObject.service.dependencies.workspace -ThrowIfUnavailable -ThrowIfMultiple } if (!$SettingsObject.logRetentionPeriodInDays) { $logRetentionPeriodInDays = 30 } else { $logRetentionPeriodInDays = $SettingsObject.logRetentionPeriodInDays } [system.Collections.ArrayList]$servers = @() [system.Collections.ArrayList]$sharedServers = @() [system.Collections.ArrayList]$UniqueSqlServerNames = @() Write-Verbose "Starting to build object for deployment.." $SettingsObject.sqlConfig | ForEach-Object { [System.Collections.ArrayList] $databaseCollection = @() Write-Verbose "Working on $($_.serverName)" if ($_.databases) { foreach ($database in $_.databases) { if ($database -is [string]) { $databaseObject = @{ "name" = Get-CmAzResourceName -Resource "AzureSQLDatabase" -Architecture "PaaS" -Location $SettingsObject.Location -Name $database } Set-GlobalServiceValues -GlobalServiceContainer $SettingsObject -ServiceKey "database" -ResourceServiceContainer $databaseObject $databaseCollection.Add($databaseObject) > $Null } if ($database -is [Hashtable]) { $database.name = Get-CmAzResourceName -Resource "AzureSQLDatabase" -Architecture "PaaS" -Location $SettingsObject.Location -Name $database.name Set-GlobalServiceValues -GlobalServiceContainer $SettingsObject -ServiceKey "database" -ResourceServiceContainer $database $databaseCollection.Add($database) > $Null } } } else { $databaseObject = @{ "name" = Get-CmAzResourceName -Resource "AzureSQLDatabase" -Architecture "PaaS" -Location $SettingsObject.Location -Name $_.serverName; } Set-GlobalServiceValues -GlobalServiceContainer $SettingsObject -ServiceKey "database" -ResourceServiceContainer $databaseObject $databaseCollection.Add($databaseObject) > $Null } Set-GlobalServiceValues -GlobalServiceContainer $SettingsObject -ServiceKey "keyvault" -ResourceServiceContainer $_ -IsDependency $keyVault = Get-CmAzService -Service $_.service.dependencies.keyvault -ThrowIfUnavailable -ThrowIfMultiple $preserveName = $_.serverName $templateName = Get-CmAzResourceName -Resource "deployment" -Architecture "PaaS" -Location $SettingsObject.Location -Name "$commandName-$($_.serverName)" $serverName = Get-CmAzResourceName -Resource "AzureSQLDatabaseserver" -Architecture "PaaS" -Location $SettingsObject.Location -Name $_.serverName if ($UniqueSqlServerNames -contains $_.serverName) { $sharedServer = $true } else { $sharedServer = $false $UniqueSqlServerNames.add($_.serverName) > $Null } $dbFamily = switch ($_.family) { azuresql { "Microsoft.Sql" } postgressql { "Microsoft.DBforPostgreSQL" } mariadb { "Microsoft.DBforMariaDB" } mysql { "Microsoft.DBforMySQL" } } Set-GlobalServiceValues -GlobalServiceContainer $SettingsObject -ServiceKey "server" -ResourceServiceContainer $_ Set-GlobalServiceValues -GlobalServiceContainer $SettingsObject -ServiceKey "elasticPool" -ResourceServiceContainer $_ if (!$_.firewallRules) { $_.firewallRules = @(@{ "startIpAddress" = "0.0.0.0"; "endIpAddress" = "255.255.255.255" }) } $elasticPool = "none" if ($_.type -eq "elasticPool") { if ($_.elasticPoolName) { $elasticPool = Get-CmAzResourceName -Resource "AzureSQLElasticPool" -Architecture "PaaS" -Location $SettingsObject.Location -Name $_.elasticPoolName } else { Write-Error "Please provide an elastic pool name for the elastic pool type deployment." } } $server = @{ "resourceDetails" = @{ "family" = $dbFamily "sharedServer" = $sharedServer "templateName" = $templateName "type" = ($_.type ?? "").Tolower() "name" = $preserveName "serverName" = $serverName; "service" = $_.service; "databases" = $databaseCollection; "sku" = $_.sku; "version" = $_version; "elasticPoolProperties" = @{ "collation" = "SQL_Latin1_General_CP1_CI_AS"; "requestedServiceObjectiveName" = "ElasticPool"; "elasticPoolName" = $elasticPool; }; "administratorLogin" = $_.administratorLogin; "workspace" = $workspace; "logRetentionDays" = $logRetentionPeriodInDays; "firewallRules" = $_.firewallRules }; "adminLoginPassword" = @{ "keyVaultid" = $keyVault.resourceId; "secretName" = $_.passwordSecretName } } if ($_.privateEndpoints) { $server.resourceDetails.privateEndpoints = $_.privateEndpoints } if ($sharedServer) { $sharedServers.Add($server) > $Null } else { $servers.Add($server) > $Null } } $joinedSqlServers = @($servers, $sharedServers) Write-Verbose "Deploying Sql Servers and databases..." $joinedSqlServers | ForEach-Object { if ($_) { $deploymentName = Get-CmAzResourceName -Resource "Deployment" -Architecture "PaaS" -Location $SettingsObject.Location -Name $commandName New-AzResourceGroupDeployment ` -Name $deploymentName ` -ResourceGroupName $resourceGroup.ResourceGroupName ` -TemplateFile "$PSScriptRoot\New-CmAzPaasSql.json" ` -TemplateParameterObject @{ Servers = $_ Location = $SettingsObject.Location } } } if ($joinedSqlServers.resourceDetails | Where-Object { $_.privateEndpoints }) { foreach ($serverType in (($joinedSqlServers.resourceDetails | Where-Object { $_.privateEndpoints }).family | Get-Unique)) { $SettingsObject.servers = $joinedSqlServers.resourceDetails | Where-Object { $_.family -eq $serverType -and $_.privateEndpoints } $globalSubResourceName = switch ($serverType) { Microsoft.Sql { "sqlServer" } Microsoft.DBforPostgreSQL { "postgresqlServer" } Microsoft.DBforMariaDB { "mariadbServer" } Microsoft.DBforMySQL { "mysqlServer" } } Write-Verbose "Building private endpoints for $globalSubResourceName..." Build-PrivateEndpoints -SettingsObject $SettingsObject -LookupProperty "servers" -ResourceName "server" -GlobalSubResourceName $globalSubResourceName } } [system.Collections.ArrayList]$resourcesToSet = @() $resourcesToSet += ($joinedSqlServers.resourceDetails | where-object -Property family -eq 'Microsoft.Sql').databases.name $resourcesToSet += ($joinedSqlServers.resourceDetails | where-object -Property type -eq 'elasticPool').elasticPoolProperties.elasticPoolName $resourcesToSet += $joinedSqlServers.resourceDetails.serverName Set-DeployedResourceTags -TagSettingsFile $TagSettingsFile -ResourceIds $resourcesToSet Write-CommandStatus -CommandName $commandName -Start $false } } catch { $PSCmdlet.ThrowTerminatingError($PSitem); } } |