private createTaskDefinition()

in packages/aws-rfdk/lib/deadline/lib/render-queue.ts [752:856]


  private createTaskDefinition(props: {
    image: ContainerImage,
    portNumber: number,
    protocol: ApplicationProtocol,
    repository: IRepository,
    runAsUser?: { uid: number, gid?: number },
    secretsManagementOptions?: { credentials: ISecret, posixUsername: string },
  }) {
    const { image, portNumber, protocol, repository } = props;

    const taskDefinition = new Ec2TaskDefinition(this, 'RCSTask');

    // Mount the repo filesystem to RenderQueue.HOST_REPO_FS_MOUNT_PATH
    const connection = repository.configureClientECS({
      containerInstances: {
        hosts: [this.asg],
      },
      containers: {
        taskDefinition,
      },
    });

    const environment = connection.containerEnvironment;

    if (protocol === ApplicationProtocol.HTTPS) {
      // Generate a self-signed X509 certificate, private key and passphrase for use by the RCS containers.
      // Note: the Application Load Balancer does not validate the certificate in any way.
      const rcsCertPem = new X509CertificatePem(this, 'TlsCaCertPem', {
        subject: {
          cn: 'renderfarm.local',
        },
      });
      const rcsCertPkcs = new X509CertificatePkcs12(this, 'TlsRcsCertBundle', {
        sourceCertificate: rcsCertPem,
      });
      [rcsCertPem.cert, rcsCertPkcs.cert, rcsCertPkcs.passphrase].forEach(secret => {
        secret.grantRead(taskDefinition.taskRole);
      });
      environment.RCS_TLS_CA_CERT_URI = rcsCertPem.cert.secretArn;
      environment.RCS_TLS_CERT_URI = rcsCertPkcs.cert.secretArn;
      environment.RCS_TLS_CERT_PASSPHRASE_URI = rcsCertPkcs.passphrase.secretArn;
      environment.RCS_TLS_REQUIRE_CLIENT_CERT = 'no';
    }

    if (props.secretsManagementOptions !== undefined) {
      environment.RCS_SM_CREDENTIALS_URI = props.secretsManagementOptions.credentials.secretArn;
    }

    // We can ignore this in test coverage because we always use RenderQueue.RCS_USER
    /* istanbul ignore next */
    const user = props.runAsUser ? `${props.runAsUser.uid}:${props.runAsUser.gid}` : undefined;
    const containerDefinition = taskDefinition.addContainer('ContainerDefinition', {
      image,
      memoryReservationMiB: 2048,
      environment,
      logging: LogDriver.awsLogs({
        logGroup: this.logGroup,
        streamPrefix: 'RCS',
      }),
      user,
    });

    containerDefinition.addMountPoints(connection.readWriteMountPoint);

    if (props.secretsManagementOptions !== undefined) {
      // Create volume to persist the RSA keypairs generated by Deadline between ECS tasks
      // This makes it so subsequent ECS tasks use the same initial Secrets Management identity
      const volumeName = 'deadline-user-keypairs';
      taskDefinition.addVolume({
        name: volumeName,
        dockerVolumeConfiguration: {
          scope: Scope.SHARED,
          autoprovision: true,
          driver: 'local',
        },
      });

      // Mount the volume into the container at the location where Deadline expects it
      containerDefinition.addMountPoints({
        readOnly: false,
        sourceVolume: volumeName,
        containerPath: `/home/${props.secretsManagementOptions.posixUsername}/.config/.mono/keypairs`,
      });
    }

    // Increase ulimits
    containerDefinition.addUlimits(
      {
        name: UlimitName.NOFILE,
        softLimit: 200000,
        hardLimit: 200000,
      }, {
        name: UlimitName.NPROC,
        softLimit: 64000,
        hardLimit: 64000,
      },
    );

    containerDefinition.addPortMappings({
      containerPort: portNumber,
      hostPort: portNumber,
    });

    return taskDefinition;
  }