AWSTemplateFormatVersion: '2010-09-09' Description: >- This template creates 2 Windows Active Directory Domain Controllers into private subnets in separate Availability Zones inside a VPC. The default Domain Administrator password will be the one retrieved from the instance. For adding members to the domain, ensure that they are launched using 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. (qs-1qup6rae5) Metadata: cfn-lint: config: ignore_checks: - W9006 - E9101 - W9901 QuickStartDocumentation: EntrypointName: Parameters for deploying self-managed AD into an existing VPC Order: '2' AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Network configuration Parameters: - VPCCIDR - VPCID - DHCPOptionSet - PrivateSubnet1ID - PrivateSubnet2ID - Label: default: Amazon EC2 configuration Parameters: - ADServer1InstanceType - ADServer1NetBIOSName - ADServer1PrivateIP - ADServer2InstanceType - ADServer2NetBIOSName - ADServer2PrivateIP - DataDriveSizeGiB - EbsEncryptionKmsKeyId - EnableAdvancedAudtingandMetrics - KeyPairName - WINFULLBASE - SetupAppInsightsMonitoring - AppInsightsApplicationName - Label: default: Microsoft Active Directory Domain Services configuration Parameters: - DomainAdminUser - DomainAdminPassword - DomainDNSName - DomainNetBIOSName - CreateDefaultOUs - TombstoneLifetime - DeletedObjectLifetime - Label: default: Microsoft Active Directory Certificate Services configuration Parameters: - PKI - PKIEnableAdvancedAudtingandMetrics - CaServerInstanceType - CaDataDriveSizeGiB - CaAmi - OrCaServerNetBIOSName - EntCaServerNetBIOSName - CaKeyLength - CaHashAlgorithm - OrCaValidityPeriodUnits - CaValidityPeriodUnits - UseS3ForCRL - S3CRLBucketName - Label: default: AWS Quick Start configuration Parameters: - QSS3BucketName - QSS3BucketRegion - 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 AppInsightsApplicationName: default: Registered Application Name CaAmi: default: CA SSM Parameter Value for Latest AMI ID CaDataDriveSizeGiB: default: CA Data Drive Size CaHashAlgorithm: default: CA Hash Algorithm CaKeyLength: default: CA Key Length CaServerInstanceType: default: CA Instance Type CaValidityPeriodUnits: default: Enterprise Root or Subordinate CA Certificate Validity Period in Years CreateDefaultOUs: default: Create Default OUs DHCPOptionSet: default: Create a DHCP Options set DataDriveSizeGiB: default: SYSVOL and NTDS Data Drive Size DeletedObjectLifetime: default: Set new Deleted Objects Lifetime in Days DomainAdminPassword: default: Alternate Domain Admin Password DomainAdminUser: default: Alternate Domain Admin User Name DomainDNSName: default: Domain DNS Name DomainNetBIOSName: default: Domain NetBIOS Name EbsEncryptionKmsKeyId: default: KMS Key for EBS Encryption EnableAdvancedAudtingandMetrics: default: Advanced Auditing and Metrics for Domain Controllers EntCaServerNetBIOSName: default: Enterprise Root or Subordinate CA NetBIOS Name KeyPairName: default: Key Pair Name OrCaServerNetBIOSName: default: Offline Root CA NetBIOS Name (Only Used For Two Tier PKI) OrCaValidityPeriodUnits: default: Offline Root CA Certificate Validity Period in Years (Only Used For Two Tier PKI) PKI: default: CA Deployment Type PKIEnableAdvancedAudtingandMetrics: default: Advanced Auditing and Metrics for PKI Instance(s) PrivateSubnet1ID: default: Subnet 1 ID PrivateSubnet2ID: default: Subnet 2 ID QSS3BucketName: default: Quick Start S3 Bucket Name QSS3BucketRegion: default: Quick Start S3 Bucket Region QSS3KeyPrefix: default: Quick Start S3 Key Prefix SetupAppInsightsMonitoring: default: Setup Application Insights Monitoring S3CRLBucketName: default: CA CRL S3 Bucket Name TombstoneLifetime: default: Set new Tombstone Lifetime in Days UseS3ForCRL: default: Use S3 for CA CRL Location VPCCIDR: default: VPC CIDR VPCID: default: VPC ID WINFULLBASE: default: SSM Parameter Value for Latest AMI ID Parameters: ADServer1InstanceType: AllowedValues: - t3.medium - t3.large - t3.xlarge - t3.2xlarge - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge Default: m5.large Description: Amazon EC2 instance type for the first Active Directory Domain Controller instance Type: String ADServer1NetBIOSName: AllowedPattern: '^[a-zA-Z0-9]+$' Default: DC1 Description: NetBIOS name of the first Active Directory Domain Controller (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 Domain Controller located in Availability Zone 1 Type: String ADServer2InstanceType: AllowedValues: - t3.medium - t3.large - t3.xlarge - t3.2xlarge - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge Default: m5.large Description: Amazon EC2 instance type for the second Active Directory Domain Controller instance Type: String ADServer2NetBIOSName: AllowedPattern: '^[a-zA-Z0-9]+$' Default: DC2 Description: NetBIOS name of the second Active Directory Domain Controller (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 Domain Controller located in Availability Zone 2 Type: String AppInsightsApplicationName: Description: Application name to be used with AppInsights monitoring Type: String Default: '' MaxLength: '300' AllowedPattern: '^[a-zA-Z0-9\-]*$' CaAmi: AllowedPattern: '^[\w\/-]+$' Default: /aws/service/ami-windows-latest/Windows_Server-2022-English-Full-Base Description: Enterprise Root CA SSM Parameter Value to grab the latest AMI ID Type: String CaDataDriveSizeGiB: Default: '2' Description: Size of the data drive in GiB for the CA instance(s) Type: Number MinValue: '2' MaxValue: '16384' CaHashAlgorithm: AllowedValues: - SHA256 - SHA384 - SHA512 Default: SHA256 Description: CA(s) Hash Algorithm for Signing Certificates Type: String CaKeyLength: AllowedValues: - '2048' - '4096' Default: '2048' Description: CA(s) Cryptographic provider key length. Type: String CaServerInstanceType: AllowedValues: - t3.small - t3.medium - t3.large - t3.xlarge - t3.2xlarge - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge Default: t3.medium Description: Amazon EC2 instance type for the CA instance(s) Type: String CaValidityPeriodUnits: Default: '5' Description: Validity Period in Years Type: Number MinValue: '1' CreateDefaultOUs: AllowedValues: - 'Yes' - 'No' Default: 'No' Description: Domain Elevated Accounts, Domain Users, Domain Computers, Domain Servers, Domain Service Accounts, and Domain Groups OUs and set the default users and computers containers to Domain Users and Domain Computers Type: String DHCPOptionSet: AllowedValues: - 'Yes' - 'No' Default: 'Yes' Description: Do you want to create and apply a new DHCP Options Set Type: String DataDriveSizeGiB: Default: '10' Description: Size of SYSVOL and NTDS data drive in GiB Type: Number MinValue: '1' MaxValue: '16384' DeletedObjectLifetime: Default: '180' Description: The number of days before a deleted object is removed from the Active Directory recycle bin, minimum number is 2 MinValue: '2' Type: Number DomainAdminPassword: AllowedPattern: '(?=^.{8,32}$)((?=.*\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 account named above. 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: Admin Description: User name for the account that will be added as a Domain Administrator. This is separate from the default "Administrator" account MaxLength: '25' MinLength: '5' Type: String DomainDNSName: AllowedPattern: '^([a-zA-Z0-9]+[\.\-])+([a-zA-Z0-9])+$' Default: example.com Description: Fully qualified domain name (FQDN) of the forest root domain e.g. example.com MaxLength: '64' 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 EbsEncryptionKmsKeyId: AllowedPattern: '^(arn:[^:]+:kms:[^:]+:\d{12}:(key|alias)\/[\w\-\/]+)$|^(alias\/)?[\w\-\/]+$' Default: alias/aws/ebs Description: The identifier of the AWS KMS key to use for Amazon EBS encryption. You can specify the KMS key using any of the following; Key ID, Key alias, Key ARN, Alias ARN Type: String EnableAdvancedAudtingandMetrics: Description: Enable advanced auditing and metrics and upload them to CloudWatch using the Amazon Kinesis Agent for Microsoft Windows AllowedValues: - 'true' - 'false' Type: String Default: 'false' EntCaServerNetBIOSName: AllowedPattern: '^[a-zA-Z0-9]+$' Default: ENTCA1 Description: NetBIOS name of the Enterprise Root or Subordinate CA server (up to 15 characters) 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 OrCaServerNetBIOSName: AllowedPattern: '^[a-zA-Z0-9]+$' Default: ORCA1 Description: NetBIOS name of the Offline Root CA server (Only Used For Two Tier PKI) (up to 15 characters) MaxLength: '15' MinLength: '1' Type: String OrCaValidityPeriodUnits: Default: '10' Description: Validity Period in Years (Only Used For Two Tier PKI) MinValue: '1' Type: Number PKI: AllowedValues: - One-Tier - Two-Tier - 'No' Default: 'No' Description: Deploy Two Tier (Offline Root with Subordinate Enterprise CA) or One Tier (Enterprise Root CA) PKI Infrastructure Type: String PKIEnableAdvancedAudtingandMetrics: AllowedValues: - 'true' - 'false' Default: 'false' Description: Enable advanced auditing and metrics and upload them to CloudWatch using the Amazon Kinesis Agent for Microsoft Windows Type: String PrivateSubnet1ID: Description: ID of subnet 1 in Availability Zone 1 (e.g., subnet-a0246dcd) Type: AWS::EC2::Subnet::Id PrivateSubnet2ID: Description: ID of subnet 2 in Availability Zone 2 (e.g., subnet-a0246dcd) Type: AWS::EC2::Subnet::Id QSS3BucketName: AllowedPattern: '^[a-z0-9]+[a-z0-9\.\-]*[a-z0-9]+$' 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 QSS3BucketRegion: AllowedPattern: '^[a-z]+\-[a-z\-]+\-[0-9]{1}$' Default: us-east-1 Description: The AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. When using your own bucket, you must specify this value Type: String QSS3KeyPrefix: AllowedPattern: '^[a-zA-Z0-9\-\/]+$' 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 S3CRLBucketName: AllowedPattern: '^[a-z0-9]+[a-z0-9\.\-]*[a-z0-9]+$' Default: examplebucket Description: S3 bucket name for CA CRL(s) storage. Bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-) Type: String SetupAppInsightsMonitoring: AllowedValues: - 'true' - 'false' Default: 'false' Type: String TombstoneLifetime: Default: '180' Description: The number of days before a deleted object is removed from Active Directory, minimum number is 2 MinValue: '2' Type: Number UseS3ForCRL: AllowedValues: - 'Yes' - 'No' Default: 'No' Description: Store CA CRL(s) in an S3 bucket 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 (e.g., vpc-0343606e) Type: AWS::EC2::VPC::Id WINFULLBASE: Default: /aws/service/ami-windows-latest/Windows_Server-2022-English-Full-Base Description: System Manager parameter value for latest Windows Server AMI Type: AWS::SSM::Parameter::Value Rules: SubnetsInVPC: Assertions: - Assert: !EachMemberIn - !ValueOfAll - AWS::EC2::Subnet::Id - VpcId - !RefAll 'AWS::EC2::VPC::Id' AssertDescription: All subnets must in the VPC S3CRLBucketNameValidation: RuleCondition: !And - !Equals [!Ref UseS3ForCRL, 'Yes'] - !Not [!Equals [!Ref PKI, 'No']] Assertions: - AssertDescription: CRL BucketName cannot must be valid BucketName Assert: !Not [!Equals [!Ref S3CRLBucketName, 'examplebucket']] Conditions: ShouldCreateDHCPOption: !Not [!Equals [!Ref DHCPOptionSet, 'No']] ShouldCreateOneTierPkiResource: !Equals [!Ref PKI, 'One-Tier'] ShouldCreateTwoTierPkiResource: !Equals [!Ref PKI, 'Two-Tier'] UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart'] AppInsightsEnabled: !Equals [!Ref SetupAppInsightsMonitoring, 'true'] UsingDefaultAppName: !Equals [!Ref AppInsightsApplicationName, ''] Resources: DHCPOptions: Condition: ShouldCreateDHCPOption DependsOn: - DomainController1 - DomainController2 Type: AWS::EC2::DHCPOptions Properties: DomainName: !Ref DomainDNSName DomainNameServers: - !Ref ADServer1PrivateIP - !Ref ADServer2PrivateIP Tags: - Key: Domain Value: !Ref DomainDNSName VPCDHCPOptionsAssociation: Condition: ShouldCreateDHCPOption Type: AWS::EC2::VPCDHCPOptionsAssociation Properties: VpcId: !Ref VPCID DhcpOptionsId: !Ref DHCPOptions AWSQuickstartActiveDirectoryDS: Type: AWS::SSM::Document Properties: DocumentType: Automation Tags: - Key: StackName Value: !Ref AWS::StackName Content: schemaVersion: '0.3' description: 'Deploy AD with SSM Automation' parameters: 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]))$' default: '10.0.0.0/16' description: 'CIDR Block for the VPC' type: String ADServer1NetBIOSName: allowedPattern: '^[a-zA-Z0-9]+$' default: 'DC1' description: 'NetBIOS name of the first Active Directory Domain Controller (up to 15 characters)' type: String maxChars: '15' minChars: '1' 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 Domain Controller located in Availability Zone 1' type: String ADServer2NetBIOSName: allowedPattern: '^[a-zA-Z0-9]+$' default: 'DC2' description: 'NetBIOS name of the second Active Directory Domain Controller (up to 15 characters)' type: String maxChars: '15' minChars: '1' 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 Domain Controller located in Availability Zone 2' type: String ADAdminSecParamName: allowedPattern: '^arn:[^:]+:secretsmanager:[^:]+:\d{12}:secret:[\w\/+=.@-]{1,512}$' description: 'AWS Secrets Parameter Name that has Password and User namer for the built-in administrator' type: String maxChars: '2048' minChars: '20' ADAltUserSecParamName: allowedPattern: '^arn:[^:]+:secretsmanager:[^:]+:\d{12}:secret:[\w\/+=.@-]{1,512}$' description: 'AWS Secrets Parameter Name for the account that will be added as Domain Administrator. This is separate from the built-in Administrator account' type: String maxChars: '2048' minChars: '20' RestoreModeSecParamName: allowedPattern: '^arn:[^:]+:secretsmanager:[^:]+:\d{12}:secret:[\w\/+=.@-]{1,512}$' description: 'AWS Secrets Parameter Name for the Active Directory Restore Mode Password' type: String maxChars: '2048' minChars: '20' DomainDNSName: allowedPattern: '^([a-zA-Z0-9]+[\.\-])+([a-zA-Z0-9])+$' default: 'example.com' description: 'Fully qualified domain name (FQDN) of the forest root domain e.g. example.com' type: String maxChars: '64' minChars: '2' 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' type: String maxChars: '15' minChars: '1' EnableAdvancedAudtingandMetrics: allowedValues: - 'true' - 'false' default: 'false' description: Enable advanced auditing and metrics type: String CreateDefaultOUs: allowedValues: - 'Yes' - 'No' default: 'No' description: 'Create Domain Elevated Accounts, Domain Users, Domain Computers, Domain Servers, Domain Service Accounts, and Domain Groups OUs' type: String TombstoneLifetime: default: '180' description: The number of days before a deleted object is removed from the directory services type: String allowedPattern: '^[\d]+$' DeletedObjectLifetime: default: '180' description: The number of days before a deleted object is removed from the directory services recycling bin type: String allowedPattern: '^[\d]+$' QSS3BucketName: allowedPattern: '^[a-z0-9]+[a-z0-9\.\-]*[a-z0-9]+$' 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 QSS3BucketRegion: allowedPattern: '^[a-z]+\-[a-z\-]+\-[0-9]{1}$' default: 'us-east-1' description: 'The AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. When using your own bucket, you must specify this value' type: String QSS3KeyPrefix: allowedPattern: '^[a-zA-Z0-9\-\/]+$' 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 StackName: allowedPattern: '^[a-zA-Z][A-Za-z0-9\-]+$' description: 'Stack Name Input for cfn resource signal' maxChars: '128' minChars: '1' type: String URLSuffix: allowedPattern: '^[a-zA-Z0-9\-\.]+$' default: 'amazonaws.com' description: 'AWS URL suffix' type: String mainSteps: - name: dcsInstanceIds action: aws:executeAwsApi onFailure: step:signalfailure inputs: Service: ec2 Api: DescribeInstances Filters: - Name: tag:Name Values: ['{{ADServer1NetBIOSName}}', '{{ADServer2NetBIOSName}}'] - Name: tag:aws:cloudformation:stack-name Values: ['{{StackName}}'] - Name: instance-state-name Values: ['running'] outputs: - Name: InstanceIds Selector: $.Reservations..Instances..InstanceId Type: StringList nextStep: dc1InstanceId - name: dc1InstanceId action: aws:executeAwsApi onFailure: step:signalfailure inputs: Service: ec2 Api: DescribeInstances Filters: - Name: tag:Name Values: ['{{ADServer1NetBIOSName}}'] - Name: tag:aws:cloudformation:stack-name Values: ['{{StackName}}'] - Name: instance-state-name Values: ['running'] outputs: - Name: InstanceId Selector: $.Reservations[0].Instances[0].InstanceId Type: String nextStep: dc2InstanceId - name: dc2InstanceId action: aws:executeAwsApi onFailure: step:signalfailure inputs: Service: ec2 Api: DescribeInstances Filters: - Name: tag:Name Values: ['{{ADServer2NetBIOSName}}'] - Name: tag:aws:cloudformation:stack-name Values: ['{{StackName}}'] - Name: instance-state-name Values: ['running'] outputs: - Name: InstanceId Selector: $.Reservations[0].Instances[0].InstanceId Type: String nextStep: intializeInstance - name: intializeInstance action: aws:runCommand inputs: DocumentName: AWS-RunPowerShellScript InstanceIds: - '{{dcsInstanceIds.InstanceIds}}' Parameters: commands: |- [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $S3BucketName = '{{QSS3BucketName}}' $S3KeyPrefix = '{{QSS3KeyPrefix}}' $S3BucketRegion = '{{QSS3BucketRegion}}' $CustomModules = @( 'Module-AD.psd1', 'Module-AD.psm1' ) $Modules = @( @{ Name = 'NetworkingDsc' Version = '8.2.0' }, @{ Name = 'ActiveDirectoryDsc' Version = '6.0.1' }, @{ Name = 'ComputerManagementDsc' Version = '8.5.0' }, @{ Name = 'DnsServerDsc' Version = '3.0.0' }, @{ Name = 'AuditPolicyDsc' Version = '1.4.0.0' } ) Write-Output 'Creating AWSQuickstart Directory' Try { $Null = New-Item -Path 'C:\AWSQuickstart\Module-AD' -ItemType 'Directory' -ErrorAction Stop } Catch [System.Exception] { Write-Output "Failed to create AWSQuickstart directory $_" Exit 1 } $S3KeyPrefix = $S3KeyPrefix.Substring(0,$S3KeyPrefix.Length -1) Write-Output 'Downloading AD PowerShell Module' Foreach ($CustomModule in $CustomModules) { Try { $Null = Read-S3Object -BucketName $S3BucketName -Key "$($S3KeyPrefix)/scripts/Modules/Module-AD/$CustomModule" -File "C:\AWSQuickstart\Module-AD\$CustomModule" -Region $S3BucketRegion } Catch [System.Exception] { Write-Output "Failed to read and download $CustomModule.Name from S3 $_" Exit 1 } } Write-Output 'Installing NuGet Package Provider' Try { $Null = Install-PackageProvider -Name 'NuGet' -MinimumVersion '2.8.5' -Force -ErrorAction Stop } Catch [System.Exception] { Write-Output "Failed to install NuGet Package Provider $_" Exit 1 } Write-Output 'Setting PSGallery Respository to trusted' Try { Set-PSRepository -Name 'PSGallery' -InstallationPolicy 'Trusted' -ErrorAction Stop } Catch [System.Exception] { Write-Output "Failed to set PSGallery Respository to trusted $_" Exit 1 } Write-Output 'Installing the needed Powershell DSC modules for this Quick Start' Foreach ($Module in $Modules) { Try { Install-Module -Name $Module.Name -RequiredVersion $Module.Version -ErrorAction Stop } Catch [System.Exception] { Write-Output "Failed to Import Modules $_" Exit 1 } } CloudWatchOutputConfig: CloudWatchOutputEnabled: true CloudWatchLogGroupName: !Sub /aws/Quick_Start/${AWS::StackName} nextStep: configureInstance - name: configureInstance action: aws:runCommand inputs: DocumentName: AWS-RunPowerShellScript InstanceIds: - '{{dcsInstanceIds.InstanceIds}}' Parameters: commands: |- Try { Import-Module -Name 'C:\AWSQuickstart\Module-AD\Module-AD.psm1' -Force } Catch [System.Exception] { Write-Output "Failed to import AD PS Module $_" Exit 1 } New-VolumeFromRawDisk Invoke-PreConfig Invoke-LcmConfig CloudWatchOutputConfig: CloudWatchOutputEnabled: true CloudWatchLogGroupName: !Sub /aws/Quick_Start/${AWS::StackName} nextStep: configureDc1Mof - name: configureDc1Mof action: aws:runCommand inputs: DocumentName: AWS-RunPowerShellScript InstanceIds: - '{{dc1InstanceId.InstanceId}}' Parameters: commands: |- Try { Import-Module -Name 'C:\AWSQuickstart\Module-AD\Module-AD.psm1' -Force } Catch [System.Exception] { Write-Output "Failed to import AD PS Module $_" Exit 1 } $EniConfig = Get-EniConfig $DaSecret = Get-SecretInfo -Domain '{{DomainNetBIOSName}}' -SecretArn '{{ADAdminSecParamName}}' $RmSecret = Get-SecretInfo -Domain '{{DomainNetBIOSName}}' -SecretArn '{{RestoreModeSecParamName}}' $AltSecret = Get-SecretInfo -Domain '{{DomainNetBIOSName}}' -SecretArn '{{ADAltUserSecParamName}}' Set-DscConfiguration -AltAdminCredentials $AltSecret.Credentials -AltAdminUserName $AltSecret.Username -DaCredentials $DaSecret.DomainCredentials -DeploymentType 'FirstDc' -DomainDNSName '{{DomainDNSName}}' -DomainNetBIOSName '{{DomainNetBIOSName}}' -GatewayAddress $EniConfig.GatewayAddress -InstanceIP $EniConfig.IpAddress -InstanceNetBIOSName '{{ADServer1NetBIOSName}}' -LaCredentials $DaSecret.Credentials -MacAddress $EniConfig.MacAddress -RestoreModeCredentials $RmSecret.Credentials -SiteName '{{global:REGION}}' -VPCCIDR '{{VPCCIDR}}' CloudWatchOutputConfig: CloudWatchOutputEnabled: true CloudWatchLogGroupName: !Sub /aws/Quick_Start/${AWS::StackName} nextStep: runDc1Mof - name: runDc1Mof action: aws:runCommand onFailure: step:signalfailure inputs: DocumentName: AWS-RunPowerShellScript InstanceIds: - '{{dc1InstanceId.InstanceId}}' Parameters: commands: |- Try { Import-Module -Name 'C:\AWSQuickstart\Module-AD\Module-AD.psm1' -Force } Catch [System.Exception] { Write-Output "Failed to import AD PS Module $_" Exit 1 } Start-DscConfiguration 'C:\AWSQuickstart\ConfigInstance' -Wait -Verbose -Force Invoke-DscStatusCheck CloudWatchOutputConfig: CloudWatchOutputEnabled: true CloudWatchLogGroupName: !Sub /aws/Quick_Start/${AWS::StackName} nextStep: configureDc2Mof - name: configureDc2Mof action: aws:runCommand inputs: DocumentName: AWS-RunPowerShellScript InstanceIds: - '{{dc2InstanceId.InstanceId}}' Parameters: commands: |- Try { Import-Module -Name 'C:\AWSQuickstart\Module-AD\Module-AD.psm1' -Force } Catch [System.Exception] { Write-Output "Failed to import AD PS Module $_" Exit 1 } $EniConfig = Get-EniConfig $DaSecret = Get-SecretInfo -Domain '{{DomainNetBIOSName}}' -SecretArn '{{ADAdminSecParamName}}' $RmSecret = Get-SecretInfo -Domain '{{DomainNetBIOSName}}' -SecretArn '{{RestoreModeSecParamName}}' Set-DscConfiguration -DaCredentials $DaSecret.DomainCredentials -DeploymentType 'SecondaryDC' -DomainDNSName '{{DomainDNSName}}' -DomainNetBIOSName '{{DomainNetBIOSName}}' -ExistingDcIP01 '{{ADServer1PrivateIP}}' -GatewayAddress $EniConfig.GatewayAddress -InstanceIP $EniConfig.IpAddress -InstanceIPDns $EniConfig.DnsIpAddress -InstanceNetBIOSName '{{ADServer2NetBIOSName}}' -MacAddress $EniConfig.MacAddress -RestoreModeCredentials $RmSecret.Credentials CloudWatchOutputConfig: CloudWatchOutputEnabled: true CloudWatchLogGroupName: !Sub /aws/Quick_Start/${AWS::StackName} nextStep: runDc2Mof - name: runDc2Mof action: aws:runCommand onFailure: step:signalfailure inputs: DocumentName: AWS-RunPowerShellScript InstanceIds: - '{{dc2InstanceId.InstanceId}}' Parameters: commands: |- Try { Import-Module -Name 'C:\AWSQuickstart\Module-AD\Module-AD.psm1' -Force } Catch [System.Exception] { Write-Output "Failed to import AD PS Module $_" Exit 1 } Start-DscConfiguration 'C:\AWSQuickstart\ConfigInstance' -Wait -Verbose -Force Invoke-DscStatusCheck CloudWatchOutputConfig: CloudWatchOutputEnabled: true CloudWatchLogGroupName: !Sub /aws/Quick_Start/${AWS::StackName} nextStep: DisableFW - name: DisableFW action: aws:runCommand inputs: DocumentName: AWS-RunPowerShellScript InstanceIds: - '{{dcsInstanceIds.InstanceIds}}' Parameters: commands: |- Try { Get-NetFirewallProfile -ErrorAction Stop | Set-NetFirewallProfile -Enabled False -ErrorAction Stop } Catch [System.Exception] { Write-Output "Failed to disable Windows Firewall $_" Exit 1 } CloudWatchOutputConfig: CloudWatchOutputEnabled: true CloudWatchLogGroupName: !Sub /aws/Quick_Start/${AWS::StackName} nextStep: DnsConfig - name: DnsConfig action: aws:runCommand onFailure: step:signalfailure inputs: DocumentName: AWS-RunPowerShellScript InstanceIds: - '{{dc2InstanceId.InstanceId}}' Parameters: commands: |- Try { Import-Module -Name 'C:\AWSQuickstart\Module-AD\Module-AD.psm1' -Force } Catch [System.Exception] { Write-Output "Failed to import AD PS Module $_" Exit 1 } $DaSecret = Get-SecretInfo -Domain '{{DomainNetBIOSName}}' -SecretArn '{{ADAdminSecParamName}}' Set-DnsDscConfiguration -AD1Deployment -ADServer1NetBIOSName '{{ADServer1NetBIOSName}}' -ADServer2NetBIOSName '{{ADServer2NetBIOSName}}' -ADServer1PrivateIP '{{ADServer1PrivateIP}}' -ADServer2PrivateIP '{{ADServer2PrivateIP}}' -DomainDNSName '{{DomainDNSName}}' -DaCredentials $DaSecret.Credentials -VPCCIDR '{{VPCCIDR}}' CloudWatchOutputConfig: CloudWatchOutputEnabled: true CloudWatchLogGroupName: !Sub /aws/Quick_Start/${AWS::StackName} nextStep: PostConfig - name: PostConfig action: aws:runCommand inputs: DocumentName: AWS-RunPowerShellScript InstanceIds: - '{{dcsInstanceIds.InstanceIds}}' Parameters: commands: |- Try { Import-Module -Name 'C:\AWSQuickstart\Module-AD\Module-AD.psm1' -Force } Catch [System.Exception] { Write-Output "Failed to import AD PS Module $_" Exit 1 } Set-PostPromoConfig -S3BucketName '{{QSS3BucketName}}' -S3BucketRegion '{{QSS3BucketRegion}}' -S3KeyPrefix '{{QSS3KeyPrefix}}' -CreateDefaultOUs '{{CreateDefaultOUs}}' -TombstoneLifetime '{{TombstoneLifetime}}' -DeletedObjectLifetime '{{DeletedObjectLifetime}}' If ('{{EnableAdvancedAudtingandMetrics}}' -eq 'true') { Set-DcAuditDscConfiguration Set-LogsAndMetricsCollection -Role 'DomainController' -Stackname '{{StackName}}' } Invoke-Cleanup -VPCCIDR '{{VPCCIDR}}' CloudWatchOutputConfig: CloudWatchOutputEnabled: true CloudWatchLogGroupName: !Sub /aws/Quick_Start/${AWS::StackName} - name: CFNSignalEnd action: aws:branch inputs: Choices: - NextStep: signalsuccess Not: Variable: '{{StackName}}' StringEquals: '' - NextStep: sleepend Variable: '{{StackName}}' StringEquals: '' - name: signalsuccess action: aws:executeAwsApi isEnd: True inputs: Service: cloudformation Api: SignalResource LogicalResourceId: DomainController2 StackName: '{{StackName}}' Status: SUCCESS UniqueId: '{{dc2InstanceId.InstanceId}}' - name: sleepend action: aws:sleep isEnd: True inputs: Duration: PT1S - name: signalfailure action: aws:executeAwsApi inputs: Service: cloudformation Api: SignalResource LogicalResourceId: DomainController2 StackName: '{{StackName}}' Status: FAILURE UniqueId: '{{dc2InstanceId.InstanceId}}' ADServerRole: Type: AWS::IAM::Role Metadata: cfn_nag: rules_to_suppress: - id: W11 reason: "* required" Properties: Policies: - PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: s3:GetObject Resource: - !Sub arn:${AWS::Partition}:s3:::aws-ssm-${AWS::Region}/* - !Sub arn:${AWS::Partition}:s3:::aws-windows-downloads-${AWS::Region}/* - !Sub arn:${AWS::Partition}:s3:::amazon-ssm-${AWS::Region}/* - !Sub arn:${AWS::Partition}:s3:::amazon-ssm-packages-${AWS::Region}/* - !Sub arn:${AWS::Partition}:s3:::${AWS::Region}-birdwatcher-prod/* - !Sub arn:${AWS::Partition}:s3:::patch-baseline-snapshot-${AWS::Region}/* - !Sub arn:${AWS::Partition}:s3:::aws-ssm-distributor-file-${AWS::Region}/* - !Sub arn:${AWS::Partition}:s3:::aws-ssm-document-attachments-${AWS::Region}/* PolicyName: SSMAgent - PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: s3:ListBucket Resource: !Sub - 'arn:${AWS::Partition}:s3:::${S3Bucket}' - S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] - Effect: Allow Action: s3:GetObject Resource: !Sub - 'arn:${AWS::Partition}:s3:::${S3Bucket}/${QSS3KeyPrefix}*' - S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] - Effect: Allow Action: ssm:StartAutomationExecution Resource: !Sub arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${AWSQuickstartActiveDirectoryDS}:$DEFAULT - Effect: Allow Action: ssm:SendCommand Resource: - !Sub arn:${AWS::Partition}:ssm:${AWS::Region}:*:document/AWS-RunRemoteScript - !Sub arn:${AWS::Partition}:ssm:${AWS::Region}:*:document/AWS-RunPowerShellScript - Effect: Allow Action: ssm:SendCommand Resource: !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:instance/* Condition: StringEquals: 'ssm:ResourceTag/aws:cloudformation:stack-name': !Ref AWS::StackName - Sid: ReadOperations Effect: Allow Action: - ec2:DescribeInstances - ssm:DescribeInstanceInformation - ssm:ListCommands - ssm:ListCommandInvocations Resource: '*' - Effect: Allow Action: cloudformation:SignalResource Resource: !Sub 'arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${AWS::StackName}/*' PolicyName: AWS-Mgmt-Quick-Start-Policy - PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - secretsmanager:GetSecretValue - secretsmanager:DescribeSecret Resource: - !Ref ADAdminSecrets - !Ref RestoreModeSecrets - !Ref ADAltUserSecrets PolicyName: AWS-Mgd-AD-Secret-Policy Path: / ManagedPolicyArns: - !Sub arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore - !Sub arn:${AWS::Partition}:iam::aws:policy/CloudWatchAgentServerPolicy Tags: - Key: StackName Value: !Ref AWS::StackName AssumeRolePolicyDocument: Statement: - Effect: Allow Action: sts:AssumeRole Principal: Service: - ec2.amazonaws.com Version: '2012-10-17' ADServerProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref ADServerRole Path: / ADAdminSecrets: Type: AWS::SecretsManager::Secret Properties: Name: !Sub ADAdministratorSecret-${AWS::StackName} Description: Administrator Password for AD Quick Start GenerateSecretString: SecretStringTemplate: '{"username": "Administrator"}' GenerateStringKey: 'password' PasswordLength: 30 ExcludeCharacters: '"@/\' RestoreModeSecrets: Type: AWS::SecretsManager::Secret Properties: Name: !Sub RestoreModeSecrets-${AWS::StackName} Description: Restore Mode Password for AD Quick Start GenerateSecretString: SecretStringTemplate: '{"username": "Administrator"}' GenerateStringKey: 'password' PasswordLength: 30 ExcludeCharacters: '"@/\' ADAltUserSecrets: Type: AWS::SecretsManager::Secret Properties: Name: !Sub ADAltUserSecrets-${AWS::StackName} Description: Alternate AD Admin User from AD Quick Start SecretString: !Sub '{ "username" : "${DomainAdminUser}", "password" : "${DomainAdminPassword}" }' DomainController1: Type: AWS::EC2::Instance Properties: ImageId: !Ref WINFULLBASE IamInstanceProfile: !Ref ADServerProfile InstanceType: !Ref ADServer1InstanceType SubnetId: !Ref PrivateSubnet1ID Tags: - Key: Name Value: !Ref ADServer1NetBIOSName - Key: Domain Value: !Ref DomainDNSName - Key: Role Value: Domain Controller BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeSize: 60 VolumeType: gp3 Encrypted: true KmsKeyId: !Ref EbsEncryptionKmsKeyId DeleteOnTermination: true - DeviceName: /dev/xvdf Ebs: VolumeSize: !Ref DataDriveSizeGiB VolumeType: gp3 Encrypted: true KmsKeyId: !Ref EbsEncryptionKmsKeyId DeleteOnTermination: true SecurityGroupIds: - !Ref DomainControllersSG PrivateIpAddress: !Ref ADServer1PrivateIP KeyName: !Ref KeyPairName DomainController2: CreationPolicy: ResourceSignal: Timeout: PT60M Count: 1 DependsOn: DomainController1 Type: AWS::EC2::Instance Properties: ImageId: !Ref WINFULLBASE IamInstanceProfile: !Ref ADServerProfile InstanceType: !Ref ADServer2InstanceType SubnetId: !Ref PrivateSubnet2ID Tags: - Key: Name Value: !Ref ADServer2NetBIOSName - Key: Domain Value: !Ref DomainDNSName - Key: Role Value: Domain Controller BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeSize: 60 VolumeType: gp3 Encrypted: true KmsKeyId: !Ref EbsEncryptionKmsKeyId DeleteOnTermination: true - DeviceName: /dev/xvdf Ebs: VolumeSize: !Ref DataDriveSizeGiB VolumeType: gp3 Encrypted: true KmsKeyId: !Ref EbsEncryptionKmsKeyId DeleteOnTermination: true SecurityGroupIds: - !Ref DomainControllersSG PrivateIpAddress: !Ref ADServer2PrivateIP KeyName: !Ref KeyPairName UserData: Fn::Base64: !Sub - | $Params = @{ ADAdminSecParamName = '${ADAdminSecrets}' ADServer1NetBIOSName = '${ADServer1NetBIOSName}' ADServer1PrivateIP = '${ADServer1PrivateIP}' ADServer2NetBIOSName = '${ADServer2NetBIOSName}' ADServer2PrivateIP = '${ADServer2PrivateIP}' ADAltUserSecParamName = '${ADAltUserSecrets}' CreateDefaultOUs = '${CreateDefaultOUs}' DeletedObjectLifetime = '${DeletedObjectLifetime}' DomainDNSName = '${DomainDNSName}' DomainNetBIOSName = '${DomainNetBIOSName}' EnableAdvancedAudtingandMetrics = '${EnableAdvancedAudtingandMetrics}' RestoreModeSecParamName = '${RestoreModeSecrets}' QSS3BucketName = '${QSS3BucketName}' QSS3BucketRegion = '${QSS3BucketRegion}' QSS3KeyPrefix = '${QSS3KeyPrefix}' StackName = '${AWS::StackName}' TombstoneLifetime = '${TombstoneLifetime}' URLSuffix = '${AWS::URLSuffix}' VPCCIDR = '${VPCCIDR}' } Start-SSMAutomationExecution -DocumentName '${AWSQuickstartActiveDirectoryDS}' -Parameter $Params - QSS3BucketName: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Sub '${QSS3BucketName}'] QSS3BucketRegion: !If [UsingDefaultBucket, !Sub '${AWS::Region}', !Sub '${QSS3BucketRegion}'] DomainControllersSG: Type: AWS::EC2::SecurityGroup Metadata: cfn_nag: rules_to_suppress: - id: F1000 reason: "Standard Amazon practice" - id: W42 reason: "Standard Amazon practice" - id: W27 reason: "Standard Amazon practice" Properties: GroupDescription: Domain Controllers Security Group VpcId: !Ref VPCID SecurityGroupIngress: - IpProtocol: tcp Description: DNS FromPort: 53 ToPort: 53 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: udp Description: DNS FromPort: 53 ToPort: 53 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: Kerberos FromPort: 88 ToPort: 88 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: udp Description: Kerberos FromPort: 88 ToPort: 88 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: udp Description: Windows Time FromPort: 123 ToPort: 123 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: RPC Port FromPort: 135 ToPort: 135 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: udp Description: Netlogon FromPort: 138 ToPort: 138 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: LDAP FromPort: 389 ToPort: 389 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: udp Description: LDAP FromPort: 389 ToPort: 389 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: SMB FromPort: 445 ToPort: 445 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: udp Description: SMB FromPort: 445 ToPort: 445 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: udp Description: Kerberos Set & Change Password FromPort: 464 ToPort: 464 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: Kerberos Set & Change Password FromPort: 464 ToPort: 464 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: LDAP over SSL FromPort: 636 ToPort: 636 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: LDAP Global Catalog FromPort: 3268 ToPort: 3268 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: LDAP Global Catalog over SSL FromPort: 3269 ToPort: 3269 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: RDP FromPort: 3389 ToPort: 3389 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: WinRM FromPort: 5985 ToPort: 5985 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: SOAP ADWS FromPort: 9389 ToPort: 9389 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: tcp Description: Random RPC FromPort: 49152 ToPort: 65535 SourceSecurityGroupId: !Ref DomainMembersSG - IpProtocol: udp Description: Random RPC FromPort: 49152 ToPort: 65535 SourceSecurityGroupId: !Ref DomainMembersSG Tags: - Key: Name Value: DomainControllersSecurityGroup DomainMembersSG: Type: AWS::EC2::SecurityGroup Metadata: cfn_nag: rules_to_suppress: - id: F1000 reason: "Standard Amazon practice" Properties: GroupDescription: Domain Members VpcId: !Ref VPCID Tags: - Key: Name Value: DomainMembersSecurityGroup DomainMembersIngressRDP: Type: AWS::EC2::SecurityGroupIngress Properties: Description: RDP GroupId: !Ref DomainMembersSG IpProtocol: tcp FromPort: 3389 ToPort: 3389 SourceSecurityGroupId: !Ref DomainMembersSG DomainMembersIngressWinRMHTTP: Type: AWS::EC2::SecurityGroupIngress Properties: Description: WinRM-HTTP GroupId: !Ref DomainMembersSG IpProtocol: tcp FromPort: 5985 ToPort: 5985 SourceSecurityGroupId: !Ref DomainMembersSG DomainMembersIngressWinRMHTTPS: Type: AWS::EC2::SecurityGroupIngress Properties: Description: WinRM-HTTPS GroupId: !Ref DomainMembersSG IpProtocol: tcp FromPort: 5986 ToPort: 5986 SourceSecurityGroupId: !Ref DomainMembersSG DCSecurityGroupIngress: Type: AWS::EC2::SecurityGroupIngress Properties: Description: Security Group Rule between Domain Controllers GroupId: !Ref DomainControllersSG IpProtocol: '-1' FromPort: -1 ToPort: -1 SourceSecurityGroupId: !Ref DomainControllersSG EntCAStack: Condition: ShouldCreateOneTierPkiResource DependsOn: DomainController2 Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-microsoft-pki/templates/one-tier.template' - S3Region: !If [UsingDefaultBucket, !Ref AWS::Region, !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: AMI: !Ref CaAmi AdministratorSecret: !Ref ADAltUserSecrets DirectoryType: SelfManaged DomainController1IP: !Ref ADServer1PrivateIP DomainController2IP: !Ref ADServer2PrivateIP DomainDNSName: !Ref DomainDNSName DomainMembersSG: !Ref DomainMembersSG DomainNetBIOSName: !Ref DomainNetBIOSName EnableAdvancedAudtingandMetrics: !Ref PKIEnableAdvancedAudtingandMetrics EntCaDataDriveSizeGiB: !Ref CaDataDriveSizeGiB EntCaHashAlgorithm: !Ref CaHashAlgorithm EntCaKeyLength: !Ref CaKeyLength EntCaServerInstanceType: !Ref CaServerInstanceType EntCaServerNetBIOSName: !Ref EntCaServerNetBIOSName EntCaServerSubnet: !Ref PrivateSubnet1ID EntCaValidityPeriodUnits: !Ref CaValidityPeriodUnits KeyPairName: !Ref KeyPairName QSS3BucketName: !Ref QSS3BucketName QSS3BucketRegion: !Ref QSS3BucketRegion QSS3KeyPrefix: !Sub ${QSS3KeyPrefix}submodules/quickstart-microsoft-pki/ S3CRLBucketName: !Ref S3CRLBucketName UseS3ForCRL: !Ref UseS3ForCRL VPCCIDR: !Ref VPCCIDR VPCID: !Ref VPCID TwoTierCAStack: Condition: ShouldCreateTwoTierPkiResource DependsOn: DomainController2 Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-microsoft-pki/templates/two-tier.template' - S3Region: !If [UsingDefaultBucket, !Ref AWS::Region, !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: AMI: !Ref CaAmi AdministratorSecret: !Ref ADAltUserSecrets DirectoryType: SelfManaged DomainController1IP: !Ref ADServer1PrivateIP DomainController2IP: !Ref ADServer2PrivateIP DomainDNSName: !Ref DomainDNSName DomainMembersSG: !Ref DomainMembersSG DomainNetBIOSName: !Ref DomainNetBIOSName EnableAdvancedAudtingandMetrics: !Ref PKIEnableAdvancedAudtingandMetrics KeyPairName: !Ref KeyPairName OrCaDataDriveSizeGiB: !Ref CaDataDriveSizeGiB OrCaHashAlgorithm: !Ref CaHashAlgorithm OrCaKeyLength: !Ref CaKeyLength OrCaServerInstanceType: !Ref CaServerInstanceType OrCaServerNetBIOSName: !Ref OrCaServerNetBIOSName OrCaServerSubnet: !Ref PrivateSubnet1ID OrCaValidityPeriodUnits: !Ref OrCaValidityPeriodUnits QSS3BucketName: !Ref QSS3BucketName QSS3BucketRegion: !Ref QSS3BucketRegion QSS3KeyPrefix: !Sub ${QSS3KeyPrefix}submodules/quickstart-microsoft-pki/ S3CRLBucketName: !Ref S3CRLBucketName SubCaDataDriveSizeGiB: !Ref CaDataDriveSizeGiB SubCaHashAlgorithm: !Ref CaHashAlgorithm SubCaKeyLength: !Ref CaKeyLength SubCaServerInstanceType: !Ref CaServerInstanceType SubCaServerNetBIOSName: !Ref EntCaServerNetBIOSName SubCaServerSubnet: !Ref PrivateSubnet1ID SubCaValidityPeriodUnits: !Ref CaValidityPeriodUnits UseS3ForCRL: !Ref UseS3ForCRL VPCCIDR: !Ref VPCCIDR VPCID: !Ref VPCID ADResourceGroup: Condition: AppInsightsEnabled Type: AWS::ResourceGroups::Group Properties: Name: !If [UsingDefaultAppName, !Sub "ApplicationInsights-${AWS::StackName}", !Ref AppInsightsApplicationName] ResourceQuery: Query: TagFilters: - Key: 'aws:cloudformation:stack-name' Values: - !Sub "${AWS::StackName}" Type: 'TAG_FILTERS_1_0' ApplicationInsightsAD: Condition: AppInsightsEnabled Type: AWS::ApplicationInsights::Application Properties: ResourceGroupName: !Ref ADResourceGroup AutoConfigurationEnabled: true DependsOn: ADResourceGroup Outputs: ADSecretsArn: Description: Alternate AD User Secrets ARN Value: !Ref ADAltUserSecrets DC1InstanceId: Description: DomainController 1 instance ID Value: !Ref DomainController1 DC2InstanceId: Description: DomainController 2 instance ID Value: !Ref DomainController2 DomainAdmin: Description: Domain administrator account Value: !Sub ${DomainNetBIOSName}\${DomainAdminUser} DomainControllersSGID: Description: Domain Controllers Security Group ID Value: !Ref DomainControllersSG DomainMemberSGID: Description: Domain Member Security Group ID Value: !Ref DomainMembersSG