From bd31a8d6b748d6a4e242a0528addd42a71d2d55f Mon Sep 17 00:00:00 2001 From: Eugene Kozlov <68875428+kozlove-aws@users.noreply.github.com> Date: Mon, 20 Sep 2021 17:18:06 -0500 Subject: [PATCH] feat(examples): add deadline secrets management options to basic example app (#562) --- .../python/README.md | 28 +++++++++++++++++-- .../python/package/app.py | 7 ++++- .../python/package/config.py | 7 +++++ .../python/package/lib/service_tier.py | 14 +++++++++- .../ts/README.md | 24 ++++++++++++++++ .../ts/bin/app.ts | 6 ++++ .../ts/bin/config.ts | 11 ++++++++ .../ts/lib/service-tier.ts | 16 +++++++++-- 8 files changed, 107 insertions(+), 6 deletions(-) diff --git a/examples/deadline/All-In-AWS-Infrastructure-Basic/python/README.md b/examples/deadline/All-In-AWS-Infrastructure-Basic/python/README.md index ffec591cd..ace63a10d 100644 --- a/examples/deadline/All-In-AWS-Infrastructure-Basic/python/README.md +++ b/examples/deadline/All-In-AWS-Infrastructure-Basic/python/README.md @@ -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": "", + "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] = '' + ``` + + 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 "*" diff --git a/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/app.py b/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/app.py index 2a270165b..bdba29ef6 100644 --- a/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/app.py +++ b/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/app.py @@ -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 # ------------------------------ @@ -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) diff --git a/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/config.py b/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/config.py index 0c6d94777..f5550f581 100644 --- a/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/config.py +++ b/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/config.py @@ -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 diff --git a/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/lib/service_tier.py b/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/lib/service_tier.py index 6a6d0f785..f4979ec53 100644 --- a/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/lib/service_tier.py +++ b/examples/deadline/All-In-AWS-Infrastructure-Basic/python/package/lib/service_tier.py @@ -42,6 +42,7 @@ RenderQueueTrafficEncryptionProps, RenderQueueExternalTLSProps, Repository, + SecretsManagementProps, ThinkboxDockerImages, UsageBasedLicense, UsageBasedLicensing, @@ -72,6 +73,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): @@ -122,6 +127,12 @@ 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', @@ -130,7 +141,8 @@ def __init__(self, scope: Construct, stack_id: str, *, props: ServiceTierProps, 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( diff --git a/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/README.md b/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/README.md index 6fe0d0bdf..cb54996cb 100644 --- a/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/README.md +++ b/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/README.md @@ -119,6 +119,30 @@ These instructions assume that your working directory is `examples/deadline/All- ```ts public readonly alarmEmailAddress?: string = 'username@yourdomain.com'; ``` + +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 `enableSecretsManagement` variable in `package/config.ts`. + + ```ts + public readonly enableSecretsManagement: boolean = 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": "", + "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 `secretsManagementSecretArn` variable in `package/config.ts` should be changed to this secret's ARN: + + ```ts + public readonly secretsManagementSecretArn?: string = ''; + ``` + It is highly recommended that you leave this parameter undefined to enable the automatic generation of a strong password. + 14. Build the `aws-rfdk` package, and then build the sample app. There is some magic in the way yarn workspaces and lerna packages work that will link the built `aws-rfdk` from the base directory as the dependency to be used in the example's directory: ```bash # Navigate to the root directory of the RFDK repository (assumes you started in the example's directory) diff --git a/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/bin/app.ts b/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/bin/app.ts index 916d5ec4f..2c682294b 100644 --- a/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/bin/app.ts +++ b/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/bin/app.ts @@ -51,6 +51,10 @@ import { WorkstationTier } from '../lib/workstation-tier'; throw new Error('Deadline Client Linux AMI map is required but was not specified.'); } + if (!config.enableSecretsManagement && config.secretsManagementSecretArn) { + console.warn('Deadline Secrets Management is disabled, so the admin credentials specified in the provided secret will not be used.'); + } + // ------------------- // // --- Application --- // // ------------------- // @@ -114,6 +118,8 @@ const service = new ServiceTier(app, 'ServiceTier', { rootCa: security.rootCa, dnsZone: network.dnsZone, acceptAwsThinkboxEula: config.acceptAwsThinkboxEula, + enableSecretsManagement: config.enableSecretsManagement, + secretsManagementSecretArn: config.secretsManagementSecretArn }); // -------------------- // diff --git a/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/bin/config.ts b/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/bin/config.ts index a818980c3..8e4b66ae5 100644 --- a/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/bin/config.ts +++ b/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/bin/config.ts @@ -72,6 +72,17 @@ class AppConfig { */ public readonly deployMongoDB: boolean = false; + /** + * Whether to enable Deadline Secrets Management. + */ + public readonly enableSecretsManagement: boolean = 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. + */ + public readonly secretsManagementSecretArn?: string; + /** * This is only relevant if deployMongoDB = true. * diff --git a/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/lib/service-tier.ts b/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/lib/service-tier.ts index e2b20975f..4a0473876 100644 --- a/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/lib/service-tier.ts +++ b/examples/deadline/All-In-AWS-Infrastructure-Basic/ts/lib/service-tier.ts @@ -79,7 +79,7 @@ export interface ServiceTierProps extends cdk.StackProps { /** * Version of Deadline to use. - * @default The latest available release of Deadline is used + * @default - The latest available release of Deadline is used */ readonly deadlineVersion?: string; @@ -87,6 +87,17 @@ export interface ServiceTierProps extends cdk.StackProps { * Whether the AWS Thinkbox End-User License Agreement is accepted or not */ readonly acceptAwsThinkboxEula: AwsThinkboxEulaAcceptance; + + /** + * Whether to enable Deadline Secrets Management. + */ + readonly enableSecretsManagement: boolean; + + /** + * The ARN of the AWS Secret containing the admin credentials for Deadline Secrets Management. + * @default - If Deadline Secrets Management is enabled, an AWS Secret with admin credentials will be generated. + */ + readonly secretsManagementSecretArn?: string; } /** @@ -129,7 +140,8 @@ export class ServiceTier extends cdk.Stack { repositoryInstallationTimeout: cdk.Duration.minutes(20), repositoryInstallationPrefix: "/", secretsManagementSettings: { - enabled: true, + enabled: props.enableSecretsManagement, + credentials: props.secretsManagementSecretArn ? Secret.fromSecretCompleteArn(this, 'SMAdminUser', props.secretsManagementSecretArn) : undefined, }, });