AWSTemplateFormatVersion: '2010-09-09' Description: This master template creates a VPC infrastructure for a multi-AZ, multi-tier deployment of a workload on AWS. It deploys a VPC with bastions and a workload cluster behind an ELB. The cluster is configured to use an S3 bucket for storage **WARNING** This template creates EC2 instances 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 - VPCCIDR - PrivateSubnet1CIDR - PrivateSubnet2CIDR - PublicSubnet1CIDR - PublicSubnet2CIDR - RemoteAccessCIDR - Label: default: Choose Environment Access Type Parameters: - EnvironmentAccessType - KeyPairName - Label: default: Bastion configuration (Only Used if EnvironmentAccessType is "Bastion") Parameters: - BastionAMIOS - BastionInstanceType - Label: default: Microsoft Remote Desktop Gateway Configuration (Only Used if EnvironmentAccessType is "RDGW") Parameters: - RDGWInstanceType - NumberOfRDGWHosts - LatestAmiId - NumberOfRDGWHosts - AdminUser - AdminPassword - DomainDNSName - Label: default: Workload nodes configuration Parameters: - WorkloadInstanceType - WorkloadNodesMinSize - NodesMaxSize - WorkloadoNodesDesiredCapacity - WorkloadNodesMaxSize - OperatorEmail - Label: default: Workload storage configuration Parameters: - S3BucketName - Label: default: AWS Quick Start configuration Parameters: - QSS3BucketName - QSS3BucketRegion - QSS3KeyPrefix ParameterLabels: AvailabilityZones: default: Availability Zones BastionAMIOS: default: Bastion AMI operating system BastionInstanceType: default: Bastion instance type AdminPassword: default: Admin Password AdminUser: default: Admin User Name LatestAmiId: default: SSM Parameter to Grab Latest AMI ID NumberOfRDGWHosts: default: Number of RDGW Hosts RDGWInstanceType: default: Remote Desktop Gateway Instance Type KeyPairName: default: Key pair name OperatorEmail: default: Operator email PrivateSubnet1CIDR: default: Private subnet 1 CIDR PrivateSubnet2CIDR: default: Private subnet 2 CIDR PublicSubnet1CIDR: default: Public subnet 1 CIDR PublicSubnet2CIDR: default: Public subnet 2 CIDR QSS3BucketName: default: Quick Start S3 bucket name QSS3BucketRegion: default: Quick Start S3 bucket region QSS3KeyPrefix: default: Quick Start S3 Key Prefix S3BucketName: default: S3 bucket name RemoteAccessCIDR: default: Allowed bastion external access CIDR VPCCIDR: default: VPC CIDR WorkloadInstanceType: default: Workload servers instance type WorkloadoNodesDesiredCapacity: default: Workload nodes desired capacity WorkloadNodesMaxSize: default: Workload nodes max size WorkloadNodesMinSize: default: Workload nodes min size Parameters: AvailabilityZones: Description: List of Availability Zones to use for the subnets in the VPC. Only two Availability Zones are used for this deployment, and the logical order of your selections is preserved. Type: List EnvironmentAccessType: AllowedValues: - Bastion - RDGW Default: Bastion Description: Select whether you want to use a Linux Bastion or Windows RDGateway to access the envirnoment. If you select Bastion only fill in the Bastion specfic parameters. If you selected RDGW only fill in the RDGW parameters. Type: String BastionAMIOS: AllowedValues: - Amazon-Linux2-HVM - CentOS-7-HVM - Ubuntu-Server-20.04-LTS-HVM - SUSE-SLES-15-HVM Default: Amazon-Linux2-HVM Description: Only select if "EnvironmentAccessType" is "Bastion". Linux distribution for the AMI to be used for the bastion instances. Type: String BastionInstanceType: AllowedValues: - t2.nano - t2.micro - t2.small - t2.medium - t2.large - m3.large - m3.xlarge - m3.2xlarge - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge Default: t2.micro Description: Only select if "EnvironmentAccessType" is "Bastion". Amazon EC2 instance type for the bastion instances. Type: String AdminPassword: Description: Only select if "EnvironmentAccessType" is "RDGW". 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: Only select if "EnvironmentAccessType" is "RDGW". User name for the new local administrator account Type: String Default: StackAdmin MinLength: '5' MaxLength: '25' AllowedPattern: '[a-zA-Z0-9]*' LatestAmiId: Type: AWS::SSM::Parameter::Value Default: /aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base Description: Only select if "EnvironmentAccessType" is "RDGW". NumberOfRDGWHosts: AllowedValues: - '1' - '2' - '3' - '4' Default: '1' Description: Enter the number of Remote Desktop Gateway hosts to create Type: String RDGWInstanceType: Description: Only select if "EnvironmentAccessType" is "RDGW". Amazon EC2 instance type for the Remote Desktop Gateway instances Type: String Default: t2.large AllowedValues: - t2.small - t2.medium - t2.large - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge DomainDNSName: Description: Only select if "EnvironmentAccessType" is "RDGW". Fully qualified domain name (FQDN) e.g. example.com Type: String Default: example.com MinLength: '2' MaxLength: '255' AllowedPattern: '[a-zA-Z0-9\-]+\..+' KeyPairName: Description: 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 OperatorEmail: AllowedPattern: ([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?) ConstraintDescription: Must be a valid email address. Description: Email address that notifications of any scaling operations will be sent to. 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 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 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 QSS3BucketRegion: 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: ^[0-9a-zA-Z-/]*$ ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/). Default: quickstart-workshop/ 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 RemoteAccessCIDR: 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: CIDR IP range that is permitted to access the bastion/rdgw. We recommend that you set this value to a trusted IP range. Type: String S3BucketName: AllowedPattern: ^[a-z0-9][a-z0-9-.]*$ Default: type-unique-value-here-in-lowercase Description: Name of the S3 bucket that will be created for your workload to store data. Enter a unique name that does not include uppercase characters. 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 WorkloadInstanceType: AllowedValues: - t2.large - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge - m4.10xlarge - m3.medium - m3.large - m3.xlarge - m3.2xlarge - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - c3.large - c3.xlarge - c3.2xlarge - c3.4xlarge - c3.8xlarge - r3.large - r3.xlarge ConstraintDescription: Must contain valid instance type Default: m4.xlarge Description: EC2 instance type for the workload instances. Type: String WorkloadNodesDesiredCapacity: Default: '2' Description: Desired capacity for the workload nodes Auto Scaling group. Type: String WorkloadNodesMaxSize: Default: '4' Description: Maximum size of the Auto Scaling group. Type: String WorkloadNodesMinSize: Default: '2' Description: Minimum size of the Auto Scaling group. Type: String Conditions: UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart'] BastionCond: !Equals [!Ref EnvironmentAccessType, 'Bastion'] RDGWCond: !Equals [!Ref EnvironmentAccessType, 'RDGW'] Resources: VPCStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template.yaml' - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: AvailabilityZones: !Join [',', !Ref 'AvailabilityZones'] NumberOfAZs: '2' PrivateSubnet1ACIDR: !Ref PrivateSubnet1CIDR PrivateSubnet2ACIDR: !Ref PrivateSubnet2CIDR PublicSubnet1CIDR: !Ref PublicSubnet1CIDR PublicSubnet2CIDR: !Ref PublicSubnet2CIDR VPCCIDR: !Ref VPCCIDR BastionStack: DependsOn: VPCStack Condition: BastionCond Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-linux-bastion/templates/linux-bastion.template' - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: QSS3BucketName: !Ref QSS3BucketName QSS3BucketRegion: !Ref QSS3BucketRegion QSS3KeyPrefix: !Sub '${QSS3KeyPrefix}submodules/quickstart-linux-bastion/' BastionAMIOS: !Ref BastionAMIOS BastionInstanceType: !Ref BastionInstanceType KeyPairName: !Ref KeyPairName PublicSubnet1ID: !GetAtt VPCStack.Outputs.PublicSubnet1ID PublicSubnet2ID: !GetAtt VPCStack.Outputs.PublicSubnet2ID RemoteAccessCIDR: !Ref RemoteAccessCIDR VPCID: !GetAtt VPCStack.Outputs.VPCID RDGWStack: Type: 'AWS::CloudFormation::Stack' DependsOn: VPCStack Condition: RDGWCond Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-microsoft-rdgateway/templates/rdgw-standalone.template' - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: AdminUser: 'admin' AdminPassword: !Ref AdminPassword DomainDNSName: !Ref DomainDNSName KeyPairName: !Ref KeyPairName PublicSubnet1ID: !GetAtt VPCStack.Outputs.PublicSubnet1ID PublicSubnet2ID: !GetAtt VPCStack.Outputs.PublicSubnet2ID QSS3BucketName: !Ref QSS3BucketName QSS3BucketRegion: !Ref QSS3BucketRegion QSS3KeyPrefix: !Sub '${QSS3KeyPrefix}submodules/quickstart-microsoft-rdgateway/' RDGWInstanceType: !Ref RDGWInstanceType RDGWCIDR: !Ref RemoteAccessCIDR VPCID: !GetAtt VPCStack.Outputs.VPCID WorkloadStack: Metadata: PseudoDependsOn: - !If [BastionCond, !Ref 'BastionStack', !Ref 'AWS::NoValue'] - !If [RDGWCond, !Ref 'RDGWStack', !Ref 'AWS::NoValue'] Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/workshop.template.yaml' - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: WorkloadInstanceType: !Ref WorkloadInstanceType WorkloadNodesDesiredCapacity: !Ref WorkloadNodesDesiredCapacity WorkloadNodesMaxSize: !Ref WorkloadNodesMaxSize WorkloadNodesMinSize: !Ref WorkloadNodesMinSize SecurityGroupID: !If [BastionCond, !GetAtt BastionStack.Outputs.BastionSecurityGroupID, !GetAtt RDGWStack.Outputs.RemoteDesktopGatewaySGID] KeyPairName: !Ref KeyPairName OperatorEmail: !Ref OperatorEmail PrivateSubnet1ID: !GetAtt VPCStack.Outputs.PrivateSubnet1AID PrivateSubnet2ID: !GetAtt VPCStack.Outputs.PrivateSubnet2AID PublicSubnet1ID: !GetAtt VPCStack.Outputs.PublicSubnet1ID PublicSubnet2ID: !GetAtt VPCStack.Outputs.PublicSubnet2ID QSS3BucketName: !Ref QSS3BucketName QSS3KeyPrefix: !Ref QSS3KeyPrefix S3BucketName: !Ref S3BucketName VPCID: !GetAtt VPCStack.Outputs.VPCID