/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */ import { BastionHostLinux , BlockDeviceVolume , IVpc , } from '@aws-cdk/aws-ec2' ; import { ApplicationProtocol , } from '@aws-cdk/aws-elasticloadbalancingv2' ; import { IPrivateHostedZone , } from '@aws-cdk/aws-route53' ; import * as cdk from '@aws-cdk/core' ; import { MountableEfs , X509CertificatePem , } from 'aws-rfdk' ; import { AwsThinkboxEulaAcceptance , DatabaseConnection , RenderQueue , Repository , ThinkboxDockerImages , UsageBasedLicense , UsageBasedLicensing , VersionQuery , } from 'aws-rfdk/deadline' ; import { Secret , } from '@aws-cdk/aws-secretsmanager' ; import { SessionManagerHelper } from 'aws-rfdk/lib/core' ; import { Subnets } from './subnets' ; /**
 * Properties for  ServiceTier .
  export interface ServiceTierProps extends cdk . StackProps { /**
     * The VPC to deploy service tier resources into.
     */ readonly vpc : IVpc ; /**
     * The database to connect to.
     */ readonly database : DatabaseConnection ; /**
     * The file-system to install Deadline Repository to.
     */ readonly mountableFileSystem : MountableEfs ; /**
     * Our self-signed root CA certificate for the internal endpoints in the farm.
     */ readonly rootCa : X509CertificatePem ; /**
     * Internal DNS zone for the VPC.
     */ readonly dnsZone : IPrivateHostedZone ; default readonly ublCertsSecretArn ? : string ; default readonly ublLicenses ? : UsageBasedLicense [ ] ; default readonly deadlineVersion ? : string ; /**
     * Whether the AWS Thinkbox End-User License Agreement is accepted or not
     */ readonly acceptAwsThinkboxEula : AwsThinkboxEulaAcceptance ; /**
     * Whether to enable Deadline Secrets Management.
     */ readonly enableSecretsManagement : boolean ; default readonly secretsManagementSecretArn ? : string ; } /**
 * The service tier contains all "business-logic" constructs (e.g. Render Queue, UBL Licensing / License Forwarder, etc.).
 */ export class ServiceTier extends cdk . Stack { /**
     * A bastion host to connect to the render farm with.
     */ public readonly bastion : BastionHostLinux ; /**
     * The render queue.
     */ public readonly renderQueue : RenderQueue ; /**
     * The UBL licensing construct. (License Forwarder)
     */ public readonly ublLicensing ? : UsageBasedLicensing ; /**
     * The version of Deadline configured by the app.
     */ public readonly version : VersionQuery ; /**
     * Initializes a new instance of  ServiceTier .
     *  param scope param id param props constructor ( scope , id , props ) { super ( scope , id , props ) ; this . bastion = new BastionHostLinux ( this , 'Bastion' , { vpc : props . vpc , subnetSelection : { subnetGroupName : Subnets . PUBLIC . name , } , blockDevices : [ { deviceName : '/dev/xvda' , volume : BlockDeviceVolume . ebs ( 50 , { encrypted : true , } ) } , ] , } ) ; props . database . allowConnectionsFrom ( this . bastion ) ; new MountableEfs ( this , { filesystem : props . mountableFileSystem . fileSystem , } ) . mountToLinuxInstance ( this . bastion . instance , { location : '/mnt/efs' , } ) ; this . version = new VersionQuery ( this , 'Version' , { version : props . deadlineVersion , } ) ; const repository = new Repository ( this , 'Repository' , { vpc : props . vpc , vpcSubnets : { subnetGroupName : Subnets . INFRASTRUCTURE . name , } , version : this . version , database : props . database , fileSystem : props . mountableFileSystem , repositoryInstallationTimeout : cdk . Duration . minutes ( 20 ) , repositoryInstallationPrefix : "/" , secretsManagementSettings : { enabled : props . enableSecretsManagement , credentials : props . secretsManagementSecretArn ? Secret . fromSecretCompleteArn ( this , 'SMAdminUser' , props . secretsManagementSecretArn ) : undefined , } , } ) ; const images = new ThinkboxDockerImages ( this , 'Images' , { version : this . version , userAwsThinkboxEulaAcceptance : props . acceptAwsThinkboxEula , } ) ; const serverCert = new X509CertificatePem ( this , 'RQCert' , { subject : { cn : `renderqueue.${ props . dnsZone . zoneName }` , o : 'RFDK-Sample' , ou : 'RenderQueueExternal' , } , signingCertificate : props . rootCa , } ) ; this . renderQueue = new RenderQueue ( this , 'RenderQueue' , { vpc : props . vpc , vpcSubnets : { subnetGroupName : Subnets . INFRASTRUCTURE . name , } , /**
             * It is considered good practice to put the Render Queue's load blanacer in dedicated subnets because:
             *
             * 1. Deadline Secrets Management identity registration settings will be scoped down to least-privilege
             *
             *    (see https://github.com/aws/aws-rfdk/blob/release/packages/aws-rfdk/lib/deadline/README.md#render-queue-subnet-placement)
             *
             * 2. The load balancer can scale to use IP addresses in the subnet without conflicts from other AWS resources
             *
             *    (see https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#subnets-load-balancer)
             */ vpcSubnetsAlb : { subnetGroupName : Subnets . RENDER_QUEUE_ALB . name , } , images : images , repository , hostname : { hostname : 'renderqueue' , zone : props . dnsZone , } , trafficEncryption : { externalTLS : { rfdkCertificate : serverCert , } , internalProtocol : ApplicationProtocol . HTTPS , } , version : this . version , deletionProtection : false , enableLocalFileCaching : true , } ) ; this . renderQueue . connections . allowDefaultPortFrom ( this . bastion ) ; SessionManagerHelper . grantPermissionsTo ( this . renderQueue . asg ) ; if ( props . ublLicenses ) { if ( ! props . ublCertsSecretArn ) { throw new Error ( 'UBL licenses were set but no UBL Certs Secret Arn was set.' ) ; } const ublCertSecret = Secret . fromSecretCompleteArn ( this , 'UBLCertsSecret' , props . ublCertsSecretArn ) ; this . ublLicensing = new UsageBasedLicensing ( this , 'UBLLicensing' , { vpc : props . vpc , vpcSubnets : { subnetGroupName : Subnets . USAGE_BASED_LICENSING . name , } , images : images , licenses : props . ublLicenses , renderQueue : this . renderQueue , certificateSecret : ublCertSecret , } ) ; SessionManagerHelper . grantPermissionsTo ( this . ublLicensing . asg ) ; } } }