{ "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 installs 2 Windows 2016 Active Directory Domain Controllers into private subnets in separate Availability Zones inside a VPC, as well as Remote Desktop Gateway instances and managed NAT gateways into the public subnet for each Availability Zone. The default Domain Administrator password will be the one retrieved from the instance. For adding members to the domain, ensure that they are launched into the domain member security group created by this template and then configure them to use the AD instances fixed private IP addresses as the DNS server. **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": [ "AvailabilityZones", "NumberOfAZs", "VPCCIDR", "PrivateSubnet1CIDR", "PrivateSubnet1ID", "PrivateSubnet2CIDR", "PrivateSubnet3CIDR", "PrivateSubnet2ID", "PublicSubnet1CIDR", "PublicSubnet2CIDR", "PublicSubnet3CIDR", "RDGWCIDR" ] }, { "Label": { "default": "Amazon EC2 Configuration" }, "Parameters": [ "KeyPairName", "ADServer1InstanceType", "ADServer1NetBIOSName", "ADServer1PrivateIP", "ADServer2InstanceType", "ADServer2NetBIOSName", "ADServer2PrivateIP", "RDGWInstanceType" ] }, { "Label": { "default": "Microsoft Active Directory Configuration" }, "Parameters": [ "DomainDNSName", "DomainNetBIOSName", "RestoreModePassword", "DomainAdminUser", "DomainAdminPassword" ] }, { "Label": { "default": "Microsoft Remote Desktop Gateway Configuration" }, "Parameters": [ "NumberOfRDGWHosts" ] }, { "Label": { "default": "AWS Quick Start Configuration" }, "Parameters": [ "QSS3BucketName", "QSS3KeyPrefix" ] } ], "ParameterLabels": { "ADServer1InstanceType": { "default": "Domain Controller 1 Instance Type" }, "ADServer1NetBIOSName": { "default": "Domain Controller 1 NetBIOS Name" }, "ADServer1PrivateIP": { "default": "Domain Controller 1 Private IP Address" }, "ADServer2InstanceType": { "default": "Domain Controller 2 Instance Type" }, "ADServer2NetBIOSName": { "default": "Domain Controller 2 NetBIOS Name" }, "ADServer2PrivateIP": { "default": "Domain Controller 2 Private IP Address" }, "AvailabilityZones": { "default": "Availability Zones" }, "DomainAdminPassword": { "default": "Domain Admin Password" }, "DomainAdminUser": { "default": "Domain Admin User Name" }, "DomainDNSName": { "default": "Domain DNS Name" }, "DomainNetBIOSName": { "default": "Domain NetBIOS Name" }, "KeyPairName": { "default": "Key Pair Name" }, "NumberOfRDGWHosts": { "default": "Number of RDGW hosts" }, "NumberOfAZs": { "default": "Number of Availability Zones" }, "PrivateSubnet1CIDR": { "default": "Private Subnet 1 CIDR" }, "PrivateSubnet2CIDR": { "default": "Private Subnet 2 CIDR" }, "PrivateSubnet3CIDR": { "default": "(Optional) Private Subnet 3 CIDR" }, "PublicSubnet1CIDR": { "default": "Public Subnet 1 CIDR" }, "PublicSubnet2CIDR": { "default": "Public Subnet 2 CIDR" }, "PublicSubnet3CIDR": { "default": "(Optional) Public Subnet 3 CIDR" }, "QSS3BucketName": { "default": "Quick Start S3 Bucket Name" }, "QSS3KeyPrefix": { "default": "Quick Start S3 Key Prefix" }, "RDGWInstanceType": { "default": "Remote Desktop Gateway Instance Type" }, "RDGWCIDR": { "default": "Allowed Remote Desktop Gateway External Access CIDR" }, "RestoreModePassword": { "default": "Restore Mode Password" }, "VPCCIDR": { "default": "VPC CIDR" } } } }, "Parameters": { "ADServer1InstanceType": { "AllowedValues": [ "t2.large", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m5.large", "m5.xlarge", "m5.2xlarge", "m5.4xlarge" ], "Default": "m4.xlarge", "Description": "Amazon EC2 instance type for the first Active Directory instance", "Type": "String" }, "ADServer1NetBIOSName": { "AllowedPattern": "[a-zA-Z0-9\\-]+", "Default": "DC1", "Description": "NetBIOS name of the first Active Directory server (up to 15 characters)", "MaxLength": "15", "MinLength": "1", "Type": "String" }, "ADServer1PrivateIP": { "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])$", "Default": "10.0.0.10", "Description": "Fixed private IP for the first Active Directory server located in Availability Zone 1", "Type": "String" }, "ADServer2InstanceType": { "AllowedValues": [ "t2.large", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m5.large", "m5.xlarge", "m5.2xlarge", "m5.4xlarge" ], "Default": "m4.xlarge", "Description": "Amazon EC2 instance type for the second Active Directory instance", "Type": "String" }, "ADServer2NetBIOSName": { "AllowedPattern": "[a-zA-Z0-9\\-]+", "Default": "DC2", "Description": "NetBIOS name of the second Active Directory server (up to 15 characters)", "MaxLength": "15", "MinLength": "1", "Type": "String" }, "ADServer2PrivateIP": { "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])$", "Default": "10.0.32.10", "Description": "Fixed private IP for the second Active Directory server located in Availability Zone 2", "Type": "String" }, "AvailabilityZones": { "Description": "List of Availability Zones to use for the subnets in the VPC. Note: The logical order is preserved and only 2 AZs are used for this deployment.", "Type": "List" }, "NumberOfAZs": { "AllowedValues": [ "2", "3" ], "Default": "2", "Description": "Number of Availability Zones to use in the VPC. This must match your selections in the list of Availability Zones parameter.", "Type": "String" }, "DomainAdminPassword": { "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]))^.*", "Description": "Password for the domain admin user. Must be at least 8 characters containing letters, numbers and symbols", "MaxLength": "32", "MinLength": "8", "NoEcho": "true", "Type": "String" }, "DomainAdminUser": { "AllowedPattern": "[a-zA-Z0-9]*", "Default": "StackAdmin", "Description": "User name for the account that will be added as Domain Administrator. This is separate from the default \"Administrator\" account", "MaxLength": "25", "MinLength": "5", "Type": "String" }, "DomainDNSName": { "AllowedPattern": "[a-zA-Z0-9\\-]+\\..+", "Default": "example.com", "Description": "Fully qualified domain name (FQDN) of the forest root domain e.g. example.com", "MaxLength": "255", "MinLength": "2", "Type": "String" }, "DomainNetBIOSName": { "AllowedPattern": "[a-zA-Z0-9\\-]+", "Default": "example", "Description": "NetBIOS name of the domain (up to 15 characters) for users of earlier versions of Windows e.g. EXAMPLE", "MaxLength": "15", "MinLength": "1", "Type": "String" }, "KeyPairName": { "Description": "Public/private key pairs allow you to securely connect to your instance after it launches", "Type": "AWS::EC2::KeyPair::KeyName" }, "NumberOfRDGWHosts": { "AllowedValues": [ "1", "2", "3", "4" ], "Default": "1", "Description": "Enter the number of Remote Desktop Gateway hosts to create", "Type": "String" }, "PrivateSubnet1CIDR": { "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/19", "Description": "CIDR block for private subnet 1 located in Availability Zone 1.", "Type": "String" }, "PrivateSubnet2CIDR": { "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.32.0/19", "Description": "CIDR block for private subnet 2 located in Availability Zone 2.", "Type": "String" }, "PrivateSubnet3CIDR": { "Default": "", "Description": "CIDR block for private subnet 3 located in Availability Zone 3.", "Type": "String" }, "PublicSubnet1CIDR": { "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.128.0/20", "Description": "CIDR Block for the public DMZ subnet 1 located in Availability Zone 1", "Type": "String" }, "PublicSubnet2CIDR": { "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.144.0/20", "Description": "CIDR Block for the public DMZ subnet 2 located in Availability Zone 2", "Type": "String" }, "PublicSubnet3CIDR": { "Default": "", "Description": "CIDR Block for the public DMZ subnet 3 located in Availability Zone 3", "Type": "String" }, "QSS3BucketName": { "AllowedPattern": "^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$", "ConstraintDescription": "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": "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": { "AllowedPattern": "^[0-9a-zA-Z-/]*$", "ConstraintDescription": "Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/).", "Default": "quickstart-microsoft-activedirectory/", "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" }, "RDGWInstanceType": { "Description": "Amazon EC2 instance type for the Remote Desktop Gateway instances", "Type": "String", "Default": "t2.large", "AllowedValues": [ "t2.large", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge" ] }, "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 Gateways", "Type": "String" }, "RestoreModePassword": { "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]))^.*", "Description": "Password for a separate Administrator account when the domain controller is in Restore Mode. Must be at least 8 characters containing letters, numbers and symbols", "MaxLength": "32", "MinLength": "8", "NoEcho": "True", "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" } }, "Conditions": { "GovCloudCondition": { "Fn::Equals": [ { "Ref": "AWS::Region" }, "us-gov-west-1" ] } }, "Rules": { "CheckSupportedInstances": { "RuleCondition": { "Fn::Or" : [ {"Fn::Contains" : [[ "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge" ], {"Ref" : "ADServer1InstanceType"}]}, {"Fn::Contains" : [[ "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge" ], {"Ref" : "ADServer2InstanceType"}]} ] }, "Assertions": [ { "Assert": { "Fn::Not": [ { "Fn::Contains": [ [ "eu-west-3" ], { "Ref": "AWS::Region" } ] } ] }, "AssertDescription": "M4 instances are not available in the Paris region" } ] } }, "Resources": { "VPCStack": { "Type": "AWS::CloudFormation::Stack", "Properties": { "TemplateURL": { "Fn::Sub": [ "https://${QSS3BucketName}.${QSS3Region}.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template", { "QSS3Region": { "Fn::If": [ "GovCloudCondition", "s3-us-gov-west-1", "s3" ] } } ] }, "Parameters": { "AvailabilityZones": { "Fn::Join": [ ",", { "Ref": "AvailabilityZones" } ] }, "KeyPairName": { "Ref": "KeyPairName" }, "NumberOfAZs": { "Ref": "NumberOfAZs" }, "PrivateSubnet1ACIDR": { "Ref": "PrivateSubnet1CIDR" }, "PrivateSubnet2ACIDR": { "Ref": "PrivateSubnet2CIDR" }, "PublicSubnet1CIDR": { "Ref": "PublicSubnet1CIDR" }, "PublicSubnet2CIDR": { "Ref": "PublicSubnet2CIDR" }, "VPCCIDR": { "Ref": "VPCCIDR" } } } }, "ADStack": { "DependsOn": "VPCStack", "Type": "AWS::CloudFormation::Stack", "Properties": { "TemplateURL": { "Fn::Sub": [ "https://${QSS3BucketName}.${QSS3Region}.amazonaws.com/${QSS3KeyPrefix}templates/ad-1.template", { "QSS3Region": { "Fn::If": [ "GovCloudCondition", "s3-us-gov-west-1", "s3" ] } } ] }, "Parameters": { "ADServer1InstanceType": { "Ref": "ADServer1InstanceType" }, "ADServer1NetBIOSName": { "Ref": "ADServer1NetBIOSName" }, "ADServer1PrivateIP": { "Ref": "ADServer1PrivateIP" }, "ADServer2InstanceType": { "Ref": "ADServer2InstanceType" }, "ADServer2NetBIOSName": { "Ref": "ADServer2NetBIOSName" }, "ADServer2PrivateIP": { "Ref": "ADServer2PrivateIP" }, "DomainAdminPassword": { "Ref": "DomainAdminPassword" }, "DomainAdminUser": { "Ref": "DomainAdminUser" }, "DomainDNSName": { "Ref": "DomainDNSName" }, "DomainNetBIOSName": { "Ref": "DomainNetBIOSName" }, "KeyPairName": { "Ref": "KeyPairName" }, "NumberOfAZs": { "Ref": "NumberOfAZs" }, "PrivateSubnet1CIDR": { "Ref": "PrivateSubnet1CIDR" }, "PrivateSubnet1ID": { "Fn::GetAtt": [ "VPCStack", "Outputs.PrivateSubnet1AID" ] }, "PrivateSubnet2CIDR": { "Ref": "PrivateSubnet2CIDR" }, "PrivateSubnet2ID": { "Fn::GetAtt": [ "VPCStack", "Outputs.PrivateSubnet2AID" ] }, "PrivateSubnet3CIDR": { "Ref": "PrivateSubnet3CIDR" }, "PublicSubnet1CIDR": { "Ref": "PublicSubnet1CIDR" }, "PublicSubnet2CIDR": { "Ref": "PublicSubnet2CIDR" }, "PublicSubnet3CIDR": { "Ref": "PublicSubnet3CIDR" }, "QSS3BucketName": { "Ref": "QSS3BucketName" }, "QSS3KeyPrefix": { "Ref": "QSS3KeyPrefix" }, "RestoreModePassword": { "Ref": "RestoreModePassword" }, "VPCCIDR": { "Ref": "VPCCIDR" }, "VPCID": { "Fn::GetAtt": [ "VPCStack", "Outputs.VPCID" ] } } } }, "RDGWStack": { "DependsOn": "ADStack", "Type": "AWS::CloudFormation::Stack", "Properties": { "TemplateURL": { "Fn::Sub": [ "https://${QSS3BucketName}.${QSS3Region}.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-microsoft-rdgateway/templates/rdgw-domain.template", { "QSS3Region": { "Fn::If": [ "GovCloudCondition", "s3-us-gov-west-1", "s3" ] } } ] }, "Parameters": { "DomainAdminPassword": { "Ref": "DomainAdminPassword" }, "DomainAdminUser": { "Ref": "DomainAdminUser" }, "DomainDNSName": { "Ref": "DomainDNSName" }, "DomainMemberSGID": { "Fn::GetAtt": [ "ADStack", "Outputs.DomainMemberSGID" ] }, "DomainNetBIOSName": { "Ref": "DomainNetBIOSName" }, "KeyPairName": { "Ref": "KeyPairName" }, "NumberOfRDGWHosts": { "Ref": "NumberOfRDGWHosts" }, "PublicSubnet1ID": { "Fn::GetAtt": [ "VPCStack", "Outputs.PublicSubnet1ID" ] }, "PublicSubnet2ID": { "Fn::GetAtt": [ "VPCStack", "Outputs.PublicSubnet2ID" ] }, "QSS3BucketName": { "Ref": "QSS3BucketName" }, "QSS3KeyPrefix": { "Fn::Sub": "${QSS3KeyPrefix}submodules/quickstart-microsoft-rdgateway/" }, "RDGWInstanceType": { "Ref": "RDGWInstanceType" }, "RDGWCIDR": { "Ref": "RDGWCIDR" }, "VPCID": { "Fn::GetAtt": [ "VPCStack", "Outputs.VPCID" ] } } } } } }