**Configure high availability with Always On Availability Groups on Amazon RDS Custom for SQL Server**
===
###### tags: `AWS`
要設置 HA 配置,您需要創建兩個 RDS Custom for SQL Server 數據庫實例作為主節點和輔助節點,以及一個Amazon Elastic Compute Cloud (Amazon EC2) 實例作為witness node。強烈建議您在同一區域的不同可用區中創建這些實例。
下圖說明了使用 Always On AG 的 HA 設置。

通過以下步驟實施解決方案:
Create RDS Custom for SQL Server and EC2 instances.
Prepare the RDS Custom for SQL Server DB instances.
Set up the witness disk using iSCSI.
Set up a Windows cluster.
Set up an Always On AG.
<style>
.red {
color: red;
}
</style>
<span class="red">※您需要先擁有名稱為AWSRDSCustomInstanceProfileForRdsCustomInstance的rules,並且有設置KMS</span>
### **為 SQL Server 和 EC2 實例創建 RDS Custom**
[第一步是為 SQL Server 實例啟動 RDS Custom。有關為 SQL Server 實例創建 RDS Custom 的更多詳細信息,請參閱為Amazon RDS Custom for SQL Server 創建並連接到數據庫實例。](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/custom-creating-sqlserver.html)
以下LAB演示了在同一 VPC 和安全組中啟動兩個 RDS Custom for SQL Server 實例。您需要兩個不同的數據庫子網組才能使其在不同的可用區中可用。
#### **在 ap-northeast-1c 可用區中啟動Node-1 、RDS-custom-sqlserver-1**
簡化成CLI如下
```
aws rds create-db-instance
–engine custom-sqlserver-ee
–engine-version 15.00.4261.1.v1
–db-instance-identifier RDS-custom-sqlserver-1
–db-instance-class db.m5.xlarge
–allocated-storage 1000 –storage-type io1 –iops 10000
–master-username admin
–master-user-password <XXXXX>
–kms-key-id <kms-key-id>
–custom-iam-instance-profile RDSCustomIAMProfile
–db-subnet-group-name RDS-custom-sng-1
–vpc-security-group-ids RDS-usw2-vpc-sg-1
–publicly-accessible
–region ap-northeast-1C
–profile RDS_Custom
```
#### **在 ap-northeast-1a 可用區中啟動Node-1 、RDS-custom-sqlserver-1**
簡化成CLI如下
```
aws rds create-db-instance
–engine custom-sqlserver-ee
–engine-version 15.00.4261.1.v1
–db-instance-identifier RDS-custom-sqlserver-1
–db-instance-class db.m5.xlarge
–allocated-storage 1000 –storage-type io1 –iops 10000
–master-username admin
–master-user-password <XXXXX>
–kms-key-id <kms-key-id>
–custom-iam-instance-profile RDSCustomIAMProfile
–db-subnet-group-name RDS-custom-sng-1
–vpc-security-group-ids RDS-usw2-vpc-sg-1
–publicly-accessible
–region ap-northeast-1A
–profile RDS_Custom
```
#### **接下來,我們啟動一個充當witness node的 EC2 實例**
選擇 Amazon 系統映像 (AMI)。對於本次LAB,我們使用Microsoft Windows Server 2019 Base的 AMI 。
選擇實例類型。我們使用 t2.micro 實例類型。
配置實例詳細信息:
我們使用 RDS Custom for SQL Server 數據庫實例使用的相同 VPC 網絡,但在不同的可用區 (ap-northeast-1d) 中。在前面的步驟中,我們在 ap-northeast-1c 和 ap-northeast-1a 可用區中為 SQL Server 數據庫實例啟動了 RDS Custom。
將自動分配公共 IP 設置為啟用。
添加存儲大小為 100 GB 的新卷類型 GP2。
配置VPC安全組。我們選擇與之前為 SQL Server 數據庫實例的 RDS 自定義指定的相同)。
查看實例啟動並選擇一個密鑰對。
### **為 SQL Server 數據庫實例準備 RDS Custom**
[將兩台RDS Custom暫停自動化,以免干擾本次的lab](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/custom-managing.html#custom-managing.pausing)

修改完成會顯示如下

[需要先透過 Session Manager 開啟 RDS 的 RDP 連線,並透過 Secrets Manager 獲取RDP的登錄密碼](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/custom-creating-sqlserver.html)
在Node-1和Node-2 打開Windows Power Shell 上運行以下命令啟動MSiSCSI service:
```
net start MSiSCSI
Set-Service msiscsi –StartupType "Automatic"
```
設置 DNS 後綴。以下示例為名為 custom.com 的域創建一個 DNS 後綴:
```
Set-ItemProperty "HKLM:SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "NV Domain" -Value "custom.com"
```
安裝故障轉移集群功能:
```
Install-WindowsFeature -Name Failover-Clustering –IncludeManagementTools
```
確保Node-1和Node-2 的管理員密碼相同並重啟VM確保生效:
```
net user administrator XXXXXXXX
Restart-Computer
```
輸出會如下

### **使用 iSCSI 設置witness disk**
要設置witness disk,請在Node-1和Node-2以及witness node上運行命令。
#### **Witness node:**
啟動 MSiSCSI 服務:
```
net start MSiSCSI
Set-Service msiscsi -StartupType "Automatic"
```
Set up the disk for quorum:
```
diskpart
list disk
select disk 1
```
<span class="red">※**witness node建立時少掛一個磁碟,因此重新掛載一顆新的**</span>

```
online disk noerr
attribute disk clear readonly
convert dynamic noerr
```
<span class="red">※**出現相同錯誤請先下clean**</span>

```
create volume simple align=1024 disk=1
format fs=NTFS label=”rdsquorum01″ quick UNIT=65536
list volume
select volume=0
```

```
assign letter d noerr
exit
```
#### **Install the iSCSI target server role:**
```
Add-WindowsFeature FS-iSCSITarget-Server
```

創建具有指定文件路徑和大小的 iSCSI 虛擬硬盤 (VHDX) 對象:
```
New-IscsiVirtualDisk D:\rdsquorumrdscustomquorum01.vhdx -size 512MB -UseFixed
```

我們使用以下私人IP地址:
**Node-1 (RDS-custom-sqlserver-1) — 172.31.7.150**
**Node-2 (RDS-custom-sqlserver-2) — 172.31.36.230**
Run the following code:
```
New-IscsiServerTarget rdscustomquorum -InitiatorIds IPAddress:172.31.7.150,IPAddress:172.31.36.230
```

Assign the virtual disk "D:\rdsquorumrdscustomquorum01.vhdx" to the iSCSI target rdscustomquorum:
```
Add-IscsiVirtualDiskTargetMapping rdscustomquorum D:rdsquorumrdscustomquorum01.vhdx
```

### **設置Node-1 and Node-2**
Node-1 and Node-2 to add a new iSCSI target portal
```
New-IscsiTargetPortal -TargetPortalAddress rdscustomwitness
Get-IscsiTarget
```
[<span class="red">出現相同錯誤的情況需開啟iSCSi的Targets設定點選connect</span>](https://github.com/dsccommunity/iSCSIDsc/issues/9)

### **Node-1, Node-2, and witness node**
綁定本機的host文件,並且確保彼此放行所有端口和協議再透過ping測試
<span class="red">※使用CMD輸入notepad c:\windows\system32\drivers\etc\hosts即可編輯host</span>
```
172.31.7.150 rdsamaz-63sdoia rdsamaz-63sdoia.custom.com rdscustomnode01
172.31.36.230 rdsamaz-a1bjtfg rdsamaz-a1bjtfg.custom.com rdscustomnode02
172.31.23.17 ec2amaz-d2au9ie ec2amaz-d2au9ie.custom.com rdscustomwitness
```

### **設置Windows cluster**
要設置 Windows 集群,請在Node-1和Node-2上運行命令。在Node-1上完成步驟 1–10 :
```
diskpart
list disk
select disk 3
online disk noerr
attribute disk clear readonly
convert dynamic noerr
convert basic noerr
create partition primary
```

```
format fs=NTFS label="rdscustomquorum01″ quick UNIT=65536
exit
```

以下示例創建一個名為“rdscustomcluster”的新的獨立於域的 Windows 集群。要創建集群,請在給定的子網範圍內標識一個未分配的 IP 地址,該地址可用作集群的 IP 地址。在以下示例中,我們使用 172.31.7.152 作為 IP 地址:
```
New-Cluster -Name rdscustomcluster -AdministrativeAccessPoint DNS -NoStorage -StaticAddress 172.31.7.152
Get-ClusterAvailableDisk
Get-ClusterAvailableDisk | Add-ClusterDisk
Set-ClusterQuorum -NodeAndDiskMajority “Cluster Disk 1”
```

將Node-2添加到集群:
```
Add-ClusterNode rdsamaz-a1bjtfg
Get-ClusterResource "Cluster IP Address"| % { $_.Name="IP Address 172.31.7.152"}
Get-ClusterResource
```

為Node-2的子網添加一個新的集群資源。在以下代碼中,Node-2的私有 IP 地址為 172.31.36.230。我們可以選擇給定子網範圍內的任何可用 IP 地址,例如:172.31.36.232。
```
Add-ClusterResource -Name "IP Address 172.31.36.232" -ResourceType "IP Address" -Group "Cluster Group"
```

為集群資源添加Node-2控制子網的 IP 地址:
```
$res = Get-ClusterResource "IP Address 172.31.36.232"
$param1 = New-Object Microsoft.FailoverClusters.PowerShell.ClusterParameter $res,Address,172.31.36.232
$param2 = New-Object Microsoft.FailoverClusters.PowerShell.ClusterParameter $res,SubnetMask,255.255.240.0
$params = $param1,$param2
$params | Set-ClusterParameter
```

將集群依賴性設置為Node-1或Node-2子網集群資源:
```
Set-ClusterResourceDependency ‘Cluster Name’ “[IP Address 172.31.36.232] or [IP Address 172.31.7.152]”
```

在Node-1和Node-2上,啟用 SQLAlways On 並重新啟動:
```
Enable-SqlAlwaysOn -Path SQLSERVER:\SQL\$env:COMPUTERNAME\DEFAULT -Force
Restart-Computer
```

當執行重新開機命令時,可以看到Windows cluster已經正常運作的切換中

### **設置 Always On AG**
#### **我們通過在Node-1和Node-2上執行以下步驟序列,在 SQL Server 實例的 RDS Custom 上配置 Always On AG :**
在Node-1上,創建端點和備份證書:
```
USE master;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Aasd1234';
CREATE CERTIFICATE HOST_A_cert WITH SUBJECT = 'HOST_A certificate for database mirroring', EXPIRY_DATE = '11/30/2023';
CREATE ENDPOINT Endpoint_Mirroring STATE = STARTED AS TCP ( LISTENER_PORT=1120 , LISTENER_IP = ALL) FOR DATABASE_MIRRORING ( AUTHENTICATION = CERTIFICATE HOST_A_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL);
BACKUP CERTIFICATE HOST_A_cert TO FILE = 'D:\rdsdbdata\BACKUP\HOST_A_cert.cer';
```

路徑填寫錯誤會需要重新執行T-SQL 語句

在Node-2上,創建端點和備份證書:
```
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Aasd1234';
CREATE CERTIFICATE HOST_B_cert WITH SUBJECT = 'HOST_B certificate for database mirroring', EXPIRY_DATE = '11/30/2023′;
CREATE ENDPOINT Endpoint_Mirroring STATE = STARTED AS TCP (LISTENER_PORT=1120 , LISTENER_IP = ALL) FOR DATABASE_MIRRORING (AUTHENTICATION = CERTIFICATE HOST_B_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL);
BACKUP CERTIFICATE HOST_B_cert TO FILE = 'D:\rdsdbdata\BACKUP\HOST_B_cert.cer';
```

<span class="red">※先將Node-1上的證書A複製到Node-2主機,Node-2上的證書B複製到Node-1上
在Node-1上,使用Node-2的備份證書創建證書:
```
USE master;
CREATE LOGIN HOST_B_login WITH PASSWORD = 'Aasd1234';
CREATE USER HOST_B_user FOR LOGIN HOST_B_login;
CREATE CERTIFICATE HOST_B_cert AUTHORIZATION HOST_B_user FROM FILE = 'D:\rdsdbdata\BACKUP\HOST_B_cert.cer';
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_B_login];
```

在Node-2上,使用Node-1的備份證書創建證書:
```
USE master;
CREATE LOGIN HOST_A_login WITH PASSWORD = 'Aasd1234';
CREATE USER HOST_A_user FOR LOGIN HOST_A_login;
CREATE CERTIFICATE HOST_A_cert AUTHORIZATION HOST_A_user FROM FILE = 'D:\rdsdbdata\BACKUP\HOST_A_cert.cer';
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_A_login];
```

在Node-1上,創建一個availability group:
```
create availability group customag1
with
(
automated_backup_preference = primary,
db_failover = on,
dtc_support = none
)
for
replica on
'rdsamaz-63sdoia' with
(
endpoint_url = 'tcp://rdsamaz-63sdoia:1120',
failover_mode = automatic,
availability_mode = synchronous_commit,
seeding_mode = automatic,
secondary_role
(
allow_connections = all
)
),
'rdsamaz-a1bjtfg' with
(
endpoint_url = 'tcp://rdsamaz-a1bjtfg:1120',
failover_mode = automatic,
availability_mode = synchronous_commit,
seeding_mode = automatic,
secondary_role
(
allow_connections = all
)
)
go
```


### **新建database並添加到availability group**
在Node-1上,創建一個database:
```
create database test;
backup database test to disk ='D:\rdsdbdata\backup\test.bak';
alter availability group customag1 add database test;
```

在Node-2上,加入availability group:
```
alter availability group customag1 join;
alter availability group customag1 grant create any database;
```

### **從Node-2點選availability replicas點選rdsamaz-63sdoia(Node-1)進行connect是成功的**

### **透過Fail Over Availability Group進行Connect To Replica進行connect成功**

---
## **摘要**
#### **在上述的Lab中,解釋如何使用 Always On AG 在 RDS Custom 上為 SQL Server 數據庫實例配置 HA。**