Skip to content

Commit

Permalink
SqlServerDsc: Resources work with automatic seeding (#1915)
Browse files Browse the repository at this point in the history
- SqlAg
  - Added optional parameter `SeedingMode` that will set the SeedingMode for the
    SQL Server 2016 and higher. This parameter can only be used together with the
    module _SqlServer_ installed (tested  v21.0.17099). The parameter will be
    ignored if SQLPS module will be used.
- SqlAgReplica
  - Added optional parameter `SeedingMode` that will set the SeedingMode for the
    SQL Server 2016 and higher (issue #487).
    This parameter can only be used together with the module _SqlServer_ installed
    (tested v21.0.17099). The parameter will be ignored if SQLPS module will be
    used.
  • Loading branch information
Sidoran authored May 4, 2023
1 parent 39fd195 commit 753c556
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 21 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- SqlServerDsc
- Temporary disable integration tests for dbatools.
- SqlAg
- Added optional parameter `SeedingMode` that will set the SeedingMode for the
SQL Server 2016 and higher. This parameter can only be used together with the
module _SqlServer_ installed (tested v21.0.17099). The parameter will be
ignored if SQLPS module will be used.
- SqlAgReplica
- Added optional parameter `SeedingMode` that will set the SeedingMode for the
SQL Server 2016 and higher ([issue #487](https://github.com/dsccommunity/SqlServerDsc/issues/487)).
This parameter can only be used together with the module _SqlServer_ installed
(tested v21.0.17099). The parameter will be ignored if SQLPS module will be
used.

## [16.3.0] - 2023-04-26

Expand Down
51 changes: 49 additions & 2 deletions source/DSCResources/DSC_SqlAG/DSC_SqlAG.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ function Get-TargetResource
$alwaysOnAvailabilityGroupResource.Add('BasicAvailabilityGroup', $availabilityGroup.BasicAvailabilityGroup)
$alwaysOnAvailabilityGroupResource.Add('DatabaseHealthTrigger', $availabilityGroup.DatabaseHealthTrigger)
$alwaysOnAvailabilityGroupResource.Add('DtcSupportEnabled', $availabilityGroup.DtcSupportEnabled)
# Microsoft.SqlServer.Management.Smo.Server from Connect-SQL supports the SeedingMode for SQL 2016 and higher, but New-SqlAvailabilityReplica may not.
# Will setting SeedingMode as $null to match ability of Microsoft.SqlServer.Management.Smo.Server and New-SqlAvailabilityReplica
if ( (Get-Command -Name 'New-SqlAvailabilityReplica').Parameters.ContainsKey('SeedingMode') )
{
$alwaysOnAvailabilityGroupResource.Add('SeedingMode', $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].SeedingMode)
}
else
{
$alwaysOnAvailabilityGroupResource.Add('SeedingMode', $null)
}
}
}

Expand Down Expand Up @@ -122,7 +132,7 @@ function Get-TargetResource
Specifies the replica availability mode. When creating a group the default is 'AsynchronousCommit'.
.PARAMETER BackupPriority
Specifies the desired priority of the replicas in performing backups. The acceptable values for this parameter are integers from 0 through 100. Of the set of replicas which are online and available, the replica that has the highest priority performs the backup. When creating a group the efault is 50.
Specifies the desired priority of the replicas in performing backups. The acceptable values for this parameter are integers from 0 through 100. Of the set of replicas which are online and available, the replica that has the highest priority performs the backup. When creating a group the default is 50.
.PARAMETER BasicAvailabilityGroup
Specifies the type of availability group is Basic. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions.
Expand All @@ -148,6 +158,10 @@ function Get-TargetResource
.PARAMETER FailoverMode
Specifies the failover mode. When creating a group the default is 'Manual'.
.PARAMETER SeedingMode
Specifies the seeding mode. When creating a group the default is 'Manual'.
This parameter can only be used when the module SqlServer is installed.
.PARAMETER HealthCheckTimeout
Specifies the length of time, in milliseconds, after which AlwaysOn availability groups declare an unresponsive server to be unhealthy. When creating a group the default is 30,000.
Expand Down Expand Up @@ -234,6 +248,11 @@ function Set-TargetResource
[System.String]
$FailoverMode = 'Manual',

[Parameter()]
[ValidateSet('Automatic', 'Manual')]
[System.String]
$SeedingMode = 'Manual',

[Parameter()]
[System.UInt32]
$HealthCheckTimeout = 30000,
Expand Down Expand Up @@ -337,6 +356,11 @@ function Set-TargetResource
$newReplicaParams.Add('ConnectionModeInSecondaryRole', $ConnectionModeInSecondaryRole)
}

if ( ( $sqlMajorVersion -ge 13 ) -and (Get-Command -Name 'New-SqlAvailabilityReplica').Parameters.ContainsKey('SeedingMode') )
{
$newReplicaParams.Add('SeedingMode', $SeedingMode)
}

# Create the new replica object
try
{
Expand Down Expand Up @@ -496,6 +520,15 @@ function Set-TargetResource
$availabilityGroup.HealthCheckTimeout = $HealthCheckTimeout
Update-AvailabilityGroup -AvailabilityGroup $availabilityGroup
}

if ( ( $submittedParameters -contains 'SeedingMode' ) -and ( $sqlMajorVersion -ge 13 ) -and ( $SeedingMode -ne $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].SeedingMode ) )
{
if ( (Get-Command -Name 'New-SqlAvailabilityReplica').Parameters.ContainsKey('SeedingMode') )
{
$availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].SeedingMode = $SeedingMode
Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName]
}
}
}
}
}
Expand Down Expand Up @@ -550,6 +583,10 @@ function Set-TargetResource
.PARAMETER FailoverMode
Specifies the failover mode. When creating a group the default is 'Manual'.
.PARAMETER SeedingMode
Specifies the seeding mode. When creating a group the default is 'Manual'.
This parameter can only be used when the module SqlServer is installed.
.PARAMETER HealthCheckTimeout
Specifies the length of time, in milliseconds, after which AlwaysOn availability groups declare an unresponsive server to be unhealthy. When creating a group the default is 30,000.
Expand All @@ -558,7 +595,7 @@ function Set-TargetResource
#>
function Test-TargetResource
{
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('SqlServerDsc.AnalyzerRules\Measure-CommandsNeededToLoadSMO', '', Justification='The command Connect-Sql is called when Get-TargetResource is called')]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('SqlServerDsc.AnalyzerRules\Measure-CommandsNeededToLoadSMO', '', Justification = 'The command Connect-Sql is called when Get-TargetResource is called')]
[CmdletBinding()]
[OutputType([System.Boolean])]
param
Expand Down Expand Up @@ -631,6 +668,11 @@ function Test-TargetResource
[System.String]
$FailoverMode = 'Manual',

[Parameter()]
[ValidateSet('Automatic', 'Manual')]
[System.String]
$SeedingMode = 'Manual',

[Parameter()]
[System.UInt32]
$HealthCheckTimeout = 30000,
Expand Down Expand Up @@ -705,11 +747,16 @@ function Test-TargetResource
<#
Add properties compatible with SQL Server 2016 or later versions
DtcSupportEnabled is enabled at the creation of the Availability Group only, hence it will not be checked in this block
SeedingMode should be checked only in case if New-SqlAvailabilityReplica support the SeedingMode parameter
#>
if ( $sqlMajorVersion -ge 13 )
{
$parametersToCheck += 'BasicAvailabilityGroup'
$parametersToCheck += 'DatabaseHealthTrigger'
if ( $getTargetResourceResult.SeedingMode )
{
$parametersToCheck += 'SeedingMode'
}
}

if ( $getTargetResourceResult.Ensure -eq 'Present' )
Expand Down
1 change: 1 addition & 0 deletions source/DSCResources/DSC_SqlAG/DSC_SqlAG.schema.mof
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class DSC_SqlAG : OMI_BaseResource
[Write, Description("Specifies the hostname or IP address of the availability group replica endpoint. When creating a group the default is the instance network name.")] String EndpointHostName;
[Write, Description("Specifies the automatic failover behavior of the availability group."), ValueMap{"OnServerDown","OnServerUnresponsive","OnCriticalServerErrors","OnModerateServerErrors","OnAnyQualifiedFailureCondition"}, Values{"OnServerDown","OnServerUnresponsive","OnCriticalServerErrors","OnModerateServerErrors","OnAnyQualifiedFailureCondition"}] String FailureConditionLevel;
[Write, Description("Specifies the failover mode. When creating a group the default is `'Manual'`."), ValueMap{"Automatic","Manual"}, Values{"Automatic","Manual"}] String FailoverMode;
[Write, Description("Specifies the seeding mode. When creating a group the default is `'Manual`'."), ValueMap{"Automatic","Manual"}, Values{"Automatic","Manual"}] String SeedingMode;
[Write, Description("Specifies the length of time, in milliseconds, after which _AlwaysOn Availability Groups_ declare an unresponsive server to be unhealthy. When creating a group the default is `30000`.")] UInt32 HealthCheckTimeout;
[Write, Description("Specifies that the resource will only determine if a change is needed if the target node is the active host of the _SQL Server_ instance.")] Boolean ProcessOnlyOnActiveNode;
[Read, Description("Returns the URL of the availability group replica endpoint.")] String EndpointUrl;
Expand Down
66 changes: 63 additions & 3 deletions source/DSCResources/DSC_SqlAGReplica/DSC_SqlAGReplica.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Import-Module -Name $script:sqlServerDscHelperModulePath
Import-Module -Name $script:resourceHelperModulePath

$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US'

<#
.SYNOPSIS
Gets the specified Availability Group Replica from the specified Availability Group.
Expand Down Expand Up @@ -52,6 +53,9 @@ function Get-TargetResource
# Connect to the instance
$serverObject = Connect-SQL -ServerName $ServerName -InstanceName $InstanceName -ErrorAction 'Stop'

# Define current version for check compatibility
$sqlMajorVersion = $serverObject.Version.Major

# Is this node actively hosting the SQL instance?
$isActiveNode = Test-ActiveNode -ServerObject $serverObject

Expand Down Expand Up @@ -82,6 +86,11 @@ function Get-TargetResource
EndpointHostName = $serverObject.NetName
}

if ( ( $sqlMajorVersion -ge 13 ) )
{
$alwaysOnAvailabilityGroupReplicaResource.Add('SeedingMode', '')
}

# Get the availability group
$availabilityGroup = $serverObject.AvailabilityGroups[$AvailabilityGroupName]

Expand All @@ -102,6 +111,18 @@ function Get-TargetResource
$alwaysOnAvailabilityGroupReplicaResource.EndpointUrl = $availabilityGroupReplica.EndpointUrl
$alwaysOnAvailabilityGroupReplicaResource.ReadOnlyRoutingConnectionUrl = $availabilityGroupReplica.ReadOnlyRoutingConnectionUrl
$alwaysOnAvailabilityGroupReplicaResource.ReadOnlyRoutingList = $availabilityGroupReplica.ReadOnlyRoutingList

if ( $sqlMajorVersion -ge 13 )
{
if ( (Get-Command -Name 'New-SqlAvailabilityReplica').Parameters.ContainsKey('SeedingMode') )
{
$alwaysOnAvailabilityGroupReplicaResource.'SeedingMode' = $availabilityGroupReplica.SeedingMode
}
else
{
$alwaysOnAvailabilityGroupReplicaResource.'SeedingMode' = $null
}
}
}
}

Expand Down Expand Up @@ -161,6 +182,10 @@ function Get-TargetResource
.PARAMETER ProcessOnlyOnActiveNode
Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance.
Not used in Set-TargetResource.
.PARAMETER SeedingMode
Specifies the seeding mode. When creating a replica the default is 'Manual'.
This parameter can only be used when the module SqlServer is installed.
#>
function Set-TargetResource
{
Expand Down Expand Up @@ -235,14 +260,22 @@ function Set-TargetResource

[Parameter()]
[System.Boolean]
$ProcessOnlyOnActiveNode
$ProcessOnlyOnActiveNode,

[Parameter()]
[ValidateSet('Automatic', 'Manual')]
[System.String]
$SeedingMode = 'Manual'
)

Import-SqlDscPreferredModule

# Connect to the instance
$serverObject = Connect-SQL -ServerName $ServerName -InstanceName $InstanceName -ErrorAction 'Stop'

# Define current version for check compatibility
$sqlMajorVersion = $serverObject.Version.Major

# Determine if HADR is enabled on the instance. If not, throw an error
if ( -not $serverObject.IsHadrEnabled )
{
Expand Down Expand Up @@ -396,6 +429,15 @@ function Set-TargetResource
$availabilityGroupReplicaUpdatesRequired = $true
}

if ( ( $submittedParameters -contains 'SeedingMode' ) -and ( $sqlMajorVersion -ge 13 ) -and ( $SeedingMode -ne $availabilityGroupReplica.SeedingMode ) )
{
if ((Get-Command -Name 'New-SqlAvailabilityReplica').Parameters.ContainsKey('SeedingMode'))
{
$availabilityGroupReplica.SeedingMode = $SeedingMode
$availabilityGroupReplicaUpdatesRequired = $true
}
}

if ( $availabilityGroupReplicaUpdatesRequired )
{
Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroupReplica
Expand Down Expand Up @@ -457,6 +499,11 @@ function Set-TargetResource
$newAvailabilityGroupReplicaParams.Add('ReadOnlyRoutingList', $ReadOnlyRoutingList)
}

if ( ( $sqlMajorVersion -ge 13 ) -and (Get-Command -Name 'New-SqlAvailabilityReplica').Parameters.ContainsKey('SeedingMode') )
{
$newAvailabilityGroupReplicaParams.Add('SeedingMode', $SeedingMode)
}

# Create the Availability Group Replica
try
{
Expand Down Expand Up @@ -550,10 +597,14 @@ function Set-TargetResource
.PARAMETER ProcessOnlyOnActiveNode
Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance.
.PARAMETER SeedingMode
Specifies the seeding mode. When creating a replica the default is 'Manual'.
This parameter can only be used when the module SqlServer is installed.
#>
function Test-TargetResource
{
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('SqlServerDsc.AnalyzerRules\Measure-CommandsNeededToLoadSMO', '', Justification='The command Connect-Sql is called when Get-TargetResource is called')]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('SqlServerDsc.AnalyzerRules\Measure-CommandsNeededToLoadSMO', '', Justification = 'The command Connect-Sql is called when Get-TargetResource is called')]
[CmdletBinding()]
[OutputType([System.Boolean])]
param
Expand Down Expand Up @@ -626,7 +677,12 @@ function Test-TargetResource

[Parameter()]
[System.Boolean]
$ProcessOnlyOnActiveNode
$ProcessOnlyOnActiveNode,

[Parameter()]
[ValidateSet('Automatic', 'Manual')]
[System.String]
$SeedingMode = 'Manual'
)

$getTargetResourceParameters = @{
Expand Down Expand Up @@ -683,6 +739,10 @@ function Test-TargetResource
'ReadOnlyRoutingConnectionUrl',
'ReadOnlyRoutingList'
)
if ( $getTargetResourceResult.SeedingMode)
{
$parametersToCheck += 'SeedingMode'
}

if ( $getTargetResourceResult.Ensure -eq 'Present' )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class DSC_SqlAGReplica : OMI_BaseResource
[Write, Description("Specifies the fully qualified domain name (FQDN) and port to use when routing to the replica for read only connections.")] String ReadOnlyRoutingConnectionUrl;
[Write, Description("Specifies an ordered list of replica server names that represent the probe sequence for connection director to use when redirecting read-only connections through this availability replica. This parameter applies if the availability replica is the current primary replica of the availability group.")] String ReadOnlyRoutingList[];
[Write, Description("Specifies that the resource will only determine if a change is needed if the target node is the active host of the _SQL Server_ instance.")] Boolean ProcessOnlyOnActiveNode;
[Write, Description("Specifies the seeding mode. When creating a replica the default value is `'Manual`'."), ValueMap{"Automatic","Manual"}, Values{"Automatic","Manual"}] String SeedingMode;
[Read, Description("Returns the network port the endpoint is listening on.")] Uint16 EndpointPort;
[Read, Description("Returns the URL of the availability group replica endpoint.")] String EndpointUrl;
[Read, Description("Returns if the current node is actively hosting the _SQL Server Database Engine_ instance.")] Boolean IsActiveNode;
Expand Down
Loading

0 comments on commit 753c556

Please sign in to comment.