templates/mssqlfsx-mad.template.yaml [354:565]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      SecretString: !Sub '{ "username" : "${DomainAdminUser}", "password" : "${DomainAdminPassword}" }'
  QuickStartLogs:
    Type: AWS::Logs::LogGroup
    Properties: 
      LogGroupName: !Sub '/aws/Quick_Start/${AWS::StackName}'
      RetentionInDays: 30
  WindowsBaseAMIInfo:
    Type: Custom::WindowsBaseAMIInfo
    Properties:
      ServiceToken:
        Fn::GetAtt:
        - AMIInfoFunction
        - Arn
      Region:
        Ref: AWS::Region
      AMIName: !Ref WindowsVersion
  AMIInfoFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile:
          Fn::Join:
          - ''
          - - "/**\n"
            - "* A Lambda function that looks up the latest AMI ID for a given region
              and architecture.\n"
            - "**/\n"
            - 'var aws = require("aws-sdk");'
            - 'exports.handler = function(event, context) {'
            - '    console.log("REQUEST RECEIVED:\n" + JSON.stringify(event));'
            - "    // For Delete requests, immediately send a SUCCESS response.\n"
            - '    if (event.RequestType == "Delete") {'
            - '        sendResponse(event, context, "SUCCESS");'
            - "        return;\n"
            - "    }\n"
            - '    var responseStatus = "FAILED";'
            - "    var responseData = {};\n"
            - "    var ec2 = new aws.EC2({region: event.ResourceProperties.Region});\n"
            - "    var describeImagesParams = {\n"
            - '        Filters: [{ Name: "name", Values: [event.ResourceProperties.AMIName]}],'
            - '        Owners: ["amazon"]'
            - "    };\n"
            - "    // Get AMI IDs with the specified name pattern and owner\n"
            - "    ec2.describeImages(describeImagesParams, function(err, describeImagesResult)
              {\n"
            - "        if (err) {\n"
            - '            responseData = {Error: "DescribeImages call failed"};'
            - '            console.log(responseData.Error + ":\n", err);'
            - "        }\n"
            - "        else {\n"
            - "            var images = describeImagesResult.Images;\n"
            - "            // Sort images by name in decscending order. The names
              contain the AMI version, formatted as YYYY.MM.Ver.\n"
            - "            images.sort(function(x, y) { return y.CreationDate.localeCompare(x.CreationDate);
              });\n"
            - "            for (var j = 0; j < images.length; j++) {\n"
            - "                if (isBeta(images[j].Name)) continue;\n"
            - '                responseStatus = "SUCCESS";'
            - '                responseData["Id"] = images[j].ImageId;'
            - "                break;\n"
            - "            }\n"
            - "        }\n"
            - "        sendResponse(event, context, responseStatus, responseData);\n"
            - "    });\n"
            - "};\n"
            - "\n"
            - "// Check if the image is a beta or rc image. The Lambda function won't
              return any of those images.\n"
            - 'function isBeta(imageName) {'
            - '    return imageName.toLowerCase().indexOf("beta") > -1 || imageName.toLowerCase().indexOf(".rc")
              > -1;'
            - "}\n"
            - "// Send response to the pre-signed S3 URL \n"
            - 'function sendResponse(event, context, responseStatus, responseData)
              {'
            - "    var responseBody = JSON.stringify({\n"
            - "        Status: responseStatus,\n"
            - '        Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,'
            - "        PhysicalResourceId: context.logStreamName,\n"
            - "        StackId: event.StackId,\n"
            - "        RequestId: event.RequestId,\n"
            - "        LogicalResourceId: event.LogicalResourceId,\n"
            - "        Data: responseData\n"
            - "    });\n"
            - '    console.log("RESPONSE BODY:\n", responseBody);'
            - '    var https = require("https");'
            - '    var url = require("url");'
            - "    var parsedUrl = url.parse(event.ResponseURL);\n"
            - "    var options = {\n"
            - "        hostname: parsedUrl.hostname,\n"
            - "        port: 443,\n"
            - "        path: parsedUrl.path,\n"
            - '        method: "PUT",'
            - "        headers: {\n"
            - '            "content-type": "",'
            - '            "content-length": responseBody.length'
            - "        }\n"
            - "    };\n"
            - '    console.log("SENDING RESPONSE...\n");'
            - "    var request = https.request(options, function(response) {\n"
            - '        console.log("STATUS: " + response.statusCode);'
            - '        console.log("HEADERS: " + JSON.stringify(response.headers));'
            - "        // Tell AWS Lambda that the function execution is done  \n"
            - "        context.done();\n"
            - "    });\n"
            - '    request.on("error", function(error) {'
            - '        console.log("sendResponse Error:" + error);'
            - "        // Tell AWS Lambda that the function execution is done  \n"
            - "        context.done();\n"
            - "    });\n"
            - "    // write data to request body\n"
            - "    request.write(responseBody);\n"
            - "    request.end();\n"
            - "}"
      Handler: index.handler
      Role:
        Fn::GetAtt:
        - AMIInfoFunctionLambdaExecutionRole
        - Arn
      Runtime: nodejs12.x
      Timeout: 30
  AMIInfoFunctionLambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: root
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Resource: arn:aws:logs:*:*:*
          - Effect: Allow
            Action:
            - ec2:DescribeImages
            Resource: "*"
  AWSQuickstartSqlFSxRole:
    Type: AWS::IAM::Role
    Properties:
      Policies:
        - PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Action:
                  - s3:GetObject
                  - s3:ListBucket
                Resource:
                  - !Sub ['arn:${AWS::Partition}:s3:::${S3Bucket}/${QSS3KeyPrefix}*', S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]]
                  - !Sub ['arn:${AWS::Partition}:s3:::${S3Bucket}', S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]]
                Effect: Allow
          PolicyName: aws-quick-start-s3-policy
        - PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - cloudformation:SignalResource
                Resource: !Sub 'arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${AWS::StackName}/*'
              - Effect: Allow
                Action:
                  - ec2:DescribeInstances
                  - ec2:DescribeInstanceStatus
                  - ec2:StopInstances
                  - ec2:StartInstances
                  - ec2:DescribeNetworkInterfaces
                  - ec2:DescribeSubnets
                  - ssm:*
                  - fsx:Describe*
                  - fsx:ListTagsForResource
                Resource: '*'
          PolicyName: SqlFSx-SSM-AutomationExecution
      Path: /
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Principal:
              Service:
                - ec2.amazonaws.com
                - ssm.amazonaws.com
            Effect: Allow
        Version: '2012-10-17'
  SqlFSxAutomation:
    Type: AWS::SSM::Document
    Properties:
      DocumentType: Automation
      Content:
        schemaVersion: "0.3"
        description: Deploy SqlFSx with SSM Automation
        # Role that is utilized to perform the steps within the Automation Document.
        assumeRole: "{{AutomationAssumeRole}}"
        # Gathering parameters needed to configure DCs in the Quick Start
        parameters:
          DomainDNSName: 
            default: !Sub "${DomainDNSName}"
            description: "Fully qualified domain name (FQDN) of the forest root domain."
            type: "String"
          DomainNetBIOSName: 
            default: !Sub "${DomainNetBIOSName}"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



templates/mssqlfsx.template.yaml [346:557]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      SecretString: !Sub '{ "username" : "${DomainAdminUser}", "password" : "${DomainAdminPassword}" }'
  QuickStartLogs:
    Type: AWS::Logs::LogGroup
    Properties: 
      LogGroupName: !Sub '/aws/Quick_Start/${AWS::StackName}'
      RetentionInDays: 30
  WindowsBaseAMIInfo:
    Type: Custom::WindowsBaseAMIInfo
    Properties:
      ServiceToken:
        Fn::GetAtt:
        - AMIInfoFunction
        - Arn
      Region:
        Ref: AWS::Region
      AMIName: !Ref WindowsVersion
  AMIInfoFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile:
          Fn::Join:
          - ''
          - - "/**\n"
            - "* A Lambda function that looks up the latest AMI ID for a given region
              and architecture.\n"
            - "**/\n"
            - 'var aws = require("aws-sdk");'
            - 'exports.handler = function(event, context) {'
            - '    console.log("REQUEST RECEIVED:\n" + JSON.stringify(event));'
            - "    // For Delete requests, immediately send a SUCCESS response.\n"
            - '    if (event.RequestType == "Delete") {'
            - '        sendResponse(event, context, "SUCCESS");'
            - "        return;\n"
            - "    }\n"
            - '    var responseStatus = "FAILED";'
            - "    var responseData = {};\n"
            - "    var ec2 = new aws.EC2({region: event.ResourceProperties.Region});\n"
            - "    var describeImagesParams = {\n"
            - '        Filters: [{ Name: "name", Values: [event.ResourceProperties.AMIName]}],'
            - '        Owners: ["amazon"]'
            - "    };\n"
            - "    // Get AMI IDs with the specified name pattern and owner\n"
            - "    ec2.describeImages(describeImagesParams, function(err, describeImagesResult)
              {\n"
            - "        if (err) {\n"
            - '            responseData = {Error: "DescribeImages call failed"};'
            - '            console.log(responseData.Error + ":\n", err);'
            - "        }\n"
            - "        else {\n"
            - "            var images = describeImagesResult.Images;\n"
            - "            // Sort images by name in decscending order. The names
              contain the AMI version, formatted as YYYY.MM.Ver.\n"
            - "            images.sort(function(x, y) { return y.CreationDate.localeCompare(x.CreationDate);
              });\n"
            - "            for (var j = 0; j < images.length; j++) {\n"
            - "                if (isBeta(images[j].Name)) continue;\n"
            - '                responseStatus = "SUCCESS";'
            - '                responseData["Id"] = images[j].ImageId;'
            - "                break;\n"
            - "            }\n"
            - "        }\n"
            - "        sendResponse(event, context, responseStatus, responseData);\n"
            - "    });\n"
            - "};\n"
            - "\n"
            - "// Check if the image is a beta or rc image. The Lambda function won't
              return any of those images.\n"
            - 'function isBeta(imageName) {'
            - '    return imageName.toLowerCase().indexOf("beta") > -1 || imageName.toLowerCase().indexOf(".rc")
              > -1;'
            - "}\n"
            - "// Send response to the pre-signed S3 URL \n"
            - 'function sendResponse(event, context, responseStatus, responseData)
              {'
            - "    var responseBody = JSON.stringify({\n"
            - "        Status: responseStatus,\n"
            - '        Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,'
            - "        PhysicalResourceId: context.logStreamName,\n"
            - "        StackId: event.StackId,\n"
            - "        RequestId: event.RequestId,\n"
            - "        LogicalResourceId: event.LogicalResourceId,\n"
            - "        Data: responseData\n"
            - "    });\n"
            - '    console.log("RESPONSE BODY:\n", responseBody);'
            - '    var https = require("https");'
            - '    var url = require("url");'
            - "    var parsedUrl = url.parse(event.ResponseURL);\n"
            - "    var options = {\n"
            - "        hostname: parsedUrl.hostname,\n"
            - "        port: 443,\n"
            - "        path: parsedUrl.path,\n"
            - '        method: "PUT",'
            - "        headers: {\n"
            - '            "content-type": "",'
            - '            "content-length": responseBody.length'
            - "        }\n"
            - "    };\n"
            - '    console.log("SENDING RESPONSE...\n");'
            - "    var request = https.request(options, function(response) {\n"
            - '        console.log("STATUS: " + response.statusCode);'
            - '        console.log("HEADERS: " + JSON.stringify(response.headers));'
            - "        // Tell AWS Lambda that the function execution is done  \n"
            - "        context.done();\n"
            - "    });\n"
            - '    request.on("error", function(error) {'
            - '        console.log("sendResponse Error:" + error);'
            - "        // Tell AWS Lambda that the function execution is done  \n"
            - "        context.done();\n"
            - "    });\n"
            - "    // write data to request body\n"
            - "    request.write(responseBody);\n"
            - "    request.end();\n"
            - "}"
      Handler: index.handler
      Role:
        Fn::GetAtt:
        - AMIInfoFunctionLambdaExecutionRole
        - Arn
      Runtime: nodejs12.x
      Timeout: 30
  AMIInfoFunctionLambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: root
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Resource: arn:aws:logs:*:*:*
          - Effect: Allow
            Action:
            - ec2:DescribeImages
            Resource: "*"
  AWSQuickstartSqlFSxRole:
    Type: AWS::IAM::Role
    Properties:
      Policies:
        - PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Action:
                  - s3:GetObject
                  - s3:ListBucket
                Resource:
                  - !Sub ['arn:${AWS::Partition}:s3:::${S3Bucket}/${QSS3KeyPrefix}*', S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]]
                  - !Sub ['arn:${AWS::Partition}:s3:::${S3Bucket}', S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]]
                Effect: Allow
          PolicyName: aws-quick-start-s3-policy
        - PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - cloudformation:SignalResource
                Resource: !Sub 'arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${AWS::StackName}/*'
              - Effect: Allow
                Action:
                  - ec2:DescribeInstances
                  - ec2:DescribeInstanceStatus
                  - ec2:StopInstances
                  - ec2:StartInstances
                  - ec2:DescribeNetworkInterfaces
                  - ec2:DescribeSubnets
                  - ssm:*
                  - fsx:Describe*
                  - fsx:ListTagsForResource
                Resource: '*'
          PolicyName: SqlFSx-SSM-AutomationExecution
      Path: /
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Principal:
              Service:
                - ec2.amazonaws.com
                - ssm.amazonaws.com
            Effect: Allow
        Version: '2012-10-17'
  SqlFSxAutomation:
    Type: AWS::SSM::Document
    Properties:
      DocumentType: Automation
      Content:
        schemaVersion: "0.3"
        description: Deploy SqlFSx with SSM Automation
        # Role that is utilized to perform the steps within the Automation Document.
        assumeRole: "{{AutomationAssumeRole}}"
        # Gathering parameters needed to configure DCs in the Quick Start
        parameters:
          DomainDNSName: 
            default: !Sub "${DomainDNSName}"
            description: "Fully qualified domain name (FQDN) of the forest root domain."
            type: "String"
          DomainNetBIOSName: 
            default: !Sub "${DomainNetBIOSName}"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



