AWSTemplateFormatVersion: '2010-09-09' Description: CloudFormation template for creating a new VPC with AD controller Parameters: AvailabilityZones: Description: The list of Availability Zones to use for the subnets in the VPC. Three Availability Zones are used for this deployment, and the logical order of your selections is preserved. Default: us-east-1a,us-east-1b,us-east-1c # AllowedValues: ["us-east-1a,us-east-1b,us-east-1c"] Type: List KeyPairName: Description: The name of an existing public/private key pair, which allows you to securely connect to your instance after it launches Type: AWS::EC2::KeyPair::KeyName 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 AllowedValues: [ '10.0.0.0/19' ] Description: The 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 AllowedValues: [ '10.0.32.0/19' ] Description: The CIDR block for private subnet 2 located in Availability Zone 2 Type: String PrivateSubnet3CIDR: 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.64.0/19 AllowedValues: [ '10.0.64.0/19' ] Description: The 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 AllowedValues: [ '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 AllowedValues: [ '10.0.144.0/20' ] Description: The CIDR block for the public (DMZ) subnet 2 located in Availability Zone 2 Type: String PublicSubnet3CIDR: 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.160.0/20 AllowedValues: [ '10.0.160.0/20' ] Description: The 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. This string can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). Type: String AllowedValues: [ 'aws-quickstart' ] QSS3KeyPrefix: AllowedPattern: ^[0-9a-zA-Z-/.]*$ ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), dots(.) and forward slash (/). Default: quickstart-amazon-eks/ Description: S3 key prefix for the Quick Start assets. Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), dots(.) and forward slash (/). Type: String AllowedValues: [ 'quickstart-amazon-eks/' ] CIDRAccessToADAndBastion: 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: The CIDR IP range that is permitted to access the instances. We recommend that you set this value to a trusted IP range. Type: String Default: 10.0.0.0/16 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 AllowedValues: [ '10.0.0.0/16' ] Description: The CIDR block for the VPC Type: String NumberOfAZs: Type: String AllowedValues: [ "2", "3" ] Default: "3" Description: Number of Availability Zones to use in the VPC. This must match your selections in the list of Availability Zones parameter. S3Bucket: Description: S3Bucket for the code [works for all AWS regions - no update required] Type: String Default: aws-bigdata-blog AllowedValues: [ "aws-bigdata-blog" ] S3Key: Description: S3Key of the code [works for all AWS regions - no update required] Type: String Default: artifacts/aws-blog-emr-ranger AllowedValues: [ "artifacts/aws-blog-emr-ranger" ] S3ArtifactBucket: Description: S3Bucket where artifacts are stored Type: String Default: aws-bigdata-blog AllowedValues: [ "aws-bigdata-blog" ] S3ArtifactKey: Description: S3Key of the Lambda code Type: String Default: artifacts/aws-blog-emr-ranger AllowedValues: [ "artifacts/aws-blog-emr-ranger" ] ProjectVersion: Default: 3.0 Description: Project version Type: String AllowedValues: - 3.0 - beta 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 - Eg: CheckSum123' MaxLength: '32' MinLength: '8' NoEcho: 'true' Type: String CrossRealmTrustPrincipalPassword: Description: 'Password that you want to use for your cross-realm trust - Eg: CheckSum123' MaxLength: '32' MinLength: '5' NoEcho: 'true' Type: String LDAPBindPassword: Description: LDAPBindPassword AD server Type: String NoEcho: true DefaultADUserPassword: Description: Default Password for all users created in the AD server. Eg - analyst1, analyst2 Type: String NoEcho: true ADServerAMI: Type: 'AWS::SSM::Parameter::Value' Default: '/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base' Description: SSM Parameter alias of a Windows Server AMI AttachAdditionalSourcePrefixToSG: Description: (Optional) Attaches additional sources prefix lists to Bastion Host and AD server Default: false Type: String AllowedValues: [ true, false ] AdditionalSourcePrefixToSG: Description: (Optional) Sources that are allowd to access to Bastion Host and AD server. Should be a source prefix e.g., pl-xxx Type: String Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Minimum required fields (others can be kept as default) Parameters: - KeyPairName - CIDRAccessToADAndBastion - CrossRealmTrustPrincipalPassword - DomainAdminPassword - LDAPBindPassword - DefaultADUserPassword Mappings: DefaultConfiguration: MachineConfiguration: BastionInstanceType: t3.small NetworkConfiguration: VPCCIDR: 10.0.0.0/16 PublicSubnet1CIDR: 10.0.1.0/24 PrivateSubnet1CIDR: 10.0.2.0/24 PublicSubnet2CIDR: 10.0.3.0/24 PrivateSubnet2CIDR: 10.0.4.0/24 PublicSubnet3CIDR: 10.0.5.0/24 PrivateSubnet3CIDR: 10.0.6.0/24 Conditions: 3AZDeployment: !Equals [ !Ref NumberOfAZs, "3" ] 2AZDeployment: !Or - !Equals [ !Ref NumberOfAZs, "2" ] - !Equals [ !Ref NumberOfAZs, "3" ] AttachAdditionalSourcePrefixToSG: !Equals [ true, !Ref AttachAdditionalSourcePrefixToSG ] Resources: STEP1VPC: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template.yaml' Parameters: AvailabilityZones: !Join [ ',', !Ref 'AvailabilityZones' ] NumberOfAZs: !Ref 'NumberOfAZs' PrivateSubnet1ACIDR: !FindInMap - DefaultConfiguration - NetworkConfiguration - PrivateSubnet1CIDR PrivateSubnet2ACIDR: !FindInMap - DefaultConfiguration - NetworkConfiguration - PrivateSubnet2CIDR PrivateSubnet3ACIDR: !FindInMap - DefaultConfiguration - NetworkConfiguration - PrivateSubnet3CIDR PublicSubnet1CIDR: !FindInMap - DefaultConfiguration - NetworkConfiguration - PublicSubnet1CIDR PublicSubnet2CIDR: !FindInMap - DefaultConfiguration - NetworkConfiguration - PublicSubnet2CIDR PublicSubnet3CIDR: !FindInMap - DefaultConfiguration - NetworkConfiguration - PublicSubnet3CIDR VPCCIDR: !FindInMap - DefaultConfiguration - NetworkConfiguration - VPCCIDR PublicSubnetTag2: "emr-cluster=" STEP1aBastionHost: Type: AWS::CloudFormation::Stack DependsOn: - STEP1VPC Properties: TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-linux-bastion/templates/linux-bastion-entrypoint-existing-vpc.template.yaml' Parameters: BastionInstanceType: !FindInMap - DefaultConfiguration - MachineConfiguration - BastionInstanceType KeyPairName: !Ref 'KeyPairName' RemoteAccessCIDR: !Ref 'CIDRAccessToADAndBastion' PublicSubnet1ID: !GetAtt 'STEP1VPC.Outputs.PublicSubnet1ID' PublicSubnet2ID: !GetAtt 'STEP1VPC.Outputs.PublicSubnet2ID' VPCID: !GetAtt 'STEP1VPC.Outputs.VPCID' BastionHostAdditionalInboundRule: Condition: AttachAdditionalSourcePrefixToSG Type: AWS::EC2::SecurityGroupIngress Properties: IpProtocol: '-1' SourcePrefixListId: !Ref AdditionalSourcePrefixToSG GroupId: !GetAtt [ STEP1aBastionHost, Outputs.BastionSecurityGroupID ] STEP2WinAD: DependsOn: STEP1VPC Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Join [ '', [ 'https://s3.amazonaws.com/', !Ref 'S3ArtifactBucket', '/', !Ref 'S3ArtifactKey', '/', !Ref 'ProjectVersion', '/cloudformation/', 'ec2-win-ad.template' ] ] Parameters: KeyPairName: !Ref 'KeyPairName' # ImageId: !GetAtt 'STEP0AMILookup.Outputs.AMIID' ImageId: !Ref ADServerAMI Subnet: !GetAtt 'STEP1VPC.Outputs.PublicSubnet1ID' VPC: !GetAtt 'STEP1VPC.Outputs.VPCID' # SecurityGroup: !GetAtt 'STEP1VPC.Outputs.SecurityGroup' CIDRAccessToADAndBastion: !Ref 'CIDRAccessToADAndBastion' DomainAdminPassword: !Ref 'DomainAdminPassword' LDAPBindPassword: !Ref 'LDAPBindPassword' DefaultADUserPassword: !Ref 'DefaultADUserPassword' CrossRealmTrustPrincipalPassword: !Ref 'CrossRealmTrustPrincipalPassword' ADAdditionalInboundRule: Condition: AttachAdditionalSourcePrefixToSG Type: AWS::EC2::SecurityGroupIngress Properties: IpProtocol: '-1' SourcePrefixListId: !Ref AdditionalSourcePrefixToSG GroupId: !GetAtt [ STEP2WinAD, Outputs.ADSecurityGroupID ] Outputs: LDAPHostPrivateIP: Value: !GetAtt [ STEP2WinAD, Outputs.LDAPHostPrivateIP ] Description: LDAP Host Private IP address VPC: Value: !GetAtt [ STEP1VPC, Outputs.VPCID ] Description: VPC ID PrivateSubnet1AID: Value: !GetAtt [ STEP1VPC, Outputs.PrivateSubnet1AID ] Description: PrivateSubnet1AID PrivateSubnet2AID: Value: !GetAtt [ STEP1VPC, Outputs.PrivateSubnet2AID ] Description: PrivateSubnet2AID PublicSubnet1AID: Value: !GetAtt [ STEP1VPC, Outputs.PublicSubnet1ID ] Description: PublicSubnet1AID PublicSubnet2AID: Value: !GetAtt [ STEP1VPC, Outputs.PublicSubnet2ID ] Description: PublicSubnet2AID