AWSTemplateFormatVersion: '2010-09-09'
Description: >-
  This template creates a VPC infrastructure for a multi-AZ, multi-tier deployment
  of a Windows based Application infrastructure. It will deploy
  managed NAT gateways into the public subnet for each Availability
  Zone. **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-1rudc1sbj)
Metadata:
  QuickStartDocumentation:
    EntrypointName: "Parameters for deploying into an existing VPC"
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Network configuration
        Parameters:
          - VPCID
          - VPCCIDR
          - PublicSubnet1ID
          - PublicSubnet2ID
          - PrivateSubnet1AID
          - PrivateSubnet2AID
      - Label:
          default: Amazon EC2 configuration
        Parameters:
          - KeyPairName
          - RDGWInstanceType
      - Label:
          default: Microsoft Remote Desktop Gateway configuration
        Parameters:
          - NumberOfRDGWHosts
          - AdminUser
          - AdminPassword
          - DomainDNSName
          - RDGWCIDR
      - Label:
          default: AWS License Manager configuration
        Parameters:
          - LMConfigRuleName
          - LicenseCountingType
          - LicenseCount
          - LicenseCountHardLimit
          - PlatformName
          - PlatformVersion
      - Label:
          default: Host resource group configuration
        Parameters:
          - HostResourceGroupName
          - AllowedInstanceFamily
          - AutoAllocateHost
          - AutoRecoverHost
          - AutoReleaseHost
      - Label:
          default: BYOL configuration
        Parameters:
          - BYOLAMI
          - BYOLInstanceType
          - NumberOfBYOLInstances
      - Label:
          default: AWS Quick Start configuration
        Parameters:
          - QSS3BucketName
          - QSS3KeyPrefix
          - QSS3BucketRegion
    ParameterLabels:
      AdminPassword:
        default: Admin password
      AdminUser:
        default: Admin user name
      DomainDNSName:
        default: Domain DNS name
      AutoAllocateHost:
        default: Automatically allocate host
      AutoRecoverHost:
        default: Automatically recover host
      AutoReleaseHost:
        default: Automatically release host
      KeyPairName:
        default: Key pair name
      NumberOfBYOLInstances:
        default: Number of BYOL instances
      BYOLInstanceType:
        default: BYOL instance type
      BYOLAMI:
        default: BYOL instance AMI
      HostResourceGroupName:
        default: Host resource group name
      LMConfigRuleName:
        default: LCM config rule name
      LicenseCountingType:
        default: License counting type
      LicenseCount:
        default: License count
      LicenseCountHardLimit:
        default: License count hard limit
      NumberOfRDGWHosts:
        default: Number of Remote Desktop Gateway hosts
      PlatformName:
        default: Platform name
      PlatformVersion:
        default: Platform version
      AllowedInstanceFamily:
        default: Allowed instance family
      QSS3BucketName:
        default: Quick Start S3 bucket name
      QSS3KeyPrefix:
        default: Quick Start S3 key prefix
      QSS3BucketRegion:
        default: Quick Start S3 bucket Region
      RDGWInstanceType:
        default: Remote Desktop Gateway instance type
      RDGWCIDR:
        default: Allowed Remote Desktop Gateway external access CIDR
      VPCCIDR:
        default: VPC CIDR
      PublicSubnet1ID:
        default: Public subnet 1 ID
      PublicSubnet2ID:
        default: Public subnet 2 ID
      PrivateSubnet1AID:
        default: Private subnet 1 ID
      PrivateSubnet2AID:
        default: Private subnet 2 ID
      VPCID:
        default: VPC ID
Parameters:
  AdminPassword:
    Description: Password for the administrative 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'
  AdminUser:
    Description: User name for the new local administrator account.
    Type: String
    Default: StackAdmin
    MinLength: '5'
    MaxLength: '25'
    AllowedPattern: '[a-zA-Z0-9]*'
  DomainDNSName:
    Description: Fully qualified domain name (FQDN), such as example.com.
    Type: String
    Default: example.com
    MinLength: '2'
    MaxLength: '255'
    AllowedPattern: '[a-zA-Z0-9\-]+\..+'
  KeyPairName:
    Description: Public/private key pairs allow you to securely connect to your instance
      after it launches.
    Type: AWS::EC2::KeyPair::KeyName
  NumberOfRDGWHosts:
    AllowedValues:
      - '0'
      - '1'
      - '2'
      - '3'
      - '4'
    Default: '1'
    Description: The number of Remote Desktop Gateway hosts to create. If set to 0, the
      Remote Desktop Gateway Auto Scaling group is not created.
    Type: String
  NumberOfBYOLInstances:
    AllowedValues:
      - '0'
      - '1'
      - '2'
      - '4'
    Default: '0'
    Description: The number of BYOL instances to launch.
    Type: String
  QSS3BucketName:
    AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$
    ConstraintDescription: The Quick Start bucket name can include numbers, lowercase
      letters, uppercase letters, and hyphens (-). It cannot start or end with a 
      hyphen (-).
    Default: aws-quickstart
    Description: Name of the S3 bucket for your copy of the Quick Start assets. 
      Keep the default name unless you are customizing the template. 
      Changing the name updates code references to point to a new Quick 
      Start location. This name can include numbers, lowercase letters, 
      uppercase letters, and hyphens, but do not start or end with a hyphen (-). 
      See https://aws-quickstart.github.io/option1.html.
    Type: String
  QSS3KeyPrefix:
    AllowedPattern: ^[0-9a-zA-Z-/]*$
    ConstraintDescription: The Quick Start S3 key prefix can include numbers, lowercase letters,
      uppercase letters, hyphens (-), and forward slash (/).
    Default: quickstart-microsoft-dedicated-host/
    Description: S3 key prefix that is used to simulate a directory for your copy of the 
      Quick Start assets. Keep the default prefix unless you are customizing 
      the template. Changing this prefix updates code references to point to 
      a new Quick Start location. This prefix can include numbers, lowercase 
      letters, uppercase letters, hyphens (-), and forward slashes (/). 
      See https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html 
      and https://aws-quickstart.github.io/option1.html.
    Type: String
  QSS3BucketRegion:
    Default: 'us-east-1'
    Description: "Region of staging bucket (BucketName)."
    Type: String
  RDGWInstanceType:
    Description: Amazon EC2 instance type for the Remote Desktop Gateway instances.
    Type: String
    Default: t3.2xlarge
    AllowedValues:
      - t2.large
      - t3.micro
      - t3.small
      - t3.medium
      - t3.large
      - t3.xlarge
      - t3.2xlarge
      - t3a.micro
      - t3a.small
      - t3a.medium
      - t3a.large
      - t3a.xlarge
      - t3a.2xlarge
      - m5.large
      - m5.xlarge
      - m5.2xlarge
      - m5a.large
      - m5a.xlarge
      - m5a.2xlarge
  BYOLInstanceType:
    Description: Amazon EC2 instance type for BYOL instances.
    Type: String
    Default: c5.xlarge
    AllowedValues:
      - c5.xlarge
      - c5.2xlarge
      - r5.xlarge
      - r5.2xlarge
      - m5.xlarge
      - m5.2xlarge
  BYOLAMI:
    Default: 'ami-077f1edd46ddb3129'
    Description: "AMI ID."
    Type: String
  RDGWCIDR:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x.
    Description: Allowed CIDR block for external access to the Remote Desktop Gateway instances.
    Type: String
  VPCCIDR:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28.
    Default: 10.0.0.0/16
    Description: CIDR block for the VPC.
    Type: String
  VPCID:
    Description: ID of the VPC (for example, vpc-0343606e).
    Type: AWS::EC2::VPC::Id
  PublicSubnet1ID:
    Description: ID of the public subnet 1 that you want to provision the first Remote
      Desktop Gateway into (for example, subnet-a0246dcd).
    Type: AWS::EC2::Subnet::Id
  PublicSubnet2ID:
    Description: ID of the public subnet 2 you want to provision the second Remote
      Desktop Gateway into (for example, subnet-e3246d8e).
    Type: AWS::EC2::Subnet::Id
  PrivateSubnet1AID:
    Description: ID of the private subnet 1 you want to provision the second Remote
      Desktop Gateway into (for example, subnet-e3246d8e).
    Type: AWS::EC2::Subnet::Id
  PrivateSubnet2AID:
    Description: ID of the Private subnet 2 that you want to provision the first Remote
      Desktop Gateway into (for example, subnet-a0246dcd).
    Type: AWS::EC2::Subnet::Id
  HostResourceGroupName:
    Default: 'WindowsHost'
    Description: "The host resource group name."
    Type: String
  LMConfigRuleName:
    Default: 'demorule'
    Description: "The license configuration rule name."
    Type: String
  LicenseCountingType:
    Default: 'Core'
    Description: "The license type."
    AllowedValues:
      - Core
      - vCPU
    Type: String
  LicenseCount:
    Default: 100
    Description: "The total license count."
    Type: Number
  LicenseCountHardLimit:
    Default: 'true'
    Description: "Specify whether a hard limit exists for the license count."
    AllowedValues:
      - true
      - false
    Type: String
  PlatformName:
    Default: windows-server-datacenter
    Description: "The platform name."
    AllowedValues:
      - windows-server-datacenter
    Type: String
  PlatformVersion:
    Default: '2016'
    Description: "The platform version."
    AllowedValues:
      - '2016'
      - '2012'
      - '2008'
      - '2008 R2'
    Type: String
  AllowedInstanceFamily:
    Default: 'c5'
    Description: "The allowed instance family."
    AllowedValues:
      - c5
      - r5
      - m5
    Type: String
  AutoAllocateHost:
    Default: 'true'
    Description: "Specify whether to automatically allocate the host."
    AllowedValues:
      - true
      - false
    Type: String
  AutoRecoverHost:
    Default: 'true'
    Description: "Specify whether to automatically recover the host."
    AllowedValues:
      - true
      - false
    Type: String
  AutoReleaseHost:
    Default: 'true'
    Description: "Specify whether to automatically release the host."
    AllowedValues:
      - true
      - false
    Type: String
Rules:
  ValidC5InstanceType:
    RuleCondition: !Equals
      - !Ref AllowedInstanceFamily
      - c5
    Assertions:
      - Assert: !Or
        - !Equals [!Ref BYOLInstanceType, 'c5.xlarge']
        - !Equals [!Ref BYOLInstanceType, 'c5.2xlarge']
        AssertDescription: "Instance type must match instance family"
  ValidR5InstanceType:
    RuleCondition: !Equals
      - !Ref AllowedInstanceFamily
      - r5
    Assertions:
      - Assert: !Or
        - !Equals [!Ref BYOLInstanceType, 'r5.xlarge']
        - !Equals [!Ref BYOLInstanceType, 'r5.2xlarge']
        AssertDescription: "Instance type must match instance family"
  ValidM5InstanceType:
    RuleCondition: !Equals
      - !Ref AllowedInstanceFamily
      - m5
    Assertions:
      - Assert: !Or
        - !Equals [!Ref BYOLInstanceType, 'm5.xlarge']
        - !Equals [!Ref BYOLInstanceType, 'm5.2xlarge']
        AssertDescription: "Instance type must match instance family"
Conditions:
  UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart']
  IncludeRDGW: !Not
    - !Equals
      - !Ref NumberOfRDGWHosts
      - '0'
Resources:
  LMStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: 
        Fn::Sub:
          - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/licensemanager.template.yaml'
          - S3Region: !If [UsingDefaultBucket, !Sub '${AWS::Region}', !Ref QSS3BucketRegion]
            S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]
      Parameters:
        LMConfigRuleName: !Ref 'LMConfigRuleName'
        LicenseCountingType: !Ref 'LicenseCountingType'
        LicenseCount: !Ref 'LicenseCount'
        LicenseCountHardLimit: !Ref 'LicenseCountHardLimit'
        HostResourceGroupName: !Ref 'HostResourceGroupName'
        AllowedInstanceFamily: !Ref 'AllowedInstanceFamily'
        AutoAllocateHost: !Ref 'AutoAllocateHost'
        AutoRecoverHost: !Ref 'AutoRecoverHost'
        AutoReleaseHost: !Ref 'AutoReleaseHost'
        PlatformName: !Ref 'PlatformName'
        PlatformVersion: !Ref 'PlatformVersion'
  DHStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: 
        Fn::Sub:
          - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/dedicatedhost.template.yaml'
          - S3Region: !If [UsingDefaultBucket, !Sub '${AWS::Region}', !Ref QSS3BucketRegion]
            S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]
      Parameters:
        AdminPassword: !Ref 'AdminPassword'
        NumberOfBYOLInstances: !Ref 'NumberOfBYOLInstances'
        QSS3BucketName: !Ref 'QSS3BucketName'
        QSS3KeyPrefix: !Ref 'QSS3KeyPrefix'
        QSS3BucketRegion: !Ref QSS3BucketRegion
        LicenseArn: !GetAtt 'LMStack.Outputs.LicenseArn'
        GroupArn: !GetAtt 'LMStack.Outputs.GroupArn'
        PrivateSubnet1AID: !Ref 'PrivateSubnet1AID'
        PrivateSubnet2AID: !Ref 'PrivateSubnet2AID'
        BYOLAMI: !Ref 'BYOLAMI'
        BYOLInstanceType: !Ref 'BYOLInstanceType'
        VPCID: !Ref 'VPCID'
        VPCCIDR: !Ref 'VPCCIDR'
  RDGWStack:
    Condition: IncludeRDGW
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL:
        Fn::Sub:
          - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-microsoft-rdgateway/templates/rdgw-standalone.template'
          - S3Region: !If [UsingDefaultBucket, !Sub '${AWS::Region}', !Ref QSS3BucketRegion]
            S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]
      Parameters:
        AdminUser: !Ref 'AdminUser'
        AdminPassword: !Ref 'AdminPassword'
        DomainDNSName: !Ref 'DomainDNSName'
        KeyPairName: !Ref 'KeyPairName'
        NumberOfRDGWHosts: !Ref 'NumberOfRDGWHosts'
        PublicSubnet1ID: !Ref 'PublicSubnet1ID'
        PublicSubnet2ID: !Ref 'PublicSubnet2ID'
        QSS3BucketName: !Ref 'QSS3BucketName'
        QSS3BucketRegion: !Ref 'QSS3BucketRegion'
        QSS3KeyPrefix: !Sub '${QSS3KeyPrefix}submodules/quickstart-microsoft-rdgateway/'
        RDGWInstanceType: !Ref 'RDGWInstanceType'
        RDGWCIDR: !Ref 'RDGWCIDR'
        VPCID: !Ref 'VPCID'