Skip to content

Commit e6610aa

Browse files
committed
chore(deadline): Add README.md for the deadline module
1 parent 07c353b commit e6610aa

File tree

2 files changed

+368
-0
lines changed

2 files changed

+368
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Docker Image Recipes
2+
3+
RFDK uses Docker image recipes to build and deploy Docker images to machines. These recipes typically live in a _stage directory_.
4+
5+
## Stage Directory Convention
6+
7+
A stage directory must contain a `Dockerfile` and a manifest file at the root of the directory. It can also have a directory for each Docker image recipe that contains contextual information for that recipe.
8+
9+
**Dockerfile** - The Dockerfile that Docker uses to assemble container images from Docker recipes.
10+
11+
**Manifest File** - This file contains meta-data about each recipe and is used by RFDK to build up the corresponding [DockerImageAsset](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ecr-assets.DockerImageAsset.html) objects. In addition to the recipe meta-data, it also includes other useful information, such as the schema version. For more information, see [Manifest File Schema](#manifest-file-schema).
12+
13+
## Docker Image Recipe Composition
14+
15+
A Docker image recipe is composed of the following:
16+
17+
**Recipe**
18+
- Dockerfile
19+
- An entry in the manifest file containing:
20+
- Title of the image
21+
- (Optional) Description of the image
22+
- (Optional) Docker build arguments
23+
- (Optional) Docker target/stage
24+
25+
**Context directory**
26+
- Deadline Client installer
27+
- Configuration scripts
28+
29+
The **recipe** contains instructions that use the items in the **context directory** to create a Docker image.
30+
31+
When using a recipe, RFDK runs the Dockerfile with the build arguments for that recipe from the manifest file. The Dockerfile will then use the configuration scripts and Deadline Client installer to build the Docker image that will be deployed.
32+
33+
The Dockerfile can either be:
34+
- A Dockerfile that supports [multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/), containing branches for each recipe
35+
- A common Dockerfile that is used by all recipes
36+
37+
## Manifest File Schema
38+
39+
The manifest file in a stage directory contains information about each Docker image recipe in the `recipes` field. The `buildArgs` field of a recipe specifies the arguments passed into the Dockerfile that will dictate what the Dockerfile does.
40+
41+
### Version 1
42+
43+
This schema version takes on the following form:
44+
45+
```json
46+
{
47+
"schema": 1,
48+
"recipes": {
49+
"<recipe-name>": {
50+
"title": "<recipe-title>",
51+
"description": "<recipe-description>",
52+
"target": "<recipe-target>",
53+
"buildArgs": {
54+
"<arg-1>": "<value-1>",
55+
...
56+
}
57+
},
58+
...
59+
}
60+
}
61+
```
+307
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
# AWS Thinkbox Deadline Construct Library
2+
3+
<!--BEGIN STABILITY BANNER-->
4+
---
5+
6+
![cdk-constructs: Experimental](https://img.shields.io/static/v1?label=CDK-CONSTRUCTS&message=EXPERIMENTAL&color=orange&style=for-the-badge)
7+
8+
---
9+
<!--END STABILITY BANNER-->
10+
11+
The `aws-rfdk/deadline` sub-module contains Deadline-specific constructs that can be used to deploy and manage a Deadline render farm in the cloud.
12+
13+
```ts nofixture
14+
import * as deadline from 'aws-rfdk/deadline';
15+
```
16+
17+
## Repository
18+
19+
The `Repository` contains the central database and file system used by Deadline. An EC2 instance is temporarily created to run the Deadline Repository installer which configures the database and file system. This construct has optional parameters for the database and file system to use, giving you the option to either provide your own resources or to have the construct create its own. Log messages emitted by the construct are forwarded to Cloudwatch via a CloudWatch agent.
20+
21+
You can create a `Repository` like this:
22+
23+
```ts
24+
const repository = new Repository(stack, 'Repository', {
25+
vpc: props.vpc,
26+
version: VersionQuery.exactString(stack, 'Version', '1.2.3.4')
27+
});
28+
```
29+
30+
### Configuring Deadline Client Connections
31+
32+
Deadline Clients can be configured to connect directly to the `Repository`, which will:
33+
- Allow ingress traffic to database & file system Security Groups
34+
- Create IAM Permissions for database & file system
35+
- Mount the Repository file system via [UserData](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html)
36+
37+
Deadline Clients can be configured either in ECS or EC2.
38+
39+
#### 1. Configure Deadline Client in ECS
40+
41+
An ECS Container Instance and Task Definition for deploying Deadline Client can be configured to directly connect to the `Repository`. A mapping of environment variables and ECS [`MountPoint`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ecs.MountPoint.html)s are produced which can be used to configure a [`ContainerDefinition`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ecs.ContainerDefinition.html) to connect to the `Repository`.
42+
43+
The example below demonstrates configuration of Deadline Client in ECS:
44+
```ts
45+
const taskDefinition = new Ec2TaskDefinition(stack, 'TaskDefinition');
46+
const ecsConnection = repository.configureClientECS({
47+
containerInstances: /* ... */,
48+
containers: {
49+
taskDefinition
50+
},
51+
});
52+
53+
const containerDefinition = taskDefinition.addContainer('ContainerDefinition', {
54+
image: /* ... */,
55+
environment: ecsConnection.containerEnvironment
56+
});
57+
containerDefinition.addMountPoints(ecsConnection.readWriteMountPoint);
58+
```
59+
#### 2. Configure Deadline Client on EC2
60+
61+
An EC2 instance running Deadline Client can be configured to directly connect to the `Repository`.
62+
63+
The example below demonstrates configuration of Deadline Client in an EC2 instance:
64+
```ts
65+
const instance = new Instance(stack, 'Instance', {
66+
vpc,
67+
instanceType: new InstanceType(/* ... */),
68+
machineImage: MachineImage.latestAmazonLinux()
69+
});
70+
repository.configureClientInstance({
71+
host: instance,
72+
mountPoint: '/mnt/repository'
73+
});
74+
```
75+
76+
## Stage
77+
78+
A stage is a directory that conforms to a [conventional structure](../../docs/DockerImageRecipes.md#stage-directory-convention) that RFDK requires to deploy Deadline. This directory contains the Docker image recipes that RFDK uses to build Docker images.
79+
80+
### Staging Docker Recipes
81+
82+
Docker image recipes required by various constructs in Deadline (e.g. `RenderQueue`, `UsageBasedLicensing`, etc.) must be staged to a local directory that RFDK can consume. For information on what a Docker image recipe is and how it should be organized, see [Docker Image Recipes](../../docs/DockerImageRecipes.md). You can either stage your own recipes or use ones provided by AWS Thinkbox via `ThinkboxDockerRecipes`.
83+
84+
#### Using Thinkbox Docker Recipes
85+
86+
---
87+
88+
_**Note:** The `ThinkboxDockerRecipes` class requires a [multi-stage Dockerfile](https://docs.docker.com/develop/develop-images/multistage-build/), so your version of Docker must meet the minimum version that supports multi-stage builds (version 17.05)._
89+
90+
_**Note:** Regardless of what language is consuming `aws-rfdk`, the Node.js package is required since the `stage-deadline` script is used by `ThinkboxDockerRecipes` when running `cdk synth` or `cdk deploy`._
91+
92+
---
93+
94+
AWS Thinkbox provides Docker recipes for use with Deadline constructs. To stage these recipes, use the `stage-deadline` script found in the `bin/` directory (e.g. `node_modules/aws-rfdk/bin/stage-deadline` for npm). The following example shows how to stage version 10.1.7.1 of Deadline:
95+
96+
```
97+
npx stage-deadline \
98+
--deadlineInstallerURI s3://thinkbox-installers/Deadline/10.1.7.1/Linux/DeadlineClient-10.1.7.1-linux-x64-installer.run \
99+
--dockerRecipesURI s3://thinkbox-installers/DeadlineDocker/10.1.7.1/DeadlineDocker-10.1.7.1.tar.gz
100+
```
101+
102+
This command will download the Deadline installers and Docker recipes for Deadline version 10.1.7.1 to a local subdirectory `stage`. The Deadline versions in the URIs **must** be equal. For more information, run `stage-deadline --help`.
103+
104+
In your typescript code, you can then create an instance of `ThinkboxDockerRecipes` from this stage directory like this:
105+
106+
```ts
107+
const recipes = new ThinkboxDockerRecipes(scope, 'DockerRecipes', {
108+
stage: Stage.fromDirectory(/* <path-to-stage-directory> */),
109+
});
110+
```
111+
112+
#### Conveniently Run stage-deadline Script
113+
114+
Having to memorize the path conventions used in the URIs of the arguments to the `stage-deadline` can be cumbersome and error-prone. The following recommendations provide a more convenient way to use `stage-deadline`.
115+
116+
**Typescript/Javascript**
117+
118+
We recommend adding a `script` field in your `package.json` that runs the `stage-deadline` script with pre-populated parameters to ease the burden of having to remember the path conventions used in the thinkbox-installers S3 bucket. You can also leverage the built-in support for accessing the values of fields in `package.json` using the `${npm_package_<field1_innerfield1_...>}` syntax.
119+
120+
```json
121+
{
122+
// ...
123+
"config": {
124+
"deadline_ver": "10.1.7.1",
125+
"stage_path": "stage"
126+
},
127+
// ...
128+
"scripts": {
129+
// ...
130+
"stage": "stage-deadline -d s3://thinkbox-installers/Deadline/${npm_package_config_deadline_ver}/Linux/DeadlineClient-${npm_package_config_deadline_ver}-linux-x64-installer.run -c s3://thinkbox-installers/DeadlineDocker/${npm_package_config_deadline_ver}/DeadlineDocker-${npm_package_config_deadline_ver}.tar.gz -o ${npm_package_config_stage_path}",
131+
},
132+
// ...
133+
}
134+
```
135+
136+
With this in place, staging the Deadline Docker recipes can be done simply by running `npm run stage`.
137+
138+
## VersionQuery
139+
140+
The `VersionQuery` construct encapsulates a version of Deadline and the location in Amazon S3 to retrieve the installers for that version. Deadline versions follow a `<major>.<minor>.<release>.<patch>` schema (e.g. `1.2.3.4`). Various constructs in this library use `VersionQuery` to determine the version of Deadline to work with.
141+
142+
You can specify a Deadline version as follows:
143+
```ts
144+
const version = VersionQuery.exact(stack, 'ExactVersion', {
145+
majorVersion: '1',
146+
minorVersion: '2',
147+
releaseVersion: '3',
148+
patchVersion: '4'
149+
});
150+
```
151+
152+
## Worker Fleet
153+
154+
A `WorkerInstanceFleet` represents a fleet of instances that are the render nodes of your render farm. These instances are created in an [`AutoScalingGroup`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-autoscaling.AutoScalingGroup.html) with a provided AMI that should have Deadline Client installed as well as any desired render applications. Each of the instances will configure itself to connect to the specified [`RenderQueue`](#renderqueue) so that they are able to communicate with Deadline to pick up render jobs. Any logs emitted by the workers are sent to CloudWatch via a CloudWatch agent.
155+
156+
You can create a `WorkerInstanceFleet` like this:
157+
```ts
158+
const fleet = new WorkerInstanceFleet(stack, 'WorkerFleet', {
159+
vpc,
160+
renderQueue,
161+
workerMachineImage: /* ... */,
162+
});
163+
```
164+
165+
### Worker Fleet Health Monitoring
166+
167+
The `WorkerInstanceFleet` uses Elastic Load Balancing (ELB) health checks with its `AutoScalingGroup` to ensure the fleet is operating as expected. ELB health checks have two components:
168+
169+
1. **EC2 Status Checks** - Amazon EC2 identifies any hardware or software issues on instances. If a status check fails for an instance, it will be replaced. For more information, see [here](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-system-instance-status-check.html).
170+
2. **Load Balancer Health Checks** - Load balancers send periodic pings to instances in the `AutoScalingGroup`. If a ping to an instance fails, the instance is considered unhealthy. For more information, see [here](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-add-elb-healthcheck.html).
171+
172+
EC2 status checks are great for detecting lower level issues with instances and automatically replacing them. If you also want to detect any issues with Deadline on your instances, you can do this by setting up a health monitoring options on the `WorkerInstanceFleet` along with a `HealthMonitor` (see [`aws-rfdk`](../core/README.md)). The `HealthMonitor` will ensure that your `WorkerInstanceFleet` remains healthy by checking that a minimum number of hosts are healthy for a given grace period. If the fleet is found to be unhealthy, its capacity will set to 0, meaning that all instances will be terminated. This is a precaution to save on costs in the case of a misconfigured render farm.
173+
174+
Below is an example of setting up health monitoring in a `WorkerInstanceFleet`.
175+
```ts
176+
const healthMonitor = new HealthMonitor(stack, 'HealthMonitor', {
177+
vpc,
178+
elbAccountLimits: /* ... */
179+
});
180+
181+
const workerFleet = new WorkerInstanceFleet(stack, 'WorkerFleet', {
182+
vpc,
183+
renderQueue: /* ... */,
184+
workerMachineImage: /* ... */,
185+
healthMonitor: healthMonitor,
186+
healthCheckConfig: {
187+
interval: Duration.minutes(5)
188+
}
189+
});
190+
```
191+
192+
## Render Queue
193+
194+
The `RenderQueue` is the central service of a Deadline render farm. It consists of the following components:
195+
196+
- **Deadline Repository** - The repository that initializes the persistent data schema used by Deadline such as job information, connected workers, rendered output files, etc.
197+
- **Deadline Remote Connection Server (RCS)** - The central server that all Deadline applications connect to. The RCS contains the core business logic to manage the render farm.
198+
199+
The `RenderQueue` construct sets up the RCS and configures it to communicate with the Repository and to listen for requests using the configured protocol (HTTP or HTTPS). Docker container images are used to deploy the `RenderQueue` as a fleet of instances within an Elastic Container Service (ECS) cluster. This fleet of instances is load balanced by an [Application Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html) which has built-in health monitoring functionality that can be configured through this construct.
200+
201+
---
202+
203+
_**Note:** The number of instances running the Render Queue is currently limited to a maximum of one._
204+
205+
---
206+
207+
The following example outlines how to construct a `RenderQueue`:
208+
209+
```ts
210+
const recipes = new ThinkboxDockerRecipes(stack, 'Recipes', {
211+
stage: Stage.fromDirectory(/* ... */)
212+
});
213+
const version = VersionQuery.exactString(stack, 'Version', '1.2.3.4');
214+
const repository = new Repository(stack, 'Repository', { /* ...*/});
215+
216+
const renderQueue = new RenderQueue(stack, 'RenderQueue', {
217+
vpc: vpc,
218+
images: recipes.renderQueueImages,
219+
version: version,
220+
repository: repository,
221+
});
222+
```
223+
224+
### Render Queue Encryption
225+
226+
The `RenderQueue` provides end-to-end encryption of communications and data at rest. However, it currently does not do any client validation or application authentication due to limitations with Application Load Balancers that made it necessary to disable Deadline Worker TLS certificate authentication.
227+
228+
---
229+
230+
_**Note:** Be extra careful when setting up security group rules that govern access to the `RenderQueue` and, for the machines that do have access to it, ensure you trust the Operating System as well as any software being used._
231+
232+
---
233+
234+
### Render Queue Health Monitoring
235+
236+
The `RenderQueue` construct leverages the built-in health monitoring functionality provided by Application Load Balancers. The health check grace period and interval can be configured by specifying the `healthCheckConfig` property of the construct. For more information, see [Application Load Balancer Health Checks](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/target-group-health-checks.html).
237+
238+
### Render Queue Deletion Protection
239+
240+
By default, the Load Balancer in the `RenderQueue` has [deletion protection](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#deletion-protection) enabled to ensure that it does not get accidentally deleted. This also means that it cannot be automatically destroyed by CDK when you destroy your stack and must be done manually (see [here](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#deletion-protection)).
241+
242+
You can specify deletion protection with a property in the `RenderQueue`:
243+
```ts
244+
const renderQueue = new RenderQueue(stack, 'RenderQueue', {
245+
//...
246+
deletionProtection: false
247+
});
248+
```
249+
250+
### Render Queue Docker Container Images
251+
252+
The `RenderQueue` currently requires only one Docker container image for the Deadline Remote Connection Server (RCS). An RCS image must satisfy the following criteria to be compatible with RFDK:
253+
254+
- Deadline Client must be installed
255+
- The port the RCS will be listening on must be exposed
256+
- The default command must launch the RCS
257+
258+
AWS Thinkbox provides Docker recipes that set these up for you. These can be accessed with the `ThinkboxDockerRecipes` class (see [Staging Docker Recipes](#staging-docker-recipes)).
259+
260+
## Usage-Based Licensing (UBL)
261+
262+
Usage-Based Licensing is an on-demand licensing model (see [Deadline Documentation](https://docs.thinkboxsoftware.com/products/deadline/10.1/1_User%20Manual/manual/licensing-usage-based.html)). The RFDK supports this type of licensing with the `UsageBasedLicensing` construct. This construct contains the following components:
263+
264+
- **Deadline License Forwarder** - Forwards licenses to Deadline Workers that are rendering jobs.
265+
266+
The `UsageBasedLicensing` construct sets up the License Forwarder, configures the defined license limits, and allows communication with the Render Queue. Docker container images are used to deploy the License Forwarder as a fleet of instances within an Elastic Container Service (ECS) cluster.
267+
268+
---
269+
270+
_**Note:** This construct does not currently implement the Deadline License Forwarder's Web Forwarding functionality._
271+
272+
_**Note:** This construct is not usable in any China region._
273+
274+
---
275+
276+
The following example outlines how to construct `UsageBasedLicensing`:
277+
278+
```ts
279+
const recipes = new ThinkboxDockerRecipes(stack, 'Recipes', {
280+
stage: Stage.fromDirectory(/* ... */)
281+
});
282+
283+
const ubl = new UsageBasedLicensing(stack, 'UsageBasedLicensing', {
284+
vpc: vpc,
285+
renderQueue: renderQueue,
286+
images: recipes.ublImages,
287+
licenses: [ UsageBasedLicense.forKrakatoa(/* ... */), /* ... */ ],
288+
certificateSecret: /* ... */, // This must be a binary secret (see below)
289+
memoryReservationMiB: /* ... */
290+
});
291+
```
292+
293+
#### Uploading Binary Secrets to SecretsManager
294+
295+
The `UsageBasedLicensing` construct expects a `.zip` file containing usage-based licenses stored as a binary secret in SecretsManager. The AWS web console does not provide a way to upload binary secrets to SecretsManager, but this can be done via [AWS CLI](https://aws.amazon.com/cli/). You can use the following command to upload a binary secret:
296+
```
297+
aws secretsmanager create-secret --name <secret-name> --secret-binary fileb://<path-to-file>
298+
```
299+
300+
### Usage-Based Licensing Docker Container Images
301+
302+
`UsageBasedLicensing` currently requires only one Docker container image for the Deadline License Forwarder. A License Forwarder image must satisfy the following criteria to be compatible with AWS RFDK:
303+
304+
- Deadline Client must be installed
305+
- The default command must launch the License Forwarder
306+
307+
AWS Thinkbox provides Docker recipes that sets these up for you. These can be accessed with the `ThinkboxDockerRecipes` class (see [Staging Docker Recipes](#staging-docker-recipes)).

0 commit comments

Comments
 (0)