Skip to content

Commit

Permalink
Merge branch 'mainline' into min_version_for_sm
Browse files Browse the repository at this point in the history
  • Loading branch information
kozlove-aws authored Oct 18, 2021
2 parents 2eb941f + d2f6fd8 commit bd69cd2
Show file tree
Hide file tree
Showing 83 changed files with 6,303 additions and 839 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ name: CI

on:
push:
branches: [ mainline ]
branches: [ mainline, 'feature*' ]
pull_request:
branches: [ mainline ]
branches: [ mainline, 'feature*' ]

jobs:
build:
Expand Down
28 changes: 26 additions & 2 deletions examples/deadline/All-In-AWS-Infrastructure-Basic/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,36 @@ These instructions assume that your working directory is `examples/deadline/All-
```python
self.alarm_email_address: Optional[str] = 'username@yourdomain.com'
```
15. Deploy all the stacks in the sample app:
15. Deadline Secrets Management is a feature used to encrypt certain values in the database that need to be kept secret. Additional documentation about the feature and how it works in the RFDK can be found in the [RFDK README](../../../../packages/aws-rfdk/lib/deadline/README.md). By default, Deadline Secrets Management is enabled, but it can be disabled by changing the `enable_secrets_management` variable in `package/config.py`.

```python
self.enable_secrets_management: bool = False
```

16. When you are using Deadline Secrets Management you can define your own admin credentials by creating a Secret in AWS SecretsManager in the following format:

```json
{
"username": "<admin user name>",
"password": "<admin user password>",
}
```
The password must be at least 8 characters long and contain at least one lowercase, one uppercase, one digit, and one special character.

Then the value of the `secrets_management_secret_arn` variable in `package/config.py` should be changed to this Secret's ARN:
```python
self.secrets_management_secret_arn: Optional[str] = '<your secret arn>'
```
It is highly recommended that you leave this parameter undefined to enable the automatic generation of a strong password.
17. Deploy all the stacks in the sample app:
```bash
cdk deploy "*"
```
16. Once you are finished with the sample app, you can tear it down by running:
18. Once you are finished with the sample app, you can tear it down by running:
```bash
cdk destroy "*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ def main():
if 'region' in config.deadline_client_linux_ami_map:
raise ValueError('Deadline Client Linux AMI map is required but was not specified.')

if not config.enable_secrets_management and config.secrets_management_secret_arn:
print('Deadline Secrets Management is disabled, so the admin credentials specified in the provided secret will not be used.')

# ------------------------------
# Application
# ------------------------------
Expand Down Expand Up @@ -110,7 +113,9 @@ def main():
root_ca=security.root_ca,
dns_zone=network.dns_zone,
deadline_version=config.deadline_version,
accept_aws_thinkbox_eula=config.accept_aws_thinkbox_eula
accept_aws_thinkbox_eula=config.accept_aws_thinkbox_eula,
enable_secrets_management=config.enable_secrets_management,
secrets_management_secret_arn=config.secrets_management_secret_arn
)
service = service_tier.ServiceTier(app, 'ServiceTier', props=service_props, env=env)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ def __init__(self):
# If false, then we use Amazon DocumentDB to back the render farm.
self.deploy_mongo_db: bool = False

# Whether to enable Deadline Secrets Management.
self.enable_secrets_management: bool = True

# A Secret in AWS SecretsManager that stores the admin credentials for Deadline Secrets Management.
# If not defined and Secrets Management is enabled, an AWS Secret with admin credentials will be generated.
self.secrets_management_secret_arn: Optional[str] = None

# This is only relevant if deploy_mongo_db is True.
#
# Change this value to MongoDbSsplLicenseAcceptance.USER_ACCEPTS_SSPL
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

import os
from dataclasses import dataclass
from typing import (
List,
Expand All @@ -16,7 +17,8 @@
BastionHostLinux,
IMachineImage,
IVpc,
Port
Port,
SubnetSelection
)
from aws_cdk.aws_s3_assets import (
Asset
Expand All @@ -34,7 +36,8 @@
WorkerInstanceFleet,
)

import os

from . import subnets

@dataclass
class ComputeTierProps(StackProps):
Expand Down Expand Up @@ -101,6 +104,9 @@ def __init__(self, scope: Construct, stack_id: str, *, props: ComputeTierProps,
self,
'HealthMonitor',
vpc=props.vpc,
vpc_subnets=SubnetSelection(
subnet_group_name=subnets.INFRASTRUCTURE.name
),
# TODO - Evaluate deletion protection for your own needs. This is set to false to
# cleanly remove everything when this stack is destroyed. If you would like to ensure
# that this resource is not accidentally deleted, you should set this to true.
Expand All @@ -111,6 +117,9 @@ def __init__(self, scope: Construct, stack_id: str, *, props: ComputeTierProps,
self,
'WorkerFleet',
vpc=props.vpc,
vpc_subnets=SubnetSelection(
subnet_group_name=subnets.WORKERS.name
),
render_queue=props.render_queue,
worker_machine_image=props.worker_machine_image,
health_monitor=self.health_monitor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
GatewayVpcEndpointAwsService,
InterfaceVpcEndpointAwsService,
Vpc,
SubnetConfiguration,
SubnetSelection,
SubnetType
)
Expand All @@ -21,6 +20,9 @@
PrivateHostedZone
)

from . import subnets


_INTERFACE_ENDPOINT_SERVICES = [
{'name': 'CLOUDWATCH', 'service': InterfaceVpcEndpointAwsService.CLOUDWATCH},
{'name': 'CLOUDWATCH_EVENTS', 'service': InterfaceVpcEndpointAwsService.CLOUDWATCH_EVENTS},
Expand Down Expand Up @@ -61,16 +63,25 @@ def __init__(self, scope: Construct, stack_id: str, **kwargs) -> None:
'Vpc',
max_azs=2,
subnet_configuration=[
SubnetConfiguration(
name='Public',
subnet_type=SubnetType.PUBLIC,
cidr_mask=28
),
SubnetConfiguration(
name='Private',
subnet_type=SubnetType.PRIVATE,
cidr_mask=18 # 16,382 IP addresses
)
# Subnets for undistinguished render farm back-end infrastructure
subnets.INFRASTRUCTURE,
# Subnets for publicly accessible infrastructure
subnets.PUBLIC,
# Subnets for the Render Queue Application Load Balancer (ALB).
#
# It is considered good practice to put a load blanacer in dedicated subnets. Additionally, the subnets
# must have a CIDR block with a bitmask of at least /27 and at least 8 free IP addresses per subnet.
# ALBs can scale up to a maximum of 100 IP addresses distributed across all subnets. Assuming only 2 AZs
# (the minimum) we should have 50 IPs per subnet = CIDR mask of /26
#
# See:
# - https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#subnets-load-balancer
# - https://github.com/aws/aws-rfdk/blob/release/packages/aws-rfdk/lib/deadline/README.md#render-queue-subnet-placement
subnets.RENDER_QUEUE_ALB,
# Subnets for Usage-Based Licensing
subnets.USAGE_BASED_LICENSING,
# Subnets for the Worker instances
subnets.WORKERS
]
)
# VPC flow logs are a security best-practice as they allow us
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
BlockDevice,
BlockDeviceVolume,
IVpc,
SubnetSelection,
SubnetType
SubnetSelection
)
from aws_cdk.aws_elasticloadbalancingv2 import (
ApplicationProtocol
Expand All @@ -42,12 +41,15 @@
RenderQueueTrafficEncryptionProps,
RenderQueueExternalTLSProps,
Repository,
SecretsManagementProps,
ThinkboxDockerImages,
UsageBasedLicense,
UsageBasedLicensing,
VersionQuery,
)

from . import subnets


@dataclass
class ServiceTierProps(StackProps):
Expand All @@ -72,6 +74,10 @@ class ServiceTierProps(StackProps):
deadline_version: str
# Whether the AWS Thinkbox End-User License Agreement is accepted or not
accept_aws_thinkbox_eula: AwsThinkboxEulaAcceptance
# Whether to enable Deadline Secrets Management.
enable_secrets_management: bool
# The ARN of the AWS Secret containing the admin credentials for Deadline Secrets Management.
secrets_management_secret_arn: typing.Optional[str]


class ServiceTier(Stack):
Expand Down Expand Up @@ -99,7 +105,7 @@ def __init__(self, scope: Construct, stack_id: str, *, props: ServiceTierProps,
'Bastion',
vpc=props.vpc,
subnet_selection=SubnetSelection(
subnet_type=SubnetType.PUBLIC
subnet_group_name=subnets.PUBLIC.name
),
block_devices=[
BlockDevice(
Expand All @@ -122,15 +128,25 @@ def __init__(self, scope: Construct, stack_id: str, *, props: ServiceTierProps,
version=props.deadline_version
)

secrets_management_settings = SecretsManagementProps(
enabled = props.enable_secrets_management
)
if props.enable_secrets_management and props.secrets_management_secret_arn is not None:
secrets_management_settings["credentials"] = Secret.from_secret_arn(self, 'SMAdminUser', props.secrets_management_secret_arn)

repository = Repository(
self,
'Repository',
vpc=props.vpc,
vpc_subnets=SubnetSelection(
subnet_group_name=subnets.INFRASTRUCTURE.name
),
database=props.database,
file_system=props.mountable_file_system,
repository_installation_timeout=Duration.minutes(20),
repository_installation_prefix='/',
version=self.version
version=self.version,
secrets_management_settings=secrets_management_settings
)

images = ThinkboxDockerImages(
Expand All @@ -155,6 +171,22 @@ def __init__(self, scope: Construct, stack_id: str, *, props: ServiceTierProps,
self,
'RenderQueue',
vpc=props.vpc,
vpc_subnets=SubnetSelection(
subnet_group_name=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)
vpc_subnets_alb=SubnetSelection(
subnet_group_name=subnets.RENDER_QUEUE_ALB.name
),
images=images,
repository=repository,
hostname=RenderQueueHostNameProps(
Expand Down Expand Up @@ -195,6 +227,9 @@ def __init__(self, scope: Construct, stack_id: str, *, props: ServiceTierProps,
self,
'UsageBasedLicensing',
vpc=props.vpc,
vpc_subnets=SubnetSelection(
subnet_group_name=subnets.USAGE_BASED_LICENSING.name
),
images=images,
licenses=props.ubl_licenses,
render_queue=self.render_queue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
from aws_cdk.aws_ec2 import (
InstanceType,
IVpc,
SubnetSelection,
SubnetType
SubnetSelection
)
from aws_cdk.aws_efs import (
AccessPoint,
Expand Down Expand Up @@ -73,6 +72,8 @@
DatabaseConnection
)

from . import subnets


@dataclass
class StorageTierProps(StackProps):
Expand Down Expand Up @@ -109,6 +110,9 @@ def __init__(self, scope: Construct, stack_id: str, *, props: StorageTierProps,
self,
'EfsFileSystem',
vpc=props.vpc,
vpc_subnets=SubnetSelection(
subnet_group_name=subnets.INFRASTRUCTURE.name
),
encrypted=True,
# TODO - Evaluate this removal policy for your own needs. This is set to DESTROY to
# cleanly remove everything when this stack is destroyed. If you would like to ensure
Expand Down Expand Up @@ -207,6 +211,9 @@ def __init__(self, scope: Construct, stack_id: str, *, props: StorageTierProps,
self,
'PadEfsStorage',
vpc=props.vpc,
vpc_subnets=SubnetSelection(
subnet_group_name=subnets.INFRASTRUCTURE.name
),
access_point=pad_access_point,
desired_padding=Size.gibibytes(40), # Provides 2 MiB/s of baseline throughput. Costs $12/month.
)
Expand Down Expand Up @@ -331,7 +338,9 @@ def __init__(self, scope: Construct, stack_id: str, *, props: StorageTierDocDBPr
self,
'DocDBCluster',
vpc=props.vpc,
vpc_subnets=SubnetSelection(subnet_type=SubnetType.PRIVATE),
vpc_subnets=SubnetSelection(
subnet_group_name=subnets.INFRASTRUCTURE.name
),
instance_type=props.database_instance_type,
# TODO - For cost considerations this example only uses 1 Database instance.
# It is recommended that when creating your render farm you use at least 2 instances for redundancy.
Expand Down Expand Up @@ -418,7 +427,7 @@ def __init__(self, scope: Construct, stack_id: str, *, props: StorageTierMongoDB
availability_zone = props.vpc.availability_zones[0]

mongo_vpc_subnet = SubnetSelection(
subnet_type=SubnetType.PRIVATE,
subnet_group_name=subnets.INFRASTRUCTURE.name,
availability_zones=[availability_zone]
)

Expand Down
Loading

0 comments on commit bd69cd2

Please sign in to comment.