AWSTemplateFormatVersion: '2010-09-09'
Description: >-
  (0003) - This template deploys two Windows Server Failover Clustering (WSFC) and
  SQL Server 2012 AlwaysOn Availability Group nodes. This template is intended to
  be installed into an existing VPC that was built using the sample reference architecture
  titled: "Implementing Active Directory Domain Services in the AWS Cloud" **WARNING**
  This template creates Amazon EC2 Windows instance and related resources. You will
  be billed for the AWS resources used if you create a stack from this template. (qs-1tsaami1i)
Metadata:
  cfn-lint:
    config:
      ignore_checks:
        - W2001
        - W4002
        - W9002
        - W9003
        - W9006
        - E9007
        - E9010
Parameters:
  KeyPairName:
    Description: Public/private key pairs allow you to securely connect to your instance
      after it launches
    Type: AWS::EC2::KeyPair::KeyName
  WSFCNode1InstanceType:
    Description: Amazon EC2 instance type for the 1st WSFC Node
    Type: String
    Default: r3.2xlarge
    AllowedValues:
      - r3.xlarge
      - r3.2xlarge
      - r3.4xlarge
    ConstraintDescription: Only EBS Optimized instance types r3.xlarge, r3.2xlarge,
      r3.4xlarge allowed
  WSFCNode2InstanceType:
    Description: Amazon EC2 instance type for the 1st WSFC Node
    Type: String
    Default: r3.2xlarge
    AllowedValues:
      - r3.xlarge
      - r3.2xlarge
      - r3.4xlarge
    ConstraintDescription: Only EBS Optimized instance types r3.xlarge, r3.2xlarge,
      r3.4xlarge allowed
  DomainDNSName:
    Description: Fully qualified domain name (FQDN) of the forest root domain e.g.
      corp.example.com
    Type: String
    Default: example.com
    MinLength: '3'
    MaxLength: '25'
    AllowedPattern: '[a-zA-Z0-9\-]+\..+'
  DomainNetBIOSName:
    Description: NetBIOS name of the domain (upto 15 characters) for users of earlier
      versions of Windows e.g. CORP
    Type: String
    Default: example
    MinLength: '1'
    MaxLength: '15'
    AllowedPattern: '[a-zA-Z0-9\-]+'
  WSFCNode1NetBIOSName:
    Description: NetBIOS name of the 1st WSFC Node (up to 15 characters)
    Type: String
    Default: WSFCNode1
    MinLength: '1'
    MaxLength: '15'
    AllowedPattern: '[a-zA-Z0-9\-]+'
  WSFCNode2NetBIOSName:
    Description: NetBIOS name of the 2nd WSFC Node (up to 15 characters)
    Type: String
    Default: WSFCNode2
    MinLength: '1'
    MaxLength: '15'
    AllowedPattern: '[a-zA-Z0-9\-]+'
  ADServerNetBIOSName1:
    Description: NetBIOS name of the existing Domain Controller in AZ1
    Type: String
    Default: DC1
    MinLength: '1'
    MaxLength: '15'
    AllowedPattern: '[a-zA-Z0-9\-]+'
  ADServerNetBIOSName2:
    Description: NetBIOS name of the existing Domain Controller in AZ2
    Type: String
    Default: DC2
    MinLength: '1'
    MaxLength: '15'
    AllowedPattern: '[a-zA-Z0-9\-]+'
  DomainAdminUser:
    Description: User name for the account that will be added as Domain Administrator.
      This is separate from the default "Administrator" account
    Type: String
    Default: StackAdmin
    MinLength: '5'
    MaxLength: '25'
    AllowedPattern: '[a-zA-Z0-9]*'
  DomainAdminPassword:
    Description: Password for the domain admin user. Must be at least 8 characters
      containing letters, numbers and symbols
    Type: String
    MinLength: '8'
    MaxLength: '32'
    AllowedPattern: (?=^.{6,255}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*
    NoEcho: true
  SQLServiceAccount:
    Description: User name for the SQL Server Service Account. This Account is a Domain
      User.
    Type: String
    Default: sqlsa
    MinLength: '5'
    MaxLength: '25'
    AllowedPattern: '[a-zA-Z0-9]*'
  SQLServiceAccountPassword:
    Description: Password for the SQL Service account. Must be at least 8 characters
      containing letters, numbers and symbols
    Type: String
    MinLength: '8'
    MaxLength: '32'
    AllowedPattern: (?=^.{6,255}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*
    NoEcho: true
  ADServer1PrivateIp:
    Description: Fixed private IP for the first existing Active Directory server located
      in AZ1
    Type: String
    Default: 10.0.0.10
  ADServer2PrivateIp:
    Description: Fixed private IP for the second existing Active Directory serverr
      located in AZ2
    Type: String
    Default: 10.0.64.10
  WSFCNode1PrivateIp:
    Description: Primary private IP for the 1st WSFC Node located in AZ1
    Type: String
    Default: 10.0.0.100
  WSFCNode1PrivateIp2:
    Description: Secondary private IP for WSFC cluster on 1st WSFC Node
    Type: String
    Default: 10.0.0.101
  WSFCNode1PrivateIp3:
    Description: Third private IP for Availability Group Listner on 1st WSFC Node
    Type: String
    Default: 10.0.0.102
  WSFCNode2PrivateIp:
    Description: Primary private IP for the 2nd WSFC Node located in AZ2
    Type: String
    Default: 10.0.64.100
  WSFCNode2PrivateIp2:
    Description: Secondary private IP for WSFC cluster on 2nd WSFC Node
    Type: String
    Default: 10.0.64.101
  WSFCNode2PrivateIp3:
    Description: Third private IP for Availability Group Listner on 2nd WSFC Node
    Type: String
    Default: 10.0.64.102
  DomainMemberSGID:
    Description: ID of the Domain Member Security Group (e.g., sg-7f16e910)
    Type: AWS::EC2::SecurityGroup::Id
  VPC:
    Description: ID of the VPC (e.g., vpc-0343606e)
    Type: AWS::EC2::VPC::Id
  PrivateSubnet1Id:
    Description: ID of the subnet you want to provision the first WSFC node into (e.g.,
      subnet-a0246dcd)
    Type: AWS::EC2::Subnet::Id
  PrivateSubnet2Id:
    Description: ID of the subnet you want to provision the second WSFC node into
      (e.g., subnet-e3246d8e)
    Type: AWS::EC2::Subnet::Id
  PrivSub1CIDR:
    Description: CIDR Block for Private Subnet located in AZ1
    Type: String
    Default: 10.0.0.0/19
    AllowedPattern: '[a-zA-Z0-9]+\..+'
  PrivSub2CIDR:
    Description: CIDR Block for for Private Subnet located in AZ2
    Type: String
    Default: 10.0.64.0/19
    AllowedPattern: '[a-zA-Z0-9]+\..+'
  SQLServerVersion:
    Description: Version of SQL Server to install on WSFC Nodes. Options include either
      "2014" or "2012"
    Type: String
    AllowedValues:
      - '2014'
      - '2012'
    Default: '2014'
  VPCCIDR:
    Description: CIDR Block used by the VPC
    Type: String
    Default: 10.0.0.0/16
    AllowedPattern: '[a-zA-Z0-9]+\..+'
Mappings:
  AWSAMIRegionMap:
    AMI:
      WS2012R2: Windows_Server-2012-R2_RTM-English-64Bit-Base-2019.07.12
    ap-northeast-1:
      WS2012R2: ami-06823103be2218b98
    ap-northeast-2:
      WS2012R2: ami-050e65d9f2ec90145
    ap-northeast-3:
      WS2012R2: ami-04dfed75117825fec
    ap-south-1:
      WS2012R2: ami-045e1f06f29929467
    ap-southeast-1:
      WS2012R2: ami-0c322369af7718803
    ap-southeast-2:
      WS2012R2: ami-0813db0de4ddab990
    ca-central-1:
      WS2012R2: ami-0850dfaa3ee6f6233
    eu-central-1:
      WS2012R2: ami-024652d0a3df40e74
    eu-west-1:
      WS2012R2: ami-0d2f69fcc5f00c97a
    eu-west-2:
      WS2012R2: ami-0998a91bb1756752d
    eu-west-3:
      WS2012R2: ami-0d6e54e3504cc1615
    sa-east-1:
      WS2012R2: ami-044d56b6baa621d7d
    us-east-1:
      WS2012R2: ami-094a644f1fb9e4ce3
    us-east-2:
      WS2012R2: ami-0a1a54d8690206089
    us-west-1:
      WS2012R2: ami-094dcbdb1aa24c8da
    us-west-2:
      WS2012R2: ami-0f8967b5f815400c0
Resources:
  WSFCNode1WaitCondition:
    Type: AWS::CloudFormation::WaitCondition
    DependsOn: WSFCNode1
    Properties:
      Handle: !Ref 'WSFCNode1WaitHandle'
      Timeout: '5400'
  WSFCNode1WaitHandle:
    Type: AWS::CloudFormation::WaitConditionHandle
  WSFCNode2WaitCondition:
    Type: AWS::CloudFormation::WaitCondition
    DependsOn: WSFCNode2
    Properties:
      Handle: !Ref 'WSFCNode2WaitHandle'
      Timeout: '5400'
  WSFCNode2WaitHandle:
    Type: AWS::CloudFormation::WaitConditionHandle
  WSFCNode1:
    Type: AWS::EC2::Instance
    Metadata:
      AWS::CloudFormation::Init:
        configSets:
          config:
            - CFNsetup
            - rename
            - join
            - createSqlAccount
            - installsql
            - finalize
        CFNsetup:
          files:
            c:\cfn\cfn-hup.conf:
              content: !Join
                - ''
                - - "[main]\n"
                  - stack=
                  - !Ref 'AWS::StackId'
                  - "\n"
                  - region=
                  - !Ref 'AWS::Region'
                  - "\n"
            c:\cfn\hooks.d\cfn-auto-reloader.conf:
              content: !Join
                - ''
                - - "[cfn-auto-reloader-hook]\n"
                  - "triggers=post.update\n"
                  - "path=Resources.WSFCNode1.Metadata.AWS::CloudFormation::Init\n"
                  - 'action=cfn-init.exe -v -s '
                  - !Ref 'AWS::StackId'
                  - ' -r WSFCNode1'
                  - ' --region '
                  - !Ref 'AWS::Region'
                  - "\n"
          services:
            windows:
              cfn-hup:
                enabled: true
                ensureRunning: true
                files:
                  - c:\cfn\cfn-hup.conf
                  - c:\cfn\hooks.d\cfn-auto-reloader.conf
          commands:
            a-set-execution-policy:
              command: !Join
                - ''
                - - powershell.exe -command Set-ExecutionPolicy RemoteSigned -Force
              waitAfterCompletion: '0'
        rename:
          commands:
            1-execute-powershell-script-RenameComputer:
              command: !Join
                - ''
                - - 'powershell.exe -Command Rename-Computer -NewName '
                  - !Ref 'WSFCNode1NetBIOSName'
                  - ' -Restart'
              waitAfterCompletion: forever
        join:
          commands:
            a-set-dns-servers:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"'
                  - 'Get-NetAdapter | Set-DnsClientServerAddress -ServerAddresses '
                  - !Ref 'ADServer1PrivateIp'
                  - ','
                  - !Ref 'ADServer2PrivateIp'
                  - '"'
              waitAfterCompletion: '30'
            b-join-domain:
              command: !Join
                - ''
                - - 'powershell.exe '
                  - -Command "
                  - 'Add-Computer -DomainName '
                  - !Ref 'DomainDNSName'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - -Restart"
              waitAfterCompletion: forever
        createSqlAccount:
          commands:
            1-create-sqlacct:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"Invoke-Command -Scriptblock{ New-ADUser '
                  - '-Name '
                  - !Ref 'SQLServiceAccount'
                  - ' '
                  - '-UserPrincipalName '
                  - !Ref 'SQLServiceAccount'
                  - '@'
                  - !Ref 'DomainDNSName'
                  - ' '
                  - '-AccountPassword (ConvertTo-SecureString '
                  - !Ref 'SQLServiceAccountPassword'
                  - ' -AsPlainText -Force) '
                  - '-Enabled $true '
                  - '-PasswordNeverExpires $true -EA 0} -ComputerName '
                  - !Ref 'ADServerNetBIOSName1'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
        installsql:
          files:
            C:\cfn\scripts\WSFC.ps1:
              content: !Join
                - ''
                - - Install-WindowsFeature failover-clustering -IncludeManagementTools
                  - "\n"
            c:\cfn\scripts\DownloadSQLEE.ps1:
              source: https://s3.amazonaws.com/aws-quickstart/quickstart-microsoft-sql/scripts/DownloadSQLEE-Legacy.ps1
            c:\cfn\scripts\OpenWSFCPorts.bat:
              source: https://s3.amazonaws.com/aws-quickstart/quickstart-microsoft-sql/scripts/OpenWSFCPorts.bat
            C:\cfn\scripts\AddUserToGroup.ps1:
              content: !Join
                - ''
                - - Param(
                  - "\n"
                  - '[Parameter(Mandatory=$True)]'
                  - "\n"
                  - '[string]$ServerName,'
                  - "\n"
                  - '[Parameter(Mandatory=$True)]'
                  - "\n"
                  - '[string]$GroupName,'
                  - "\n"
                  - '[Parameter(Mandatory=$True)]'
                  - "\n"
                  - '[string]$DomainNetBIOSName,'
                  - "\n"
                  - '[Parameter(Mandatory=$True)]'
                  - "\n"
                  - '[string]$UserName'
                  - "\n"
                  - )
                  - $de = [ADSI]"WinNT://$ServerName/$GroupName,group"
                  - "\n"
                  - $de.psbase.Invoke("Add",([ADSI]"WinNT://$DomainNetBIOSName/$UserName").path)
                  - "\n"
            C:\Users\Default\Desktop\InstallSQLEE.bat:
              content: !Join
                - ''
                - - powershell.exe -command Install-WindowsFeature NET-Framework-Core
                  - "\n"
                  - powershell.exe -command "dir \\
                  - !Ref 'ADServerNetBIOSName1'
                  - \sqlinstall\*.iso | Mount-DiskImage"
                  - "\n"
                  - powershell.exe -command "Get-Volume | ?{$_.DriveType -eq 'CD-ROM'}
                    | select -ExpandProperty DriveLetter" > %temp%\driveletter.txt
                  - "\n"
                  - SET /p driveletter=<%temp%\driveletter.txt
                  - "\n"
                  - '%driveletter%:\SETUP.EXE '
                  - '/QS '
                  - '/Action=Install '
                  - '/Features=SQLEngine,Replication,FullText,Conn,BOL,ADV_SSMS '
                  - '/INSTANCENAME=MSSQLSERVER '
                  - /SQLSVCACCOUNT="
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'SQLServiceAccount'
                  - '" '
                  - /SQLSVCPASSWORD="
                  - !Ref 'SQLServiceAccountPassword'
                  - '" '
                  - /AGTSVCACCOUNT="
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'SQLServiceAccount'
                  - '" '
                  - /AGTSVCPASSWORD="
                  - !Ref 'SQLServiceAccountPassword'
                  - '" '
                  - /SQLSYSADMINACCOUNTS="
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - '" '
                  - '/SQLUSERDBDIR="D:\MSSQL\DATA" '
                  - '/SQLUSERDBLOGDIR="E:\MSSQL\LOG" '
                  - '/SQLBACKUPDIR="f:\MSSQL\Backup" '
                  - '/SQLTEMPDBDIR="f:\MSSQL\TempDB" '
                  - '/SQLTEMPDBLOGDIR="f:\MSSQL\TempDB" '
                  - /IACCEPTSQLSERVERLICENSETERMS
                  - "\n"
                  - C:\PROGRA~1\MICROS~1\CLIENT~1\ODBC\110\Tools\Binn\SQLCMD.EXE -i
                    c:\cfn\scripts\MaxDOP.sql
            c:\cfn\scripts\MaxDOP.sql:
              source: https://s3.amazonaws.com/aws-quickstart/quickstart-microsoft-sql/scripts/MaxDOP.sql
          commands:
            a-execute-powershell-script-WSFC:
              command: !Join
                - ''
                - - 'powershell.exe '
                  - -ExecutionPolicy
                  - ' RemoteSigned'
                  - ' C:\cfn\scripts\WSFC.ps1'
              waitAfterCompletion: '0'
            b-create-folder:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"'
                  - 'Invoke-Command -ScriptBlock {New-Item -ItemType directory -Path
                    c:\ -Name sqlinstall} -ComputerName '
                  - !Ref 'ADServerNetBIOSName1'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
            c-create-share:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"'
                  - 'Invoke-Command -ScriptBlock { New-SmbShare -Name sqlinstall -Path
                    c:\sqlinstall -FullAccess everyone } -ComputerName '
                  - !Ref 'ADServerNetBIOSName1'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
            d-execute-powershell-DownloadSQLEE:
              command: !Join
                - ''
                - - 'powershell.exe '
                  - -ExecutionPolicy
                  - ' RemoteSigned'
                  - ' C:\cfn\scripts\DownloadSQLEE.ps1 -SQLServerVersion '
                  - !Ref 'SQLServerVersion'
                  - ' -DestServer '
                  - !Ref 'ADServerNetBIOSName1'
                  - ' -DestShare sqlinstall'
              waitAfterCompletion: '0'
            e-open-WSFC-ports:
              command: C:\cfn\scripts\OpenWSFCPorts.bat
            f-execute-powershell-script-AddUserToGroup:
              command: !Join
                - ''
                - - 'powershell.exe '
                  - -ExecutionPolicy
                  - ' RemoteSigned'
                  - ' C:\cfn\scripts\AddUserToGroup.ps1 -UserName '
                  - !Ref 'DomainAdminUser'
                  - ' -ServerName '
                  - !Ref 'WSFCNode1NetBIOSName'
                  - ' -DomainNetBIOSName '
                  - !Ref 'DomainNetBIOSName'
                  - ' -GroupName "Administrators"'
                  - "\n"
              waitAfterCompletion: '0'
            g-execute-powershell-script-AddUserToGroup:
              command: !Join
                - ''
                - - 'powershell.exe '
                  - -ExecutionPolicy
                  - ' RemoteSigned'
                  - ' C:\cfn\scripts\AddUserToGroup.ps1 -UserName '
                  - !Ref 'SQLServiceAccount'
                  - ' -ServerName '
                  - !Ref 'WSFCNode1NetBIOSName'
                  - ' -DomainNetBIOSName '
                  - !Ref 'DomainNetBIOSName'
                  - ' -GroupName "Administrators"'
                  - "\n"
              waitAfterCompletion: '0'
            h-enable-autologon:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"New-ItemProperty -Path ''HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon''
                    -Name AutoAdminLogon -Value 1'
                  - ;
                  - 'New-ItemProperty -Path ''HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon''
                    -Name DefaultUserName -Value '
                  - !Ref 'DomainAdminUser'
                  - '@'
                  - !Ref 'DomainDNSName'
                  - ' | out-null'
                  - ;
                  - 'New-ItemProperty -Path ''HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon''
                    -Name DefaultPassword -Value '
                  - !Ref 'DomainAdminPassword'
                  - '"'
              waitAfterCompletion: '0'
            i-set-startup-script:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
                    -Name InstallSQL -Value C:\Users\Default\Desktop\InstallSQLEE.bat'
                  - '"'
              waitAfterCompletion: '0'
            j-reboot:
              command: !Join
                - ''
                - - powershell.exe -Command Restart-Computer -Force
              waitAfterCompletion: forever
            k-force-ad-replication:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"Invoke-Command -Scriptblock{ repadmin /syncall /A /e /P } -ComputerName '
                  - !Ref 'ADServerNetBIOSName1'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
            l-cleanup-registry:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"Remove-ItemProperty -Path ''HKLM:\SOFTWARE\Microsoft\Windows
                    NT\CurrentVersion\Winlogon'' -Name AutoAdminLogon'
                  - ;
                  - Remove-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
                    -Name DefaultUserName
                  - ;
                  - Remove-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
                    -Name DefaultPassword
                  - '"'
              waitAfterCompletion: '900'
        finalize:
          commands:
            1-signal-success:
              command: !Join
                - ''
                - - cfn-signal.exe -e 0 "
                  - !Ref 'WSFCNode1WaitHandle'
                  - '"'
    Properties:
      ImageId: !FindInMap
        - AWSAMIRegionMap
        - !Ref 'AWS::Region'
        - WS2012R2
      InstanceType: !Ref 'WSFCNode1InstanceType'
      EbsOptimized: true
      NetworkInterfaces:
        - DeleteOnTermination: true
          DeviceIndex: "0"
          SubnetId: !Ref 'PrivateSubnet1Id'
          PrivateIpAddresses:
            - Primary: true
              PrivateIpAddress: !Ref 'WSFCNode1PrivateIp'
            - Primary: false
              PrivateIpAddress: !Ref 'WSFCNode1PrivateIp2'
            - Primary: false
              PrivateIpAddress: !Ref 'WSFCNode1PrivateIp3'
          GroupSet:
            - !Ref 'DomainMemberSGID'
            - !Ref 'WSFCSecurityGroup'
            - !Ref 'WSFCClientSecurityGroup'
      Tags:
        - Key: Name
          Value: !Ref 'WSFCNode1NetBIOSName'
      BlockDeviceMappings:
        - DeviceName: /dev/sda1
          Ebs:
            VolumeSize: 100
            VolumeType: gp2
        - DeviceName: /dev/xvdca
          VirtualName: ephemeral0
      Volumes:
        - VolumeId: !Ref 'WSFCNode1Volume1'
          Device: /dev/xvdb
        - VolumeId: !Ref 'WSFCNode1Volume2'
          Device: /dev/xvdc
        - VolumeId: !Ref 'WSFCNode1Volume3'
          Device: /dev/xvdd
      KeyName: !Ref 'KeyPairName'
      UserData: !Base64
        Fn::Join:
          - ''
          - - "<script>\n"
            - 'cfn-init.exe -v -c config -s '
            - !Ref 'AWS::StackId'
            - ' -r WSFCNode1 '
            - ' --region '
            - !Ref 'AWS::Region'
            - "\n"
            - </script>
  WSFCNode2:
    Type: AWS::EC2::Instance
    DependsOn: WSFCNode1WaitCondition
    Metadata:
      AWS::CloudFormation::Init:
        configSets:
          config:
            - CFNsetup
            - rename
            - join
            - installsql
            - configsql
            - finalize
        CFNsetup:
          files:
            c:\cfn\cfn-hup.conf:
              content: !Join
                - ''
                - - "[main]\n"
                  - stack=
                  - !Ref 'AWS::StackId'
                  - "\n"
                  - region=
                  - !Ref 'AWS::Region'
                  - "\n"
            c:\cfn\hooks.d\cfn-auto-reloader.conf:
              content: !Join
                - ''
                - - "[cfn-auto-reloader-hook]\n"
                  - "triggers=post.update\n"
                  - "path=Resources.WSFCNode2.Metadata.AWS::CloudFormation::Init\n"
                  - 'action=cfn-init.exe -v -s '
                  - !Ref 'AWS::StackId'
                  - ' -r WSFCNode2'
                  - ' --region '
                  - !Ref 'AWS::Region'
                  - "\n"
            c:\cfn\scripts\MaxDOP.sql:
              source: https://s3.amazonaws.com/aws-quickstart/quickstart-microsoft-sql/scripts/MaxDOP.sql
          services:
            windows:
              cfn-hup:
                enabled: true
                ensureRunning: true
                files:
                  - c:\cfn\cfn-hup.conf
                  - c:\cfn\hooks.d\cfn-auto-reloader.conf
          commands:
            a-set-execution-policy:
              command: !Join
                - ''
                - - powershell.exe -command Set-ExecutionPolicy RemoteSigned -Force
              waitAfterCompletion: '0'
        rename:
          commands:
            1-execute-powershell-script-RenameComputer:
              command: !Join
                - ''
                - - 'powershell.exe -Command Rename-Computer -NewName '
                  - !Ref 'WSFCNode2NetBIOSName'
                  - ' -Restart'
              waitAfterCompletion: forever
        join:
          commands:
            a-set-dns-servers:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"'
                  - 'Get-NetAdapter | Set-DnsClientServerAddress -ServerAddresses '
                  - !Ref 'ADServer2PrivateIp'
                  - ','
                  - !Ref 'ADServer1PrivateIp'
                  - '"'
              waitAfterCompletion: '30'
            b-join-domain:
              command: !Join
                - ''
                - - 'powershell.exe '
                  - -Command "
                  - 'Add-Computer -DomainName '
                  - !Ref 'DomainDNSName'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - -Restart"
              waitAfterCompletion: forever
        installsql:
          files:
            C:\cfn\scripts\WSFC.ps1:
              content: !Join
                - ''
                - - Install-WindowsFeature failover-clustering -IncludeManagementTools
                  - "\n"
            c:\cfn\scripts\OpenWSFCPorts.bat:
              source: https://s3.amazonaws.com/aws-quickstart/quickstart-microsoft-sql/scripts/OpenWSFCPorts.bat
            C:\cfn\scripts\AddUserToGroup.ps1:
              content: !Join
                - ''
                - - Param(
                  - "\n"
                  - '[Parameter(Mandatory=$True)]'
                  - "\n"
                  - '[string]$ServerName,'
                  - "\n"
                  - '[Parameter(Mandatory=$True)]'
                  - "\n"
                  - '[string]$GroupName,'
                  - "\n"
                  - '[Parameter(Mandatory=$True)]'
                  - "\n"
                  - '[string]$DomainNetBIOSName,'
                  - "\n"
                  - '[Parameter(Mandatory=$True)]'
                  - "\n"
                  - '[string]$UserName'
                  - "\n"
                  - )
                  - $de = [ADSI]"WinNT://$ServerName/$GroupName,group"
                  - "\n"
                  - $de.psbase.Invoke("Add",([ADSI]"WinNT://$DomainNetBIOSName/$UserName").path)
                  - "\n"
            C:\Users\Default\Desktop\InstallSQLEE.bat:
              content: !Join
                - ''
                - - powershell.exe -command Install-WindowsFeature NET-Framework-Core
                  - "\n"
                  - powershell.exe -command "dir \\
                  - !Ref 'ADServerNetBIOSName1'
                  - \sqlinstall\*.iso | Mount-DiskImage"
                  - "\n"
                  - powershell.exe -command "Get-Volume | ?{$_.DriveType -eq 'CD-ROM'}
                    | select -ExpandProperty DriveLetter" > %temp%\driveletter.txt
                  - "\n"
                  - SET /p driveletter=<%temp%\driveletter.txt
                  - "\n"
                  - '%driveletter%:\SETUP.EXE '
                  - '/QS '
                  - '/Action=Install '
                  - '/Features=SQLEngine,Replication,FullText,Conn,BOL,ADV_SSMS '
                  - '/INSTANCENAME=MSSQLSERVER '
                  - /SQLSVCACCOUNT="
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'SQLServiceAccount'
                  - '" '
                  - /SQLSVCPASSWORD="
                  - !Ref 'SQLServiceAccountPassword'
                  - '" '
                  - /AGTSVCACCOUNT="
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'SQLServiceAccount'
                  - '" '
                  - /AGTSVCPASSWORD="
                  - !Ref 'SQLServiceAccountPassword'
                  - '" '
                  - /SQLSYSADMINACCOUNTS="
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - '" '
                  - '/SQLUSERDBDIR="D:\MSSQL\DATA" '
                  - '/SQLUSERDBLOGDIR="E:\MSSQL\LOG" '
                  - '/SQLBACKUPDIR="f:\MSSQL\Backup" '
                  - '/SQLTEMPDBDIR="f:\MSSQL\TempDB" '
                  - '/SQLTEMPDBLOGDIR="f:\MSSQL\TempDB" '
                  - /IACCEPTSQLSERVERLICENSETERMS
                  - "\n"
                  - C:\PROGRA~1\MICROS~1\CLIENT~1\ODBC\110\Tools\Binn\SQLCMD.EXE -i
                    c:\cfn\scripts\MaxDOP.sql
          commands:
            a-execute-powershell-script-WSFC:
              command: !Join
                - ''
                - - 'powershell.exe '
                  - -ExecutionPolicy
                  - ' RemoteSigned'
                  - ' C:\cfn\scripts\WSFC.ps1'
              waitAfterCompletion: '0'
            b-open-WSFC-ports:
              command: C:\cfn\scripts\OpenWSFCPorts.bat
            c-execute-powershell-script-AddUserToGroup:
              command: !Join
                - ''
                - - 'powershell.exe '
                  - -ExecutionPolicy
                  - ' RemoteSigned'
                  - ' C:\cfn\scripts\AddUserToGroup.ps1 -UserName '
                  - !Ref 'SQLServiceAccount'
                  - ' -ServerName '
                  - !Ref 'WSFCNode2NetBIOSName'
                  - ' -DomainNetBIOSName '
                  - !Ref 'DomainNetBIOSName'
                  - ' -GroupName "Administrators"'
                  - "\n"
              waitAfterCompletion: '0'
            d-enable-autologon:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"New-ItemProperty -Path ''HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon''
                    -Name AutoAdminLogon -Value 1'
                  - ;
                  - 'New-ItemProperty -Path ''HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon''
                    -Name DefaultUserName -Value '
                  - !Ref 'DomainAdminUser'
                  - '@'
                  - !Ref 'DomainDNSName'
                  - ;
                  - 'New-ItemProperty -Path ''HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon''
                    -Name DefaultPassword -Value '
                  - !Ref 'DomainAdminPassword'
                  - '"'
              waitAfterCompletion: '0'
            e-set-startup-script:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
                    -Name InstallSQL -Value C:\Users\Default\Desktop\InstallSQLEE.bat'
                  - '"'
              waitAfterCompletion: '0'
            f-reboot:
              command: !Join
                - ''
                - - powershell.exe -Command Restart-Computer -Force
              waitAfterCompletion: forever
        configsql:
          files:
            c:\cfn\scripts\InstallWsfc.ps1:
              content: !Join
                - ''
                - - 'New-Cluster -Name WSFCluster1 -Node  '
                  - !Ref 'WSFCNode1NetBIOSName'
                  - ','
                  - !Ref 'WSFCNode2NetBIOSName'
                  - ' -StaticAddress '
                  - !Ref 'WSFCNode1PrivateIp2'
                  - ','
                  - !Ref 'WSFCNode2PrivateIp2'
                  - "\n"
          commands:
            a-set-startup-script:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
                    -Name InstallWSFC -Value ''powershell.exe -ExecutionPolicy RemoteSigned
                    -Command  c:\cfn\scripts\InstallWsfc.ps1'''
                  - '"'
              waitAfterCompletion: '1500'
            b-reboot:
              command: !Join
                - ''
                - - powershell.exe -Command Restart-Computer -Force
              waitAfterCompletion: forever
            c-force-ad-replication:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"Invoke-Command -Scriptblock{ repadmin /syncall /A /e /P } -ComputerName '
                  - !Ref 'ADServerNetBIOSName2'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '300'
            d-create-folder:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"'
                  - 'Invoke-Command -ScriptBlock {New-Item -ItemType directory -Path
                    c:\ -Name witness} -ComputerName '
                  - !Ref 'ADServerNetBIOSName1'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
            e-create-folder2:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"'
                  - 'Invoke-Command -ScriptBlock {New-Item -ItemType directory -Path
                    c:\ -Name replica} -ComputerName '
                  - !Ref 'ADServerNetBIOSName1'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
            f-create-share:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"'
                  - 'Invoke-Command -ScriptBlock { New-SmbShare -Name witness -Path
                    c:\witness -FullAccess everyone } -ComputerName '
                  - !Ref 'ADServerNetBIOSName1'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
            g-create-share2:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"'
                  - 'Invoke-Command -ScriptBlock { New-SmbShare -Name replica -Path
                    c:\replica -FullAccess everyone } -ComputerName '
                  - !Ref 'ADServerNetBIOSName1'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
            h-set-share-permissions:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"'
                  - Invoke-Command -ScriptBlock {
                  - '    $acl = Get-Acl c:\witness;'
                  - '    $rule = New-Object System.Security.AccessControl.FileSystemAccessRule('''
                  - !Ref 'DomainNetBIOSName'
                  - \WSFCluster1$','FullControl', 'ContainerInherit, ObjectInherit',
                    'None', 'Allow');
                  - '    $acl.AddAccessRule($rule);'
                  - '    Set-Acl c:\witness $acl'
                  - '} -ComputerName '
                  - !Ref 'ADServerNetBIOSName1'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
            i-set-share-permissions2:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"'
                  - Invoke-Command -ScriptBlock {
                  - '    $acl = Get-Acl c:\replica;'
                  - '    $rule = New-Object System.Security.AccessControl.FileSystemAccessRule('''
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'SQLServiceAccount'
                  - ''',''FullControl'', ''ContainerInherit, ObjectInherit'', ''None'',
                    ''Allow'');'
                  - '    $acl.AddAccessRule($rule);'
                  - '    Set-Acl c:\replica $acl'
                  - '} -ComputerName '
                  - !Ref 'ADServerNetBIOSName1'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
            j-set-wsfc-cluster-quorum:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"Invoke-Command -Scriptblock{ '
                  - Set-ClusterQuorum -NodeAndFileShareMajority \\
                  - !Ref 'ADServerNetBIOSName1'
                  - \witness
                  - ' } -ComputerName '
                  - !Ref 'WSFCNode2NetBIOSName'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
            k-enable-always-on-node1:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"'
                  - 'Invoke-Command -ScriptBlock {Set-ExecutionPolicy -Scope Process
                    -ExecutionPolicy RemoteSigned;Enable-SqlAlwaysOn -ServerInstance '
                  - !Ref 'WSFCNode1NetBIOSName'
                  - ' -Force} -ComputerName '
                  - !Ref 'WSFCNode1NetBIOSName'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
            l-enable-always-on-node2:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"Invoke-Command -Scriptblock{ '
                  - 'Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned;Enable-SqlAlwaysOn
                    -ServerInstance '
                  - !Ref 'WSFCNode2NetBIOSName'
                  - ' -Force'
                  - ' } -ComputerName '
                  - !Ref 'WSFCNode2NetBIOSName'
                  - ' -Credential '
                  - (New-Object System.Management.Automation.PSCredential('
                  - !Ref 'DomainNetBIOSName'
                  - \
                  - !Ref 'DomainAdminUser'
                  - ''','
                  - '(ConvertTo-SecureString '
                  - !Ref 'DomainAdminPassword'
                  - ' -AsPlainText -Force))) '
                  - '"'
              waitAfterCompletion: '0'
        finalize:
          commands:
            a-cleanup-registry:
              command: !Join
                - ''
                - - 'powershell.exe -Command '
                  - '"Remove-ItemProperty -Path ''HKLM:\SOFTWARE\Microsoft\Windows
                    NT\CurrentVersion\Winlogon'' -Name AutoAdminLogon'
                  - ;
                  - Remove-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
                    -Name DefaultUserName
                  - ;
                  - Remove-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
                    -Name DefaultPassword
                  - '"'
              waitAfterCompletion: '0'
            b-signal-success:
              command: !Join
                - ''
                - - cfn-signal.exe -e 0 "
                  - !Ref 'WSFCNode2WaitHandle'
                  - '"'
    Properties:
      ImageId: !FindInMap
        - AWSAMIRegionMap
        - !Ref 'AWS::Region'
        - WS2012R2
      InstanceType: !Ref 'WSFCNode2InstanceType'
      EbsOptimized: true
      NetworkInterfaces:
        - DeleteOnTermination: true
          DeviceIndex: "0"
          SubnetId: !Ref 'PrivateSubnet2Id'
          PrivateIpAddresses:
            - Primary: true
              PrivateIpAddress: !Ref 'WSFCNode2PrivateIp'
            - Primary: false
              PrivateIpAddress: !Ref 'WSFCNode2PrivateIp2'
            - Primary: false
              PrivateIpAddress: !Ref 'WSFCNode2PrivateIp3'
          GroupSet:
            - !Ref 'DomainMemberSGID'
            - !Ref 'WSFCSecurityGroup'
            - !Ref 'WSFCClientSecurityGroup'
      Tags:
        - Key: Name
          Value: !Ref 'WSFCNode2NetBIOSName'
      BlockDeviceMappings:
        - DeviceName: /dev/sda1
          Ebs:
            VolumeSize: 100
            VolumeType: gp2
            Encrypted: true
        - DeviceName: /dev/xvdca
          VirtualName: ephemeral0
      Volumes:
        - VolumeId: !Ref 'WSFCNode2Volume1'
          Device: /dev/xvdb
        - VolumeId: !Ref 'WSFCNode2Volume2'
          Device: /dev/xvdc
        - VolumeId: !Ref 'WSFCNode2Volume3'
          Device: /dev/xvdd
      KeyName: !Ref 'KeyPairName'
      UserData: !Base64
        Fn::Join:
          - ''
          - - "<script>\n"
            - 'cfn-init.exe -v -c config -s '
            - !Ref 'AWS::StackId'
            - ' -r WSFCNode2 '
            - ' --region '
            - !Ref 'AWS::Region'
            - "\n"
            - </script>
  WSFCNode1Volume1:
    Type: AWS::EC2::Volume
    Properties:
      Size: 500
      VolumeType: gp2
      Encrypted: true
      AvailabilityZone: !Select
        - 0
        - !GetAZs ''
  WSFCNode1Volume2:
    Type: AWS::EC2::Volume
    Properties:
      Size: 500
      VolumeType: gp2
      Encrypted: true
      AvailabilityZone: !Select
        - 0
        - !GetAZs ''
  WSFCNode1Volume3:
    Type: AWS::EC2::Volume
    Properties:
      Size: 500
      VolumeType: gp2
      Encrypted: true
      AvailabilityZone: !Select
        - 0
        - !GetAZs ''
  WSFCNode2Volume1:
    Type: AWS::EC2::Volume
    Properties:
      Size: 500
      VolumeType: gp2
      Encrypted: true
      AvailabilityZone: !Select
        - 1
        - !GetAZs ''
  WSFCNode2Volume2:
    Type: AWS::EC2::Volume
    Properties:
      Size: 500
      VolumeType: gp2
      Encrypted: true
      AvailabilityZone: !Select
        - 1
        - !GetAZs ''
  WSFCNode2Volume3:
    Type: AWS::EC2::Volume
    Properties:
      Size: 500
      VolumeType: gp2
      Encrypted: true
      AvailabilityZone: !Select
        - 1
        - !GetAZs ''
  WSFCSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable the WSFC and SQL AlwaysOn Availability Group communications
      VpcId: !Ref 'VPC'
      SecurityGroupIngress:
        - IpProtocol: icmp
          FromPort: -1
          ToPort: -1
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: icmp
          FromPort: -1
          ToPort: -1
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: tcp
          FromPort: 135
          ToPort: 135
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: tcp
          FromPort: 135
          ToPort: 135
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: tcp
          FromPort: 137
          ToPort: 137
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: tcp
          FromPort: 137
          ToPort: 137
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: tcp
          FromPort: 445
          ToPort: 445
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: tcp
          FromPort: 445
          ToPort: 445
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: tcp
          FromPort: 1433
          ToPort: 1433
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: tcp
          FromPort: 1433
          ToPort: 1433
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: tcp
          FromPort: 3343
          ToPort: 3343
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: tcp
          FromPort: 3343
          ToPort: 3343
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: tcp
          FromPort: 5022
          ToPort: 5022
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: tcp
          FromPort: 5022
          ToPort: 5022
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: tcp
          FromPort: 5985
          ToPort: 5985
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: tcp
          FromPort: 5985
          ToPort: 5985
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: tcp
          FromPort: 49152
          ToPort: 65535
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: tcp
          FromPort: 49152
          ToPort: 65535
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: udp
          FromPort: 137
          ToPort: 137
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: udp
          FromPort: 137
          ToPort: 137
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: udp
          FromPort: 3343
          ToPort: 3343
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: udp
          FromPort: 3343
          ToPort: 3343
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: udp
          FromPort: 49152
          ToPort: 65535
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: udp
          FromPort: 49152
          ToPort: 65535
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: tcp
          FromPort: 1433
          ToPort: 1434
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: tcp
          FromPort: 1433
          ToPort: 1434
          CidrIp: !Ref 'PrivSub2CIDR'
        - IpProtocol: tcp
          FromPort: 1433
          ToPort: 1434
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: tcp
          FromPort: 1433
          ToPort: 1434
          CidrIp: !Ref 'PrivSub2CIDR'
  WSFCClientSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SQL Client Connections from instances inside the VPC
      VpcId: !Ref 'VPC'
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 1433
          ToPort: 1433
          CidrIp: !Ref 'PrivSub1CIDR'
        - IpProtocol: tcp
          FromPort: 1433
          ToPort: 1433
          CidrIp: !Ref 'PrivSub2CIDR'
Outputs:
  DomainAdmin:
    Value: !Join
      - ''
      - - !Ref 'DomainNetBIOSName'
        - \
        - !Ref 'DomainAdminUser'
    Description: Domain administrator account
  LocalAdmin:
    Value: Administrator
    Description: Please retrieve Administrator password of the instance
  WSFCNode1NetBIOSName:
    Value: !Ref 'WSFCNode1NetBIOSName'
    Description: NetBIOS name of the 1st WSFC Node
  WSFCNode2NetBIOSName:
    Value: !Ref 'WSFCNode2NetBIOSName'
    Description: NetBIOS name of the 2nd WSFC Node