AWSTemplateFormatVersion: '2010-09-09' Description: >- This template is intended to be installed into an existing VPC with two public subnets. It will create an auto-scaling group of RD Gateway instances in the public VPC subnets. It will also create an auto-scaling group of Dedicated hosts in the private VPC subnets. **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. Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Network configuration Parameters: - VPCID - PublicSubnet1ID - PublicSubnet2ID - RDGWCIDR - Label: default: Amazon EC2 configuration Parameters: - KeyPairName - RDGWInstanceType - LatestAmiId - Label: default: Microsoft Remote Desktop Gateway configuration Parameters: - NumberOfRDGWHosts - AdminUser - AdminPassword - DomainDNSName - 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 KeyPairName: default: Key pair name LatestAmiId: default: SSM parameter to grab latest AMI ID NumberOfRDGWHosts: default: Number of RDGW hosts PublicSubnet1ID: default: Public subnet 1 ID PublicSubnet2ID: default: Public subnet 2 ID 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 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\-]+\..+' LicenseArn: Description: specify license arn Type: String GroupArn: Description: specify group arn Type: String KeyPairName: Description: Public/private key pairs allow you to securely connect to your instance after it launches. Type: AWS::EC2::KeyPair::KeyName LatestAmiId: Type: AWS::SSM::Parameter::Value Default: /aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base NumberOfRDGWHosts: AllowedValues: - '1' - '2' - '3' - '4' Default: '1' Description: Enter the number of Remote Desktop Gateway hosts to create. Type: String NumberOfBYOLInstances: AllowedValues: - '0' - '1' - '2' - '4' Default: '0' Description: Enter the number of BYOL Instances to be launched. 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 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 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-rdgateway/ 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: 'AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. Keep the default Region unless you are customizing the template. Changing this Region updates code references to point to a new Quick Start location. When using your own bucket, specify the Region. See https://aws-quickstart.github.io/option1.html.' 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-XXXXX' Description: "Please specify BYOL Image 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]))$ Description: Allowed CIDR Block for external access to the Remote Desktop Gateways. Type: String VPCID: Description: ID of the VPC (for example, vpc-0343606e). Type: AWS::EC2::VPC::Id Rules: SubnetsInVPC: Assertions: - Assert: !EachMemberIn - !ValueOfAll - AWS::EC2::Subnet::Id - VpcId - !RefAll 'AWS::EC2::VPC::Id' AssertDescription: All subnets must be in the VPC. 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" Conditions: UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart'] Resources: RDGWLocalUserSecrets: Type: AWS::SecretsManager::Secret Properties: Name: !Sub 'RDGWLocalUserSecrets-${AWS::StackName}' Description: Secrets to join AD domain SecretString: !Sub '{"username":"${AdminUser}","password":"${AdminPassword}"}' SetupConfigurationDoc: Type: AWS::SSM::Document Properties: DocumentType: Automation Content: schemaVersion: "0.3" description: "Configure instances on launch." assumeRole: "{{AutomationAssumeRole}}" parameters: InstanceId: description: "ID of the instance." type: "String" ASGName: description: "Auto Scaling group name." type: "String" LCHName: description: "Life cycle hook name." type: "String" DomainDNSName: default: "example.com" description: "Fully qualified domain name (FQDN) of the forest root domain (for example, example.com)." type: "String" AdminSecParam: description: "AWS Secrets parameter name that has password and user name for the domain administrator." type: "String" QSS3BucketName: 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: default: "quickstart-microsoft-rdgateway/" 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" URLSuffix: default: "amazonaws.com" description: "AWS URL suffix." type: "String" AutomationAssumeRole: default: "" description: "(Optional) The ARN of the role that allows automation to perform actions on your behalf." type: "String" mainSteps: - name: waitUntilInstanceStateRunning action: aws:waitForAwsResourceProperty timeoutSeconds: 600 inputs: Service: ec2 Api: DescribeInstanceStatus InstanceIds: - "{{InstanceId}}" PropertySelector: "$.InstanceStatuses[0].InstanceState.Name" DesiredValues: - running - name: assertInstanceStateRunning action: aws:assertAwsResourceProperty inputs: Service: ec2 Api: DescribeInstanceStatus InstanceIds: - "{{InstanceId}}" PropertySelector: "$.InstanceStatuses[0].InstanceState.Name" DesiredValues: - running - name: "installRDP" action: aws:runCommand onFailure: "step:abandonHookAction" inputs: DocumentName: AWS-RunPowerShellScript InstanceIds: - "{{InstanceId}}" CloudWatchOutputConfig: CloudWatchOutputEnabled: "true" CloudWatchLogGroupName: "/QuickStart/rdgateway/SetupConfiguration" Parameters: commands: - | Write-Output 'Installing RD Gateway components' Try { Install-WindowsFeature RDS-Gateway,RSAT-RDS-Gateway } Catch [System.Exception] { Write-Output "Failed to install RD Gateway components $_" Exit 1 } - name: "createLocalUser" action: "aws:runCommand" onFailure: "step:abandonHookAction" inputs: DocumentName: "AWS-RunRemoteScript" InstanceIds: - "{{InstanceId}}" CloudWatchOutputConfig: CloudWatchOutputEnabled: "true" CloudWatchLogGroupName: !Sub '/aws/Quick_Start/${AWS::StackName}' Parameters: sourceType: "S3" sourceInfo: !Sub - '{"path": "https://${S3Bucket}.s3.${S3Region}.{{URLSuffix}}/{{QSS3KeyPrefix}}scripts/Create-LocalUser.ps1"}' - S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName S3Region: !If - UsingDefaultBucket - !Ref AWS::Region - !Ref QSS3BucketRegion commandLine: "./Create-LocalUser.ps1 -AdminSecParam {{AdminSecParam}}" - name: "configurerdgw" action: "aws:runCommand" onFailure: "step:abandonHookAction" inputs: DocumentName: "AWS-RunRemoteScript" InstanceIds: - "{{InstanceId}}" CloudWatchOutputConfig: CloudWatchOutputEnabled: "true" CloudWatchLogGroupName: !Sub '/aws/Quick_Start/${AWS::StackName}' Parameters: sourceType: "S3" sourceInfo: !Sub - '{"path": "https://${S3Bucket}.s3.${S3Region}.{{URLSuffix}}/{{QSS3KeyPrefix}}scripts/Initialize-RDGW.ps1"}' - S3Bucket: !If - UsingDefaultBucket - !Sub '${QSS3BucketName}-${AWS::Region}' - !Ref QSS3BucketName S3Region: !If - UsingDefaultBucket - !Ref AWS::Region - !Ref QSS3BucketRegion commandLine: "./Initialize-RDGW.ps1 -DomainDNSName {{DomainDNSName}} -DomainNetBiosName BUILTIN -GroupName administrators" - name: "completeHookAction" action: aws:executeAwsApi isEnd: true inputs: Service: autoscaling Api: CompleteLifecycleAction AutoScalingGroupName: "{{ASGName}}" InstanceId: "{{InstanceId}}" LifecycleActionResult: CONTINUE LifecycleHookName: "{{LCHName}}" - name: "abandonHookAction" action: aws:executeAwsApi isEnd: true inputs: Service: autoscaling Api: CompleteLifecycleAction AutoScalingGroupName: "{{ASGName}}" InstanceId: "{{InstanceId}}" LifecycleActionResult: ABANDON LifecycleHookName: "{{LCHName}}" DHTemplate: Type: "AWS::EC2::LaunchTemplate" Properties: LaunchTemplateData: ImageId: !Ref 'BYOLAMI' InstanceType: !Ref 'BYOLInstanceType' SecurityGroupIds: - !Ref BYOLInstanceSG UserData: 'Fn::Base64': !Sub | $Admin=[adsi]("WinNT://$env:COMPUTERNAME/Administrator, user") $Admin.SetPassword(${AdminPassword}) #######end ########### BlockDeviceMappings: - DeviceName: /dev/sdk Ebs: VolumeSize: '50' - DeviceName: /dev/sdc VirtualName: ephemeral0 Placement: HostResourceGroupArn: !Ref 'GroupArn' LicenseSpecifications: - LicenseConfigurationArn: !Ref 'LicenseArn' AutoScalingGroup: Type: 'AWS::AutoScaling::AutoScalingGroup' DependsOn: - DHTemplate Properties: AutoScalingGroupName: !Sub "Dedicatedhost-${AWS::StackName}" VPCZoneIdentifier: - !Ref PrivateSubnet1AID - !Ref PrivateSubnet2AID MinSize: !Ref 'NumberOfBYOLInstances' MaxSize: !Ref 'NumberOfBYOLInstances' Tags: - Key: 'Launchedby' Value: 'Quickstart-Automation' PropagateAtLaunch: 'true' LaunchTemplate: LaunchTemplateId: !Ref 'DHTemplate' Version: !GetAtt 'DHTemplate.LatestVersionNumber' RDGWHostRole: Type: AWS::IAM::Role Properties: ManagedPolicyArns: - !Sub 'arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore' - !Sub 'arn:${AWS::Partition}:iam::aws:policy/CloudWatchAgentServerPolicy' Policies: - PolicyDocument: Version: '2012-10-17' Statement: - Action: - s3:GetObject Resource: !Sub - arn:${AWS::Partition}:s3:::${S3Bucket}/${QSS3KeyPrefix}* - S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Effect: Allow - Action: - s3:ListBucket Resource: !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: - Action: - s3:GetObject Resource: - !Sub 'arn:aws:s3:::aws-ssm-${AWS::Region}/*' - !Sub 'arn:aws:s3:::aws-windows-downloads-${AWS::Region}/*' - !Sub 'arn:aws:s3:::amazon-ssm-${AWS::Region}/*' - !Sub 'arn:aws:s3:::amazon-ssm-packages-${AWS::Region}/*' - !Sub 'arn:aws:s3:::${AWS::Region}-birdwatcher-prod/*' - !Sub 'arn:aws:s3:::patch-baseline-snapshot-${AWS::Region}/*' Effect: Allow PolicyName: ssm-custom-s3-policy - PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - secretsmanager:GetSecretValue - secretsmanager:DescribeSecret Resource: - !Ref 'RDGWLocalUserSecrets' PolicyName: ssm-secrets-policy Path: / AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Principal: Service: - ec2.amazonaws.com Effect: Allow Version: '2012-10-17' RDGWHostProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref 'RDGWHostRole' Path: / EventBridgeSSMAutoRole: Type: AWS::IAM::Role Properties: Policies: - PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - ssm:StartAutomationExecution Resource: - !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${SetupConfigurationDoc}:$DEFAULT' - Effect: Allow Action: - iam:PassRole Resource: - !GetAtt ExecutionResourceRole.Arn Condition: {"StringLikeIfExists": {"iam:PassedToService": "ssm.amazonaws.com"}} PolicyName: "EventBridge_Invoke_SSM_Automation" Path: /service-role/ AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - events.amazonaws.com Action: sts:AssumeRole ExecutionResourceRole: Type: AWS::IAM::Role Properties: Policies: - PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - autoscaling:CompleteLifecycleAction Resource: !Sub arn:aws:autoscaling:*:${AWS::AccountId}:autoScalingGroup:*:autoScalingGroupName/${AWS::StackName} PolicyName: asg-lch-complete AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - ssm.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole Description: New IAM Role to allow SSM access. ALBResource: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Type: network Subnets: - !Ref 'PublicSubnet1ID' - !Ref 'PublicSubnet2ID' ALBTargetGroup3389: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Port: 3389 Protocol: TCP VpcId: !Ref 'VPCID' TargetGroupAttributes: - Key: deregistration_delay.timeout_seconds Value: '60' - Key: stickiness.enabled Value: 'true' ALBTargetGroup443: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Port: 443 Protocol: TCP VpcId: !Ref 'VPCID' TargetGroupAttributes: - Key: deregistration_delay.timeout_seconds Value: '60' - Key: stickiness.enabled Value: 'true' ALBTargetGroup3391: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Port: 3391 Protocol: UDP VpcId: !Ref 'VPCID' TargetGroupAttributes: - Key: deregistration_delay.timeout_seconds Value: '60' - Key: stickiness.enabled Value: 'true' ALBListener3389: Type: AWS::ElasticLoadBalancingV2::Listener Properties: LoadBalancerArn: !Ref 'ALBResource' Port: 3389 Protocol: TCP DefaultActions: - Type: forward TargetGroupArn: !Ref 'ALBTargetGroup3389' ALBListener443: Type: AWS::ElasticLoadBalancingV2::Listener Properties: LoadBalancerArn: !Ref 'ALBResource' Port: 443 Protocol: TCP DefaultActions: - Type: forward TargetGroupArn: !Ref 'ALBTargetGroup443' ALBListener3391: Type: AWS::ElasticLoadBalancingV2::Listener Properties: LoadBalancerArn: !Ref 'ALBResource' Port: 3391 Protocol: UDP DefaultActions: - Type: forward TargetGroupArn: !Ref 'ALBTargetGroup3391' RDGWLaunchTemplate: Type: AWS::EC2::LaunchTemplate DeletionPolicy: Delete Properties: LaunchTemplateData: InstanceType: !Ref 'RDGWInstanceType' ImageId: !Ref 'LatestAmiId' SecurityGroupIds: - !Ref RemoteDesktopGatewaySG IamInstanceProfile: Name: !Ref 'RDGWHostProfile' BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeSize: 50 VolumeType: gp2 KeyName: !Ref 'KeyPairName' TagSpecifications: - ResourceType: 'instance' Tags: - Key: "Name" Value: "RDGW" RDGWAutoScalingGroup: DependsOn: ScaleUpEventBridgeResource Type: AWS::AutoScaling::AutoScalingGroup Properties: AutoScalingGroupName: !Sub "${AWS::StackName}" LaunchTemplate: LaunchTemplateId: !Ref 'RDGWLaunchTemplate' Version: !GetAtt 'RDGWLaunchTemplate.LatestVersionNumber' VPCZoneIdentifier: - !Ref 'PublicSubnet1ID' - !Ref 'PublicSubnet2ID' MinSize: !Ref 'NumberOfRDGWHosts' MaxSize: !Ref 'NumberOfRDGWHosts' Cooldown: '300' DesiredCapacity: !Ref 'NumberOfRDGWHosts' TargetGroupARNs: - !Ref 'ALBTargetGroup3389' - !Ref 'ALBTargetGroup443' - !Ref 'ALBTargetGroup3391' LifecycleHookSpecificationList: - LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING LifecycleHookName: DomainJoinHook DefaultResult: ABANDON HeartbeatTimeout: 1200 RemoteDesktopGatewaySG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Enable RDP access from the internet. VpcId: !Ref 'VPCID' SecurityGroupIngress: - IpProtocol: tcp FromPort: 3389 ToPort: 3389 CidrIp: !Ref 'RDGWCIDR' - IpProtocol: tcp FromPort: 3389 ToPort: 3389 CidrIp: !Ref 'RDGWCIDR' - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: !Ref 'RDGWCIDR' - IpProtocol: udp FromPort: 3391 ToPort: 3391 CidrIp: !Ref 'RDGWCIDR' - IpProtocol: icmp FromPort: -1 ToPort: -1 CidrIp: !Ref 'RDGWCIDR' BYOLInstanceSG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Enable RDP access from the internet. VpcId: !Ref 'VPCID' SecurityGroupIngress: - IpProtocol: tcp FromPort: 3389 ToPort: 3389 CidrIp: !Ref 'VPCCIDR' - IpProtocol: tcp FromPort: 3389 ToPort: 3389 CidrIp: !Ref 'VPCCIDR' - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: !Ref 'VPCCIDR' - IpProtocol: udp FromPort: 3391 ToPort: 3391 CidrIp: !Ref 'VPCCIDR' - IpProtocol: icmp FromPort: -1 ToPort: -1 CidrIp: !Ref 'VPCCIDR' ScaleUpEventBridgeResource: Type: AWS::Events::Rule Properties: State: ENABLED Description: Run configuration document that joins domain and configures IIS. EventPattern: source: - aws.autoscaling detail-type: - EC2 Instance-launch Lifecycle Action detail: AutoScalingGroupName: - !Sub "${AWS::StackName}" Targets: - Arn: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${SetupConfigurationDoc}:$DEFAULT' Id: Windows-Scale-Out RoleArn: !GetAtt EventBridgeSSMAutoRole.Arn InputTransformer: InputPathsMap: InstanceId: $.detail.EC2InstanceId ASGName: $.detail.AutoScalingGroupName LCHName: $.detail.LifecycleHookName InputTemplate: !Sub '{"AutomationAssumeRole":["${ExecutionResourceRole.Arn}"],"InstanceId":[],"ASGName":[],"LCHName":[],"DomainDNSName":["${DomainDNSName}"],"AdminSecParam":["${RDGWLocalUserSecrets}"],"QSS3BucketName":["${QSS3BucketName}"],"QSS3KeyPrefix":["${QSS3KeyPrefix}"],"URLSuffix":["${AWS::URLSuffix}"]}' Outputs: RDPURL: Description: ELB DNS name to connect to RDP Gateway. Value: !GetAtt 'ALBResource.DNSName' RemoteDesktopGatewaySGID: Value: !Ref 'RemoteDesktopGatewaySG' Description: Remote Desktop Gateway Security Group ID