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 deploys a managed Microsoft AD Directory Service 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. Amazon WorkSpace and RADIUS server are launched in the selected subnets. Ensure the selected Availability Zones are supported by WorkSpaces. The default domain administrator user is 'admin'. This is the user a WorkSpace is created for. **WARNING** This template creates Amazon EC2 Windows instances, WorkSpace, RDS Cluster, and other related resources. You'll be billed for the AWS resources used if you create a stack from this template. (qs-1t9sl8r1u) Metadata: QuickStartDocumentation: EntrypointName: 'Parameters for deploying AWS Managed Microsoft AD into a new VPC.' Order: '1' cfn-lint: config: ignore_checks: - E9101 - W9006 - E0002 - W9001 ignore_reason: - "Execution part SSM Automation" - "Referenced file does not have parameter, " AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Network configuration Parameters: - AvailabilityZones - NumberOfAZs - VPCCIDR - DHCPOptionSet - PrivateSubnet1CIDR - PrivateSubnet2CIDR - PrivateSubnet3CIDR - PublicSubnet1CIDR - PublicSubnet2CIDR - PublicSubnet3CIDR - Label: default: Amazon EC2 configuration Parameters: - KeyPairName - Label: default: Microsoft AD configuration Parameters: - DomainDNSName - DomainNetBIOSName - DomainAdminPassword - NonWindowsDomainJoin - ADEdition - Label: default: Microsoft Windows Server management instance Parameters: - MgmtServer - MgmtServerInstanceType - MgmtDataDriveSizeGiB - MgmtServerNetBIOSName - MgmtServerEnableAdvancedAudtingandMetrics - Label: default: Microsoft AD Certificate Services configuration Parameters: - PKI - CaServerInstanceType - CaDataDriveSizeGiB - OrCaServerNetBIOSName - EntCaServerNetBIOSName - CaKeyLength - CaHashAlgorithm - OrCaValidityPeriodUnits - CaValidityPeriodUnits - UseS3ForCRL - S3CRLBucketName - Label: default: Microsoft RD Gateway configuration Parameters: - NumberOfRDGWHosts - RDGWInstanceType - RDGWCIDR - Label: default: WorkSpaces and WorkSpaces directory configuration. Parameters: - DomainUser - Tenancy - EnableSelfService - EnableWorkDocs - BundleId - ComputeTypeName - RunningMode - UserVolumeEncryptionEnabled - RootVolumeEncryptionEnabled - VolumeEncryptionKey - UserVolumeSizeGib - RootVolumeSizeGib - Label: default: RADIUS database and server configuration. Parameters: - LinOTPDBName - LinOTPAdminPassword - LinOTPReamlName - RADIUSServerInstanceType - Label: default: AWS solution configuration Parameters: - QSS3BucketName - QSS3BucketRegion - QSS3KeyPrefix - Label: default: SNS/KMS configurations Parameters: - QuickStartAdminEmail ParameterLabels: ADEdition: default: AWS Managed Microsoft AD edition AvailabilityZones: default: Availability Zones 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 DHCPOptionSet: default: Create DHCP options set DomainAdminPassword: default: Admin account password DomainDNSName: default: Domain DNS name DomainNetBIOSName: default: Domain NetBIOS name EntCaServerNetBIOSName: default: Enterprise root or subordinate CA NetBIOS name KeyPairName: default: Key pair name MgmtDataDriveSizeGiB: default: Data drive size MgmtServer: default: Deploy Management Server MgmtServerEnableAdvancedAudtingandMetrics: default: Advanced auditing and metrics MgmtServerInstanceType: default: Management Server instance type MgmtServerNetBIOSName: default: Management Server NetBIOS name NonWindowsDomainJoin: default: Create AD user with minimum permissions used by non-Windows instances to join domain NumberOfAZs: default: Number of Availability Zones NumberOfRDGWHosts: default: Number of RDGW hosts OrCaServerNetBIOSName: default: Offline root CA NetBIOS name OrCaValidityPeriodUnits: default: Offline root CA certificate validity period PKI: default: Deploy PKI infrastructure 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 DomainUser: default: Domain admin user Tenancy: default: WorkSpaces VPC tenancy BundleId: default: WorkSpace bundle ID ComputeTypeName: default: 'Workspaces compute type' RunningMode: default: WorkSpaces running mode UserVolumeEncryptionEnabled: default: Encrypt WorkSpace user volume RootVolumeEncryptionEnabled: default: Encrypt WorkSpace user volume VolumeEncryptionKey: default: Enter WorkSpace KMS key to encrypt volumes UserVolumeSizeGib: default: Size of WorkSpace user volume storage RootVolumeSizeGib: default: Size of WorkSpace root volume storage LinOTPDBName: default: Database name for LinOTP configuration QSS3BucketName: AllowedPattern: ^[0-9a-z]+([0-9a-z-\.]*[0-9a-z])*$ ConstraintDescription: >- The S3 bucket name can include numbers, lowercase letters, and hyphens (-), but it cannot start or end with a hyphen. Default: 'aws-quickstart' Description: >- Name of the S3 bucket for your copy of the deployment assets. Keep the default name unless you are customizing the template. Changing the name updates code references to point to a new location. MinLength: 3 MaxLength: 63 Type: 'String' QSS3BucketRegion: Default: us-east-1 Description: >- AWS Region where the S3 bucket (QSS3BucketName) is hosted. Keep the default Region unless you are customizing the template. Changing the Region updates code references to point to a new location. When using your own bucket, specify the Region. Type: String QSS3KeyPrefix: AllowedPattern: ^([0-9a-zA-Z!-_\.\*'\(\)/]+/)*$ ConstraintDescription: >- The S3 key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), underscores (_), periods (.), asterisks (*), single quotes ('), open parenthesis ((), close parenthesis ()), and forward slashes (/). End the prefix with a forward slash. Default: quickstart-freeradius-mfa-workspaces/ Description: >- S3 key prefix that is used to simulate a folder for your copy of the deployment assets. Keep the default prefix unless you are customizing the template. Changing the prefix updates code references to point to a new location. Type: 'String' RDGWCIDR: default: Allowed RD Gateway external access CIDR RDGWInstanceType: default: RD Gateway instance type S3CRLBucketName: default: CA CRL S3 bucket name UseS3ForCRL: default: Use S3 for CA CRL location VPCCIDR: default: VPC CIDR QuickStartAdminEmail: default: Admin email for notifications upon successful creation Parameters: ADEdition: AllowedValues: - Standard - Enterprise Default: Enterprise Description: AWS Managed Microsoft AD edition to deploy. Type: String AvailabilityZones: Description: 'List of Availability Zones to use for subnets in VPC. Logical order is preserved and only 2 Availability Zones are used for this deployment. Choose Availability Zones supported by Amazon WorkSpaces.' Type: List CaDataDriveSizeGiB: Default: '2' Description: Size of data drive (in GiB) for CA instance(s). Type: Number 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 CA instance(s). Type: String CaValidityPeriodUnits: Default: '5' Description: Validity period (in years). Type: String DHCPOptionSet: AllowedValues: - 'Yes' - 'No' Default: 'Yes' Description: DCreate and apply new DHCP options set. 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 admin user account. Minimum of 8 characters containing letters, numbers, and symbols. MaxLength: '32' MinLength: '8' NoEcho: 'true' Type: String DomainDNSName: AllowedPattern: '[a-zA-Z0-9\-]+\..+' Default: example.com Description: Fully qualified domain name (FQDN) of forest root domain (example-demo.com). MaxLength: '255' MinLength: '2' Type: String DomainNetBIOSName: AllowedPattern: '[a-zA-Z0-9\-]+' Default: example Description: NetBIOS name of domain (maximum 15 characters) for users of earlier versions of Windows (example-DEMO). MaxLength: '15' MinLength: '1' Type: String EntCaServerNetBIOSName: AllowedPattern: '[a-zA-Z0-9\-]+' Default: ENTCA1 Description: NetBIOS name of enterprise root or subordinate CA server (maximum 15 characters). MaxLength: '15' MinLength: '1' Type: String KeyPairName: Description: Public/private key pairs to securely connect to your instance after it launches. Type: AWS::EC2::KeyPair::KeyName MgmtDataDriveSizeGiB: Default: '2' Description: Size of Management Server data drive (in GiB). Type: Number MgmtServer: AllowedValues: - 'true' - 'false' Default: 'true' Description: Deploy Management Server. Type: String MgmtServerEnableAdvancedAudtingandMetrics: Description: Enable advanced auditing and metrics, and upload to CloudWatch using Amazon Kinesis Agent for Microsoft Windows. AllowedValues: - 'true' - 'false' Type: String Default: 'false' MgmtServerInstanceType: AllowedValues: - 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 Management Server. Type: String MgmtServerNetBIOSName: AllowedPattern: '[a-zA-Z0-9\-]+' Default: MGMT1 Description: NetBIOS name of Management Server server (maximum 15 characters). MaxLength: '15' MinLength: '1' Type: String NonWindowsDomainJoin: AllowedValues: - 'true' - 'false' Default: 'false' Description: | Create AD user with minimal permissions. Allows non-Windows instances to join domain. User name and password are stored in Secrets Manager and policy to access secret is created. Type: String NumberOfAZs: AllowedValues: - '2' - '3' Default: '2' Description: Number of Availability Zones to use in VPC. Must match your selections in list of Availability Zones parameter. Type: String NumberOfRDGWHosts: AllowedValues: - '0' - '1' - '2' - '3' - '4' Default: '1' Description: Number of RD Gateway instances to create. Type: String OrCaServerNetBIOSName: AllowedPattern: '[a-zA-Z0-9\-]+' Default: ORCA1 Description: NetBIOS name of offline root CA server (only used for two tier PKI) (maximum 15 characters). MaxLength: '15' MinLength: '1' Type: String OrCaValidityPeriodUnits: Default: '10' Description: Validity period (in years) (only used for two tier PKI). Type: String 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 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 format 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 format 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 format x.x.x.x/16-28). Default: 10.0.128.0/20 Description: CIDR block for public 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 format x.x.x.x/16-28). Default: 10.0.144.0/20 Description: CIDR block for public subnet 2 located in Availability Zone 2. Type: String PublicSubnet3CIDR: Default: '' Description: CIDR Block for public subnet 3 located in Availability Zone 3. Type: String QSS3BucketName: AllowedPattern: ^[0-9a-z]+([0-9a-z-\.]*[0-9a-z])*$ ConstraintDescription: >- The S3 bucket name can include numbers, lowercase letters, and hyphens (-), but it cannot start or end with a hyphen. Default: 'aws-quickstart' Description: >- Name of the S3 bucket for your copy of the deployment assets. Keep the default name unless you are customizing the template. Changing the name updates code references to point to a new location. MinLength: 3 MaxLength: 63 Type: 'String' QSS3BucketRegion: Default: us-east-1 Description: >- AWS Region where the S3 bucket (QSS3BucketName) is hosted. Keep the default Region unless you are customizing the template. Changing the Region updates code references to point to a new location. When using your own bucket, specify the Region. Type: String QSS3KeyPrefix: AllowedPattern: ^([0-9a-zA-Z!-_\.\*'\(\)/]+/)*$ ConstraintDescription: >- The S3 key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), underscores (_), periods (.), asterisks (*), single quotes ('), open parenthesis ((), close parenthesis ()), and forward slashes (/). End the prefix with a forward slash. Default: quickstart-freeradius-mfa-workspaces/ Description: >- S3 key prefix that is used to simulate a folder for your copy of the deployment assets. Keep the default prefix unless you are customizing the template. Changing the prefix updates code references to point to a new location. 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]))$ ConstraintDescription: CIDR block parameter (must be in format x.x.x.x/x). Default: 10.0.0.0/16 Description: Allowed CIDR block for external access to RD Gateways. Type: String RDGWInstanceType: AllowedValues: - t2.small - t2.medium - t2.large - t3.small - t3.medium - t3.large - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge Default: t3.large Description: Amazon EC2 instance type for RD Gateway instances. Type: String S3CRLBucketName: AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ Default: examplebucket Description: S3 bucket name for CA CRL(s) storage. Bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It can't start or end with a hyphen (-). Type: String UseS3ForCRL: AllowedValues: - 'Yes' - 'No' Default: 'No' Description: Store CA CRL(s) in 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 format x.x.x.x/16-28). Default: 10.0.0.0/16 Description: CIDR block for VPC. Type: String ## WorkSpaces Configuration DomainUser: Default: Admin Description: Domain admin user. Type: String Tenancy: AllowedValues: - 'DEDICATED' - 'SHARED' Default: 'SHARED' Description: WorkSpace directory is dedicated or shared. To use Bring Your Own License (BYOL) images, set this value to DEDICATED and enable your AWS account for BYOL. If your account hasn't been enabled for BYOL, you'll receive an InvalidParameterValuesException error. Type: String EnableWorkDocs: AllowedValues: - 'true' - 'false' Default: 'false' Description: Amazon WorkDocs is enabled or disabled. If enabled and WorkDocs isn't available in the region, you'll receive an OperationNotSupportedException error. Set EnableWorkDocs to disabled and try again. Type: String EnableSelfService: AllowedValues: - 'true' - 'false' Default: 'true' Description: Self-service capabilities are enabled or disabled. Type: String RootVolumeEncryptionEnabled: AllowedValues: - 'true' - 'false' Default: 'true' Description: Data stored on root volume is encrypted. Type: String UserVolumeEncryptionEnabled: AllowedValues: - 'true' - 'false' Default: 'true' Description: Data stored on user volume is encrypted. Type: String VolumeEncryptionKey: Type: String Default: alias/aws/workspaces Description: Symmetric AWS KMS key used to encrypt data stored on your WorkSpace. WorkSpaces doesn't support asymmetric KMS keys. Specify KMS key ID. RootVolumeSizeGib: Default: '80' Description: Size of user storage. Refer to Modify Volume Sizes - https://docs.aws.amazon.com/workspaces/latest/adminguide/modify-workspaces.html#change_volume_sizes. Type: Number UserVolumeSizeGib: Default: '50' Description: Size of user storage. Refer to Modify Volume Sizes - https://docs.aws.amazon.com/workspaces/latest/adminguide/modify-workspaces.html#change_volume_sizes. Type: Number BundleId: Default: 'wsb-fn373c5rw' AllowedPattern: '^wsb-[0-9a-z]{8,63}$' Description: Identifier of bundle for WorkSpace. Use DescribeWorkspaceBundles to list available bundles. Provided bundle ID is for PCoIP streaming protocol. Type: String ComputeTypeName: Default: 'PERFORMANCE' AllowedValues: - VALUE - STANDARD - POWERPRO - POWER - PERFORMANCE - GRAPHICSPRO - GRAPHICS Description: Compute type. Valid values are VALUE | STANDARD | PERFORMANCE | POWER | GRAPHICS | POWERPRO | GRAPHICSPRO. Ensure bundle ID supports compute type selected. Type: String RunningMode: Default: 'AUTO_STOP' AllowedValues: - ALWAYS_ON - AUTO_STOP Description: Choose Workspaces running mode. Type: String ## RADIUS Server Configuration RADIUSServerInstanceType: AllowedValues: - t2.medium - t3.medium - t2.large - t3.large - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge Default: t3.large Description: Amazon EC2 instance type for RADIUS Server. Type: String LinOTPDBName: Type: String Default: LINOTP Description: RDS database name. LinOTPAdminPassword: 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 account used to manage user enrollment and LinOTP portal. Minimum 8 characters containing letters, numbers, and symbols. MaxLength: '32' MinLength: '8' NoEcho: 'true' Type: String LinOTPReamlName: Default: WSRealm AllowedPattern: '[a-zA-Z0-9]*' Description: Realm name for LinOTP/LDAP integration. Default is WSRealm. MaxLength: '12' MinLength: '5' NoEcho: 'true' Type: String ## SNS Configuration QuickStartAdminEmail: Default: workspace@example.com Description: 'Admin email for notifications upon successful creation.' Type: String AllowedPattern: '[^@]+@[^@]+\.[^@]+' Conditions: IncludeRDGW: !Not [!Equals [!Ref NumberOfRDGWHosts, '0']] IsTwoAz: !Equals [!Ref NumberOfAZs, '2'] UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart'] ShouldCreateMgmtServer: !Equals [!Ref MgmtServer, 'true'] ShouldCreateNonWindowsDomainJoinADUser: !Equals [!Ref NonWindowsDomainJoin, 'true'] ShouldCreateOneTierPkiResource: !Equals [!Ref PKI, 'One-Tier'] ShouldCreateTwoTierPkiResource: !Equals [!Ref PKI, 'Two-Tier'] WorkSpaceEncryptRootVol: !Equals [!Ref RootVolumeEncryptionEnabled, 'true'] WorkSpaceEncryptUserVol: !Equals [!Ref UserVolumeEncryptionEnabled, 'true'] KMSVolEncrptionCheck: !And [ Condition: WorkSpaceEncryptRootVol, Condition: WorkSpaceEncryptUserVol] Rules: NonWindowsDomainJoin: RuleCondition: !Equals [!Ref NonWindowsDomainJoin, 'true'] Assertions: - AssertDescription: To enable creation of an AD user for non-Windows Domain joins, you need to create a Management Server Instance Assert: !Equals [!Ref MgmtServer, 'true'] 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']] 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: !If [IsTwoAz, '2', '3'] PrivateSubnet1ACIDR: !Ref PrivateSubnet1CIDR PrivateSubnet2ACIDR: !Ref PrivateSubnet2CIDR PrivateSubnet3ACIDR: !If [IsTwoAz, !Ref AWS::NoValue, !Ref PrivateSubnet3CIDR] PublicSubnet1CIDR: !Ref PublicSubnet1CIDR PublicSubnet2CIDR: !Ref PublicSubnet2CIDR PublicSubnet3CIDR: !If [IsTwoAz, !Ref AWS::NoValue, !Ref PublicSubnet3CIDR] VPCCIDR: !Ref VPCCIDR ADStack: DependsOn: VPCStack Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-microsoft-activedirectory/templates/ad-3.template.yaml' - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: ADEdition: !Ref ADEdition CaDataDriveSizeGiB: !Ref CaDataDriveSizeGiB CaHashAlgorithm: !Ref CaHashAlgorithm CaKeyLength: !Ref CaKeyLength CaServerInstanceType: !Ref CaServerInstanceType CaValidityPeriodUnits: !Ref CaValidityPeriodUnits DHCPOptionSet: !Ref DHCPOptionSet DomainAdminPassword: !Ref DomainAdminPassword DomainDNSName: !Ref DomainDNSName DomainNetBIOSName: !Ref DomainNetBIOSName EntCaServerNetBIOSName: !Ref EntCaServerNetBIOSName KeyPairName: !Ref KeyPairName MgmtDataDriveSizeGiB: !Ref MgmtDataDriveSizeGiB MgmtServer: !Ref MgmtServer MgmtServerEnableAdvancedAudtingandMetrics: !Ref MgmtServerEnableAdvancedAudtingandMetrics MgmtServerInstanceType: !Ref MgmtServerInstanceType MgmtServerNetBIOSName: !Ref MgmtServerNetBIOSName NonWindowsDomainJoin: !Ref NonWindowsDomainJoin OrCaServerNetBIOSName: !Ref OrCaServerNetBIOSName OrCaValidityPeriodUnits: !Ref OrCaValidityPeriodUnits PKI: !Ref PKI PrivateSubnet1ID: !GetAtt VPCStack.Outputs.PrivateSubnet1AID PrivateSubnet2ID: !GetAtt VPCStack.Outputs.PrivateSubnet2AID QSS3BucketName: !Ref QSS3BucketName QSS3BucketRegion: !Ref QSS3BucketRegion QSS3KeyPrefix: !Sub '${QSS3KeyPrefix}submodules/quickstart-microsoft-activedirectory/' S3CRLBucketName: !Ref S3CRLBucketName UseS3ForCRL: !Ref UseS3ForCRL VPCCIDR: !Ref VPCCIDR VPCID: !GetAtt VPCStack.Outputs.VPCID RDGWStack: Condition: IncludeRDGW DependsOn: ADStack Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-microsoft-rdgateway/templates/rdgw-domain.template' - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: DomainAdminPassword: !Ref DomainAdminPassword DomainAdminUser: admin DomainDNSName: !Ref DomainDNSName DomainMemberSGID: !GetAtt ADStack.Outputs.DomainMemberSGID DomainNetBIOSName: !Ref DomainNetBIOSName KeyPairName: !Ref KeyPairName NumberOfRDGWHosts: !Ref NumberOfRDGWHosts PublicSubnet1ID: !GetAtt VPCStack.Outputs.PublicSubnet1ID PublicSubnet2ID: !GetAtt VPCStack.Outputs.PublicSubnet2ID QSS3BucketName: !Ref QSS3BucketName QSS3BucketRegion: !Ref QSS3BucketRegion QSS3KeyPrefix: !Sub ${QSS3KeyPrefix}submodules/quickstart-microsoft-rdgateway/ RDGWCIDR: !Ref RDGWCIDR RDGWInstanceType: !Ref RDGWInstanceType VPCID: !GetAtt VPCStack.Outputs.VPCID Macro: Type: AWS::CloudFormation::Macro Properties: Name: WorkSpaceDefaultRoleMacro FunctionName: !GetAtt WSIAMFunc.Arn WSIAMFunc: Type: AWS::Lambda::Function Properties: FunctionName: !Sub ${AWS::StackName} Handler: index.handler Runtime: python3.8 Role: !GetAtt LambdaExecutionRole.Arn Code: ZipFile: | import boto3 import json import logging logger = logging.getLogger() logger.setLevel(logging.INFO) client = boto3.client('iam') def handler(event, context): try: fragment = event['fragment'] client.get_role(RoleName='workspaces_DefaultRole') resp = {'requestId': event['requestId'], 'status': 'success','fragment': fragment} return resp except client.exceptions.NoSuchEntityException: resources_to_be_modified = {} resources_to_be_modified = event['fragment']['Resources'] resources_to_be_modified['WorkspaceDefaultRole'] = {'Properties':{'RoleName':'workspaces_DefaultRole','Tags':[{'Key':'Created_By','Value':'WorkSpacesQuickstart_SC2'}],'ManagedPolicyArns':['arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess','arn:aws:iam::aws:policy/AmazonWorkSpacesSelfServiceAccess'],'AssumeRolePolicyDocument':{'Statement':[{'Action':['sts:AssumeRole'],'Effect':'Allow','Principal':{'Service':['workspaces.amazonaws.com']}}],'Version':'2012-10-17'},'Path':'/'}} resources_to_be_modified['WorkspaceDefaultRole']['Type'] = 'AWS::IAM::Role' resources_to_be_modified['CleanUpCustomResource']['DependsOn'] = 'WorkspaceDefaultRole' event['fragment']['Resources'] = resources_to_be_modified resp = {'requestId': event['requestId'], 'status': 'success','fragment': fragment} return resp LambdaPermission: Type: AWS::Lambda::Permission Properties: Action: 'lambda:InvokeFunction' Principal: cloudformation.amazonaws.com FunctionName: !GetAtt WSIAMFunc.Arn LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: Fn::Sub: ${AWS::StackName}-lambda-execution-role-policy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: - Fn::Sub: arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* - Effect: Allow Action: - iam:GetRole Resource: - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/* NotifyStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/notification.template.yaml' - S3Region: !If [UsingDefaultBucket, !Ref AWS::Region, !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: QuickStartAdminEmail: !Ref QuickStartAdminEmail WorkSpaceStack: DependsOn: - ADStack - Macro - NotifyStack Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/workspace-2.template.yaml' - S3Region: !If [UsingDefaultBucket, !Ref AWS::Region, !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: DirectoryID: !GetAtt 'ADStack.Outputs.DirectoryID' DomainDNSName: !Ref 'DomainDNSName' VPCID: !GetAtt 'VPCStack.Outputs.VPCID' VPCCIDR: !Ref 'VPCCIDR' PrivateSubnet1ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet1AID' PrivateSubnet2ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet2AID' ADServer1PrivateIP: !GetAtt 'ADStack.Outputs.ADServer1PrivateIP' ADServer2PrivateIP: !GetAtt 'ADStack.Outputs.ADServer2PrivateIP' MgmtServerNetBIOSName: !Ref 'MgmtServerNetBIOSName' BundleId: !Ref 'BundleId' ComputeTypeName: !Ref 'ComputeTypeName' RunningMode: !Ref 'RunningMode' Tenancy: !Ref 'Tenancy' EnableWorkDocs: !Ref 'EnableWorkDocs' EnableSelfService: !Ref 'EnableSelfService' DomainUser: !Ref 'DomainUser' UserVolumeEncryptionEnabled: !Ref UserVolumeEncryptionEnabled RootVolumeEncryptionEnabled: !Ref RootVolumeEncryptionEnabled VolumeEncryptionKey: !Ref VolumeEncryptionKey UserVolumeSizeGib: !Ref UserVolumeSizeGib RootVolumeSizeGib: !Ref RootVolumeSizeGib SNSDeliveryLambdaExecutionRoleExportName: !Sub '${AWS::StackName}-LambdaSNSPublisherRole' SNSStackStatusTopicExportName: !Sub '${AWS::StackName}-SNSStackStatusTopic' SNSDeliveryLambdaExecutionRoleExportValue: !GetAtt 'NotifyStack.Outputs.SNSDeliveryLambdaExecutionRole' SNSStackStatusTopicExportValue: !GetAtt 'NotifyStack.Outputs.SNSStackTopic' QSS3BucketName: !Ref 'QSS3BucketName' QSS3KeyPrefix: !Ref 'QSS3KeyPrefix' RadiusStack: DependsOn: - WorkSpaceStack Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/radius-2.template.yaml' - S3Region: !If [UsingDefaultBucket, !Ref AWS::Region, !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: VPCID: !GetAtt 'VPCStack.Outputs.VPCID' PrivateSubnet1ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet1AID' PrivateSubnet2ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet2AID' PublicSubnet1ID: !GetAtt 'VPCStack.Outputs.PublicSubnet1ID' PublicSubnet2ID: !GetAtt 'VPCStack.Outputs.PublicSubnet2ID' AdminUserSecrets: !GetAtt 'ADStack.Outputs.ADSecretsArn' VPCCIDR: !Ref 'VPCCIDR' RADIUSServerInstanceType: !Ref 'RADIUSServerInstanceType' LinOTPDBName: !Ref 'LinOTPDBName' LinOTPAdminPassword: !Ref 'LinOTPAdminPassword' LinOTPReamlName: !Ref 'LinOTPReamlName' KeyName: !Ref 'KeyPairName' SNSDeliveryLambdaExecutionRole: !Sub '${AWS::StackName}-LambdaSNSPublisherRole' SNSStackStatusTopic: !Sub '${AWS::StackName}-SNSStackStatusTopic'