templates/mssqlfsx-mad.template.yaml [600:894]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            type: "String"
          SqlFSxInstanceId: 
            default: ""
            description: "ID of the SqlFSx instance"
            type: "String"
          StackName: 
            default: !Sub "${AWS::StackName}"
            description: "CloudFormation stack name"
            type: "String"
          SqlFSxServerNetBIOSName1: 
            default: !Sub "${SqlFSxServerNetBIOSName1}"
            description: "CloudFormation stack name"
            type: "String"            
          AutomationAssumeRole:
            default: ""
            description: "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf."
            type: "String"
          WindowsVersion:
            default: !Sub "${WindowsVersion}"
            description: "The AMI used to deploy SqlFSx instance."
            type: "String"
          URLSuffix:
            description: "AWS URL suffix"
            type: "String"
          QSS3BucketName:
            default: "aws-quickstart"
            description: "S3 bucket name for the Quick Start assets. Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-)."
            type: "String"
          QSS3KeyPrefix:
            default: "quickstart-microsoft-sql/"
            description: "S3 key prefix for the Quick Start assets. Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/)."
            type: "String"
        mainSteps:
        #Getting cluster infrastructure resources
        - name: FindFSxVolDnsAddress
          action: 'aws:executeScript'
          onFailure: "step:signalfailure"
          inputs:
            Runtime: PowerShell Core 6.0
            Script: 
                |
                 Install-Module AWS.Tools.FSx -Force
                 Import-Module AWS.Tools.FSx
                 
                 $fsList = Get-FSXFileSystem; 
                 $fsList.forEach{
                   $tags = $_.Tags; 
                   foreach ($tag in $tags)
                   {
                     if ($tag.key -eq "Name" -And $tag.value -eq "SqlFSxFileSystem")
                     {
                       $dnsName = $_.DNSName;
                       $psEndpoint = $_.WindowsConfiguration.RemoteAdministrationEndpoint
                       break;
                     }
                   }
                 };
                 $resultStr = "{0};{1}" -f $dnsName, $psEndpoint
                 Write-Host $dnsName
                 return @{message=$resultStr}
          outputs:
            - Name: FSxDnsAddress
              Selector: $.Payload.message
              Type: String    
        - name: GetAllClusterNodes
          action: 'aws:executeAwsApi'
          outputs:
            - Name: InstanceIds
              Selector: $.Reservations..Instances..InstanceId
              Type: StringList
          inputs:
            Service: ec2
            Api: DescribeInstances
            Filters:
              - Name: 'tag:FCIName'
                Values:
                  - Ref: SqlFSxFCIName
              - Name: instance-state-name
                Values:
                  - running
          description: Get instances
        - name: GetClusterNode1
          action: 'aws:executeAwsApi'
          outputs:
            - Name: InstanceIds
              Selector: $.Reservations..Instances..InstanceId
              Type: StringList
          inputs:
            Service: ec2
            Api: DescribeInstances
            Filters:
              - Name: 'tag:Name'
                Values:
                  - Ref: SqlFSxServerNetBIOSName1
              - Name: instance-state-name
                Values:
                  - running
          description: Get instances
        - name: GetClusterNode2
          action: 'aws:executeAwsApi'
          outputs:
            - Name: InstanceIds
              Selector: $.Reservations..Instances..InstanceId
              Type: StringList
          inputs:
            Service: ec2
            Api: DescribeInstances
            Filters:
              - Name: 'tag:Name'
                Values:
                  - Ref: SqlFSxServerNetBIOSName2
              - Name: instance-state-name
                Values:
                  - running
          description: Get instances
        - name: FindSecondaryIpAddresses
          action: 'aws:executeScript'
          onFailure: "step:signalfailure"
          inputs:
            Runtime: PowerShell Core 6.0
            Script: 
                |
                 $inputPayload = $env:InputPayload | ConvertFrom-Json;                 
                 Install-Module AWS.Tools.EC2 -Force
                 Import-Module AWS.Tools.EC2
                 
                 #Function to find Subnet
                 function Get-SubnetMask($i)
                 {
                    $instance = $i
                    $subnetid = $instance.instances[0].NetworkInterfaces.SubnetId
                    $subnet = get-ec2subnet -SubnetId $subnetid
                    $cidr = $subnet.CidrBlock
                    $cidr_mask = $cidr.split('/')[1]
                    $A = 0
                    $A_Index = 8
                    $B = 0
                    $B_Index = 16
                    $C = 0
                    $C_Index = 24
                    $D = 0
                    $D_Index = 32
                    for ($i = 1; $i -le $cidr_mask; $i++)
                    {
                        if ($i -le $A_Index)
                        {
                            $A += ([Math]::Pow(2, 8 - $i))
                        }
                        elseif ($i -le $B_Index)
                        {
                            $B += ([Math]::Pow(2, 8 - $i + $A_Index))
                        }
                        elseif ($i -le $C_Index)
                        {
                            $C += ([Math]::Pow(2, 8 - $i + $B_Index))
                        }
                        elseif ($i -le $D_Index)
                        {
                            $D += ([Math]::Pow(2, 8 - $i + $C_Index))
                        }
                    }
                    $subnet_mask = "{0}.{1}.{2}.{3}" -f $A, $B, $C, $D
                    return $subnet_mask
                 }
                 
                 $instanceIds = $inputPayload.parameter
                 
                 $resultStr = ""
                 $subnetMaskStr = ""

                 #Finding secondary IP addresses of the primary instance 
                 foreach ($i in $instanceIds)
                 {               
                   $instance = get-ec2instance -InstanceId $i
                   $tags = $instance.instances[0].Tags
                   foreach ($t in $tags)
                   {
                     if ($t.Key -eq "FCIRole" -And $t.Value -eq "Primary")
                     {
                       $IPs = $instance.instances[0].NetworkInterfaces.PrivateIpAddresses
                       $ip1 = $IPs[1].PrivateIpAddress
                       $ip2 = $IPs[2].PrivateIpAddress
                       $resultStr = "{0};{1}" -f $ip1, $ip2
                       
                       $subnetMaskStr = Get-SubnetMask($instance)
                       break;
                     }                     
                   }
                   if ([System.String]::IsNullOrEmpty($resultStr) -Eq $False)
                   {
                     break;
                   }
                 }
                 
                 #Finding secondary IP addresses of the secondary instance 
                 foreach ($i in $instanceIds)
                 {               
                   $instance = get-ec2instance -InstanceId $i
                   $tags = $instance.instances[0].Tags
                   foreach ($t in $tags)
                   {
                     if ($t.Key -eq "FCIRole" -And $t.Value -eq "Secondary")
                     {
                       $IPs = $instance.instances[0].NetworkInterfaces.PrivateIpAddresses  
                       $ip1 = $IPs[1].PrivateIpAddress
                       $ip2 = $IPs[2].PrivateIpAddress                       
                       $resultStr = "{0};{1};{2}" -f $resultStr, $ip1, $ip2
                       
                       $subnetMask = Get-SubnetMask($instance)
                       $subnetMaskStr = "{0};{1}" -f $subnetMaskStr, $subnetMask
                       break;
                     }                     
                   }
                 }
                 
                 $resultStr = "{0};{1}" -f $resultStr, $subnetMaskStr
                 
                 Write-Host $dnsName
                 return @{message=$resultStr}
            InputPayload:
              parameter: '{{GetAllClusterNodes.InstanceIds}}'
          outputs:
            - Name: SecondaryPrivateIpAddresses
              Selector: $.Payload.message
              Type: String
        #Preparing requisites
        - name: "UpdateSSMAgent"
          action: "aws:runCommand"
          timeoutSeconds: 300
          onFailure: "Continue"
          inputs:
            DocumentName: AWS-UpdateSSMAgent
            InstanceIds: '{{GetAllClusterNodes.InstanceIds}}'
            CloudWatchOutputConfig:
              CloudWatchOutputEnabled: "true"
              CloudWatchLogGroupName: !Ref 'QuickStartLogs'
        - name: "InitializeDisk"
          action: "aws:runCommand"
          onFailure: "step:signalfailure"
          inputs:
            DocumentName: AWS-RunPowerShellScript
            InstanceIds: '{{GetAllClusterNodes.InstanceIds}}'
            CloudWatchOutputConfig:
              CloudWatchOutputEnabled: "true"
              CloudWatchLogGroupName: !Ref 'QuickStartLogs'
            Parameters:
              commands: 
                - |
                   C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeDisks.ps1
        - name: "InstallDSCModules"
          action: "aws:runCommand"
          onFailure: "step:signalfailure"
          inputs:
            DocumentName: "AWS-RunRemoteScript"
            InstanceIds: '{{GetAllClusterNodes.InstanceIds}}'
            CloudWatchOutputConfig:
              CloudWatchOutputEnabled: "true"
              CloudWatchLogGroupName: !Ref 'QuickStartLogs'
            Parameters:
              sourceType: "S3"
              sourceInfo:
                !Sub
                  - '{"path": "https://${S3Bucket}.s3.${S3Region}.{{URLSuffix}}/{{QSS3KeyPrefix}}scripts/install-dsc-modules.ps1"}'
                  - S3Bucket: !If 
                      - UsingDefaultBucket
                      - !Sub '${QSS3BucketName}-${AWS::Region}'
                      - !Ref QSS3BucketName
                    S3Region: !If 
                      - UsingDefaultBucket
                      - !Ref AWS::Region
                      - !Ref QSS3BucketRegion
              commandLine: "./install-dsc-modules.ps1"               
        - name: "wsfcnLCMConfig"
          action: "aws:runCommand"
          onFailure: "step:signalfailure"
          inputs:
            DocumentName: "AWS-RunRemoteScript"
            InstanceIds: '{{GetAllClusterNodes.InstanceIds}}'
            CloudWatchOutputConfig:
              CloudWatchOutputEnabled: "true"
              CloudWatchLogGroupName: !Ref 'QuickStartLogs'
            Parameters:
              sourceType: "S3"
              sourceInfo:
                !Sub
                  - '{"path": "https://${S3Bucket}.s3.${S3Region}.{{URLSuffix}}/{{QSS3KeyPrefix}}scripts/LCM-Config.ps1"}'
                  - S3Bucket: !If 
                      - UsingDefaultBucket
                      - !Sub '${QSS3BucketName}-${AWS::Region}'
                      - !Ref QSS3BucketName
                    S3Region: !If 
                      - UsingDefaultBucket
                      - !Ref AWS::Region
                      - !Ref QSS3BucketRegion
              commandLine: "./LCM-Config.ps1"              
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



templates/mssqlfsx.template.yaml [583:877]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            type: "String"
          SqlFSxInstanceId: 
            default: ""
            description: "ID of the SqlFSx instance"
            type: "String"
          StackName: 
            default: !Sub "${AWS::StackName}"
            description: "CloudFormation stack name"
            type: "String"
          SqlFSxServerNetBIOSName1: 
            default: !Sub "${SqlFSxServerNetBIOSName1}"
            description: "CloudFormation stack name"
            type: "String"            
          AutomationAssumeRole:
            default: ""
            description: "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf."
            type: "String"
          WindowsVersion:
            default: !Sub "${WindowsVersion}"
            description: "The AMI used to deploy SqlFSx instance."
            type: "String"
          URLSuffix:
            description: "AWS URL suffix"
            type: "String"
          QSS3BucketName:
            default: "aws-quickstart"
            description: "S3 bucket name for the Quick Start assets. Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-)."
            type: "String"
          QSS3KeyPrefix:
            default: "quickstart-microsoft-sql/"
            description: "S3 key prefix for the Quick Start assets. Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/)."
            type: "String"
        mainSteps:
        #Getting cluster infrastructure resources
        - name: FindFSxVolDnsAddress
          action: 'aws:executeScript'
          onFailure: "step:signalfailure"
          inputs:
            Runtime: PowerShell Core 6.0
            Script: 
                |
                 Install-Module AWS.Tools.FSx -Force
                 Import-Module AWS.Tools.FSx
                 
                 $fsList = Get-FSXFileSystem; 
                 $fsList.forEach{
                   $tags = $_.Tags; 
                   foreach ($tag in $tags)
                   {
                     if ($tag.key -eq "Name" -And $tag.value -eq "SqlFSxFileSystem")
                     {
                       $dnsName = $_.DNSName;
                       $psEndpoint = $_.WindowsConfiguration.RemoteAdministrationEndpoint
                       break;
                     }
                   }
                 };
                 $resultStr = "{0};{1}" -f $dnsName, $psEndpoint
                 Write-Host $dnsName
                 return @{message=$resultStr}
          outputs:
            - Name: FSxDnsAddress
              Selector: $.Payload.message
              Type: String    
        - name: GetAllClusterNodes
          action: 'aws:executeAwsApi'
          outputs:
            - Name: InstanceIds
              Selector: $.Reservations..Instances..InstanceId
              Type: StringList
          inputs:
            Service: ec2
            Api: DescribeInstances
            Filters:
              - Name: 'tag:FCIName'
                Values:
                  - Ref: SqlFSxFCIName
              - Name: instance-state-name
                Values:
                  - running
          description: Get instances
        - name: GetClusterNode1
          action: 'aws:executeAwsApi'
          outputs:
            - Name: InstanceIds
              Selector: $.Reservations..Instances..InstanceId
              Type: StringList
          inputs:
            Service: ec2
            Api: DescribeInstances
            Filters:
              - Name: 'tag:Name'
                Values:
                  - Ref: SqlFSxServerNetBIOSName1
              - Name: instance-state-name
                Values:
                  - running
          description: Get instances
        - name: GetClusterNode2
          action: 'aws:executeAwsApi'
          outputs:
            - Name: InstanceIds
              Selector: $.Reservations..Instances..InstanceId
              Type: StringList
          inputs:
            Service: ec2
            Api: DescribeInstances
            Filters:
              - Name: 'tag:Name'
                Values:
                  - Ref: SqlFSxServerNetBIOSName2
              - Name: instance-state-name
                Values:
                  - running
          description: Get instances
        - name: FindSecondaryIpAddresses
          action: 'aws:executeScript'
          onFailure: "step:signalfailure"
          inputs:
            Runtime: PowerShell Core 6.0
            Script: 
                |
                 $inputPayload = $env:InputPayload | ConvertFrom-Json;                 
                 Install-Module AWS.Tools.EC2 -Force
                 Import-Module AWS.Tools.EC2
                 
                 #Function to find Subnet
                 function Get-SubnetMask($i)
                 {
                    $instance = $i
                    $subnetid = $instance.instances[0].NetworkInterfaces.SubnetId
                    $subnet = get-ec2subnet -SubnetId $subnetid
                    $cidr = $subnet.CidrBlock
                    $cidr_mask = $cidr.split('/')[1]
                    $A = 0
                    $A_Index = 8
                    $B = 0
                    $B_Index = 16
                    $C = 0
                    $C_Index = 24
                    $D = 0
                    $D_Index = 32
                    for ($i = 1; $i -le $cidr_mask; $i++)
                    {
                        if ($i -le $A_Index)
                        {
                            $A += ([Math]::Pow(2, 8 - $i))
                        }
                        elseif ($i -le $B_Index)
                        {
                            $B += ([Math]::Pow(2, 8 - $i + $A_Index))
                        }
                        elseif ($i -le $C_Index)
                        {
                            $C += ([Math]::Pow(2, 8 - $i + $B_Index))
                        }
                        elseif ($i -le $D_Index)
                        {
                            $D += ([Math]::Pow(2, 8 - $i + $C_Index))
                        }
                    }
                    $subnet_mask = "{0}.{1}.{2}.{3}" -f $A, $B, $C, $D
                    return $subnet_mask
                 }
                 
                 $instanceIds = $inputPayload.parameter
                 
                 $resultStr = ""
                 $subnetMaskStr = ""

                 #Finding secondary IP addresses of the primary instance 
                 foreach ($i in $instanceIds)
                 {               
                   $instance = get-ec2instance -InstanceId $i
                   $tags = $instance.instances[0].Tags
                   foreach ($t in $tags)
                   {
                     if ($t.Key -eq "FCIRole" -And $t.Value -eq "Primary")
                     {
                       $IPs = $instance.instances[0].NetworkInterfaces.PrivateIpAddresses
                       $ip1 = $IPs[1].PrivateIpAddress
                       $ip2 = $IPs[2].PrivateIpAddress
                       $resultStr = "{0};{1}" -f $ip1, $ip2
                       
                       $subnetMaskStr = Get-SubnetMask($instance)
                       break;
                     }                     
                   }
                   if ([System.String]::IsNullOrEmpty($resultStr) -Eq $False)
                   {
                     break;
                   }
                 }
                 
                 #Finding secondary IP addresses of the secondary instance 
                 foreach ($i in $instanceIds)
                 {               
                   $instance = get-ec2instance -InstanceId $i
                   $tags = $instance.instances[0].Tags
                   foreach ($t in $tags)
                   {
                     if ($t.Key -eq "FCIRole" -And $t.Value -eq "Secondary")
                     {
                       $IPs = $instance.instances[0].NetworkInterfaces.PrivateIpAddresses  
                       $ip1 = $IPs[1].PrivateIpAddress
                       $ip2 = $IPs[2].PrivateIpAddress                       
                       $resultStr = "{0};{1};{2}" -f $resultStr, $ip1, $ip2
                       
                       $subnetMask = Get-SubnetMask($instance)
                       $subnetMaskStr = "{0};{1}" -f $subnetMaskStr, $subnetMask
                       break;
                     }                     
                   }
                 }
                 
                 $resultStr = "{0};{1}" -f $resultStr, $subnetMaskStr
                 
                 Write-Host $dnsName
                 return @{message=$resultStr}
            InputPayload:
              parameter: '{{GetAllClusterNodes.InstanceIds}}'
          outputs:
            - Name: SecondaryPrivateIpAddresses
              Selector: $.Payload.message
              Type: String
        #Preparing requisites
        - name: "UpdateSSMAgent"
          action: "aws:runCommand"
          timeoutSeconds: 300
          onFailure: "Continue"
          inputs:
            DocumentName: AWS-UpdateSSMAgent
            InstanceIds: '{{GetAllClusterNodes.InstanceIds}}'
            CloudWatchOutputConfig:
              CloudWatchOutputEnabled: "true"
              CloudWatchLogGroupName: !Ref 'QuickStartLogs'
        - name: "InitializeDisk"
          action: "aws:runCommand"
          onFailure: "step:signalfailure"
          inputs:
            DocumentName: AWS-RunPowerShellScript
            InstanceIds: '{{GetAllClusterNodes.InstanceIds}}'
            CloudWatchOutputConfig:
              CloudWatchOutputEnabled: "true"
              CloudWatchLogGroupName: !Ref 'QuickStartLogs'
            Parameters:
              commands: 
                - |
                   C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeDisks.ps1
        - name: "InstallDSCModules"
          action: "aws:runCommand"
          onFailure: "step:signalfailure"
          inputs:
            DocumentName: "AWS-RunRemoteScript"
            InstanceIds: '{{GetAllClusterNodes.InstanceIds}}'
            CloudWatchOutputConfig:
              CloudWatchOutputEnabled: "true"
              CloudWatchLogGroupName: !Ref 'QuickStartLogs'
            Parameters:
              sourceType: "S3"
              sourceInfo:
                !Sub
                  - '{"path": "https://${S3Bucket}.s3.${S3Region}.{{URLSuffix}}/{{QSS3KeyPrefix}}scripts/install-dsc-modules.ps1"}'
                  - S3Bucket: !If 
                      - UsingDefaultBucket
                      - !Sub '${QSS3BucketName}-${AWS::Region}'
                      - !Ref QSS3BucketName
                    S3Region: !If 
                      - UsingDefaultBucket
                      - !Ref AWS::Region
                      - !Ref QSS3BucketRegion
              commandLine: "./install-dsc-modules.ps1"               
        - name: "wsfcnLCMConfig"
          action: "aws:runCommand"
          onFailure: "step:signalfailure"
          inputs:
            DocumentName: "AWS-RunRemoteScript"
            InstanceIds: '{{GetAllClusterNodes.InstanceIds}}'
            CloudWatchOutputConfig:
              CloudWatchOutputEnabled: "true"
              CloudWatchLogGroupName: !Ref 'QuickStartLogs'
            Parameters:
              sourceType: "S3"
              sourceInfo:
                !Sub
                  - '{"path": "https://${S3Bucket}.s3.${S3Region}.{{URLSuffix}}/{{QSS3KeyPrefix}}scripts/LCM-Config.ps1"}'
                  - S3Bucket: !If 
                      - UsingDefaultBucket
                      - !Sub '${QSS3BucketName}-${AWS::Region}'
                      - !Ref QSS3BucketName
                    S3Region: !If 
                      - UsingDefaultBucket
                      - !Ref AWS::Region
                      - !Ref QSS3BucketRegion
              commandLine: "./LCM-Config.ps1"              
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



