Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(examples): use dedicated subnets in All-In-AWS-Infrastructure-Basic example #598

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 Down Expand Up @@ -49,6 +48,8 @@
VersionQuery,
)

from . import subnets


@dataclass
class ServiceTierProps(StackProps):
Expand Down Expand Up @@ -104,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 Down Expand Up @@ -137,6 +138,9 @@ def __init__(self, scope: Construct, stack_id: str, *, props: ServiceTierProps,
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),
Expand Down Expand Up @@ -167,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 @@ -207,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
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

from aws_cdk.aws_ec2 import SubnetConfiguration, SubnetType


# Subnets for undistinguished render farm back-end infrastructure
INFRASTRUCTURE = SubnetConfiguration(
name='Infrastructure',
subnet_type=SubnetType.PRIVATE,
# 1,022 IP addresses
cidr_mask=22
)

# Subnets for publicly accessible infrastructure
PUBLIC = SubnetConfiguration(
name='Public',
subnet_type=SubnetType.PUBLIC,
# 14 IP addresses. We only require one ENI per internet gateway per AZ, but leave some extra room
# should there be a need for externally accessible ENIs
cidr_mask=28
)

# 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
RENDER_QUEUE_ALB = SubnetConfiguration(
name='RenderQueueALB',
subnet_type=SubnetType.PRIVATE,
# 62 IP addresses
cidr_mask=26
)

# Subnets for the Usage-Based Licensing
USAGE_BASED_LICENSING = SubnetConfiguration(
name='UsageBasedLicensing',
subnet_type=SubnetType.PRIVATE,
# 14 IP addresses
cidr_mask=28
)

# Subnets for the Worker instances
WORKERS = SubnetConfiguration(
name='Workers',
subnet_type=SubnetType.PRIVATE,
# 4,094 IP addresses
cidr_mask=20
)
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
import { Asset } from '@aws-cdk/aws-s3-assets';
import * as path from 'path'

import { Subnets } from './subnets';

/**
* Properties for {@link ComputeTier}.
*/
Expand Down Expand Up @@ -123,6 +125,9 @@ export class ComputeTier extends cdk.Stack {

this.healthMonitor = new HealthMonitor(this, 'HealthMonitor', {
vpc: props.vpc,
vpcSubnets: {
subnetGroupName: 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 @@ -131,6 +136,9 @@ export class ComputeTier extends cdk.Stack {

this.workerFleet = new WorkerInstanceFleet(this, 'WorkerFleet', {
vpc: props.vpc,
vpcSubnets: {
subnetGroupName: Subnets.WORKERS.name,
},
renderQueue: props.renderQueue,
workerMachineImage: props.workerMachineImage,
healthMonitor: this.healthMonitor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
} from '@aws-cdk/aws-route53';
import * as cdk from '@aws-cdk/core';

import { Subnets } from './subnets';

/**
* The network tier consists of all constructs that are required for the foundational
* networking between the various components of the Deadline render farm.
Expand Down Expand Up @@ -71,16 +73,35 @@ export class NetworkTier extends cdk.Stack {
this.vpc = new Vpc(this, 'Vpc', {
maxAzs: 2,
subnetConfiguration: [
{
name: 'Public',
subnetType: SubnetType.PUBLIC,
cidrMask: 28,
},
{
name: 'Private',
subnetType: SubnetType.PRIVATE,
cidrMask: 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
// to capture information about the traffic going in and out of
Expand Down
Loading