From 4917c04a23852608c4c697bff02a1085fdfd4b8c Mon Sep 17 00:00:00 2001 From: Neta Nir Date: Wed, 24 Jun 2020 12:16:39 -0700 Subject: [PATCH 01/55] feat(ec2): add 6xlarge InstanceSize (#8701) closes https://github.com/aws/aws-cdk/issues/8690 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-ec2/lib/instance-types.ts | 73 +++++++++++++++++++ packages/@aws-cdk/aws-ec2/package.json | 17 ----- 2 files changed, 73 insertions(+), 17 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts index 8f27607a85f4a..28b8c9ee46554 100644 --- a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts +++ b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts @@ -383,23 +383,96 @@ export enum InstanceClass { * What size of instance to use */ export enum InstanceSize { + /** + * Instance size NANO (nano) + */ NANO = 'nano', + + /** + * Instance size MICRO (micro) + */ MICRO = 'micro', + + /** + * Instance size SMALL (small) + */ SMALL = 'small', + + /** + * Instance size MEDIUM (medium) + */ MEDIUM = 'medium', + + /** + * Instance size LARGE (large) + */ LARGE = 'large', + + /** + * Instance size XLARGE (xlarge) + */ XLARGE = 'xlarge', + + /** + * Instance size XLARGE2 (2xlarge) + */ XLARGE2 = '2xlarge', + + /** + * Instance size XLARGE4 (4xlarge) + */ XLARGE4 = '4xlarge', + + /** + * Instance size XLARGE6 (6xlarge) + */ + XLARGE6 = '6xlarge', + + /** + * Instance size XLARGE8 (8xlarge) + */ XLARGE8 = '8xlarge', + + /** + * Instance size XLARGE9 (9xlarge) + */ XLARGE9 = '9xlarge', + + /** + * Instance size XLARGE10 (10xlarge) + */ XLARGE10 = '10xlarge', + + /** + * Instance size XLARGE12 (12xlarge) + */ XLARGE12 = '12xlarge', + + /** + * Instance size XLARGE16 (16xlarge) + */ XLARGE16 = '16xlarge', + + /** + * Instance size XLARGE18 (18xlarge) + */ XLARGE18 = '18xlarge', + + /** + * Instance size XLARGE24 (24xlarge) + */ XLARGE24 = '24xlarge', + + /** + * Instance size XLARGE32 (32xlarge) + */ XLARGE32 = '32xlarge', + + /** + * Instance size METAL (metal) + */ METAL = 'metal', + } /** diff --git a/packages/@aws-cdk/aws-ec2/package.json b/packages/@aws-cdk/aws-ec2/package.json index 458f2d1b4bc2e..b49f8b3d00007 100644 --- a/packages/@aws-cdk/aws-ec2/package.json +++ b/packages/@aws-cdk/aws-ec2/package.json @@ -289,23 +289,6 @@ "docs-public-apis:@aws-cdk/aws-ec2.VpnConnectionProps", "docs-public-apis:@aws-cdk/aws-ec2.VpnTunnelOption", "docs-public-apis:@aws-cdk/aws-ec2.AmazonLinuxStorage", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.NANO", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.MICRO", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.SMALL", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.MEDIUM", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.LARGE", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.XLARGE", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.XLARGE2", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.XLARGE4", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.XLARGE8", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.XLARGE9", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.XLARGE10", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.XLARGE12", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.XLARGE16", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.XLARGE18", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.XLARGE24", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.XLARGE32", - "docs-public-apis:@aws-cdk/aws-ec2.InstanceSize.METAL", "docs-public-apis:@aws-cdk/aws-ec2.OperatingSystemType.LINUX", "docs-public-apis:@aws-cdk/aws-ec2.OperatingSystemType.WINDOWS", "docs-public-apis:@aws-cdk/aws-ec2.Protocol.ALL", From d09c121e84c0c106f25a129066b0990fb237b841 Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Wed, 24 Jun 2020 22:00:21 +0200 Subject: [PATCH 02/55] fix(backup): vault name may exceed 50 characters (#8653) Remove `AWS::StackName` from the CDK generated vault name, it's already included in the `uniqueId`. BREAKING CHANGE: existing vaults that use a generated name will be replaced but existing recovery points won't be lost. The default vault removal policy is `RETAIN` and if it was set to `DESTROY` the deployment will fail because vault with recovery points cannot be deleted. Fixes #8627 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-backup/README.md | 4 ++++ packages/@aws-cdk/aws-backup/lib/vault.ts | 8 +++++--- packages/@aws-cdk/aws-backup/package.json | 2 +- .../aws-backup/test/integ.backup.expected.json | 12 +----------- packages/@aws-cdk/aws-backup/test/vault.test.ts | 12 +----------- 5 files changed, 12 insertions(+), 26 deletions(-) diff --git a/packages/@aws-cdk/aws-backup/README.md b/packages/@aws-cdk/aws-backup/README.md index 531a324855f26..57e47aee1081a 100644 --- a/packages/@aws-cdk/aws-backup/README.md +++ b/packages/@aws-cdk/aws-backup/README.md @@ -6,6 +6,10 @@ > All classes with the `Cfn` prefix in this module ([CFN Resources](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib)) are always stable and safe to use. +![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge) + +> The APIs of higher level constructs in this module are experimental and under active development. They are subject to non-backward compatible changes or removal in any future version. These are not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be announced in the release notes. This means that while you may use them, you may need to update your source code when upgrading to a newer version of this package. + --- diff --git a/packages/@aws-cdk/aws-backup/lib/vault.ts b/packages/@aws-cdk/aws-backup/lib/vault.ts index 849f7dfa5cfa5..6f109306ce1c3 100644 --- a/packages/@aws-cdk/aws-backup/lib/vault.ts +++ b/packages/@aws-cdk/aws-backup/lib/vault.ts @@ -1,7 +1,7 @@ import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; import * as sns from '@aws-cdk/aws-sns'; -import { Aws, Construct, IResource, RemovalPolicy, Resource } from '@aws-cdk/core'; +import { Construct, IResource, RemovalPolicy, Resource } from '@aws-cdk/core'; import { CfnBackupVault } from './backup.generated'; /** @@ -21,7 +21,9 @@ export interface IBackupVault extends IResource { */ export interface BackupVaultProps { /** - * The name of a logical container where backups are stored. + * The name of a logical container where backups are stored. Backup vaults + * are identified by names that are unique to the account used to create + * them and the AWS Region where they are created. * * @default - A CDK generated name */ @@ -158,7 +160,7 @@ export class BackupVault extends Resource implements IBackupVault { private uniqueVaultName() { // Max length of 50 chars, get the last 50 chars - const id = `${this.node.uniqueId}${Aws.STACK_NAME}`; + const id = this.node.uniqueId; return id.substring(Math.max(id.length - 50, 0), id.length); } } diff --git a/packages/@aws-cdk/aws-backup/package.json b/packages/@aws-cdk/aws-backup/package.json index ce47e6dc2b249..43461ce79359f 100644 --- a/packages/@aws-cdk/aws-backup/package.json +++ b/packages/@aws-cdk/aws-backup/package.json @@ -99,7 +99,7 @@ "node": ">= 10.13.0 <13 || >=13.7.0" }, "stability": "experimental", - "maturity": "cfn-only", + "maturity": "experimental", "awscdkio": { "announce": false } diff --git a/packages/@aws-cdk/aws-backup/test/integ.backup.expected.json b/packages/@aws-cdk/aws-backup/test/integ.backup.expected.json index bad27ac4ec97f..2ba1356211377 100644 --- a/packages/@aws-cdk/aws-backup/test/integ.backup.expected.json +++ b/packages/@aws-cdk/aws-backup/test/integ.backup.expected.json @@ -29,17 +29,7 @@ "Vault23237E5B": { "Type": "AWS::Backup::BackupVault", "Properties": { - "BackupVaultName": { - "Fn::Join": [ - "", - [ - "cdkbackupVaultC2A6D3CB", - { - "Ref": "AWS::StackName" - } - ] - ] - } + "BackupVaultName": "cdkbackupVaultC2A6D3CB" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" diff --git a/packages/@aws-cdk/aws-backup/test/vault.test.ts b/packages/@aws-cdk/aws-backup/test/vault.test.ts index 31e202a16b163..b8291be0e74ff 100644 --- a/packages/@aws-cdk/aws-backup/test/vault.test.ts +++ b/packages/@aws-cdk/aws-backup/test/vault.test.ts @@ -16,17 +16,7 @@ test('create a vault', () => { // THEN expect(stack).toHaveResource('AWS::Backup::BackupVault', { - BackupVaultName: { - 'Fn::Join': [ - '', - [ - 'Vault', - { - Ref: 'AWS::StackName', - }, - ], - ], - }, + BackupVaultName: 'Vault', }); }); From 67978a1cc92c9e7bea389e533b893efedd204c66 Mon Sep 17 00:00:00 2001 From: Shiv Lakshminarayan Date: Wed, 24 Jun 2020 13:49:54 -0700 Subject: [PATCH 03/55] feat(stepfunctions): class for working with Json paths to retrieve state machine data and context (#8647) merges the shared functionality of the `Data` and `Context` classes as there is overlap. From a user's perspective, working with paths is more idiomatic without having to think about state machine Data vs. task Context ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-stepfunctions-tasks/README.md | 29 ++--- .../lib/ecs/run-ecs-task-base.ts | 2 +- .../lib/evaluate-expression.ts | 2 +- .../lib/lambda/invoke.ts | 2 +- .../lib/lambda/run-lambda-task.ts | 4 +- .../lib/sagemaker/base-types.ts | 2 +- .../lib/sagemaker/create-training-job.ts | 2 +- .../lib/sns/publish-to-topic.ts | 2 +- .../lib/sns/publish.ts | 2 +- .../lib/sqs/send-message.ts | 2 +- .../lib/sqs/send-to-queue.ts | 2 +- .../lib/start-execution.ts | 2 +- .../lib/stepfunctions/start-execution.ts | 2 +- .../test/batch/integ.run-batch-job.ts | 2 +- .../test/batch/integ.submit-job.ts | 2 +- .../test/batch/run-batch-job.test.ts | 10 +- .../test/batch/submit-job.test.ts | 12 +- .../test/dynamodb/integ.call-dynamodb.ts | 6 +- .../test/ecs/ecs-tasks.test.ts | 8 +- .../test/ecs/integ.ec2-task.ts | 2 +- .../test/ecs/integ.fargate-task.ts | 2 +- .../test/emr/emr-add-step.test.ts | 4 +- .../test/emr/emr-create-cluster.test.ts | 2 +- .../emr-modify-instance-fleet-by-name.test.ts | 8 +- .../emr-modify-instance-group-by-name.test.ts | 6 +- .../test/integ.start-execution.ts | 2 +- .../test/lambda/integ.invoke-function.ts | 2 +- .../test/lambda/invoke-function.test.ts | 2 +- .../test/lambda/invoke.test.ts | 4 +- .../test/lambda/run-lambda-task.test.ts | 2 +- .../sagemaker/create-training-job.test.ts | 2 +- .../sagemaker/create-transform-job.test.ts | 4 +- .../test/sns/publish-to-topic.test.ts | 4 +- .../test/sns/publish.test.ts | 6 +- .../test/sqs/send-message.test.ts | 8 +- .../test/sqs/send-to-queue.test.ts | 6 +- .../test/start-execution.test.ts | 4 +- .../stepfunctions/integ.start-execution.ts | 2 +- .../stepfunctions/start-execution.test.ts | 4 +- packages/@aws-cdk/aws-stepfunctions/README.md | 2 +- .../@aws-cdk/aws-stepfunctions/lib/fields.ts | 104 ++++++++++++++++-- .../@aws-cdk/aws-stepfunctions/lib/input.ts | 28 +++-- .../aws-stepfunctions/lib/states/map.ts | 6 +- .../aws-stepfunctions/lib/states/parallel.ts | 6 +- .../aws-stepfunctions/lib/states/pass.ts | 6 +- .../aws-stepfunctions/lib/states/state.ts | 11 +- .../aws-stepfunctions/lib/states/succeed.ts | 4 +- .../aws-stepfunctions/lib/states/task-base.ts | 6 +- .../aws-stepfunctions/lib/states/task.ts | 6 +- .../aws-stepfunctions/test/fields.test.ts | 48 ++++---- .../aws-stepfunctions/test/map.test.ts | 30 ++--- .../test/state-machine-resources.test.ts | 2 +- 52 files changed, 257 insertions(+), 173 deletions(-) diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md index 907fd5f5b76a1..6665cc4196b23 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md @@ -140,7 +140,7 @@ Most tasks take parameters. Parameter values can either be static, supplied dire in the workflow definition (by specifying their values), or a value available at runtime in the state machine's execution (either as its input or an output of a prior state). Parameter values available at runtime can be specified via the `Data` class, -using methods such as `Data.stringAt()`. +using methods such as `JsonPath.stringAt()`. The following example provides the field named `input` as the input to the Lambda function and invokes it asynchronously. @@ -148,7 +148,7 @@ and invokes it asynchronously. ```ts const submitJob = new tasks.LambdaInvoke(stack, 'Invoke Handler', { lambdaFunction: submitJobLambda, - payload: sfn.Data.StringAt('$.input'), + payload: sfn.JsonPath.StringAt('$.input'), invocationType: tasks.InvocationType.EVENT, }); ``` @@ -261,7 +261,7 @@ The [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API new tasks.DynamoPutItem(this, 'PutItem', { item: { MessageId: tasks.DynamoAttributeValue.fromString('message-007'), - Text: tasks.DynamoAttributeValue.fromString(sfn.Data.stringAt('$.bar')), + Text: tasks.DynamoAttributeValue.fromString(sfn.JsonPath.stringAt('$.bar')), TotalCount: tasks.DynamoAttributeValue.fromNumber(10), }, table, @@ -273,10 +273,13 @@ new tasks.DynamoPutItem(this, 'PutItem', { The [DeleteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html) operation deletes a single item in a table by primary key. ```ts +import * as sfn from '@aws-cdk/aws-stepfunctions'; +import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; + new tasks.DynamoDeleteItem(this, 'DeleteItem', { key: { MessageId: tasks.DynamoAttributeValue.fromString('message-007') }, table, - resultPath: 'DISCARD', + resultPath: sfn.JsonPath.DISCARD, }); ``` @@ -290,7 +293,7 @@ new tasks.DynamoUpdateItem(this, 'UpdateItem', { key: { MessageId: tasks.DynamoAttributeValue.fromString('message-007') }, table, expressionAttributeValues: { - ':val': tasks.DynamoAttributeValue.numberFromString(sfn.Data.stringAt('$.Item.TotalCount.N')), + ':val': tasks.DynamoAttributeValue.numberFromString(sfn.JsonPath.stringAt('$.Item.TotalCount.N')), ':rand': tasks.DynamoAttributeValue.fromNumber(20), }, updateExpression: 'SET TotalCount = :val + :rand', @@ -319,7 +322,7 @@ new ecs.RunEcsFargateTask({ environment: [ { name: 'CONTAINER_INPUT', - value: Data.stringAt('$.valueFromStateData'), + value: JsonPath.stringAt('$.valueFromStateData'), } ] } @@ -458,7 +461,7 @@ Corresponds to the [`modifyInstanceGroups`](https://docs.aws.amazon.com/emr/late ```ts new tasks.EmrModifyInstanceGroupByName(stack, 'Task', { clusterId: 'ClusterId', - instanceGroupName: sfn.Data.stringAt('$.InstanceGroupName'), + instanceGroupName: sfn.JsonPath.stringAt('$.InstanceGroupName'), instanceGroup: { instanceCount: 1, }, @@ -562,8 +565,8 @@ new tasks.LambdaInvoke(stack, 'Invoke with callback', { lambdaFunction: myLambda, integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, payload: sfn.TaskInput.fromObject({ - token: sfn.Context.taskToken, - input: sfn.Data.stringAt('$.someField'), + token: sfn.JsonPath.taskToken, + input: sfn.JsonPath.stringAt('$.someField'), }), }); ``` @@ -582,7 +585,7 @@ You can call the [`CreateTrainingJob`](https://docs.aws.amazon.com/sagemaker/lat ```ts new sfn.SagemakerTrainTask(this, 'TrainSagemaker', { - trainingJobName: sfn.Data.stringAt('$.JobName'), + trainingJobName: sfn.JsonPath.stringAt('$.JobName'), role, algorithmSpecification: { algorithmName: 'BlazingText', @@ -667,7 +670,7 @@ const task2 = new tasks.SnsPublish(this, 'Publish2', { topic, message: sfn.TaskInput.fromObject({ field1: 'somedata', - field2: sfn.Data.stringAt('$.field2'), + field2: sfn.JsonPath.stringAt('$.field2'), }) }); ``` @@ -689,7 +692,7 @@ const task = new StepFunctionsStartExecution(stack, 'ChildTask', { stateMachine: child, integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, input: sfn.TaskInput.fromObject({ - token: sfn.Context.taskToken, + token: sfn.JsonPath.taskToken, foo: 'bar' }), name: 'MyExecutionName' @@ -729,7 +732,7 @@ const task2 = new tasks.SqsSendMessage(this, 'Send2', { queue, messageBody: sfn.TaskInput.fromObject({ field1: 'somedata', - field2: sfn.Data.stringAt('$.field2'), + field2: sfn.JsonPath.stringAt('$.field2'), }), }); ``` diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base.ts index 1bc456d7c47c4..fc4d5f6efc448 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base.ts @@ -83,7 +83,7 @@ export class EcsRunTaskBase implements ec2.IConnectable, sfn.IStepFunctionsTask if (this.integrationPattern === sfn.ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN && !sfn.FieldUtils.containsTaskToken(props.containerOverrides)) { - throw new Error('Task Token is missing in containerOverrides (pass Context.taskToken somewhere in containerOverrides)'); + throw new Error('Task Token is missing in containerOverrides (pass JsonPath.taskToken somewhere in containerOverrides)'); } for (const override of this.props.containerOverrides || []) { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/evaluate-expression.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/evaluate-expression.ts index b2a630681bb83..0e13d9d90c1e3 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/evaluate-expression.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/evaluate-expression.ts @@ -61,7 +61,7 @@ export class EvaluateExpression implements sfn.IStepFunctionsTask { expressionAttributeValues = matches.reduce( (acc, m) => ({ ...acc, - [m]: sfn.Data.stringAt(m), // It's okay to always use `stringAt` here + [m]: sfn.JsonPath.stringAt(m), // It's okay to always use `stringAt` here }), {}, ); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/invoke.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/invoke.ts index ce7cd397f48c8..8345d12a83011 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/invoke.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/invoke.ts @@ -73,7 +73,7 @@ export class LambdaInvoke extends sfn.TaskStateBase { if (this.integrationPattern === sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN && !sfn.FieldUtils.containsTaskToken(props.payload)) { - throw new Error('Task Token is required in `payload` for callback. Use Context.taskToken to set the token.'); + throw new Error('Task Token is required in `payload` for callback. Use JsonPath.taskToken to set the token.'); } this.taskMetrics = { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/run-lambda-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/run-lambda-task.ts index c3ed91e724ca2..cf240ccbfa86f 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/run-lambda-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/run-lambda-task.ts @@ -22,7 +22,7 @@ export interface RunLambdaTaskProps { * The valid value for Lambda is either FIRE_AND_FORGET or WAIT_FOR_TASK_TOKEN, * it determines whether to pause the workflow until a task token is returned. * - * If this is set to WAIT_FOR_TASK_TOKEN, the Context.taskToken value must be included + * If this is set to WAIT_FOR_TASK_TOKEN, the JsonPath.taskToken value must be included * somewhere in the payload and the Lambda must call * `SendTaskSuccess/SendTaskFailure` using that token. * @@ -79,7 +79,7 @@ export class RunLambdaTask implements sfn.IStepFunctionsTask { if (this.integrationPattern === sfn.ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN && !sfn.FieldUtils.containsTaskToken(props.payload)) { - throw new Error('Task Token is missing in payload (pass Context.taskToken somewhere in payload)'); + throw new Error('Task Token is missing in payload (pass JsonPath.taskToken somewhere in payload)'); } } diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/base-types.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/base-types.ts index 6f1c5f03dcc37..f701f9e20d6e9 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/base-types.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/base-types.ts @@ -308,7 +308,7 @@ export abstract class S3Location { * @param expression the JSON expression resolving to an S3 location URI. */ public static fromJsonExpression(expression: string): S3Location { - return new StandardS3Location({ uri: sfn.Data.stringAt(expression) }); + return new StandardS3Location({ uri: sfn.JsonPath.stringAt(expression) }); } /** diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts index f541a0e692a4f..d57b9114dc7e8 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts @@ -374,7 +374,7 @@ export class SageMakerCreateTrainingJob extends sfn.TaskStateBase implements iam service: 'sagemaker', resource: 'training-job', // If the job name comes from input, we cannot target the policy to a particular ARN prefix reliably... - resourceName: sfn.Data.isJsonPathString(this.props.trainingJobName) ? '*' : `${this.props.trainingJobName}*`, + resourceName: sfn.JsonPath.isEncodedJsonPath(this.props.trainingJobName) ? '*' : `${this.props.trainingJobName}*`, }), ], }), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish-to-topic.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish-to-topic.ts index 3473984ada2fa..bc07f33b2bc9b 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish-to-topic.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish-to-topic.ts @@ -71,7 +71,7 @@ export class PublishToTopic implements sfn.IStepFunctionsTask { if (this.integrationPattern === sfn.ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN) { if (!sfn.FieldUtils.containsTaskToken(props.message)) { - throw new Error('Task Token is missing in message (pass Context.taskToken somewhere in message)'); + throw new Error('Task Token is missing in message (pass JsonPath.taskToken somewhere in message)'); } } } diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts index 273257f98743c..a9bca94666963 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts @@ -73,7 +73,7 @@ export class SnsPublish extends sfn.TaskStateBase { if (this.integrationPattern === sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN) { if (!sfn.FieldUtils.containsTaskToken(props.message)) { - throw new Error('Task Token is required in `message` Use Context.taskToken to set the token.'); + throw new Error('Task Token is required in `message` Use JsonPath.taskToken to set the token.'); } } diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-message.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-message.ts index c7ec4adb18517..c50c41e952c59 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-message.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-message.ts @@ -73,7 +73,7 @@ export class SqsSendMessage extends sfn.TaskStateBase { if (props.integrationPattern === sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN) { if (!sfn.FieldUtils.containsTaskToken(props.messageBody)) { - throw new Error('Task Token is required in `messageBody` Use Context.taskToken to set the token.'); + throw new Error('Task Token is required in `messageBody` Use JsonPath.taskToken to set the token.'); } } diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-to-queue.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-to-queue.ts index 4d7dce33f9cf6..36c1d1e7ac6be 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-to-queue.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-to-queue.ts @@ -77,7 +77,7 @@ export class SendToQueue implements sfn.IStepFunctionsTask { if (props.integrationPattern === sfn.ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN) { if (!sfn.FieldUtils.containsTaskToken(props.messageBody)) { - throw new Error('Task Token is missing in messageBody (pass Context.taskToken somewhere in messageBody)'); + throw new Error('Task Token is missing in messageBody (pass JsonPath.taskToken somewhere in messageBody)'); } } } diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/start-execution.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/start-execution.ts index 9ec81c367e4df..0572459f1e4a3 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/start-execution.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/start-execution.ts @@ -62,7 +62,7 @@ export class StartExecution implements sfn.IStepFunctionsTask { if (this.integrationPattern === sfn.ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN && !sfn.FieldUtils.containsTaskToken(props.input)) { - throw new Error('Task Token is missing in input (pass Context.taskToken somewhere in input)'); + throw new Error('Task Token is missing in input (pass JsonPath.taskToken somewhere in input)'); } } diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/stepfunctions/start-execution.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/stepfunctions/start-execution.ts index 5677d5d89021f..4bae47036558c 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/stepfunctions/start-execution.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/stepfunctions/start-execution.ts @@ -55,7 +55,7 @@ export class StepFunctionsStartExecution extends sfn.TaskStateBase { validatePatternSupported(this.integrationPattern, StepFunctionsStartExecution.SUPPORTED_INTEGRATION_PATTERNS); if (this.integrationPattern === sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN && !sfn.FieldUtils.containsTaskToken(props.input)) { - throw new Error('Task Token is required in `input` for callback. Use Context.taskToken to set the token.'); + throw new Error('Task Token is required in `input` for callback. Use JsonPath.taskToken to set the token.'); } this.taskPolicies = this.createScopedAccessPolicy(); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/integ.run-batch-job.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/integ.run-batch-job.ts index b1c53f9a80710..944039ed40bde 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/integ.run-batch-job.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/integ.run-batch-job.ts @@ -51,7 +51,7 @@ class RunBatchStack extends cdk.Stack { vcpus: 1, }, payload: { - foo: sfn.Data.stringAt('$.bar'), + foo: sfn.JsonPath.stringAt('$.bar'), }, attempts: 3, timeout: cdk.Duration.seconds(60), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/integ.submit-job.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/integ.submit-job.ts index 86e891d4331ed..5a89db1913334 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/integ.submit-job.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/integ.submit-job.ts @@ -50,7 +50,7 @@ class RunBatchStack extends cdk.Stack { vcpus: 1, }, payload: sfn.TaskInput.fromObject({ - foo: sfn.Data.stringAt('$.bar'), + foo: sfn.JsonPath.stringAt('$.bar'), }), attempts: 3, timeout: cdk.Duration.seconds(60), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/run-batch-job.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/run-batch-job.test.ts index f6be966c1cb85..a9b93a3dd2f2b 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/run-batch-job.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/run-batch-job.test.ts @@ -86,7 +86,7 @@ test('Task with all the parameters', () => { }, dependsOn: [{ jobId: '1234', type: 'some_type' }], payload: { - foo: sfn.Data.stringAt('$.bar'), + foo: sfn.JsonPath.stringAt('$.bar'), }, attempts: 3, timeout: cdk.Duration.seconds(60), @@ -136,11 +136,11 @@ test('supports tokens', () => { const task = new sfn.Task(stack, 'Task', { task: new tasks.RunBatchJob({ jobDefinition: batchJobDefinition, - jobName: sfn.Data.stringAt('$.jobName'), + jobName: sfn.JsonPath.stringAt('$.jobName'), jobQueue: batchJobQueue, - arraySize: sfn.Data.numberAt('$.arraySize'), - timeout: cdk.Duration.seconds(sfn.Data.numberAt('$.timeout')), - attempts: sfn.Data.numberAt('$.attempts'), + arraySize: sfn.JsonPath.numberAt('$.arraySize'), + timeout: cdk.Duration.seconds(sfn.JsonPath.numberAt('$.timeout')), + attempts: sfn.JsonPath.numberAt('$.attempts'), }), }); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/submit-job.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/submit-job.test.ts index 6538e8bc1733e..92c8ebeb597b8 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/submit-job.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/batch/submit-job.test.ts @@ -83,7 +83,7 @@ test('Task with all the parameters', () => { }, dependsOn: [{ jobId: '1234', type: 'some_type' }], payload: sfn.TaskInput.fromObject({ - foo: sfn.Data.stringAt('$.bar'), + foo: sfn.JsonPath.stringAt('$.bar'), }), attempts: 3, timeout: cdk.Duration.seconds(60), @@ -131,11 +131,11 @@ test('supports tokens', () => { // WHEN const task = new BatchSubmitJob(stack, 'Task', { jobDefinition: batchJobDefinition, - jobName: sfn.Data.stringAt('$.jobName'), + jobName: sfn.JsonPath.stringAt('$.jobName'), jobQueue: batchJobQueue, - arraySize: sfn.Data.numberAt('$.arraySize'), - timeout: cdk.Duration.seconds(sfn.Data.numberAt('$.timeout')), - attempts: sfn.Data.numberAt('$.attempts'), + arraySize: sfn.JsonPath.numberAt('$.arraySize'), + timeout: cdk.Duration.seconds(sfn.JsonPath.numberAt('$.timeout')), + attempts: sfn.JsonPath.numberAt('$.attempts'), }); // THEN @@ -175,7 +175,7 @@ test('supports passing task input into payload', () => { // WHEN const task = new BatchSubmitJob(stack, 'Task', { jobDefinition: batchJobDefinition, - jobName: sfn.Data.stringAt('$.jobName'), + jobName: sfn.JsonPath.stringAt('$.jobName'), jobQueue: batchJobQueue, payload: sfn.TaskInput.fromDataAt('$.foo'), }); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/integ.call-dynamodb.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/integ.call-dynamodb.ts index 3728a64295122..abf91f54cdb5b 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/integ.call-dynamodb.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/integ.call-dynamodb.ts @@ -49,7 +49,7 @@ class CallDynamoDBStack extends cdk.Stack { key: { MessageId: tasks.DynamoAttributeValue.fromString(MESSAGE_ID) }, table, expressionAttributeValues: { - ':val': tasks.DynamoAttributeValue.numberFromString(sfn.Data.stringAt('$.Item.TotalCount.N')), + ':val': tasks.DynamoAttributeValue.numberFromString(sfn.JsonPath.stringAt('$.Item.TotalCount.N')), ':rand': tasks.DynamoAttributeValue.fromNumber(secondNumber), }, updateExpression: 'SET TotalCount = :val + :rand', @@ -58,13 +58,13 @@ class CallDynamoDBStack extends cdk.Stack { const getItemTaskAfterUpdate = new tasks.DynamoGetItem(this, 'GetItemAfterUpdate', { key: { MessageId: tasks.DynamoAttributeValue.fromString(MESSAGE_ID) }, table, - outputPath: sfn.Data.stringAt('$.Item.TotalCount.N'), + outputPath: sfn.JsonPath.stringAt('$.Item.TotalCount.N'), }); const deleteItemTask = new tasks.DynamoDeleteItem(this, 'DeleteItem', { key: { MessageId: tasks.DynamoAttributeValue.fromString(MESSAGE_ID) }, table, - resultPath: 'DISCARD', + resultPath: sfn.JsonPath.DISCARD, }); const definition = new sfn.Pass(this, 'Start', { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/ecs-tasks.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/ecs-tasks.test.ts index 611339b3fe08a..a644363a9c077 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/ecs-tasks.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/ecs-tasks.test.ts @@ -64,7 +64,7 @@ test('Running a Fargate Task', () => { { containerName: 'TheContainer', environment: [ - {name: 'SOME_KEY', value: sfn.Data.stringAt('$.SomeKey')}, + {name: 'SOME_KEY', value: sfn.JsonPath.stringAt('$.SomeKey')}, ], }, ], @@ -173,7 +173,7 @@ test('Running an EC2 Task with bridge network', () => { { containerName: 'TheContainer', environment: [ - {name: 'SOME_KEY', value: sfn.Data.stringAt('$.SomeKey')}, + {name: 'SOME_KEY', value: sfn.JsonPath.stringAt('$.SomeKey')}, ], }, ], @@ -331,9 +331,9 @@ test('Running an EC2 Task with overridden number values', () => { containerOverrides: [ { containerName: 'TheContainer', - command: sfn.Data.listAt('$.TheCommand'), + command: sfn.JsonPath.listAt('$.TheCommand'), cpu: 5, - memoryLimit: sfn.Data.numberAt('$.MemoryLimit'), + memoryLimit: sfn.JsonPath.numberAt('$.MemoryLimit'), }, ], }); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-task.ts index aa4238f85a218..dc0a42c1d7bd8 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-task.ts @@ -44,7 +44,7 @@ const definition = new sfn.Pass(stack, 'Start', { environment: [ { name: 'SOME_KEY', - value: sfn.Data.stringAt('$.SomeKey'), + value: sfn.JsonPath.stringAt('$.SomeKey'), }, ], }, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-task.ts index 8c05adb3dbcba..4f981dfaa45b8 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-task.ts @@ -43,7 +43,7 @@ const definition = new sfn.Pass(stack, 'Start', { environment: [ { name: 'SOME_KEY', - value: sfn.Data.stringAt('$.SomeKey'), + value: sfn.JsonPath.stringAt('$.SomeKey'), }, ], }, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-add-step.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-add-step.test.ts index 63633412a4933..489c5612b5f2f 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-add-step.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-add-step.test.ts @@ -51,7 +51,7 @@ test('Add Step with static ClusterId and Step configuration', () => { test('Terminate cluster with ClusterId from payload and static Step configuration', () => { // WHEN const task = new tasks.EmrAddStep(stack, 'Task', { - clusterId: sfn.Data.stringAt('$.ClusterId'), + clusterId: sfn.JsonPath.stringAt('$.ClusterId'), name: 'StepName', jar: 'Jar', actionOnFailure: tasks.ActionOnFailure.CONTINUE, @@ -91,7 +91,7 @@ test('Add Step with static ClusterId and Step Name from payload', () => { // WHEN const task = new tasks.EmrAddStep(stack, 'Task', { clusterId: 'ClusterId', - name: sfn.Data.stringAt('$.StepName'), + name: sfn.JsonPath.stringAt('$.StepName'), jar: 'Jar', actionOnFailure: tasks.ActionOnFailure.CONTINUE, integrationPattern: sfn.IntegrationPattern.RUN_JOB, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-create-cluster.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-create-cluster.test.ts index 06d1a2da8d34b..54fdf8a83e63d 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-create-cluster.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-create-cluster.test.ts @@ -813,7 +813,7 @@ test('Create Cluster with InstanceGroup', () => { evaluationPeriods: 1, metricName: 'Name', namespace: 'Namespace', - period: cdk.Duration.seconds(sfn.Data.numberAt('$.CloudWatchPeriod')), + period: cdk.Duration.seconds(sfn.JsonPath.numberAt('$.CloudWatchPeriod')), statistic: EmrCreateCluster.CloudWatchAlarmStatistic.AVERAGE, threshold: 1, unit: EmrCreateCluster.CloudWatchAlarmUnit.NONE, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-modify-instance-fleet-by-name.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-modify-instance-fleet-by-name.test.ts index e6612d92b1cf4..bd8fe53e7ff51 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-modify-instance-fleet-by-name.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-modify-instance-fleet-by-name.test.ts @@ -48,7 +48,7 @@ test('Modify an InstanceFleet with static ClusterId, InstanceFleetName, and Inst test('Modify an InstanceFleet with ClusterId from payload and static InstanceFleetName and InstanceFleetConfiguration', () => { // WHEN const task = new tasks.EmrModifyInstanceFleetByName(stack, 'Task', { - clusterId: sfn.Data.stringAt('$.ClusterId'), + clusterId: sfn.JsonPath.stringAt('$.ClusterId'), instanceFleetName: 'InstanceFleetName', targetOnDemandCapacity: 2, targetSpotCapacity: 0, @@ -85,7 +85,7 @@ test('Modify an InstanceFleet with static ClusterId and InstanceFleetConfigurate // WHEN const task = new tasks.EmrModifyInstanceFleetByName(stack, 'Task', { clusterId: 'ClusterId', - instanceFleetName: sfn.Data.stringAt('$.InstanceFleetName'), + instanceFleetName: sfn.JsonPath.stringAt('$.InstanceFleetName'), targetOnDemandCapacity: 2, targetSpotCapacity: 0, }); @@ -122,8 +122,8 @@ test('Modify an InstanceFleet with static ClusterId and InstanceFleetName and Ta const task = new tasks.EmrModifyInstanceFleetByName(stack, 'Task', { clusterId: 'ClusterId', instanceFleetName: 'InstanceFleetName', - targetOnDemandCapacity: sfn.Data.numberAt('$.TargetOnDemandCapacity'), - targetSpotCapacity: sfn.Data.numberAt('$.TargetSpotCapacity'), + targetOnDemandCapacity: sfn.JsonPath.numberAt('$.TargetOnDemandCapacity'), + targetSpotCapacity: sfn.JsonPath.numberAt('$.TargetSpotCapacity'), }); // THEN diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-modify-instance-group-by-name.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-modify-instance-group-by-name.test.ts index f9bc8886de0d3..51bd3600147c1 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-modify-instance-group-by-name.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emr/emr-modify-instance-group-by-name.test.ts @@ -78,7 +78,7 @@ test('Modify an InstanceGroup with static ClusterId, InstanceGroupName, and Inst test('Modify an InstanceGroup with ClusterId from payload and static InstanceGroupName and InstanceGroupConfiguration', () => { // WHEN const task = new tasks.EmrModifyInstanceGroupByName(stack, 'Task', { - clusterId: sfn.Data.stringAt('$.ClusterId'), + clusterId: sfn.JsonPath.stringAt('$.ClusterId'), instanceGroupName: 'InstanceGroupName', instanceGroup: { instanceCount: 1, @@ -115,7 +115,7 @@ test('Modify an InstanceGroup with static ClusterId and InstanceGroupConfigurate // WHEN const task = new tasks.EmrModifyInstanceGroupByName(stack, 'Task', { clusterId: 'ClusterId', - instanceGroupName: sfn.Data.stringAt('$.InstanceGroupName'), + instanceGroupName: sfn.JsonPath.stringAt('$.InstanceGroupName'), instanceGroup: { instanceCount: 1, }, @@ -153,7 +153,7 @@ test('Modify an InstanceGroup with static ClusterId and InstanceGroupName and In clusterId: 'ClusterId', instanceGroupName: 'InstanceGroupName', instanceGroup: { - instanceCount: sfn.Data.numberAt('$.InstanceCount'), + instanceCount: sfn.JsonPath.numberAt('$.InstanceCount'), }, }); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.start-execution.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.start-execution.ts index 8624c601f8c83..865e42e9033c5 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.start-execution.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.start-execution.ts @@ -21,7 +21,7 @@ class TestStack extends Stack { definition: new sfn.Task(this, 'Task', { task: new tasks.StartExecution(child, { input: { - hello: sfn.Data.stringAt('$.hello'), + hello: sfn.JsonPath.stringAt('$.hello'), }, integrationPattern: sfn.ServiceIntegrationPattern.SYNC, }), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/integ.invoke-function.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/integ.invoke-function.ts index d3791f59782ed..7ff38d135a72d 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/integ.invoke-function.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/integ.invoke-function.ts @@ -27,7 +27,7 @@ const taskTokenHandler = new sfn.Task(stack, 'Invoke Handler with task token', { task: new tasks.RunLambdaTask(callbackHandler, { integrationPattern: sfn.ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN, payload: sfn.TaskInput.fromObject({ - token: sfn.Context.taskToken, + token: sfn.JsonPath.taskToken, }), }), inputPath: '$.guid', diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/invoke-function.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/invoke-function.test.ts index 2c5b51d4a347e..eb5341281e6b2 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/invoke-function.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/invoke-function.test.ts @@ -39,7 +39,7 @@ test('Lambda function payload ends up in Parameters', () => { definition: new sfn.Task(stack, 'Task', { task: new tasks.InvokeFunction(fn, { payload: { - foo: sfn.Data.stringAt('$.bar'), + foo: sfn.JsonPath.stringAt('$.bar'), }, }), }), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/invoke.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/invoke.test.ts index 62a6d4c632e23..5bb39f17385ff 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/invoke.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/invoke.test.ts @@ -106,7 +106,7 @@ describe('LambdaInvoke', () => { lambdaFunction, integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, payload: sfn.TaskInput.fromObject({ - token: sfn.Context.taskToken, + token: sfn.JsonPath.taskToken, }), qualifier: 'my-alias', }); @@ -183,7 +183,7 @@ describe('LambdaInvoke', () => { lambdaFunction, integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, }); - }).toThrow(/Task Token is required in `payload` for callback. Use Context.taskToken to set the token./); + }).toThrow(/Task Token is required in `payload` for callback. Use JsonPath.taskToken to set the token./); }); test('fails when RUN_JOB integration pattern is used', () => { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/run-lambda-task.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/run-lambda-task.test.ts index 6d46eeaf368cb..46538a2b41cd6 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/run-lambda-task.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/lambda/run-lambda-task.test.ts @@ -64,7 +64,7 @@ test('Lambda function can be used in a Task with Task Token', () => { task: new tasks.RunLambdaTask(fn, { integrationPattern: sfn.ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN, payload: sfn.TaskInput.fromObject({ - token: sfn.Context.taskToken, + token: sfn.JsonPath.taskToken, }), }), }); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker/create-training-job.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker/create-training-job.test.ts index 4f02f9ac048a1..5fb84bfee9981 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker/create-training-job.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker/create-training-job.test.ts @@ -294,7 +294,7 @@ test('pass param to training job', () => { }); const task = new SageMakerCreateTrainingJob(stack, 'TrainSagemaker', { - trainingJobName: sfn.Data.stringAt('$.JobName'), + trainingJobName: sfn.JsonPath.stringAt('$.JobName'), role, algorithmSpecification: { algorithmName: 'BlazingText', diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker/create-transform-job.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker/create-transform-job.test.ts index c53233523cfa7..7777f31e70074 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker/create-transform-job.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker/create-transform-job.test.ts @@ -184,8 +184,8 @@ test('create complex transform job', () => { test('pass param to transform job', () => { // WHEN const task = new SageMakerCreateTransformJob(stack, 'TransformTask', { - transformJobName: sfn.Data.stringAt('$.TransformJobName'), - modelName: sfn.Data.stringAt('$.ModelName'), + transformJobName: sfn.JsonPath.stringAt('$.TransformJobName'), + modelName: sfn.JsonPath.stringAt('$.ModelName'), role, transformInput: { transformDataSource: { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish-to-topic.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish-to-topic.test.ts index 162b3b3eee1f6..38da096791e54 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish-to-topic.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish-to-topic.test.ts @@ -46,7 +46,7 @@ test('Publish JSON to SNS topic with task token', () => { integrationPattern: sfn.ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN, message: sfn.TaskInput.fromObject({ Input: 'Publish this message', - Token: sfn.Context.taskToken, + Token: sfn.JsonPath.taskToken, }), }) }); @@ -93,7 +93,7 @@ test('Task throws if WAIT_FOR_TASK_TOKEN is supplied but task token is not inclu test('Publish to topic with ARN from payload', () => { // GIVEN const stack = new cdk.Stack(); - const topic = sns.Topic.fromTopicArn(stack, 'Topic', sfn.Data.stringAt('$.topicArn')); + const topic = sns.Topic.fromTopicArn(stack, 'Topic', sfn.JsonPath.stringAt('$.topicArn')); // WHEN const pub = new sfn.Task(stack, 'Publish', { task: new tasks.PublishToTopic(topic, { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish.test.ts index c63fb72fb719a..384c578641560 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish.test.ts @@ -50,7 +50,7 @@ describe('Publish', () => { integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, message: sfn.TaskInput.fromObject({ Input: 'Publish this message', - Token: sfn.Context.taskToken, + Token: sfn.JsonPath.taskToken, }), }); @@ -128,7 +128,7 @@ describe('Publish', () => { test('topic ARN supplied through the task input', () => { // GIVEN const stack = new cdk.Stack(); - const topic = sns.Topic.fromTopicArn(stack, 'Topic', sfn.Data.stringAt('$.topicArn')); + const topic = sns.Topic.fromTopicArn(stack, 'Topic', sfn.JsonPath.stringAt('$.topicArn')); // WHEN const task = new SnsPublish(stack, 'Publish', { @@ -172,7 +172,7 @@ describe('Publish', () => { message: sfn.TaskInput.fromText('Publish this message'), }); // THEN - }).toThrow(/Task Token is required in `message` Use Context.taskToken to set the token./); + }).toThrow(/Task Token is required in `message` Use JsonPath.taskToken to set the token./); }); test('fails when RUN_JOB integration pattern is used', () => { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sqs/send-message.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sqs/send-message.test.ts index 3ce5cd3cc6a1b..ee1ff021571e8 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sqs/send-message.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sqs/send-message.test.ts @@ -48,7 +48,7 @@ describe('SqsSendMessage', () => { const task = new SqsSendMessage(stack, 'Send', { queue, messageBody: sfn.TaskInput.fromText('Send this message'), - messageDeduplicationId: sfn.Data.stringAt('$.deduping'), + messageDeduplicationId: sfn.JsonPath.stringAt('$.deduping'), comment: 'sending a message to my SQS queue', delay: cdk.Duration.seconds(30), }); @@ -86,7 +86,7 @@ describe('SqsSendMessage', () => { integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, messageBody: sfn.TaskInput.fromObject({ Input: 'Send this message', - Token: sfn.Context.taskToken, + Token: sfn.JsonPath.taskToken, }), }); @@ -152,7 +152,7 @@ describe('SqsSendMessage', () => { queue, messageBody: sfn.TaskInput.fromObject({ literal: 'literal', - SomeInput: sfn.Data.stringAt('$.theMessage'), + SomeInput: sfn.JsonPath.stringAt('$.theMessage'), }), }); @@ -223,7 +223,7 @@ describe('SqsSendMessage', () => { integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, messageBody: sfn.TaskInput.fromText('Send this message'), }); - }).toThrow(/Task Token is required in `messageBody` Use Context.taskToken to set the token./); + }).toThrow(/Task Token is required in `messageBody` Use JsonPath.taskToken to set the token./); }); test('fails when RUN_JOB integration pattern is used', () => { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sqs/send-to-queue.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sqs/send-to-queue.test.ts index 7b77ba34f2592..69e051c903a55 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sqs/send-to-queue.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sqs/send-to-queue.test.ts @@ -16,7 +16,7 @@ test('Send message to queue', () => { // WHEN const task = new sfn.Task(stack, 'Send', { task: new tasks.SendToQueue(queue, { messageBody: sfn.TaskInput.fromText('Send this message'), - messageDeduplicationId: sfn.Data.stringAt('$.deduping'), + messageDeduplicationId: sfn.JsonPath.stringAt('$.deduping'), }) }); // THEN @@ -49,7 +49,7 @@ test('Send message to SQS queue with task token', () => { integrationPattern: sfn.ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN, messageBody: sfn.TaskInput.fromObject({ Input: 'Send this message', - Token: sfn.Context.taskToken, + Token: sfn.JsonPath.taskToken, }), }) }); @@ -127,7 +127,7 @@ test('Message body can be an object', () => { task: new tasks.SendToQueue(queue, { messageBody: sfn.TaskInput.fromObject({ literal: 'literal', - SomeInput: sfn.Data.stringAt('$.theMessage'), + SomeInput: sfn.JsonPath.stringAt('$.theMessage'), }), }), }); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/start-execution.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/start-execution.test.ts index 5d1ef3171debc..ee6a252ab09c3 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/start-execution.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/start-execution.test.ts @@ -181,7 +181,7 @@ test('Execute State Machine - Wait For Task Token', () => { task: new tasks.StartExecution(child, { integrationPattern: sfn.ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN, input: { - token: sfn.Context.taskToken, + token: sfn.JsonPath.taskToken, }, }), }); @@ -223,5 +223,5 @@ test('Execute State Machine - Wait For Task Token - Missing Task Token', () => { integrationPattern: sfn.ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN, }), }); - }).toThrow('Task Token is missing in input (pass Context.taskToken somewhere in input'); + }).toThrow('Task Token is missing in input (pass JsonPath.taskToken somewhere in input'); }); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/stepfunctions/integ.start-execution.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/stepfunctions/integ.start-execution.ts index 012189950cecd..f103d41da4a7c 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/stepfunctions/integ.start-execution.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/stepfunctions/integ.start-execution.ts @@ -21,7 +21,7 @@ class TestStack extends Stack { definition: new StepFunctionsStartExecution(this, 'Task', { stateMachine: child, input: sfn.TaskInput.fromObject({ - hello: sfn.Data.stringAt('$.hello'), + hello: sfn.JsonPath.stringAt('$.hello'), }), integrationPattern: sfn.IntegrationPattern.RUN_JOB, }), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/stepfunctions/start-execution.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/stepfunctions/start-execution.test.ts index 21d2546af8681..99228dc1491d5 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/stepfunctions/start-execution.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/stepfunctions/start-execution.test.ts @@ -173,7 +173,7 @@ test('Execute State Machine - Wait For Task Token', () => { stateMachine: child, integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, input: sfn.TaskInput.fromObject({ - token: sfn.Context.taskToken, + token: sfn.JsonPath.taskToken, }), }); @@ -213,5 +213,5 @@ test('Execute State Machine - Wait For Task Token - Missing Task Token', () => { stateMachine: child, integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, }); - }).toThrow('Task Token is required in `input` for callback. Use Context.taskToken to set the token.'); + }).toThrow('Task Token is required in `input` for callback. Use JsonPath.taskToken to set the token.'); }); diff --git a/packages/@aws-cdk/aws-stepfunctions/README.md b/packages/@aws-cdk/aws-stepfunctions/README.md index e8ed1e4fffef1..22e847ed058d9 100644 --- a/packages/@aws-cdk/aws-stepfunctions/README.md +++ b/packages/@aws-cdk/aws-stepfunctions/README.md @@ -277,7 +277,7 @@ execute the same steps for multiple entries of an array in the state input. ```ts const map = new stepfunctions.Map(this, 'Map State', { maxConcurrency: 1, - itemsPath: stepfunctions.Data.stringAt('$.inputForMap') + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap') }); map.iterator(new stepfunctions.Pass(this, 'Pass State')); ``` diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/fields.ts b/packages/@aws-cdk/aws-stepfunctions/lib/fields.ts index ab4ddfb070483..407f93cd3d162 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/fields.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/fields.ts @@ -1,8 +1,90 @@ import { Token } from '@aws-cdk/core'; import { findReferencedPaths, jsonPathString, JsonPathToken, renderObject } from './json-path'; +/** + * Extract a field from the State Machine data or context + * that gets passed around between states + * + * @see https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-paths.html + */ +export class JsonPath { + /** + * Special string value to discard state input, output or result + */ + public static readonly DISCARD = 'DISCARD'; + + /** + * Instead of using a literal string, get the value from a JSON path + */ + public static stringAt(path: string): string { + validateJsonPath(path); + return new JsonPathToken(path).toString(); + } + + /** + * Instead of using a literal string list, get the value from a JSON path + */ + public static listAt(path: string): string[] { + // does not apply to task context + validateDataPath(path); + return Token.asList(new JsonPathToken(path)); + } + + /** + * Instead of using a literal number, get the value from a JSON path + */ + public static numberAt(path: string): number { + validateJsonPath(path); + return Token.asNumber(new JsonPathToken(path)); + } + + /** + * Use the entire data structure + * + * Will be an object at invocation time, but is represented in the CDK + * application as a string. + */ + public static get entirePayload(): string { + return new JsonPathToken('$').toString(); + } + + /** + * Determines if the indicated string is an encoded JSON path + * + * @param value string to be evaluated + */ + public static isEncodedJsonPath(value: string): boolean { + return !!jsonPathString(value); + } + + /** + * Return the Task Token field + * + * External actions will need this token to report step completion + * back to StepFunctions using the `SendTaskSuccess` or `SendTaskFailure` + * calls. + */ + public static get taskToken(): string { + return new JsonPathToken('$$.Task.Token').toString(); + } + + /** + * Use the entire context data structure + * + * Will be an object at invocation time, but is represented in the CDK + * application as a string. + */ + public static get entireContext(): string { + return new JsonPathToken('$$').toString(); + } + + private constructor() {} +} + /** * Extract a field from the State Machine data that gets passed around between states + * + * @deprecated replaced by `JsonPath` */ export class Data { /** @@ -48,14 +130,15 @@ export class Data { return !!jsonPathString(value); } - private constructor() { - } + private constructor() {} } /** * Extract a field from the State Machine Context data * * @see https://docs.aws.amazon.com/step-functions/latest/dg/connect-to-resource.html#wait-token-contextobject + * + * @deprecated replaced by `JsonPath` */ export class Context { /** @@ -95,26 +178,24 @@ export class Context { return new JsonPathToken('$$').toString(); } - private constructor() { - } + private constructor() {} } /** * Helper functions to work with structures containing fields */ export class FieldUtils { - /** * Render a JSON structure containing fields to the right StepFunctions structure */ - public static renderObject(obj?: {[key: string]: any}): {[key: string]: any} | undefined { + public static renderObject(obj?: { [key: string]: any }): { [key: string]: any } | undefined { return renderObject(obj); } /** * Return all JSON paths used in the given structure */ - public static findReferencedPaths(obj?: {[key: string]: any}): string[] { + public static findReferencedPaths(obj?: { [key: string]: any }): string[] { return Array.from(findReferencedPaths(obj)).sort(); } @@ -124,12 +205,17 @@ export class FieldUtils { * The field is considered included if the field itself or one of its containing * fields occurs anywhere in the payload. */ - public static containsTaskToken(obj?: {[key: string]: any}): boolean { + public static containsTaskToken(obj?: { [key: string]: any }): boolean { const paths = findReferencedPaths(obj); return paths.has('$$.Task.Token') || paths.has('$$.Task') || paths.has('$$'); } - private constructor() { + private constructor() {} +} + +function validateJsonPath(path: string) { + if (path !== '$' && !path.startsWith('$.') && path !== '$$' && !path.startsWith('$$.')) { + throw new Error(`JSON path values must be exactly '$', '$$', start with '$.' or start with '$$.' Received: ${path}`); } } diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/input.ts b/packages/@aws-cdk/aws-stepfunctions/lib/input.ts index 9fdf42c0ef3f4..c72b1c01670e7 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/input.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/input.ts @@ -1,4 +1,4 @@ -import { Context, Data } from './fields'; +import { JsonPath } from './fields'; /** * Type union for task classes that accept multiple types of payload @@ -19,10 +19,21 @@ export class TaskInput { * This object may contain Data and Context fields * as object values, if desired. */ - public static fromObject(obj: {[key: string]: any}) { + public static fromObject(obj: { [key: string]: any }) { return new TaskInput(InputType.OBJECT, obj); } + /** + * Use a part of the execution data or task context as task input + * + * Use this when you want to use a subobject or string from + * the current state machine execution or the current task context + * as complete payload to a task. + */ + public static fromJsonPathAt(path: string) { + return new TaskInput(InputType.TEXT, JsonPath.stringAt(path)); + } + /** * Use a part of the execution data as task input * @@ -31,7 +42,7 @@ export class TaskInput { * to a task. */ public static fromDataAt(path: string) { - return new TaskInput(InputType.TEXT, Data.stringAt(path)); + return new TaskInput(InputType.TEXT, JsonPath.stringAt(path)); } /** @@ -42,7 +53,7 @@ export class TaskInput { * to a task. */ public static fromContextAt(path: string) { - return new TaskInput(InputType.TEXT, Context.stringAt(path)); + return new TaskInput(InputType.TEXT, JsonPath.stringAt(path)); } /** @@ -51,8 +62,7 @@ export class TaskInput { * @param value payload for the corresponding input type. * It can be a JSON-encoded object, context, data, etc. */ - private constructor(public readonly type: InputType, public readonly value: any) { - } + private constructor(public readonly type: InputType, public readonly value: any) {} } /** @@ -75,11 +85,11 @@ export enum InputType { * example: * { * literal: 'literal', - * SomeInput: sfn.Data.stringAt('$.someField') + * SomeInput: sfn.JsonPath.stringAt('$.someField') * } * * @see https://docs.aws.amazon.com/step-functions/latest/dg/concepts-state-machine-data.html * @see https://docs.aws.amazon.com/step-functions/latest/dg/input-output-contextobject.html */ - OBJECT -} \ No newline at end of file + OBJECT, +} diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/states/map.ts b/packages/@aws-cdk/aws-stepfunctions/lib/states/map.ts index 2721b975d43d0..14d65ccdc541a 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/states/map.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/states/map.ts @@ -19,7 +19,7 @@ export interface MapProps { /** * JSONPath expression to select part of the state to be the input to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * input to be the empty object {}. * * @default $ @@ -29,7 +29,7 @@ export interface MapProps { /** * JSONPath expression to select part of the state to be the output to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * output to be the empty object {}. * * @default $ @@ -39,7 +39,7 @@ export interface MapProps { /** * JSONPath expression to indicate where to inject the state's output * - * May also be the special value DISCARD, which will cause the state's + * May also be the special value JsonPath.DISCARD, which will cause the state's * input to become its output. * * @default $ diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/states/parallel.ts b/packages/@aws-cdk/aws-stepfunctions/lib/states/parallel.ts index 281660036e4db..4bce7313377cf 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/states/parallel.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/states/parallel.ts @@ -19,7 +19,7 @@ export interface ParallelProps { /** * JSONPath expression to select part of the state to be the input to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * input to be the empty object {}. * * @default $ @@ -29,7 +29,7 @@ export interface ParallelProps { /** * JSONPath expression to select part of the state to be the output to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * output to be the empty object {}. * * @default $ @@ -39,7 +39,7 @@ export interface ParallelProps { /** * JSONPath expression to indicate where to inject the state's output * - * May also be the special value DISCARD, which will cause the state's + * May also be the special value JsonPath.DISCARD, which will cause the state's * input to become its output. * * @default $ diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/states/pass.ts b/packages/@aws-cdk/aws-stepfunctions/lib/states/pass.ts index 982980456caaa..6d98608853b68 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/states/pass.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/states/pass.ts @@ -66,7 +66,7 @@ export interface PassProps { /** * JSONPath expression to select part of the state to be the input to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * input to be the empty object {}. * * @default $ @@ -76,7 +76,7 @@ export interface PassProps { /** * JSONPath expression to select part of the state to be the output to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * output to be the empty object {}. * * @default $ @@ -86,7 +86,7 @@ export interface PassProps { /** * JSONPath expression to indicate where to inject the state's output * - * May also be the special value DISCARD, which will cause the state's + * May also be the special value JsonPath.DISCARD, which will cause the state's * input to become its output. * * @default $ diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts b/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts index 5f69d2af2d80b..8d82eecd398d7 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts @@ -1,7 +1,8 @@ import * as cdk from '@aws-cdk/core'; import { Condition } from '../condition'; +import { JsonPath } from '../fields'; import { StateGraph } from '../state-graph'; -import { CatchProps, DISCARD, Errors, IChainable, INextable, RetryProps } from '../types'; +import { CatchProps, Errors, IChainable, INextable, RetryProps } from '../types'; /** * Properties shared by all states @@ -17,7 +18,7 @@ export interface StateProps { /** * JSONPath expression to select part of the state to be the input to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * input to be the empty object {}. * * @default $ @@ -37,7 +38,7 @@ export interface StateProps { /** * JSONPath expression to select part of the state to be the output to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * output to be the empty object {}. * * @default $ @@ -47,7 +48,7 @@ export interface StateProps { /** * JSONPath expression to indicate where to inject the state's output * - * May also be the special value DISCARD, which will cause the state's + * May also be the special value JsonPath.DISCARD, which will cause the state's * input to become its output. * * @default $ @@ -512,7 +513,7 @@ export function renderList(xs: T[], fn: (x: T) => any): any { */ export function renderJsonPath(jsonPath?: string): undefined | null | string { if (jsonPath === undefined) { return undefined; } - if (jsonPath === DISCARD) { return null; } + if (jsonPath === JsonPath.DISCARD) { return null; } if (!jsonPath.startsWith('$')) { throw new Error(`Expected JSON path to start with '$', got: ${jsonPath}`); diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/states/succeed.ts b/packages/@aws-cdk/aws-stepfunctions/lib/states/succeed.ts index b4f4da1d38c2b..75d51840e0234 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/states/succeed.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/states/succeed.ts @@ -17,7 +17,7 @@ export interface SucceedProps { /** * JSONPath expression to select part of the state to be the input to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * input to be the empty object {}. * * @default $ @@ -27,7 +27,7 @@ export interface SucceedProps { /** * JSONPath expression to select part of the state to be the output to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * output to be the empty object {}. * * @default $ diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/states/task-base.ts b/packages/@aws-cdk/aws-stepfunctions/lib/states/task-base.ts index 4617ae15adb41..e34875a02fbcc 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/states/task-base.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/states/task-base.ts @@ -21,7 +21,7 @@ export interface TaskStateBaseProps { /** * JSONPath expression to select part of the state to be the input to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * input to be the empty object {}. * * @default - The entire task input (JSON path '$') @@ -32,7 +32,7 @@ export interface TaskStateBaseProps { * JSONPath expression to select select a portion of the state output to pass * to the next state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * output to be the empty object {}. * * @default - The entire JSON node determined by the state input, the task result, @@ -43,7 +43,7 @@ export interface TaskStateBaseProps { /** * JSONPath expression to indicate where to inject the state's output * - * May also be the special value DISCARD, which will cause the state's + * May also be the special value JsonPath.DISCARD, which will cause the state's * input to become its output. * * @default - Replaces the entire input with the result (JSON path '$') diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/states/task.ts b/packages/@aws-cdk/aws-stepfunctions/lib/states/task.ts index 243f6b520b41c..1d275d3fb25f8 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/states/task.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/states/task.ts @@ -28,7 +28,7 @@ export interface TaskProps { /** * JSONPath expression to select part of the state to be the input to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * input to be the empty object {}. * * @default $ @@ -38,7 +38,7 @@ export interface TaskProps { /** * JSONPath expression to select part of the state to be the output to this state. * - * May also be the special value DISCARD, which will cause the effective + * May also be the special value JsonPath.DISCARD, which will cause the effective * output to be the empty object {}. * * @default $ @@ -48,7 +48,7 @@ export interface TaskProps { /** * JSONPath expression to indicate where to inject the state's output * - * May also be the special value DISCARD, which will cause the state's + * May also be the special value JsonPath.DISCARD, which will cause the state's * input to become its output. * * @default $ diff --git a/packages/@aws-cdk/aws-stepfunctions/test/fields.test.ts b/packages/@aws-cdk/aws-stepfunctions/test/fields.test.ts index 618ae4a6f5bb0..ef6d15fd86519 100644 --- a/packages/@aws-cdk/aws-stepfunctions/test/fields.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions/test/fields.test.ts @@ -1,5 +1,5 @@ import '@aws-cdk/assert/jest'; -import { Context, Data, FieldUtils } from '../lib'; +import { FieldUtils, JsonPath } from '../lib'; describe('Fields', () => { test('deep replace correctly handles fields in arrays', () => { @@ -8,12 +8,12 @@ describe('Fields', () => { unknown: undefined, bool: true, literal: 'literal', - field: Data.stringAt('$.stringField'), - listField: Data.listAt('$.listField'), + field: JsonPath.stringAt('$.stringField'), + listField: JsonPath.listAt('$.listField'), deep: [ 'literal', { - deepField: Data.numberAt('$.numField'), + deepField: JsonPath.numberAt('$.numField'), }, ], }), @@ -33,10 +33,10 @@ describe('Fields', () => { test('exercise contextpaths', () => { expect( FieldUtils.renderObject({ - str: Context.stringAt('$$.Execution.StartTime'), - count: Context.numberAt('$$.State.RetryCount'), - token: Context.taskToken, - entire: Context.entireContext, + str: JsonPath.stringAt('$$.Execution.StartTime'), + count: JsonPath.numberAt('$$.State.RetryCount'), + token: JsonPath.taskToken, + entire: JsonPath.entireContext, }), ).toStrictEqual({ 'str.$': '$$.Execution.StartTime', @@ -50,13 +50,13 @@ describe('Fields', () => { FieldUtils.findReferencedPaths({ bool: false, literal: 'literal', - field: Data.stringAt('$.stringField'), - listField: Data.listAt('$.listField'), + field: JsonPath.stringAt('$.stringField'), + listField: JsonPath.listAt('$.listField'), deep: [ 'literal', { - field: Data.stringAt('$.stringField'), - deepField: Data.numberAt('$.numField'), + field: JsonPath.stringAt('$.stringField'), + deepField: JsonPath.numberAt('$.numField'), }, ], }), @@ -64,39 +64,39 @@ describe('Fields', () => { }), test('cannot have JsonPath fields in arrays', () => { expect(() => FieldUtils.renderObject({ - deep: [Data.stringAt('$.hello')], + deep: [JsonPath.stringAt('$.hello')], })).toThrowError(/Cannot use JsonPath fields in an array/); }), test('datafield path must be correct', () => { - expect(Data.stringAt('$')).toBeDefined(); + expect(JsonPath.stringAt('$')).toBeDefined(); - expect(() => Data.stringAt('$hello')).toThrowError(/exactly equal to '\$' or start with '\$.'/); + expect(() => JsonPath.stringAt('$hello')).toThrowError(/exactly '\$', '\$\$', start with '\$.' or start with '\$\$.'/); - expect(() => Data.stringAt('hello')).toThrowError(/exactly equal to '\$' or start with '\$.'/); + expect(() => JsonPath.stringAt('hello')).toThrowError(/exactly '\$', '\$\$', start with '\$.' or start with '\$\$.'/); }), test('context path must be correct', () => { - expect(Context.stringAt('$$')).toBeDefined(); + expect(JsonPath.stringAt('$$')).toBeDefined(); - expect(() => Context.stringAt('$$hello')).toThrowError(/exactly equal to '\$\$' or start with '\$\$.'/); + expect(() => JsonPath.stringAt('$$hello')).toThrowError(/exactly '\$', '\$\$', start with '\$.' or start with '\$\$.'/); - expect(() => Context.stringAt('hello')).toThrowError(/exactly equal to '\$\$' or start with '\$\$.'/); + expect(() => JsonPath.stringAt('hello')).toThrowError(/exactly '\$', '\$\$', start with '\$.' or start with '\$\$.'/); }), test('test contains task token', () => { expect(true).toEqual( FieldUtils.containsTaskToken({ - field: Context.taskToken, + field: JsonPath.taskToken, }), ); expect(true).toEqual( FieldUtils.containsTaskToken({ - field: Context.stringAt('$$.Task'), + field: JsonPath.stringAt('$$.Task'), }), ); expect(true).toEqual( FieldUtils.containsTaskToken({ - field: Context.entireContext, + field: JsonPath.entireContext, }), ); @@ -108,7 +108,7 @@ describe('Fields', () => { expect(false).toEqual( FieldUtils.containsTaskToken({ - oops: Context.stringAt('$$.Execution.StartTime'), + oops: JsonPath.stringAt('$$.Execution.StartTime'), }), ); }), @@ -123,7 +123,7 @@ describe('Fields', () => { }), test('fields cannot be used somewhere in a string interpolation', () => { expect(() => FieldUtils.renderObject({ - field: `contains ${Data.stringAt('$.hello')}`, + field: `contains ${JsonPath.stringAt('$.hello')}`, })).toThrowError(/Field references must be the entire string/); }); }); diff --git a/packages/@aws-cdk/aws-stepfunctions/test/map.test.ts b/packages/@aws-cdk/aws-stepfunctions/test/map.test.ts index e70765e96c502..c5ad0bb6d5697 100644 --- a/packages/@aws-cdk/aws-stepfunctions/test/map.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions/test/map.test.ts @@ -10,10 +10,10 @@ describe('Map State', () => { // WHEN const map = new stepfunctions.Map(stack, 'Map State', { maxConcurrency: 1, - itemsPath: stepfunctions.Data.stringAt('$.inputForMap'), + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), parameters: { foo: 'foo', - bar: stepfunctions.Data.stringAt('$.bar'), + bar: stepfunctions.JsonPath.stringAt('$.bar'), }, }); map.iterator(new stepfunctions.Pass(stack, 'Pass State')); @@ -41,13 +41,11 @@ describe('Map State', () => { }, }); }), - test('synth is successful', () => { - const app = createAppWithMap((stack) => { const map = new stepfunctions.Map(stack, 'Map State', { maxConcurrency: 1, - itemsPath: stepfunctions.Data.stringAt('$.inputForMap'), + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), }); map.iterator(new stepfunctions.Pass(stack, 'Pass State')); return map; @@ -55,13 +53,11 @@ describe('Map State', () => { app.synth(); }), - test('fails in synthesis if iterator is missing', () => { - const app = createAppWithMap((stack) => { const map = new stepfunctions.Map(stack, 'Map State', { maxConcurrency: 1, - itemsPath: stepfunctions.Data.stringAt('$.inputForMap'), + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), }); return map; @@ -69,13 +65,11 @@ describe('Map State', () => { expect(() => app.synth()).toThrow(/Map state must have a non-empty iterator/); }), - test('fails in synthesis when maxConcurrency is a float', () => { - const app = createAppWithMap((stack) => { const map = new stepfunctions.Map(stack, 'Map State', { maxConcurrency: 1.2, - itemsPath: stepfunctions.Data.stringAt('$.inputForMap'), + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), }); map.iterator(new stepfunctions.Pass(stack, 'Pass State')); @@ -84,13 +78,11 @@ describe('Map State', () => { expect(() => app.synth()).toThrow(/maxConcurrency has to be a positive integer/); }), - test('fails in synthesis when maxConcurrency is a negative integer', () => { - const app = createAppWithMap((stack) => { const map = new stepfunctions.Map(stack, 'Map State', { maxConcurrency: -1, - itemsPath: stepfunctions.Data.stringAt('$.inputForMap'), + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), }); map.iterator(new stepfunctions.Pass(stack, 'Pass State')); @@ -99,13 +91,11 @@ describe('Map State', () => { expect(() => app.synth()).toThrow(/maxConcurrency has to be a positive integer/); }), - test('fails in synthesis when maxConcurrency is too big to be an integer', () => { - const app = createAppWithMap((stack) => { const map = new stepfunctions.Map(stack, 'Map State', { maxConcurrency: Number.MAX_VALUE, - itemsPath: stepfunctions.Data.stringAt('$.inputForMap'), + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), }); map.iterator(new stepfunctions.Pass(stack, 'Pass State')); @@ -114,28 +104,22 @@ describe('Map State', () => { expect(() => app.synth()).toThrow(/maxConcurrency has to be a positive integer/); }), - test('isPositiveInteger is false with negative number', () => { expect(stepfunctions.isPositiveInteger(-1)).toEqual(false); }), - test('isPositiveInteger is false with decimal number', () => { expect(stepfunctions.isPositiveInteger(1.2)).toEqual(false); }), - test('isPositiveInteger is false with a value greater than safe integer', () => { const valueToTest = Number.MAX_SAFE_INTEGER + 1; expect(stepfunctions.isPositiveInteger(valueToTest)).toEqual(false); }), - test('isPositiveInteger is true with 0', () => { expect(stepfunctions.isPositiveInteger(0)).toEqual(true); }), - test('isPositiveInteger is true with 10', () => { expect(stepfunctions.isPositiveInteger(10)).toEqual(true); }), - test('isPositiveInteger is true with max integer value', () => { expect(stepfunctions.isPositiveInteger(Number.MAX_SAFE_INTEGER)).toEqual(true); }); diff --git a/packages/@aws-cdk/aws-stepfunctions/test/state-machine-resources.test.ts b/packages/@aws-cdk/aws-stepfunctions/test/state-machine-resources.test.ts index 67fcd36752f80..dc016b87012df 100644 --- a/packages/@aws-cdk/aws-stepfunctions/test/state-machine-resources.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions/test/state-machine-resources.test.ts @@ -619,7 +619,7 @@ describe('State Machine Resources', () => { const stack = new cdk.Stack(); const task = new stepfunctions.Pass(stack, 'Pass', { parameters: { - input: stepfunctions.Data.stringAt('$.myField'), + input: stepfunctions.JsonPath.stringAt('$.myField'), }, }); From 509133373679fe514be5b4ce8d58988e3eecdd90 Mon Sep 17 00:00:00 2001 From: Somaya Date: Wed, 24 Jun 2020 14:33:36 -0700 Subject: [PATCH 04/55] chore: small updates to auto label/assign action (#8722) chore: small updates auto label/assign action - remove pull request check since github actions don't work on forks - run action when issue is edited - change issue template to brackets instead of parens ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .github/ISSUE_TEMPLATE/bug.md | 2 +- .github/ISSUE_TEMPLATE/doc.md | 2 +- .github/ISSUE_TEMPLATE/feature-request.md | 2 +- .github/ISSUE_TEMPLATE/general-issues.md | 2 +- .github/workflows/issue-label-assign.yml | 307 +++++++++++----------- 5 files changed, 156 insertions(+), 159 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 69581271f774d..d263a2a35e27e 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -1,7 +1,7 @@ --- name: "\U0001F41B Bug Report" about: Report a bug -title: "(module): " +title: "[module] " labels: bug, needs-triage --- diff --git a/.github/ISSUE_TEMPLATE/doc.md b/.github/ISSUE_TEMPLATE/doc.md index 53cacd3ae3bfd..022c04c22ed80 100644 --- a/.github/ISSUE_TEMPLATE/doc.md +++ b/.github/ISSUE_TEMPLATE/doc.md @@ -1,7 +1,7 @@ --- name: "📕 Documentation Issue" about: Issue in the reference documentation or developer guide -title: "(module): " +title: "[module] " labels: feature-request, documentation, needs-triage --- diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index 20a51e351f0e4..5fecac4f7ce57 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,7 +1,7 @@ --- name: "\U0001F680 Feature Request" about: Request a new feature -title: "(module): " +title: "[module] " labels: feature-request, needs-triage --- diff --git a/.github/ISSUE_TEMPLATE/general-issues.md b/.github/ISSUE_TEMPLATE/general-issues.md index 8cb4679f0889d..1f2d2b6ff707f 100644 --- a/.github/ISSUE_TEMPLATE/general-issues.md +++ b/.github/ISSUE_TEMPLATE/general-issues.md @@ -1,7 +1,7 @@ --- name: "\U00002753 General Issue" about: Create a new issue -title: "(module): " +title: "[module] " labels: needs-triage --- diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml index 64b8fd2e08019..6529fc960b41f 100644 --- a/.github/workflows/issue-label-assign.yml +++ b/.github/workflows/issue-label-assign.yml @@ -1,9 +1,7 @@ name: "Set Issue Label and Assignee" on: issues: - types: [opened] - pull_request: - types: [opened] + types: [opened, edited] jobs: test: @@ -15,157 +13,156 @@ jobs: title-or-body: 'title' parameters: > [ - {"keywords":["(cli)","(command line)"],"labels":["package/tools"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/alexa-ask)","(alexa-ask)","(alexa ask)"],"labels":["@aws-cdk/alexa-ask"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/app-delivery)","(app-delivery)","(app delivery)"],"labels":["@aws-cdk/app-delivery"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/assert)","(assert)"],"labels":["@aws-cdk/assert"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/assets)","(assets)"],"labels":["@aws-cdk/assets"],"assignees":["eladb"]}, - {"keywords":["(@aws-cdk/aws-accessanalyzer)","(aws-accessanalyzer)","(accessanalyzer)","(access analyzer)"],"labels":["@aws-cdk/aws-accessanalyzer"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-acmpca)","(aws-acmpca)","(acmpca)"],"labels":["@aws-cdk/aws-acmpca"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-amazonmq)","(aws-amazonmq)","(amazonmq)","(amazon mq)"],"labels":["@aws-cdk/aws-amazonmq"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-amplify)","(aws-amplify)","(amplify)"],"labels":["@aws-cdk/aws-amplify"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-apigateway)","(aws-apigateway)","(apigateway)", "(api gateway)"],"labels":["@aws-cdk/aws-apigateway"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-apigatewayv2)","(aws-apigatewayv2)","(apigatewayv2)","(apigateway v2)"],"labels":["@aws-cdk/aws-apigatewayv2"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-appconfig)","(aws-appconfig)","(appconfig)","(app config)"],"labels":["@aws-cdk/aws-appconfig"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-applicationautoscaling)","(aws-applicationautoscaling)","(applicationautoscaling)","(application autoscaling)"],"labels":["@aws-cdk/aws-applicationautoscaling"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/aws-appmesh)","(aws-appmesh)","(appmesh)","(app mesh)"],"labels":["@aws-cdk/aws-appmesh"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-appstream)","(aws-appstream)","(appstream)","(app stream)"],"labels":["@aws-cdk/aws-appstream"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/aws-appsync)","(aws-appsync)","(appsync)","(app sync)"],"labels":["@aws-cdk/aws-appsync"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-athena)","(aws-athena)","(athena)"],"labels":["@aws-cdk/aws-athena"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-autoscaling)","(aws-autoscaling)","(autoscaling)","(auto scaling)"],"labels":["@aws-cdk/aws-autoscaling"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/aws-autoscaling-api)","(aws-autoscaling-api)","(autoscaling-api)","(autoscaling api)"],"labels":["@aws-cdk/aws-autoscaling-api"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/aws-autoscaling-common)","(aws-autoscaling-common)","(autoscaling-common)","(autoscaling common)"],"labels":["@aws-cdk/aws-autoscaling-common"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/aws-autoscaling-hooktargets)","(aws-autoscaling-hooktargets)","(autoscaling-hooktargets)","(autoscaling hooktargets)"],"labels":["@aws-cdk/aws-autoscaling-hooktargets"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/aws-autoscalingplans)","(aws-autoscalingplans)","(autoscalingplans)","(autoscaling plans)"],"labels":["@aws-cdk/aws-autoscalingplans"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/aws-backup)","(aws-backup)","(backup)"],"labels":["@aws-cdk/aws-backup"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-batch)","(aws-batch)","(batch)"],"labels":["@aws-cdk/aws-batch"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-budgets)","(aws-budgets)","(budgets)"],"labels":["@aws-cdk/aws-budgets"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-cassandra)","(aws-cassandra)","(cassandra)"],"labels":["@aws-cdk/aws-cassandra"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-ce)","(aws-ce)","(ce)"],"labels":["@aws-cdk/aws-ce"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-certificatemanager)","(aws-certificatemanager)","(certificatemanager)","(certificate manager)"],"labels":["@aws-cdk/aws-certificatemanager"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-chatbot)","(aws-chatbot)","(chatbot)"],"labels":["@aws-cdk/aws-chatbot"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-cloud9)","(aws-cloud9)","(cloud9)","(cloud 9)"],"labels":["@aws-cdk/aws-cloud9"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-cloudformation)","(aws-cloudformation)","(cloudformation)","(cloud formation)"],"labels":["@aws-cdk/aws-cloudformation"],"assignees":["eladb"]}, - {"keywords":["(@aws-cdk/aws-cloudfront)","(aws-cloudfront)","(cloudfront)","(cloud front)"],"labels":["@aws-cdk/aws-cloudfront"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-cloudtrail)","(aws-cloudtrail)","(cloudtrail)","(cloud trail)"],"labels":["@aws-cdk/aws-cloudtrail"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-cloudwatch)","(aws-cloudwatch)","(cloudwatch)","(cloud watch)"],"labels":["@aws-cdk/aws-cloudwatch"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-cloudwatch-actions)","(aws-cloudwatch-actions)","(cloudwatch-actions)","(cloudwatch actions)"],"labels":["@aws-cdk/aws-cloudwatch-actions"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-codebuild)","(aws-codebuild)","(codebuild)","(code build)"],"labels":["@aws-cdk/aws-codebuild"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codecommit)","(aws-codecommit)","(codecommit)","(code commit)"],"labels":["@aws-cdk/aws-codecommit"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codedeploy)","(aws-codedeploy)","(codedeploy)","(code deploy)"],"labels":["@aws-cdk/aws-codedeploy"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codeguruprofiler)","(aws-codeguruprofiler)","(codeguruprofiler)","(codeguru profiler)"],"labels":["@aws-cdk/aws-codeguruprofiler"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codepipeline)","(aws-codepipeline)","(codepipeline)","(code pipeline)"],"labels":["@aws-cdk/aws-codepipeline"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codepipeline-actions)","(aws-codepipeline-actions)","(codepipeline-actions)","(codepipeline actions)"],"labels":["@aws-cdk/aws-codepipeline-actions"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codestar)","(aws-codestar)","(codestar)"],"labels":["@aws-cdk/aws-codestar"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codestarconnections)","(aws-codestarconnections)","(codestarconnections)","(codestar connections)"],"labels":["@aws-cdk/aws-codestarconnections"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codestarnotifications)","(aws-codestarnotifications)","(codestarnotifications)","(codestar notifications)"],"labels":["@aws-cdk/aws-codestarnotifications"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-cognito)","(aws-cognito)","(cognito)"],"labels":["@aws-cdk/aws-cognito"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-config)","(aws-config)","(config)"],"labels":["@aws-cdk/aws-config"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-datapipeline)","(aws-datapipeline)","(datapipeline)","(data pipeline)"],"labels":["@aws-cdk/aws-datapipeline"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-dax)","(aws-dax)","(dax)"],"labels":["@aws-cdk/aws-dax"],"assignees":["RomainMuller"]}, - {"keywords":["(@aws-cdk/aws-detective)","(aws-detective)","(detective)"],"labels":["@aws-cdk/aws-detective"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-directoryservice)","(aws-directoryservice)","(directoryservice)","(directory service)"],"labels":["@aws-cdk/aws-directoryservice"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/aws-dlm)","(aws-dlm)","(dlm)"],"labels":["@aws-cdk/aws-dlm"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-dms)","(aws-dms)","(dms)"],"labels":["@aws-cdk/aws-dms"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-docdb)","(aws-docdb)","(docdb)","(doc db)"],"labels":["@aws-cdk/aws-docdb"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-dynamodb)","(aws-dynamodb)","(dynamodb)","(dynamo db)"],"labels":["@aws-cdk/aws-dynamodb"],"assignees":["RomainMuller"]}, - {"keywords":["(@aws-cdk/aws-dynamodb-global)","(aws-dynamodb-global)","(dynamodb-global)","(dynamodb global)"],"labels":["@aws-cdk/aws-dynamodb-global"],"assignees":["RomainMuller"]}, - {"keywords":["(@aws-cdk/aws-ec2)","(aws-ec2)","(ec2)"],"labels":["@aws-cdk/aws-ec2"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-ecr)","(aws-ecr)","(ecr)"],"labels":["@aws-cdk/aws-ecr"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-ecr-assets)","(aws-ecr-assets)","(ecr-assets)","(ecr assets)"],"labels":["@aws-cdk/aws-ecr-assets"],"assignees":["eladb"]}, - {"keywords":["(@aws-cdk/aws-ecs)","(aws-ecs)","(ecs)"],"labels":["@aws-cdk/aws-ecs"],"assignees":["uttarasridhar"]}, - {"keywords":["(@aws-cdk/aws-ecs-patterns)","(aws-ecs-patterns)","(ecs-patterns)","(ecs patterns)"],"labels":["@aws-cdk/aws-ecs-patterns"],"assignees":["uttarasridhar"]}, - {"keywords":["(@aws-cdk/aws-efs)","(aws-efs)","(efs)"],"labels":["@aws-cdk/aws-efs"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-eks)","(aws-eks)","(eks)"],"labels":["@aws-cdk/aws-eks"],"assignees":["eladb"]}, - {"keywords":["(@aws-cdk/aws-elasticache)","(aws-elasticache)","(elasticache)","(elastic cache)"],"labels":["@aws-cdk/aws-elasticache"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-elasticbeanstalk)","(aws-elasticbeanstalk)","(elasticbeanstalk)","(elastic beanstalk)"],"labels":["@aws-cdk/aws-elasticbeanstalk"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-elasticloadbalancing)","(aws-elasticloadbalancing)","(elasticloadbalancing)","(elastic loadbalancing)","(elb)"],"labels":["@aws-cdk/aws-elasticloadbalancing"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-elasticloadbalancingv2)","(aws-elasticloadbalancingv2)","(elasticloadbalancingv2)","(elbv2)","(elb v2)"],"labels":["@aws-cdk/aws-elasticloadbalancingv2"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-elasticloadbalancingv2-targets)","(aws-elasticloadbalancingv2-targets)","(elasticloadbalancingv2-targets)","(elasticloadbalancingv2 targets)","(elbv2 targets)"],"labels":["@aws-cdk/aws-elasticloadbalancingv2-targets"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-elasticsearch)","(aws-elasticsearch)","(elasticsearch)","(elastic search)"],"labels":["@aws-cdk/aws-elasticsearch"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-emr)","(aws-emr)","(emr)"],"labels":["@aws-cdk/aws-emr"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-events)","(aws-events)","(events)", "eventbridge"],"labels":["@aws-cdk/aws-events"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-events-targets)","(aws-events-targets)","(events-targets)","(events targets)"],"labels":["@aws-cdk/aws-events-targets"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-eventschemas)","(aws-eventschemas)","(eventschemas)","(event schemas)"],"labels":["@aws-cdk/aws-eventschemas"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-fms)","(aws-fms)","(fms)"],"labels":["@aws-cdk/aws-fms"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-fsx)","(aws-fsx)","(fsx)"],"labels":["@aws-cdk/aws-fsx"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-gamelift)","(aws-gamelift)","(gamelift)","(game lift)"],"labels":["@aws-cdk/aws-gamelift"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-globalaccelerator)","(aws-globalaccelerator)","(globalaccelerator)","(global accelerator)"],"labels":["@aws-cdk/aws-globalaccelerator"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-glue)","(aws-glue)","(glue)"],"labels":["@aws-cdk/aws-glue"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-greengrass)","(aws-greengrass)","(greengrass)","(green grass)"],"labels":["@aws-cdk/aws-greengrass"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-guardduty)","(aws-guardduty)","(guardduty)", "(guard duty)"],"labels":["@aws-cdk/aws-guardduty"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-iam)","(aws-iam)","(iam)"],"labels":["@aws-cdk/aws-iam"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-imagebuilder)","(aws-imagebuilder)","(imagebuilder)","(image builder)"],"labels":["@aws-cdk/aws-imagebuilder"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-inspector)","(aws-inspector)","(inspector)"],"labels":["@aws-cdk/aws-inspector"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-iot)","(aws-iot)","(iot)"],"labels":["@aws-cdk/aws-iot"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-iot1click)","(aws-iot1click)","(iot1click)","(iot 1click)"],"labels":["@aws-cdk/aws-iot1click"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-iotanalytics)","(aws-iotanalytics)","(iotanalytics)","(iot analytics)"],"labels":["@aws-cdk/aws-iotanalytics"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-iotevents)","(aws-iotevents)","(iotevents)","(iot events)"],"labels":["@aws-cdk/aws-iotevents"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-iotthingsgraph)","(aws-iotthingsgraph)","(iotthingsgraph)","(iot things graph)"],"labels":["@aws-cdk/aws-iotthingsgraph"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-kinesis)","(aws-kinesis)","(kinesis)"],"labels":["@aws-cdk/aws-kinesis"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-kinesisanalytics)","(aws-kinesisanalytics)","(kinesisanalytics)", "(kinesis analytics)"],"labels":["@aws-cdk/aws-kinesisanalytics"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-kinesisfirehose)","(aws-kinesisfirehose)","(kinesisfirehose)", "(kinesis firehose)"],"labels":["@aws-cdk/aws-kinesisfirehose"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-kms)","(aws-kms)","(kms)"],"labels":["@aws-cdk/aws-kms"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-lakeformation)","(aws-lakeformation)","(lakeformation)", "(lake formation)"],"labels":["@aws-cdk/aws-lakeformation"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-lambda)","(aws-lambda)","(lambda)"],"labels":["@aws-cdk/aws-lambda"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-lambda-event-sources)","(aws-lambda-event-sources)","(lambda-event-sources)","(lambda event sources)"],"labels":["@aws-cdk/aws-lambda-event-sources"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-lambda-nodejs)","(aws-lambda-nodejs)","(lambda-nodejs)","(lambda nodejs)"],"labels":["@aws-cdk/aws-lambda-nodejs"],"assignees":["eladb"]}, - {"keywords":["(@aws-cdk/aws-logs)","(aws-logs)","(logs)"],"labels":["@aws-cdk/aws-logs"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-logs-destinations)","(aws-logs-destinations)","(logs-destinations)","(logs destinations)"],"labels":["@aws-cdk/aws-logs-destinations"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-managedblockchain)","(aws-managedblockchain)","(managedblockchain)","(managed blockchain)"],"labels":["@aws-cdk/aws-managedblockchain"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-mediaconvert)","(aws-mediaconvert)","(mediaconvert)","(media convert)"],"labels":["@aws-cdk/aws-mediaconvert"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-medialive)","(aws-medialive)","(medialive)","(media live)"],"labels":["@aws-cdk/aws-medialive"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-mediastore)","(aws-mediastore)","(mediastore)","(media store)"],"labels":["@aws-cdk/aws-mediastore"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-msk)","(aws-msk)","(msk)"],"labels":["@aws-cdk/aws-msk"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-neptune)","(aws-neptune)","(neptune)"],"labels":["@aws-cdk/aws-neptune"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-networkmanager)","(aws-networkmanager)","(networkmanager)","(network manager)"],"labels":["@aws-cdk/aws-networkmanager"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-opsworks)","(aws-opsworks)","(opsworks)","(ops works)"],"labels":["@aws-cdk/aws-opsworks"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-opsworkscm)","(aws-opsworkscm)","(opsworkscm)", "(opsworks cm)"],"labels":["@aws-cdk/aws-opsworkscm"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-personalize)","(aws-personalize)","(personalize)"],"labels":["@aws-cdk/aws-personalize"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/aws-pinpoint)","(aws-pinpoint)","(pinpoint)"],"labels":["@aws-cdk/aws-pinpoint"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-pinpointemail)","(aws-pinpointemail)","(pinpointemail)", "(pinpoint email)"],"labels":["@aws-cdk/aws-pinpointemail"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-qldb)","(aws-qldb)","(qldb)"],"labels":["@aws-cdk/aws-qldb"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-ram)","(aws-ram)","(ram)"],"labels":["@aws-cdk/aws-ram"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-rds)","(aws-rds)","(rds)"],"labels":["@aws-cdk/aws-rds"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-redshift)","(aws-redshift)","(redshift)","(red shift)"],"labels":["@aws-cdk/aws-redshift"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-resourcegroups)","(aws-resourcegroups)","(resourcegroups)","(resource groups)"],"labels":["@aws-cdk/aws-resourcegroups"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-robomaker)","(aws-robomaker)","(robomaker)","(robo maker)"],"labels":["@aws-cdk/aws-robomaker"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/aws-route53)","(aws-route53)","(route53)","(route 53)"],"labels":["@aws-cdk/aws-route53"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-route53-patterns)","(aws-route53-patterns)","(route53-patterns)","(route53 patterns)"],"labels":["@aws-cdk/aws-route53-patterns"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-route53-targets)","(aws-route53-targets)","(route53-targets)","(route53 targets)"],"labels":["@aws-cdk/aws-route53-targets"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-route53resolver)","(aws-route53resolver)","(route53resolver)","(route53 resolver)"],"labels":["@aws-cdk/aws-route53resolver"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-s3)","(aws-s3)","(s3)"],"labels":["@aws-cdk/aws-s3"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-s3-assets)","(aws-s3-assets)","(s3-assets)","(s3 assets)"],"labels":["@aws-cdk/aws-s3-assets"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-s3-deployment)","(aws-s3-deployment)","(s3-deployment)","(s3 deployment)"],"labels":["@aws-cdk/aws-s3-deployment"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-s3-notifications)","(aws-s3-notifications)","(s3-notifications)","(s3 notifications)"],"labels":["@aws-cdk/aws-s3-notifications"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-sagemaker)","(aws-sagemaker)","(sagemaker)","(sage maker)"],"labels":["@aws-cdk/aws-sagemaker"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/aws-sam)","(aws-sam)","(sam)"],"labels":["@aws-cdk/aws-sam"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-sdb)","(aws-sdb)","(sdb)"],"labels":["@aws-cdk/aws-sdb"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/aws-secretsmanager)","(aws-secretsmanager)","(secretsmanager)","(secrets manager)"],"labels":["@aws-cdk/aws-secretsmanager"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-securityhub)","(aws-securityhub)","(securityhub)","(security hub)"],"labels":["@aws-cdk/aws-securityhub"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-servicecatalog)","(aws-servicecatalog)","(servicecatalog)","(service catalog)"],"labels":["@aws-cdk/aws-servicecatalog"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-servicediscovery)","(aws-servicediscovery)","(servicediscovery)","(service discovery)"],"labels":["@aws-cdk/aws-servicediscovery"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-ses)","(aws-ses)","(ses)"],"labels":["@aws-cdk/aws-ses"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-ses-actions)","(aws-ses-actions)","(ses-actions)","(ses actions)"],"labels":["@aws-cdk/aws-ses-actions"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-sns)","(aws-sns)","(sns)"],"labels":["@aws-cdk/aws-sns"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-sns-subscriptions)","(aws-sns-subscriptions)","(sns-subscriptions)","(sns subscriptions)"],"labels":["@aws-cdk/aws-sns-subscriptions"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-sqs)","(aws-sqs)","(sqs)"],"labels":["@aws-cdk/aws-sqs"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-ssm)","(aws-ssm)","(ssm)"],"labels":["@aws-cdk/aws-ssm"],"assignees":["MrArnoldPalmer"]}, - {"keywords":["(@aws-cdk/aws-stepfunctions)","(aws-stepfunctions)","(stepfunctions)","(step functions)"],"labels":["@aws-cdk/aws-stepfunctions"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-stepfunctions-tasks)","(aws-stepfunctions-tasks)","(stepfunctions-tasks)","(stepfunctions tasks)"],"labels":["@aws-cdk/aws-stepfunctions-tasks"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/aws-synthetics)","(aws-synthetics)","(synthetics)"],"labels":["@aws-cdk/aws-synthetics"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-transfer)","(aws-transfer)","(transfer)"],"labels":["@aws-cdk/aws-transfer"],"assignees":["iliapolo"]}, - {"keywords":["(@aws-cdk/aws-waf)","(aws-waf)","(waf)"],"labels":["@aws-cdk/aws-waf"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-wafregional)","(aws-wafregional)","(wafregional)","(waf regional)"],"labels":["@aws-cdk/aws-wafregional"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-wafv2)","(aws-wafv2)","(wafv2)","(waf v2)"],"labels":["@aws-cdk/aws-wafv2"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-workspaces)","(aws-workspaces)","(workspaces)"],"labels":["@aws-cdk/aws-workspaces"],"assignees":["NetaNir"]}, - {"keywords":["(@aws-cdk/cfnspec)","(cfnspec)","(cfn spec)"],"labels":["@aws-cdk/cfnspec"],"assignees":["eladb"]}, - {"keywords":["(@aws-cdk/cloud-assembly-schema)","(cloud-assembly-schema)","(cloud assembly schema)"],"labels":["@aws-cdk/cloud-assembly-schema"],"assignees":["eladb"]}, - {"keywords":["(@aws-cdk/cloudformation-diff)","(cloudformation-diff)","(cloudformation diff)","(cfn diff)"],"labels":["@aws-cdk/cloudformation-diff"],"assignees":["shivlaks"]}, - {"keywords":["(@aws-cdk/cloudformation-include)","(cloudformation-include)","(cloudformation include)","(cfn include)"],"labels":["@aws-cdk/cloudformation-include"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/core)","(core)"],"labels":["@aws-cdk/core"],"assignees":["eladb"]}, - {"keywords":["(@aws-cdk/custom-resources)","(custom-resources)","(custom resources)"],"labels":["@aws-cdk/custom-resources"],"assignees":["eladb"]}, - {"keywords":["(@aws-cdk/cx-api)","(cx-api)","(cx api)"],"labels":["@aws-cdk/cx-api"],"assignees":["eladb"]}, - {"keywords":["(@aws-cdk/region-info)","(region-info)","(region info)"],"labels":["@aws-cdk/region-info"],"assignees":["RomainMuller"]} + {"keywords":["[cli]","[command line]"],"labels":["package/tools"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/alexa-ask]","[alexa-ask]","[alexa ask]"],"labels":["@aws-cdk/alexa-ask"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/app-delivery]","[app-delivery]","[app delivery]"],"labels":["@aws-cdk/app-delivery"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/assert]","[assert]"],"labels":["@aws-cdk/assert"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/assets]","[assets]"],"labels":["@aws-cdk/assets"],"assignees":["eladb"]}, + {"keywords":["[@aws-cdk/aws-accessanalyzer]","[aws-accessanalyzer]","[accessanalyzer]","[access analyzer]"],"labels":["@aws-cdk/aws-accessanalyzer"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-acmpca]","[aws-acmpca]","[acmpca]"],"labels":["@aws-cdk/aws-acmpca"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-amazonmq]","[aws-amazonmq]","[amazonmq]","[amazon mq]"],"labels":["@aws-cdk/aws-amazonmq"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-amplify]","[aws-amplify]","[amplify]"],"labels":["@aws-cdk/aws-amplify"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-apigateway]","[aws-apigateway]","[apigateway]", "[api gateway]"],"labels":["@aws-cdk/aws-apigateway"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-apigatewayv2]","[aws-apigatewayv2]","[apigatewayv2]","[apigateway v2]"],"labels":["@aws-cdk/aws-apigatewayv2"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-appconfig]","[aws-appconfig]","[appconfig]","[app config]"],"labels":["@aws-cdk/aws-appconfig"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-applicationautoscaling]","[aws-applicationautoscaling]","[applicationautoscaling]","[application autoscaling]"],"labels":["@aws-cdk/aws-applicationautoscaling"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/aws-appmesh]","[aws-appmesh]","[appmesh]","[app mesh]"],"labels":["@aws-cdk/aws-appmesh"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-appstream]","[aws-appstream]","[appstream]","[app stream]"],"labels":["@aws-cdk/aws-appstream"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/aws-appsync]","[aws-appsync]","[appsync]","[app sync]"],"labels":["@aws-cdk/aws-appsync"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-athena]","[aws-athena]","[athena]"],"labels":["@aws-cdk/aws-athena"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-autoscaling]","[aws-autoscaling]","[autoscaling]","[auto scaling]"],"labels":["@aws-cdk/aws-autoscaling"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/aws-autoscaling-api]","[aws-autoscaling-api]","[autoscaling-api]","[autoscaling api]"],"labels":["@aws-cdk/aws-autoscaling-api"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/aws-autoscaling-common]","[aws-autoscaling-common]","[autoscaling-common]","[autoscaling common]"],"labels":["@aws-cdk/aws-autoscaling-common"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/aws-autoscaling-hooktargets]","[aws-autoscaling-hooktargets]","[autoscaling-hooktargets]","[autoscaling hooktargets]"],"labels":["@aws-cdk/aws-autoscaling-hooktargets"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/aws-autoscalingplans]","[aws-autoscalingplans]","[autoscalingplans]","[autoscaling plans]"],"labels":["@aws-cdk/aws-autoscalingplans"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/aws-backup]","[aws-backup]","[backup]"],"labels":["@aws-cdk/aws-backup"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-batch]","[aws-batch]","[batch]"],"labels":["@aws-cdk/aws-batch"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-budgets]","[aws-budgets]","[budgets]"],"labels":["@aws-cdk/aws-budgets"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-cassandra]","[aws-cassandra]","[cassandra]"],"labels":["@aws-cdk/aws-cassandra"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-ce]","[aws-ce]","[ce]"],"labels":["@aws-cdk/aws-ce"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-certificatemanager]","[aws-certificatemanager]","[certificatemanager]","[certificate manager]"],"labels":["@aws-cdk/aws-certificatemanager"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-chatbot]","[aws-chatbot]","[chatbot]"],"labels":["@aws-cdk/aws-chatbot"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-cloud9]","[aws-cloud9]","[cloud9]","[cloud 9]"],"labels":["@aws-cdk/aws-cloud9"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-cloudformation]","[aws-cloudformation]","[cloudformation]","[cloud formation]"],"labels":["@aws-cdk/aws-cloudformation"],"assignees":["eladb"]}, + {"keywords":["[@aws-cdk/aws-cloudfront]","[aws-cloudfront]","[cloudfront]","[cloud front]"],"labels":["@aws-cdk/aws-cloudfront"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-cloudtrail]","[aws-cloudtrail]","[cloudtrail]","[cloud trail]"],"labels":["@aws-cdk/aws-cloudtrail"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-cloudwatch]","[aws-cloudwatch]","[cloudwatch]","[cloud watch]"],"labels":["@aws-cdk/aws-cloudwatch"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-cloudwatch-actions]","[aws-cloudwatch-actions]","[cloudwatch-actions]","[cloudwatch actions]"],"labels":["@aws-cdk/aws-cloudwatch-actions"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-codebuild]","[aws-codebuild]","[codebuild]","[code build]"],"labels":["@aws-cdk/aws-codebuild"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-codecommit]","[aws-codecommit]","[codecommit]","[code commit]"],"labels":["@aws-cdk/aws-codecommit"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-codedeploy]","[aws-codedeploy]","[codedeploy]","[code deploy]"],"labels":["@aws-cdk/aws-codedeploy"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-codeguruprofiler]","[aws-codeguruprofiler]","[codeguruprofiler]","[codeguru profiler]"],"labels":["@aws-cdk/aws-codeguruprofiler"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-codepipeline]","[aws-codepipeline]","[codepipeline]","[code pipeline]"],"labels":["@aws-cdk/aws-codepipeline"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-codepipeline-actions]","[aws-codepipeline-actions]","[codepipeline-actions]","[codepipeline actions]"],"labels":["@aws-cdk/aws-codepipeline-actions"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-codestar]","[aws-codestar]","[codestar]"],"labels":["@aws-cdk/aws-codestar"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-codestarconnections]","[aws-codestarconnections]","[codestarconnections]","[codestar connections]"],"labels":["@aws-cdk/aws-codestarconnections"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-codestarnotifications]","[aws-codestarnotifications]","[codestarnotifications]","[codestar notifications]"],"labels":["@aws-cdk/aws-codestarnotifications"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-cognito]","[aws-cognito]","[cognito]"],"labels":["@aws-cdk/aws-cognito"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-config]","[aws-config]","[config]"],"labels":["@aws-cdk/aws-config"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-datapipeline]","[aws-datapipeline]","[datapipeline]","[data pipeline]"],"labels":["@aws-cdk/aws-datapipeline"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-dax]","[aws-dax]","[dax]"],"labels":["@aws-cdk/aws-dax"],"assignees":["RomainMuller"]}, + {"keywords":["[@aws-cdk/aws-detective]","[aws-detective]","[detective]"],"labels":["@aws-cdk/aws-detective"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-directoryservice]","[aws-directoryservice]","[directoryservice]","[directory service]"],"labels":["@aws-cdk/aws-directoryservice"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/aws-dlm]","[aws-dlm]","[dlm]"],"labels":["@aws-cdk/aws-dlm"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-dms]","[aws-dms]","[dms]"],"labels":["@aws-cdk/aws-dms"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-docdb]","[aws-docdb]","[docdb]","[doc db]"],"labels":["@aws-cdk/aws-docdb"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-dynamodb]","[aws-dynamodb]","[dynamodb]","[dynamo db]"],"labels":["@aws-cdk/aws-dynamodb"],"assignees":["RomainMuller"]}, + {"keywords":["[@aws-cdk/aws-dynamodb-global]","[aws-dynamodb-global]","[dynamodb-global]","[dynamodb global]"],"labels":["@aws-cdk/aws-dynamodb-global"],"assignees":["RomainMuller"]}, + {"keywords":["[@aws-cdk/aws-ec2]","[aws-ec2]","[ec2]", "[vpc]"],"labels":["@aws-cdk/aws-ec2"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-ecr]","[aws-ecr]","[ecr]"],"labels":["@aws-cdk/aws-ecr"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-ecr-assets]","[aws-ecr-assets]","[ecr-assets]","[ecr assets]", "[ecrassets]"],"labels":["@aws-cdk/aws-ecr-assets"],"assignees":["eladb"]}, + {"keywords":["[@aws-cdk/aws-efs]","[aws-efs]","[efs]"],"labels":["@aws-cdk/aws-efs"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-eks]","[aws-eks]","[eks]"],"labels":["@aws-cdk/aws-eks"],"assignees":["eladb"]}, + {"keywords":["[@aws-cdk/aws-elasticache]","[aws-elasticache]","[elasticache]","[elastic cache]"],"labels":["@aws-cdk/aws-elasticache"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-elasticbeanstalk]","[aws-elasticbeanstalk]","[elasticbeanstalk]","[elastic beanstalk]"],"labels":["@aws-cdk/aws-elasticbeanstalk"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-elasticloadbalancing]","[aws-elasticloadbalancing]","[elasticloadbalancing]","[elastic loadbalancing]","[elb]"],"labels":["@aws-cdk/aws-elasticloadbalancing"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-elasticloadbalancingv2]","[aws-elasticloadbalancingv2]","[elasticloadbalancingv2]","[elbv2]","[elb v2]"],"labels":["@aws-cdk/aws-elasticloadbalancingv2"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-elasticloadbalancingv2-targets]","[aws-elasticloadbalancingv2-targets]","[elasticloadbalancingv2-targets]","[elasticloadbalancingv2 targets]","[elbv2 targets]"],"labels":["@aws-cdk/aws-elasticloadbalancingv2-targets"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-elasticsearch]","[aws-elasticsearch]","[elasticsearch]","[elastic search]"],"labels":["@aws-cdk/aws-elasticsearch"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-emr]","[aws-emr]","[emr]"],"labels":["@aws-cdk/aws-emr"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-events]","[aws-events]","[events]", "eventbridge"],"labels":["@aws-cdk/aws-events"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-events-targets]","[aws-events-targets]","[events-targets]","[events targets]"],"labels":["@aws-cdk/aws-events-targets"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-eventschemas]","[aws-eventschemas]","[eventschemas]","[event schemas]"],"labels":["@aws-cdk/aws-eventschemas"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-fms]","[aws-fms]","[fms]"],"labels":["@aws-cdk/aws-fms"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-fsx]","[aws-fsx]","[fsx]"],"labels":["@aws-cdk/aws-fsx"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-gamelift]","[aws-gamelift]","[gamelift]","[game lift]"],"labels":["@aws-cdk/aws-gamelift"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-globalaccelerator]","[aws-globalaccelerator]","[globalaccelerator]","[global accelerator]"],"labels":["@aws-cdk/aws-globalaccelerator"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-glue]","[aws-glue]","[glue]"],"labels":["@aws-cdk/aws-glue"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-greengrass]","[aws-greengrass]","[greengrass]","[green grass]"],"labels":["@aws-cdk/aws-greengrass"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-guardduty]","[aws-guardduty]","[guardduty]", "[guard duty]"],"labels":["@aws-cdk/aws-guardduty"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-iam]","[aws-iam]","[iam]"],"labels":["@aws-cdk/aws-iam"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-imagebuilder]","[aws-imagebuilder]","[imagebuilder]","[image builder]"],"labels":["@aws-cdk/aws-imagebuilder"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-inspector]","[aws-inspector]","[inspector]"],"labels":["@aws-cdk/aws-inspector"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-iot]","[aws-iot]","[iot]"],"labels":["@aws-cdk/aws-iot"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-iot1click]","[aws-iot1click]","[iot1click]","[iot 1click]"],"labels":["@aws-cdk/aws-iot1click"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-iotanalytics]","[aws-iotanalytics]","[iotanalytics]","[iot analytics]"],"labels":["@aws-cdk/aws-iotanalytics"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-iotevents]","[aws-iotevents]","[iotevents]","[iot events]"],"labels":["@aws-cdk/aws-iotevents"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-iotthingsgraph]","[aws-iotthingsgraph]","[iotthingsgraph]","[iot things graph]"],"labels":["@aws-cdk/aws-iotthingsgraph"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-kinesis]","[aws-kinesis]","[kinesis]"],"labels":["@aws-cdk/aws-kinesis"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-kinesisanalytics]","[aws-kinesisanalytics]","[kinesisanalytics]", "[kinesis analytics]"],"labels":["@aws-cdk/aws-kinesisanalytics"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-kinesisfirehose]","[aws-kinesisfirehose]","[kinesisfirehose]", "[kinesis firehose]"],"labels":["@aws-cdk/aws-kinesisfirehose"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-kms]","[aws-kms]","[kms]"],"labels":["@aws-cdk/aws-kms"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-lakeformation]","[aws-lakeformation]","[lakeformation]", "[lake formation]"],"labels":["@aws-cdk/aws-lakeformation"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-lambda]","[aws-lambda]","[lambda]"],"labels":["@aws-cdk/aws-lambda"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-lambda-event-sources]","[aws-lambda-event-sources]","[lambda-event-sources]","[lambda event sources]"],"labels":["@aws-cdk/aws-lambda-event-sources"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-lambda-nodejs]","[aws-lambda-nodejs]","[lambda-nodejs]","[lambda nodejs]"],"labels":["@aws-cdk/aws-lambda-nodejs"],"assignees":["eladb"]}, + {"keywords":["[@aws-cdk/aws-logs]","[aws-logs]","[logs]"],"labels":["@aws-cdk/aws-logs"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-logs-destinations]","[aws-logs-destinations]","[logs-destinations]","[logs destinations]"],"labels":["@aws-cdk/aws-logs-destinations"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-managedblockchain]","[aws-managedblockchain]","[managedblockchain]","[managed blockchain]"],"labels":["@aws-cdk/aws-managedblockchain"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-mediaconvert]","[aws-mediaconvert]","[mediaconvert]","[media convert]"],"labels":["@aws-cdk/aws-mediaconvert"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-medialive]","[aws-medialive]","[medialive]","[media live]"],"labels":["@aws-cdk/aws-medialive"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-mediastore]","[aws-mediastore]","[mediastore]","[media store]"],"labels":["@aws-cdk/aws-mediastore"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-msk]","[aws-msk]","[msk]"],"labels":["@aws-cdk/aws-msk"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-neptune]","[aws-neptune]","[neptune]"],"labels":["@aws-cdk/aws-neptune"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-networkmanager]","[aws-networkmanager]","[networkmanager]","[network manager]"],"labels":["@aws-cdk/aws-networkmanager"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-opsworks]","[aws-opsworks]","[opsworks]","[ops works]"],"labels":["@aws-cdk/aws-opsworks"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-opsworkscm]","[aws-opsworkscm]","[opsworkscm]", "[opsworks cm]"],"labels":["@aws-cdk/aws-opsworkscm"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-personalize]","[aws-personalize]","[personalize]"],"labels":["@aws-cdk/aws-personalize"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/aws-pinpoint]","[aws-pinpoint]","[pinpoint]"],"labels":["@aws-cdk/aws-pinpoint"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-pinpointemail]","[aws-pinpointemail]","[pinpointemail]", "[pinpoint email]"],"labels":["@aws-cdk/aws-pinpointemail"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-qldb]","[aws-qldb]","[qldb]"],"labels":["@aws-cdk/aws-qldb"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-ram]","[aws-ram]","[ram]"],"labels":["@aws-cdk/aws-ram"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-rds]","[aws-rds]","[rds]"],"labels":["@aws-cdk/aws-rds"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-redshift]","[aws-redshift]","[redshift]","[red shift]"],"labels":["@aws-cdk/aws-redshift"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-resourcegroups]","[aws-resourcegroups]","[resourcegroups]","[resource groups]"],"labels":["@aws-cdk/aws-resourcegroups"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-robomaker]","[aws-robomaker]","[robomaker]","[robo maker]"],"labels":["@aws-cdk/aws-robomaker"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/aws-route53]","[aws-route53]","[route53]","[route 53]"],"labels":["@aws-cdk/aws-route53"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-route53-patterns]","[aws-route53-patterns]","[route53-patterns]","[route53 patterns]"],"labels":["@aws-cdk/aws-route53-patterns"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-route53-targets]","[aws-route53-targets]","[route53-targets]","[route53 targets]"],"labels":["@aws-cdk/aws-route53-targets"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-route53resolver]","[aws-route53resolver]","[route53resolver]","[route53 resolver]"],"labels":["@aws-cdk/aws-route53resolver"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-s3]","[aws-s3]","[s3]"],"labels":["@aws-cdk/aws-s3"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-s3-assets]","[aws-s3-assets]","[s3-assets]","[s3 assets]"],"labels":["@aws-cdk/aws-s3-assets"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-s3-deployment]","[aws-s3-deployment]","[s3-deployment]","[s3 deployment]"],"labels":["@aws-cdk/aws-s3-deployment"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-s3-notifications]","[aws-s3-notifications]","[s3-notifications]","[s3 notifications]"],"labels":["@aws-cdk/aws-s3-notifications"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-sagemaker]","[aws-sagemaker]","[sagemaker]","[sage maker]"],"labels":["@aws-cdk/aws-sagemaker"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/aws-sam]","[aws-sam]","[sam]"],"labels":["@aws-cdk/aws-sam"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-sdb]","[aws-sdb]","[sdb]"],"labels":["@aws-cdk/aws-sdb"],"assignees":["nija-at"]}, + {"keywords":["[@aws-cdk/aws-secretsmanager]","[aws-secretsmanager]","[secretsmanager]","[secrets manager]"],"labels":["@aws-cdk/aws-secretsmanager"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/aws-securityhub]","[aws-securityhub]","[securityhub]","[security hub]"],"labels":["@aws-cdk/aws-securityhub"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-servicecatalog]","[aws-servicecatalog]","[servicecatalog]","[service catalog]"],"labels":["@aws-cdk/aws-servicecatalog"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-servicediscovery]","[aws-servicediscovery]","[servicediscovery]","[service discovery]"],"labels":["@aws-cdk/aws-servicediscovery"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-ses]","[aws-ses]","[ses]"],"labels":["@aws-cdk/aws-ses"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-ses-actions]","[aws-ses-actions]","[ses-actions]","[ses actions]"],"labels":["@aws-cdk/aws-ses-actions"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-sns]","[aws-sns]","[sns]"],"labels":["@aws-cdk/aws-sns"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-sns-subscriptions]","[aws-sns-subscriptions]","[sns-subscriptions]","[sns subscriptions]"],"labels":["@aws-cdk/aws-sns-subscriptions"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-sqs]","[aws-sqs]","[sqs]"],"labels":["@aws-cdk/aws-sqs"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-ssm]","[aws-ssm]","[ssm]"],"labels":["@aws-cdk/aws-ssm"],"assignees":["MrArnoldPalmer"]}, + {"keywords":["[@aws-cdk/aws-stepfunctions]","[aws-stepfunctions]","[stepfunctions]","[step functions]"],"labels":["@aws-cdk/aws-stepfunctions"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-stepfunctions-tasks]","[aws-stepfunctions-tasks]","[stepfunctions-tasks]","[stepfunctions tasks]"],"labels":["@aws-cdk/aws-stepfunctions-tasks"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/aws-synthetics]","[aws-synthetics]","[synthetics]"],"labels":["@aws-cdk/aws-synthetics"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-transfer]","[aws-transfer]","[transfer]"],"labels":["@aws-cdk/aws-transfer"],"assignees":["iliapolo"]}, + {"keywords":["[@aws-cdk/aws-waf]","[aws-waf]","[waf]"],"labels":["@aws-cdk/aws-waf"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-wafregional]","[aws-wafregional]","[wafregional]","[waf regional]"],"labels":["@aws-cdk/aws-wafregional"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-wafv2]","[aws-wafv2]","[wafv2]","[waf v2]"],"labels":["@aws-cdk/aws-wafv2"],"assignees":["rix0rrr"]}, + {"keywords":["[@aws-cdk/aws-workspaces]","[aws-workspaces]","[workspaces]"],"labels":["@aws-cdk/aws-workspaces"],"assignees":["NetaNir"]}, + {"keywords":["[@aws-cdk/cfnspec]","[cfnspec]","[cfn spec]"],"labels":["@aws-cdk/cfnspec"],"assignees":["eladb"]}, + {"keywords":["[@aws-cdk/cloud-assembly-schema]","[cloud-assembly-schema]","[cloud assembly schema]"],"labels":["@aws-cdk/cloud-assembly-schema"],"assignees":["eladb"]}, + {"keywords":["[@aws-cdk/cloudformation-diff]","[cloudformation-diff]","[cloudformation diff]","[cfn diff]"],"labels":["@aws-cdk/cloudformation-diff"],"assignees":["shivlaks"]}, + {"keywords":["[@aws-cdk/cloudformation-include]","[cloudformation-include]","[cloudformation include]","[cfn include]"],"labels":["@aws-cdk/cloudformation-include"],"assignees":["skinny85"]}, + {"keywords":["[@aws-cdk/core]","[core]"],"labels":["@aws-cdk/core"],"assignees":["eladb"]}, + {"keywords":["[@aws-cdk/custom-resources]","[custom-resources]","[custom resources]"],"labels":["@aws-cdk/custom-resources"],"assignees":["eladb"]}, + {"keywords":["[@aws-cdk/cx-api]","[cx-api]","[cx api]"],"labels":["@aws-cdk/cx-api"],"assignees":["eladb"]}, + {"keywords":["[@aws-cdk/region-info]","[region-info]","[region info]"],"labels":["@aws-cdk/region-info"],"assignees":["RomainMuller"]}, + {"keywords":["(@aws-cdk/aws-macie)","(aws-macie)","(macie)"],"labels":["@aws-cdk/aws-macie"],"assignees":["rix0rrr"]} ] From ccd577ebc2913db1aeae27940119650c5a55d684 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2020 23:53:18 +0000 Subject: [PATCH 05/55] chore(deps-dev): bump @types/lodash from 4.14.156 to 4.14.157 (#8725) Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.14.156 to 4.14.157. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-codepipeline-actions/package.json | 2 +- packages/@aws-cdk/aws-lambda/package.json | 2 +- packages/@aws-cdk/core/package.json | 2 +- yarn.lock | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/@aws-cdk/aws-codepipeline-actions/package.json b/packages/@aws-cdk/aws-codepipeline-actions/package.json index 557f8079b9b34..b34c52fc4c7ec 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/package.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-cloudtrail": "0.0.0", - "@types/lodash": "^4.14.156", + "@types/lodash": "^4.14.157", "@types/nodeunit": "^0.0.31", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index 6b79895bf02c6..779270b89375f 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -68,7 +68,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/aws-lambda": "^8.10.39", - "@types/lodash": "^4.14.156", + "@types/lodash": "^4.14.157", "@types/nodeunit": "^0.0.31", "@types/sinon": "^9.0.4", "aws-sdk": "^2.703.0", diff --git a/packages/@aws-cdk/core/package.json b/packages/@aws-cdk/core/package.json index bc6acb2a443dc..4b660f4e83c42 100644 --- a/packages/@aws-cdk/core/package.json +++ b/packages/@aws-cdk/core/package.json @@ -151,7 +151,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@types/lodash": "^4.14.156", + "@types/lodash": "^4.14.157", "@types/node": "^10.17.26", "@types/nodeunit": "^0.0.31", "@types/minimatch": "^3.0.3", diff --git a/yarn.lock b/yarn.lock index ceb77319b9efd..713889573d063 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1501,10 +1501,10 @@ dependencies: jszip "*" -"@types/lodash@^4.14.156": - version "4.14.156" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.156.tgz#cbe30909c89a1feeb7c60803e785344ea0ec82d1" - integrity sha512-l2AgHXcKUwx2DsvP19wtRPqZ4NkONjmorOdq4sMcxIjqdIuuV/ULo2ftuv4NUpevwfW7Ju/UKLqo0ZXuEt/8lQ== +"@types/lodash@^4.14.157": + version "4.14.157" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.157.tgz#fdac1c52448861dfde1a2e1515dbc46e54926dc8" + integrity sha512-Ft5BNFmv2pHDgxV5JDsndOWTRJ+56zte0ZpYLowp03tW+K+t8u8YMOzAnpuqPgzX6WO1XpDIUm7u04M8vdDiVQ== "@types/md5@^2.2.0": version "2.2.0" From 809ba7d429856de126e819cc7f5c3788f51239dc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2020 00:39:38 +0000 Subject: [PATCH 06/55] chore(deps-dev): bump @types/jest from 26.0.0 to 26.0.3 (#8721) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 26.0.0 to 26.0.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/assert/package.json | 2 +- packages/@aws-cdk/aws-dynamodb/package.json | 2 +- packages/@aws-cdk/aws-sam/package.json | 2 +- packages/@aws-cdk/cdk-assets-schema/package.json | 2 +- packages/@aws-cdk/cloud-assembly-schema/package.json | 2 +- packages/@aws-cdk/cloudformation-diff/package.json | 2 +- packages/@aws-cdk/cloudformation-include/package.json | 2 +- packages/@aws-cdk/cx-api/package.json | 2 +- packages/@monocdk-experiment/assert/package.json | 2 +- packages/@monocdk-experiment/rewrite-imports/package.json | 2 +- packages/aws-cdk/package.json | 2 +- packages/cdk-assets/package.json | 2 +- packages/cdk-dasm/package.json | 2 +- packages/decdk/package.json | 2 +- tools/cdk-build-tools/package.json | 2 +- tools/cfn2ts/package.json | 2 +- tools/yarn-cling/package.json | 2 +- yarn.lock | 8 ++++---- 18 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/@aws-cdk/assert/package.json b/packages/@aws-cdk/assert/package.json index 815abfab9ddc1..8eefc0da1c185 100644 --- a/packages/@aws-cdk/assert/package.json +++ b/packages/@aws-cdk/assert/package.json @@ -21,7 +21,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "cdk-build-tools": "0.0.0", "jest": "^25.5.4", "pkglint": "0.0.0", diff --git a/packages/@aws-cdk/aws-dynamodb/package.json b/packages/@aws-cdk/aws-dynamodb/package.json index 8be1059887c3a..c7210094771d1 100644 --- a/packages/@aws-cdk/aws-dynamodb/package.json +++ b/packages/@aws-cdk/aws-dynamodb/package.json @@ -64,7 +64,7 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/assert": "0.0.0", - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "aws-sdk": "^2.703.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-sam/package.json b/packages/@aws-cdk/aws-sam/package.json index f0c48b343da21..f49d0c41dc349 100644 --- a/packages/@aws-cdk/aws-sam/package.json +++ b/packages/@aws-cdk/aws-sam/package.json @@ -65,7 +65,7 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/assert": "0.0.0", - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "jest": "^25.5.4", diff --git a/packages/@aws-cdk/cdk-assets-schema/package.json b/packages/@aws-cdk/cdk-assets-schema/package.json index 279b10397a6db..8d65ed30aecd4 100644 --- a/packages/@aws-cdk/cdk-assets-schema/package.json +++ b/packages/@aws-cdk/cdk-assets-schema/package.json @@ -46,7 +46,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "cdk-build-tools": "0.0.0", "jest": "^25.5.4", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/cloud-assembly-schema/package.json b/packages/@aws-cdk/cloud-assembly-schema/package.json index b39ddd629873b..eac2654ff030b 100644 --- a/packages/@aws-cdk/cloud-assembly-schema/package.json +++ b/packages/@aws-cdk/cloud-assembly-schema/package.json @@ -47,7 +47,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/mock-fs": "^4.10.0", "cdk-build-tools": "0.0.0", "jest": "^25.5.4", diff --git a/packages/@aws-cdk/cloudformation-diff/package.json b/packages/@aws-cdk/cloudformation-diff/package.json index 4d128ebfc9579..3196b202c7f27 100644 --- a/packages/@aws-cdk/cloudformation-diff/package.json +++ b/packages/@aws-cdk/cloudformation-diff/package.json @@ -29,7 +29,7 @@ "table": "^5.4.6" }, "devDependencies": { - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/string-width": "^4.0.1", "@types/table": "^4.0.7", "cdk-build-tools": "0.0.0", diff --git a/packages/@aws-cdk/cloudformation-include/package.json b/packages/@aws-cdk/cloudformation-include/package.json index cad1c8249b4fe..de407f258d640 100644 --- a/packages/@aws-cdk/cloudformation-include/package.json +++ b/packages/@aws-cdk/cloudformation-include/package.json @@ -302,7 +302,7 @@ }, "devDependencies": { "@aws-cdk/assert": "0.0.0", - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/yaml": "1.2.0", "cdk-build-tools": "0.0.0", "jest": "^25.4.0", diff --git a/packages/@aws-cdk/cx-api/package.json b/packages/@aws-cdk/cx-api/package.json index 766e671454da6..859976bb7c93e 100644 --- a/packages/@aws-cdk/cx-api/package.json +++ b/packages/@aws-cdk/cx-api/package.json @@ -53,7 +53,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/mock-fs": "^4.10.0", "@types/semver": "^7.2.0", "cdk-build-tools": "0.0.0", diff --git a/packages/@monocdk-experiment/assert/package.json b/packages/@monocdk-experiment/assert/package.json index a83382da131d0..6a923bd5971a3 100644 --- a/packages/@monocdk-experiment/assert/package.json +++ b/packages/@monocdk-experiment/assert/package.json @@ -36,7 +36,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/node": "^10.17.26", "cdk-build-tools": "0.0.0", "jest": "^25.5.4", diff --git a/packages/@monocdk-experiment/rewrite-imports/package.json b/packages/@monocdk-experiment/rewrite-imports/package.json index a9932328b681c..a159df11280b2 100644 --- a/packages/@monocdk-experiment/rewrite-imports/package.json +++ b/packages/@monocdk-experiment/rewrite-imports/package.json @@ -36,7 +36,7 @@ }, "devDependencies": { "@types/glob": "^7.1.2", - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/node": "^10.17.26", "cdk-build-tools": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 5895dc62b74e1..96e92fa905005 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -44,7 +44,7 @@ "@types/archiver": "^3.1.0", "@types/fs-extra": "^8.1.0", "@types/glob": "^7.1.2", - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/minimatch": "^3.0.3", "@types/mockery": "^1.4.29", "@types/node": "^10.17.26", diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index 859e64f9df617..b04ce8c04835d 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -32,7 +32,7 @@ "devDependencies": { "@types/archiver": "^3.1.0", "@types/glob": "^7.1.2", - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/mock-fs": "^4.10.0", "@types/node": "^10.17.26", "@types/yargs": "^15.0.5", diff --git a/packages/cdk-dasm/package.json b/packages/cdk-dasm/package.json index 7554e7bee6180..c5e6b34be451b 100644 --- a/packages/cdk-dasm/package.json +++ b/packages/cdk-dasm/package.json @@ -30,7 +30,7 @@ "yaml": "1.10.0" }, "devDependencies": { - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/yaml": "1.9.7", "jest": "^25.5.4" }, diff --git a/packages/decdk/package.json b/packages/decdk/package.json index 76fb6b76b2ed7..59b0ad777f07e 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -185,7 +185,7 @@ }, "devDependencies": { "@types/fs-extra": "^8.1.0", - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/yaml": "1.9.7", "@types/yargs": "^15.0.5", "jest": "^25.5.4", diff --git a/tools/cdk-build-tools/package.json b/tools/cdk-build-tools/package.json index 0305be2513a6b..443b9649bec1c 100644 --- a/tools/cdk-build-tools/package.json +++ b/tools/cdk-build-tools/package.json @@ -34,7 +34,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/fs-extra": "^8.1.0", - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/yargs": "^15.0.5", "pkglint": "0.0.0" }, diff --git a/tools/cfn2ts/package.json b/tools/cfn2ts/package.json index 04fa146c2a4ec..d302cd2aa01be 100644 --- a/tools/cfn2ts/package.json +++ b/tools/cfn2ts/package.json @@ -37,7 +37,7 @@ }, "devDependencies": { "@types/fs-extra": "^8.1.0", - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "@types/yargs": "^15.0.5", "cdk-build-tools": "0.0.0", "jest": "^25.5.4", diff --git a/tools/yarn-cling/package.json b/tools/yarn-cling/package.json index e372356bec847..fe1b5490e0967 100644 --- a/tools/yarn-cling/package.json +++ b/tools/yarn-cling/package.json @@ -39,7 +39,7 @@ }, "devDependencies": { "@types/yarnpkg__lockfile": "^1.1.3", - "@types/jest": "^26.0.0", + "@types/jest": "^26.0.3", "jest": "^25.5.4", "@types/node": "^10.17.26", "typescript": "~3.9.5", diff --git a/yarn.lock b/yarn.lock index 713889573d063..35e131ed072ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1476,10 +1476,10 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/jest@^26.0.0": - version "26.0.0" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.0.tgz#a6d7573dffa9c68cbbdf38f2e0de26f159e11134" - integrity sha512-/yeMsH9HQ1RLORlXAwoLXe8S98xxvhNtUz3yrgrwbaxYjT+6SFPZZRksmRKRA6L5vsUtSHeN71viDOTTyYAD+g== +"@types/jest@^26.0.3": + version "26.0.3" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.3.tgz#79534e0e94857171c0edc596db0ebe7cb7863251" + integrity sha512-v89ga1clpVL/Y1+YI0eIu1VMW+KU7Xl8PhylVtDKVWaSUHBHYPLXMQGBdrpHewaKoTvlXkksbYqPgz8b4cmRZg== dependencies: jest-diff "^25.2.1" pretty-format "^25.2.1" From 84f0429ec1850515d5f2b7e529bfcc481d78030f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2020 03:05:50 +0000 Subject: [PATCH 07/55] chore(deps): bump aws-sdk from 2.703.0 to 2.704.0 (#8727) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.703.0 to 2.704.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.703.0...v2.704.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-cloudfront/package.json | 2 +- packages/@aws-cdk/aws-cloudtrail/package.json | 2 +- packages/@aws-cdk/aws-codebuild/package.json | 2 +- packages/@aws-cdk/aws-codecommit/package.json | 2 +- packages/@aws-cdk/aws-dynamodb/package.json | 2 +- packages/@aws-cdk/aws-eks/package.json | 2 +- packages/@aws-cdk/aws-events-targets/package.json | 2 +- packages/@aws-cdk/aws-lambda/package.json | 2 +- packages/@aws-cdk/aws-route53/package.json | 2 +- packages/@aws-cdk/aws-sqs/package.json | 2 +- packages/@aws-cdk/custom-resources/package.json | 2 +- packages/aws-cdk/package.json | 2 +- packages/cdk-assets/package.json | 2 +- yarn.lock | 8 ++++---- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudfront/package.json b/packages/@aws-cdk/aws-cloudfront/package.json index 50148bd7eb8af..d62af025c4754 100644 --- a/packages/@aws-cdk/aws-cloudfront/package.json +++ b/packages/@aws-cdk/aws-cloudfront/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-cloudtrail/package.json b/packages/@aws-cdk/aws-cloudtrail/package.json index c0f699140ba69..980148bdb9ae8 100644 --- a/packages/@aws-cdk/aws-cloudtrail/package.json +++ b/packages/@aws-cdk/aws-cloudtrail/package.json @@ -64,7 +64,7 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/assert": "0.0.0", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codebuild/package.json b/packages/@aws-cdk/aws-codebuild/package.json index f72cf8072fa80..e99a474e754c4 100644 --- a/packages/@aws-cdk/aws-codebuild/package.json +++ b/packages/@aws-cdk/aws-codebuild/package.json @@ -70,7 +70,7 @@ "@aws-cdk/aws-sns": "0.0.0", "@aws-cdk/aws-sqs": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codecommit/package.json b/packages/@aws-cdk/aws-codecommit/package.json index 39f382e390a3f..f99d09a81e8bc 100644 --- a/packages/@aws-cdk/aws-codecommit/package.json +++ b/packages/@aws-cdk/aws-codecommit/package.json @@ -70,7 +70,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-dynamodb/package.json b/packages/@aws-cdk/aws-dynamodb/package.json index c7210094771d1..b0fc3970d83ca 100644 --- a/packages/@aws-cdk/aws-dynamodb/package.json +++ b/packages/@aws-cdk/aws-dynamodb/package.json @@ -65,7 +65,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/jest": "^26.0.3", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index 9a7d145f01c93..4825684362795 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-events-targets/package.json b/packages/@aws-cdk/aws-events-targets/package.json index 18f0665c69a02..15b3e774c1875 100644 --- a/packages/@aws-cdk/aws-events-targets/package.json +++ b/packages/@aws-cdk/aws-events-targets/package.json @@ -68,7 +68,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-codecommit": "0.0.0", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index 779270b89375f..be5fb43825d95 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -71,7 +71,7 @@ "@types/lodash": "^4.14.157", "@types/nodeunit": "^0.0.31", "@types/sinon": "^9.0.4", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-route53/package.json b/packages/@aws-cdk/aws-route53/package.json index 60b155b6bcd7f..46b8f4c91bcbe 100644 --- a/packages/@aws-cdk/aws-route53/package.json +++ b/packages/@aws-cdk/aws-route53/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-sqs/package.json b/packages/@aws-cdk/aws-sqs/package.json index f2dc1fc22533f..9348596b74c5d 100644 --- a/packages/@aws-cdk/aws-sqs/package.json +++ b/packages/@aws-cdk/aws-sqs/package.json @@ -65,7 +65,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index 79b0fd59e5ee6..bda296354ce45 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -73,7 +73,7 @@ "@types/aws-lambda": "^8.10.39", "@types/fs-extra": "^8.1.0", "@types/sinon": "^9.0.4", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 96e92fa905005..e2036bc610189 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -71,7 +71,7 @@ "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/region-info": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "camelcase": "^6.0.0", "cdk-assets": "0.0.0", "colors": "^1.4.0", diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index b04ce8c04835d..e0edec3137f44 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -47,7 +47,7 @@ "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.703.0", + "aws-sdk": "^2.704.0", "glob": "^7.1.6", "yargs": "^15.3.1" }, diff --git a/yarn.lock b/yarn.lock index 35e131ed072ff..e2710d105039d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2124,10 +2124,10 @@ aws-sdk-mock@^5.1.0: sinon "^9.0.1" traverse "^0.6.6" -aws-sdk@^2.637.0, aws-sdk@^2.703.0: - version "2.703.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.703.0.tgz#b22a65094c65109ce52c206e5f46e05247c8aaf4" - integrity sha512-iMJueMVDp2fqopgpjPfejyFaxaksYYdRJ7bxzWEYSxR1UoSf6V9zgcrgkF+SgoxiKJ2rxsbPxhoPu2MV//b9xA== +aws-sdk@^2.637.0, aws-sdk@^2.704.0: + version "2.704.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.704.0.tgz#7b039a0a5ba8eaabb91c5f73d06d4330192c5f30" + integrity sha512-Cjkc86+9sKNn34iIiMa4MimHmr1xpNQZaPVHnnQCpBuh0p6VMDPloz3xc+4LEyoNuwIBzTRjZCVUePVyc31+gw== dependencies: buffer "4.9.2" events "1.1.1" From cc5bf4ec55506061f4e60d582859a6f9b5e3bd50 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2020 04:10:44 +0000 Subject: [PATCH 08/55] chore(deps-dev): bump @types/semver from 7.2.0 to 7.3.1 (#8729) Bumps [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver) from 7.2.0 to 7.3.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/cx-api/package.json | 2 +- packages/aws-cdk/package.json | 2 +- tools/pkglint/package.json | 2 +- yarn.lock | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/@aws-cdk/cx-api/package.json b/packages/@aws-cdk/cx-api/package.json index 859976bb7c93e..371aebc1f65fd 100644 --- a/packages/@aws-cdk/cx-api/package.json +++ b/packages/@aws-cdk/cx-api/package.json @@ -55,7 +55,7 @@ "devDependencies": { "@types/jest": "^26.0.3", "@types/mock-fs": "^4.10.0", - "@types/semver": "^7.2.0", + "@types/semver": "^7.3.1", "cdk-build-tools": "0.0.0", "jest": "^25.5.4", "mock-fs": "^4.12.0", diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index e2036bc610189..e65262c4ce654 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -49,7 +49,7 @@ "@types/mockery": "^1.4.29", "@types/node": "^10.17.26", "@types/promptly": "^3.0.0", - "@types/semver": "^7.2.0", + "@types/semver": "^7.3.1", "@types/sinon": "^9.0.4", "@types/table": "^4.0.7", "@types/uuid": "^8.0.0", diff --git a/tools/pkglint/package.json b/tools/pkglint/package.json index 88d09027159b0..1c2037573215e 100644 --- a/tools/pkglint/package.json +++ b/tools/pkglint/package.json @@ -36,7 +36,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/fs-extra": "^8.1.0", - "@types/semver": "^7.2.0", + "@types/semver": "^7.3.1", "@types/yargs": "^15.0.5", "jest": "^25.5.4", "typescript": "~3.9.5" diff --git a/yarn.lock b/yarn.lock index e2710d105039d..ab4cad2e36644 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1572,10 +1572,10 @@ resolved "https://registry.yarnpkg.com/@types/proxyquire/-/proxyquire-1.3.28.tgz#05a647bb0d8fe48fc8edcc193e43cc79310faa7d" integrity sha512-SQaNzWQ2YZSr7FqAyPPiA3FYpux2Lqh3HWMZQk47x3xbMCqgC/w0dY3dw9rGqlweDDkrySQBcaScXWeR+Yb11Q== -"@types/semver@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.2.0.tgz#0d72066965e910531e1db4621c15d0ca36b8d83b" - integrity sha512-TbB0A8ACUWZt3Y6bQPstW9QNbhNeebdgLX4T/ZfkrswAfUzRiXrgd9seol+X379Wa589Pu4UEx9Uok0D4RjRCQ== +"@types/semver@^7.3.1": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.1.tgz#7a9a5d595b6d873f338c867dcef64df289468cfa" + integrity sha512-ooD/FJ8EuwlDKOI6D9HWxgIgJjMg2cuziXm/42npDC8y4NjxplBUn9loewZiBNCt44450lHAU0OSb51/UqXeag== dependencies: "@types/node" "*" From 30cac2b30bc2528ea309a4b62591a25ebefcc0d9 Mon Sep 17 00:00:00 2001 From: Shiv Lakshminarayan Date: Thu, 25 Jun 2020 06:56:25 -0700 Subject: [PATCH 09/55] chore(stepfunctions-tasks): update tests to use 'JsonPath' instead of 'Data' class (#8730) Motivation: We recently added the `JsonPath` class in #8647 However, re-work for Dynamo was in flight and added some classes that don't leverage the new class yet and `Data` has now been marked deprecated ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../test/dynamodb/delete-item.test.ts | 2 +- .../aws-stepfunctions-tasks/test/dynamodb/get-item.test.ts | 6 +++--- .../test/dynamodb/integ.call-dynamodb.ts | 2 +- .../aws-stepfunctions-tasks/test/dynamodb/put-item.test.ts | 2 +- .../test/dynamodb/shared-types.test.ts | 2 +- .../test/dynamodb/update-item.test.ts | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/delete-item.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/delete-item.test.ts index 031055d1d0f8c..4a278249f4585 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/delete-item.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/delete-item.test.ts @@ -26,7 +26,7 @@ test('DeleteItem task', () => { conditionExpression: 'ForumName <> :f and Subject <> :s', expressionAttributeNames: { OTHER_KEY: '#OK' }, expressionAttributeValues: { - ':val': tasks.DynamoAttributeValue.numberFromString(sfn.Data.stringAt('$.Item.TotalCount.N')), + ':val': tasks.DynamoAttributeValue.numberFromString(sfn.JsonPath.stringAt('$.Item.TotalCount.N')), }, returnConsumedCapacity: tasks.DynamoConsumedCapacity.TOTAL, returnItemCollectionMetrics: tasks.DynamoItemCollectionMetrics.SIZE, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/get-item.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/get-item.test.ts index b09664737a4ef..2991c762c025d 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/get-item.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/get-item.test.ts @@ -68,12 +68,12 @@ test('supports tokens', () => { // WHEN const task = new tasks.DynamoGetItem(stack, 'GetItem', { key: { - SOME_KEY: tasks.DynamoAttributeValue.fromString(sfn.Data.stringAt('$.partitionKey')), - OTHER_KEY: tasks.DynamoAttributeValue.numberFromString(sfn.Data.stringAt('$.sortKey')), + SOME_KEY: tasks.DynamoAttributeValue.fromString(sfn.JsonPath.stringAt('$.partitionKey')), + OTHER_KEY: tasks.DynamoAttributeValue.numberFromString(sfn.JsonPath.stringAt('$.sortKey')), }, table, consistentRead: true, - expressionAttributeNames: { OTHER_KEY: sfn.Data.stringAt('$.otherKey') }, + expressionAttributeNames: { OTHER_KEY: sfn.JsonPath.stringAt('$.otherKey') }, projectionExpression: [ new tasks.DynamoProjectionExpression().withAttribute('Messages').atIndex(1).withAttribute('Tags'), new tasks.DynamoProjectionExpression().withAttribute('ID'), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/integ.call-dynamodb.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/integ.call-dynamodb.ts index abf91f54cdb5b..07e05b7414a9f 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/integ.call-dynamodb.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/integ.call-dynamodb.ts @@ -34,7 +34,7 @@ class CallDynamoDBStack extends cdk.Stack { const putItemTask = new tasks.DynamoPutItem(this, 'PutItem', { item: { MessageId: tasks.DynamoAttributeValue.fromString(MESSAGE_ID), - Text: tasks.DynamoAttributeValue.fromString(sfn.Data.stringAt('$.bar')), + Text: tasks.DynamoAttributeValue.fromString(sfn.JsonPath.stringAt('$.bar')), TotalCount: tasks.DynamoAttributeValue.fromNumber(firstNumber), }, table, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/put-item.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/put-item.test.ts index bfa6840abe287..a21a4decc0b30 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/put-item.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/put-item.test.ts @@ -26,7 +26,7 @@ test('PutItem task', () => { conditionExpression: 'ForumName <> :f and Subject <> :s', expressionAttributeNames: { OTHER_KEY: '#OK' }, expressionAttributeValues: { - ':val': tasks.DynamoAttributeValue.numberFromString(sfn.Data.stringAt('$.Item.TotalCount.N')), + ':val': tasks.DynamoAttributeValue.numberFromString(sfn.JsonPath.stringAt('$.Item.TotalCount.N')), }, returnConsumedCapacity: tasks.DynamoConsumedCapacity.TOTAL, returnItemCollectionMetrics: tasks.DynamoItemCollectionMetrics.SIZE, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/shared-types.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/shared-types.test.ts index 111be02b15027..d848ef9035132 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/shared-types.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/shared-types.test.ts @@ -43,7 +43,7 @@ describe('DynamoAttributeValue', () => { const s = '$.string'; // WHEN - const attribute = tasks.DynamoAttributeValue.fromString(sfn.Data.stringAt(s)); + const attribute = tasks.DynamoAttributeValue.fromString(sfn.JsonPath.stringAt(s)); // THEN expect(sfn.FieldUtils.renderObject(attribute)).toEqual({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/update-item.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/update-item.test.ts index fcd38f03f384c..9a4eb3cbcb66a 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/update-item.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/dynamodb/update-item.test.ts @@ -26,7 +26,7 @@ test('UpdateItem task', () => { conditionExpression: 'ForumName <> :f and Subject <> :s', expressionAttributeNames: { OTHER_KEY: '#OK' }, expressionAttributeValues: { - ':val': tasks.DynamoAttributeValue.numberFromString(sfn.Data.stringAt('$.Item.TotalCount.N')), + ':val': tasks.DynamoAttributeValue.numberFromString(sfn.JsonPath.stringAt('$.Item.TotalCount.N')), }, returnConsumedCapacity: tasks.DynamoConsumedCapacity.TOTAL, returnItemCollectionMetrics: tasks.DynamoItemCollectionMetrics.SIZE, From 8914899aafcaa28d8b7ca2d2901f86b016179b50 Mon Sep 17 00:00:00 2001 From: Martin Grund Date: Thu, 25 Jun 2020 16:40:28 +0200 Subject: [PATCH 10/55] fix(elbv2): Add missing accounts to ELBv2 Log Delivery. (#8715) This patch adds the missing regional accounts for two regions to the configuration of the ELBv2 package. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts index 15152b7fc89a5..a51e40c0df0db 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts @@ -205,11 +205,13 @@ const ELBV2_ACCOUNTS: { [region: string]: string } = { 'us-east-2': '033677994240', 'us-west-1': '027434742980', 'us-west-2': '797873946194', + 'af-south-1': '098369216593', 'ca-central-1': '985666609251', 'eu-central-1': '054676820928', 'eu-west-1': '156460612806', 'eu-west-2': '652711504416', 'eu-west-3': '009996457667', + 'eu-south-1': '635631232127', 'eu-north-1': '897822967062', 'ap-east-1': '754344448648', 'ap-northeast-1': '582318560864', From 32b54a504357922e55ac98850a8e4acc9a0349f5 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Thu, 25 Jun 2020 16:30:21 +0100 Subject: [PATCH 11/55] fix(cognito): cannot add multiple route53 targets to the same user pool domain (#8622) The root cause here is that calling `cloudFrontDomainName` getter on `UserPoolDomain` results in creating a custom resource with a fixed node id. This resulted in the error - "There is already a Construct with name 'CloudFrontDomainName' in UserPoolDomain". Changed the logic around so that the `CustomResource` construct is only created on first call to the getter, and is reused on subsequent calls. fixes #8603 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-cognito/lib/user-pool-domain.ts | 42 ++++++++++--------- .../aws-cognito/test/user-pool-domain.test.ts | 17 +++++++- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/packages/@aws-cdk/aws-cognito/lib/user-pool-domain.ts b/packages/@aws-cdk/aws-cognito/lib/user-pool-domain.ts index 3566acf7c7aee..b910cc24a41f0 100644 --- a/packages/@aws-cdk/aws-cognito/lib/user-pool-domain.ts +++ b/packages/@aws-cdk/aws-cognito/lib/user-pool-domain.ts @@ -83,6 +83,8 @@ export class UserPoolDomain extends Resource implements IUserPoolDomain { public readonly domainName: string; private isCognitoDomain: boolean; + private cloudFrontCustomResource?: AwsCustomResource; + constructor(scope: Construct, id: string, props: UserPoolDomainProps) { super(scope, id); @@ -113,25 +115,27 @@ export class UserPoolDomain extends Resource implements IUserPoolDomain { * The domain name of the CloudFront distribution associated with the user pool domain. */ public get cloudFrontDomainName(): string { - const sdkCall: AwsSdkCall = { - service: 'CognitoIdentityServiceProvider', - action: 'describeUserPoolDomain', - parameters: { - Domain: this.domainName, - }, - physicalResourceId: PhysicalResourceId.of(this.domainName), - }; - const customResource = new AwsCustomResource(this, 'CloudFrontDomainName', { - resourceType: 'Custom::UserPoolCloudFrontDomainName', - onCreate: sdkCall, - onUpdate: sdkCall, - policy: AwsCustomResourcePolicy.fromSdkCalls({ - // DescribeUserPoolDomain only supports access level '*' - // https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazoncognitouserpools.html#amazoncognitouserpools-actions-as-permissions - resources: [ '*' ], - }), - }); - return customResource.getResponseField('DomainDescription.CloudFrontDistribution'); + if (!this.cloudFrontCustomResource) { + const sdkCall: AwsSdkCall = { + service: 'CognitoIdentityServiceProvider', + action: 'describeUserPoolDomain', + parameters: { + Domain: this.domainName, + }, + physicalResourceId: PhysicalResourceId.of(this.domainName), + }; + this.cloudFrontCustomResource = new AwsCustomResource(this, 'CloudFrontDomainName', { + resourceType: 'Custom::UserPoolCloudFrontDomainName', + onCreate: sdkCall, + onUpdate: sdkCall, + policy: AwsCustomResourcePolicy.fromSdkCalls({ + // DescribeUserPoolDomain only supports access level '*' + // https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazoncognitouserpools.html#amazoncognitouserpools-actions-as-permissions + resources: [ '*' ], + }), + }); + } + return this.cloudFrontCustomResource.getResponseField('DomainDescription.CloudFrontDistribution'); } /** diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts index 41407985c8ed1..cb281e11f369a 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts @@ -103,7 +103,7 @@ describe('User Pool Client', () => { })).not.toThrow(); }); - test('custom resource is added when cloudFrontDistribution method is called', () => { + test('custom resource is added when cloudFrontDomainName property is used', () => { // GIVEN const stack = new Stack(); const pool = new UserPool(stack, 'Pool'); @@ -137,6 +137,21 @@ describe('User Pool Client', () => { }); }); + test('cloudFrontDomainName property can be called multiple times', () => { + const stack = new Stack(); + const pool = new UserPool(stack, 'Pool'); + const domain = pool.addDomain('Domain', { + cognitoDomain: { + domainPrefix: 'cognito-domain-prefix', + }, + }); + + const cfDomainNameFirst = domain.cloudFrontDomainName; + const cfDomainNameSecond = domain.cloudFrontDomainName; + + expect(cfDomainNameSecond).toEqual(cfDomainNameFirst); + }); + describe('signInUrl', () => { test('returns the expected URL', () => { // GIVEN From 2662db3218387a6264b37190c231e3b0006eb6b6 Mon Sep 17 00:00:00 2001 From: Shiv Lakshminarayan Date: Thu, 25 Jun 2020 12:39:03 -0700 Subject: [PATCH 12/55] fix(cli): post install warnings are not clearly visible when running cdk init (#8723) Modified initialization of git and post install steps to the end of the init process. Changed the current messages to use `warning` which will display them in yellow and updated guidance text. Closes #8720 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/lib/init.ts | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/packages/aws-cdk/lib/init.ts b/packages/aws-cdk/lib/init.ts index 07ec97181f551..cff039fbb9cee 100644 --- a/packages/aws-cdk/lib/init.ts +++ b/packages/aws-cdk/lib/init.ts @@ -241,15 +241,16 @@ async function initializeProject(template: InitTemplate, language: string, canUs await assertIsEmptyDirectory(workDir); print(`Applying project template ${colors.green(template.name)} for ${colors.blue(language)}`); await template.install(language, workDir); + if (await fs.pathExists('README.md')) { + print(colors.green(await fs.readFile('README.md', { encoding: 'utf-8' }))); + } + if (!generateOnly) { await initializeGitRepository(workDir); await postInstall(language, canUseNetwork, workDir); } - if (await fs.pathExists('README.md')) { - print(colors.green(await fs.readFile('README.md', { encoding: 'utf-8' }))); - } else { - print('✅ All done!'); - } + + print('✅ All done!'); } async function assertIsEmptyDirectory(workDir: string) { @@ -292,7 +293,7 @@ async function postInstallTypescript(canUseNetwork: boolean, cwd: string) { const command = 'npm'; if (!canUseNetwork) { - print(`Please run ${colors.green(`${command} install`)}!`); + warning(`Please run '${command} install'!`); return; } @@ -300,28 +301,36 @@ async function postInstallTypescript(canUseNetwork: boolean, cwd: string) { try { await execute(command, ['install'], { cwd }); } catch (e) { - throw new Error(`${colors.green(`${command} install`)} failed: ` + e.message); + warning(`${command} install failed: ` + e.message); } } async function postInstallJava(canUseNetwork: boolean, cwd: string) { + const mvnPackageWarning = 'Please run \'mvn package\'!'; if (!canUseNetwork) { - print(`Please run ${colors.green('mvn package')}!`); + warning(mvnPackageWarning); return; } - print(`Executing ${colors.green('mvn package')}...`); - await execute('mvn', ['package'], { cwd }); + print('Executing \'mvn package\''); + try { + await execute('mvn', ['package'], { cwd }); + } catch (e) { + warning('Unable to package compiled code as JAR'); + warning(mvnPackageWarning); + } + } async function postInstallPython(cwd: string) { const python = pythonExecutable(); + warning(`Please run ${python} -m venv .env'!`); print(`Executing ${colors.green('Creating virtualenv...')}`); try { await execute(python, ['-m venv', '.env'], { cwd }); } catch (e) { - print('Unable to create virtualenv automatically'); - print(`Please run ${colors.green(python + ' -m venv .env')}!`); + warning('Unable to create virtualenv automatically'); + warning(`Please run '${python} -m venv .env'!`); } } From 3b5640e9b1c41ec464d31c426f0dfadc4c296239 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2020 22:38:47 +0000 Subject: [PATCH 13/55] chore(deps): bump aws-sdk from 2.704.0 to 2.705.0 (#8744) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.704.0 to 2.705.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.704.0...v2.705.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-cloudfront/package.json | 2 +- packages/@aws-cdk/aws-cloudtrail/package.json | 2 +- packages/@aws-cdk/aws-codebuild/package.json | 2 +- packages/@aws-cdk/aws-codecommit/package.json | 2 +- packages/@aws-cdk/aws-dynamodb/package.json | 2 +- packages/@aws-cdk/aws-eks/package.json | 2 +- packages/@aws-cdk/aws-events-targets/package.json | 2 +- packages/@aws-cdk/aws-lambda/package.json | 2 +- packages/@aws-cdk/aws-route53/package.json | 2 +- packages/@aws-cdk/aws-sqs/package.json | 2 +- packages/@aws-cdk/custom-resources/package.json | 2 +- packages/aws-cdk/package.json | 2 +- packages/cdk-assets/package.json | 2 +- yarn.lock | 8 ++++---- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudfront/package.json b/packages/@aws-cdk/aws-cloudfront/package.json index d62af025c4754..dc2ec48ec8753 100644 --- a/packages/@aws-cdk/aws-cloudfront/package.json +++ b/packages/@aws-cdk/aws-cloudfront/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-cloudtrail/package.json b/packages/@aws-cdk/aws-cloudtrail/package.json index 980148bdb9ae8..531fd7e131986 100644 --- a/packages/@aws-cdk/aws-cloudtrail/package.json +++ b/packages/@aws-cdk/aws-cloudtrail/package.json @@ -64,7 +64,7 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/assert": "0.0.0", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codebuild/package.json b/packages/@aws-cdk/aws-codebuild/package.json index e99a474e754c4..f66eab3b0f48a 100644 --- a/packages/@aws-cdk/aws-codebuild/package.json +++ b/packages/@aws-cdk/aws-codebuild/package.json @@ -70,7 +70,7 @@ "@aws-cdk/aws-sns": "0.0.0", "@aws-cdk/aws-sqs": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codecommit/package.json b/packages/@aws-cdk/aws-codecommit/package.json index f99d09a81e8bc..a3f357f2b8c87 100644 --- a/packages/@aws-cdk/aws-codecommit/package.json +++ b/packages/@aws-cdk/aws-codecommit/package.json @@ -70,7 +70,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-dynamodb/package.json b/packages/@aws-cdk/aws-dynamodb/package.json index b0fc3970d83ca..58b72c7b4fb6d 100644 --- a/packages/@aws-cdk/aws-dynamodb/package.json +++ b/packages/@aws-cdk/aws-dynamodb/package.json @@ -65,7 +65,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/jest": "^26.0.3", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index 4825684362795..26d7dfdb65bc6 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-events-targets/package.json b/packages/@aws-cdk/aws-events-targets/package.json index 15b3e774c1875..57defe0356aee 100644 --- a/packages/@aws-cdk/aws-events-targets/package.json +++ b/packages/@aws-cdk/aws-events-targets/package.json @@ -68,7 +68,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-codecommit": "0.0.0", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index be5fb43825d95..ab331d92e4d5c 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -71,7 +71,7 @@ "@types/lodash": "^4.14.157", "@types/nodeunit": "^0.0.31", "@types/sinon": "^9.0.4", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-route53/package.json b/packages/@aws-cdk/aws-route53/package.json index 46b8f4c91bcbe..9c7d9198b8806 100644 --- a/packages/@aws-cdk/aws-route53/package.json +++ b/packages/@aws-cdk/aws-route53/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-sqs/package.json b/packages/@aws-cdk/aws-sqs/package.json index 9348596b74c5d..3af1a42030c88 100644 --- a/packages/@aws-cdk/aws-sqs/package.json +++ b/packages/@aws-cdk/aws-sqs/package.json @@ -65,7 +65,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index bda296354ce45..a909dd267ea5d 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -73,7 +73,7 @@ "@types/aws-lambda": "^8.10.39", "@types/fs-extra": "^8.1.0", "@types/sinon": "^9.0.4", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index e65262c4ce654..89818ce157219 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -71,7 +71,7 @@ "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/region-info": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "camelcase": "^6.0.0", "cdk-assets": "0.0.0", "colors": "^1.4.0", diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index e0edec3137f44..616082c289000 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -47,7 +47,7 @@ "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.704.0", + "aws-sdk": "^2.705.0", "glob": "^7.1.6", "yargs": "^15.3.1" }, diff --git a/yarn.lock b/yarn.lock index ab4cad2e36644..3ddfd97af1499 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2124,10 +2124,10 @@ aws-sdk-mock@^5.1.0: sinon "^9.0.1" traverse "^0.6.6" -aws-sdk@^2.637.0, aws-sdk@^2.704.0: - version "2.704.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.704.0.tgz#7b039a0a5ba8eaabb91c5f73d06d4330192c5f30" - integrity sha512-Cjkc86+9sKNn34iIiMa4MimHmr1xpNQZaPVHnnQCpBuh0p6VMDPloz3xc+4LEyoNuwIBzTRjZCVUePVyc31+gw== +aws-sdk@^2.637.0, aws-sdk@^2.705.0: + version "2.705.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.705.0.tgz#6c42851f0efdfe2685eb2dab72740a01742468bd" + integrity sha512-eD3YD3UgCdFIYlkAVYW1rbriKSNHm7nsZbYsBuo91pbyq4XYT56w2oTyNECorYPoq//Y4LQTTx8cbOuEjsNi3w== dependencies: buffer "4.9.2" events "1.1.1" From 10bd8e49709330624eee5f2c2662dee11e19e130 Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Fri, 26 Jun 2020 09:12:44 +0300 Subject: [PATCH 14/55] fix(s3-notifications): broken permissions query in `LambdaDestination` (#8741) A lambda function has a special `permissionsNode` property that should be used when adding or querying permissions. When using a `LambdaDestination`, we used `fn.node` for the permissions query, while the `fn.addPermission` function was adding the permissions to the `permissionsNode`. Fixes #8538 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-s3-notifications/lib/lambda.ts | 4 +- .../test/lambda/lambda.test.ts | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-s3-notifications/lib/lambda.ts b/packages/@aws-cdk/aws-s3-notifications/lib/lambda.ts index 1ca13bb1e763d..a1ea5ac5ac42c 100644 --- a/packages/@aws-cdk/aws-s3-notifications/lib/lambda.ts +++ b/packages/@aws-cdk/aws-s3-notifications/lib/lambda.ts @@ -13,7 +13,7 @@ export class LambdaDestination implements s3.IBucketNotificationDestination { public bind(_scope: Construct, bucket: s3.IBucket): s3.BucketNotificationDestinationConfig { const permissionId = `AllowBucketNotificationsFrom${bucket.node.uniqueId}`; - if (this.fn.node.tryFindChild(permissionId) === undefined) { + if (this.fn.permissionsNode.tryFindChild(permissionId) === undefined) { this.fn.addPermission(permissionId, { sourceAccount: Stack.of(bucket).account, principal: new iam.ServicePrincipal('s3.amazonaws.com'), @@ -23,7 +23,7 @@ export class LambdaDestination implements s3.IBucketNotificationDestination { // if we have a permission resource for this relationship, add it as a dependency // to the bucket notifications resource, so it will be created first. - const permission = this.fn.node.tryFindChild(permissionId) as CfnResource | undefined; + const permission = this.fn.permissionsNode.tryFindChild(permissionId) as CfnResource | undefined; return { type: s3.BucketNotificationDestinationType.LAMBDA, diff --git a/packages/@aws-cdk/aws-s3-notifications/test/lambda/lambda.test.ts b/packages/@aws-cdk/aws-s3-notifications/test/lambda/lambda.test.ts index bc36b562776fd..76563c2b4cccc 100644 --- a/packages/@aws-cdk/aws-s3-notifications/test/lambda/lambda.test.ts +++ b/packages/@aws-cdk/aws-s3-notifications/test/lambda/lambda.test.ts @@ -70,3 +70,52 @@ test('lambda as notification target specified by function arn', () => { }, }); }); + +test('permissions are added as a dependency to the notifications resource when using singleton function', () => { + + const stack = new Stack(); + const bucket = new s3.Bucket(stack, 'MyBucket'); + const fn = new lambda.SingletonFunction(stack, 'MyFunction', { + uuid: 'uuid', + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'index.handler', + code: lambda.Code.fromInline('foo'), + }); + + const lambdaDestination = new s3n.LambdaDestination(fn); + + bucket.addEventNotification(s3.EventType.OBJECT_CREATED, lambdaDestination, { prefix: 'v1/'}); + + const notifications = stack.node.findAll().filter(c => c.node.id === 'Notifications')[0]; + const dependencies = notifications!.node.dependencies; + + expect(dependencies[0].target.node.id).toEqual('AllowBucketNotificationsFromMyBucket'); + +}); + +test('add multiple event notifications using a singleton function', () => { + + const stack = new Stack(); + const bucket = new s3.Bucket(stack, 'MyBucket'); + const fn = new lambda.SingletonFunction(stack, 'MyFunction', { + uuid: 'uuid', + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'index.handler', + code: lambda.Code.fromInline('foo'), + }); + + const lambdaDestination = new s3n.LambdaDestination(fn); + + bucket.addEventNotification(s3.EventType.OBJECT_CREATED, lambdaDestination, { prefix: 'v1/'}); + bucket.addEventNotification(s3.EventType.OBJECT_CREATED, lambdaDestination, { prefix: 'v2/'}); + + expect(stack).toHaveResourceLike('Custom::S3BucketNotifications', { + NotificationConfiguration: { + LambdaFunctionConfigurations: [ + { Filter: { Key: { FilterRules: [{ Name: 'prefix', Value: 'v1/'}]}}}, + { Filter: { Key: { FilterRules: [{ Name: 'prefix', Value: 'v2/'}]}}}, + ], + }, + }); + +}); From 7490deef3390f024dede3da8b95bcec6140ce1be Mon Sep 17 00:00:00 2001 From: Daniel Neilson <53624638+ddneilson@users.noreply.github.com> Date: Fri, 26 Jun 2020 02:57:46 -0500 Subject: [PATCH 15/55] feat(ec2): `Volume` construct (#8219) This adds an L2 construct for AWS::EC2:Volume that supports encryption with a customer-owned KMS key, or service-owned key. It provides methods for importing an existing Volume to the stack, and for granting `AttachVolume` and `DetachVolume` to a role. ---- Resolves https://github.com/aws/aws-cdk/issues/8218 *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ec2/README.md | 69 +- packages/@aws-cdk/aws-ec2/lib/volume.ts | 489 +++++- packages/@aws-cdk/aws-ec2/package.json | 2 + packages/@aws-cdk/aws-ec2/test/test.volume.ts | 1487 +++++++++++++++++ 4 files changed, 2043 insertions(+), 4 deletions(-) create mode 100644 packages/@aws-cdk/aws-ec2/test/test.volume.ts diff --git a/packages/@aws-cdk/aws-ec2/README.md b/packages/@aws-cdk/aws-ec2/README.md index 318ffb55a1274..d3d9e070684f8 100644 --- a/packages/@aws-cdk/aws-ec2/README.md +++ b/packages/@aws-cdk/aws-ec2/README.md @@ -584,7 +584,6 @@ EBS volume for the bastion host can be encrypted like: }); ``` - ## Block Devices To add EBS block device mappings, specify the `blockDeviceMappings` property. The follow example sets the EBS-backed @@ -608,6 +607,74 @@ new ec2.Instance(this, 'Instance', { ``` +## Volumes + +Whereas a `BlockDeviceVolume` is an EBS volume that is created and destroyed as part of the creation and destruction of a specific instance. A `Volume` is for when you want an EBS volume separate from any particular instance. A `Volume` is an EBS block device that can be attached to, or detached from, any instance at any time. Some types of `Volume`s can also be attached to multiple instances at the same time to allow you to have shared storage between those instances. + +A notable restriction is that a Volume can only be attached to instances in the same availability zone as the Volume itself. + +The following demonstrates how to create a 500 GiB encrypted Volume in the `us-west-2a` availability zone, and give a role the ability to attach that Volume to a specific instance: + +```ts +const instance = new ec2.Instance(this, 'Instance', { + // ... +}); +const role = new iam.Role(stack, 'SomeRole', { + assumedBy: new iam.AccountRootPrincipal(), +}); +const volume = new ec2.Volume(this, 'Volume', { + availabilityZone: 'us-west-2a', + size: cdk.Size.gibibytes(500), + encrypted: true, +}); + +volume.grantAttachVolume(role, [instance]); +``` + +### Instances Attaching Volumes to Themselves + +If you need to grant an instance the ability to attach/detach an EBS volume to/from itself, then using `grantAttachVolume` and `grantDetachVolume` as outlined above +will lead to an unresolvable circular reference between the instance role and the instance. In this case, use `grantAttachVolumeByResourceTag` and `grantDetachVolumeByResourceTag` as follows: + +```ts +const instance = new ec2.Instance(this, 'Instance', { + // ... +}); +const volume = new ec2.Volume(this, 'Volume', { + // ... +}); + +const attachGrant = volume.grantAttachVolumeByResourceTag(instance.grantPrincipal, [instance]); +const detachGrant = volume.grantDetachVolumeByResourceTag(instance.grantPrincipal, [instance]); +``` + +### Attaching Volumes + +The Amazon EC2 documentation for +[Linux Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html) and +[Windows Instances](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ebs-volumes.html) contains information on how +to attach and detach your Volumes to/from instances, and how to format them for use. + +The following is a sample skeleton of EC2 UserData that can be used to attach a Volume to the Linux instance that it is running on: + +```ts +const volume = new ec2.Volume(this, 'Volume', { + // ... +}); +const instance = new ec2.Instance(this, 'Instance', { + // ... +}); +volume.grantAttachVolumeByResourceTag(instance.grantPrincipal, [instance]); +const targetDevice = '/dev/xvdz'; +instance.userData.addCommands( + // Attach the volume to /dev/xvdz + `aws --region ${Stack.of(this).region} ec2 attach-volume --volume-id ${volume.volumeId} --instance-id ${instance.instanceId} --device ${targetDevice}`, + // Wait until the volume has attached + `while ! test -e ${targetDevice}; do sleep 1; done` + // The volume will now be mounted. You may have to add additional code to format the volume if it has not been prepared. +); +``` + ## VPC Flow Logs VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. Flow log data can be published to Amazon CloudWatch Logs and Amazon S3. After you've created a flow log, you can retrieve and view its data in the chosen destination. (https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html). diff --git a/packages/@aws-cdk/aws-ec2/lib/volume.ts b/packages/@aws-cdk/aws-ec2/lib/volume.ts index 5108ea2effff1..6a6445dc87379 100644 --- a/packages/@aws-cdk/aws-ec2/lib/volume.ts +++ b/packages/@aws-cdk/aws-ec2/lib/volume.ts @@ -1,5 +1,10 @@ -import { Construct } from '@aws-cdk/core'; -import { CfnInstance } from './ec2.generated'; +import * as crypto from 'crypto'; + +import { AccountRootPrincipal, Grant, IGrantable } from '@aws-cdk/aws-iam'; +import { IKey, ViaServicePrincipal } from '@aws-cdk/aws-kms'; +import { Construct, IResource, Resource, Size, SizeRoundingBehavior, Stack, Tag, Token } from '@aws-cdk/core'; +import { CfnInstance, CfnVolume } from './ec2.generated'; +import { IInstance } from './instance'; /** * Block device @@ -210,4 +215,482 @@ export enum EbsDeviceVolumeType { * Cold HDD */ SC1 = 'sc1', -} \ No newline at end of file + + /** + * General purpose SSD volume that balances price and performance for a wide variety of workloads. + */ + GENERAL_PURPOSE_SSD = GP2, + + /** + * Highest-performance SSD volume for mission-critical low-latency or high-throughput workloads. + */ + PROVISIONED_IOPS_SSD = IO1, + + /** + * Low-cost HDD volume designed for frequently accessed, throughput-intensive workloads. + */ + THROUGHPUT_OPTIMIZED_HDD = ST1, + + /** + * Lowest cost HDD volume designed for less frequently accessed workloads. + */ + COLD_HDD = SC1, + + /** + * Magnetic volumes are backed by magnetic drives and are suited for workloads where data is accessed infrequently, and scenarios where low-cost + * storage for small volume sizes is important. + */ + MAGNETIC = STANDARD, +} + +/** + * An EBS Volume in AWS EC2. + */ +export interface IVolume extends IResource { + /** + * The EBS Volume's ID + * + * @attribute + */ + readonly volumeId: string; + + /** + * The availability zone that the EBS Volume is contained within (ex: us-west-2a) + */ + readonly availabilityZone: string; + + /** + * The customer-managed encryption key that is used to encrypt the Volume. + * + * @attribute + */ + readonly encryptionKey?: IKey; + + /** + * Grants permission to attach this Volume to an instance. + * CAUTION: Granting an instance permission to attach to itself using this method will lead to + * an unresolvable circular reference between the instance role and the instance. + * Use {@link IVolume.grantAttachVolumeToSelf} to grant an instance permission to attach this + * volume to itself. + * + * @param grantee the principal being granted permission. + * @param instances the instances to which permission is being granted to attach this + * volume to. If not specified, then permission is granted to attach + * to all instances in this account. + */ + grantAttachVolume(grantee: IGrantable, instances?: IInstance[]): Grant; + + /** + * Grants permission to attach the Volume by a ResourceTag condition. If you are looking to + * grant an Instance, AutoScalingGroup, EC2-Fleet, SpotFleet, ECS host, etc the ability to attach + * this volume to **itself** then this is the method you want to use. + * + * This is implemented by adding a Tag with key `VolumeGrantAttach-` to the given + * constructs and this Volume, and then conditioning the Grant such that the grantee is only + * given the ability to AttachVolume if both the Volume and the destination Instance have that + * tag applied to them. + * + * If you need to call this method multiple times on different sets of constructs, then provide a + * unique `tagKeySuffix` for each call; failure to do so will result in an inability to attach this + * volume to some of the grants because it will overwrite the tag. + * + * @param grantee the principal being granted permission. + * @param constructs The list of constructs that will have the generated resource tag applied to them. + * @param tagKeySuffix A suffix to use on the generated Tag key in place of the generated hash value. + * Defaults to a hash calculated from this volume. + */ + grantAttachVolumeByResourceTag(grantee: IGrantable, constructs: Construct[], tagKeySuffix?: string): Grant; + + /** + * Grants permission to detach this Volume from an instance + * CAUTION: Granting an instance permission to detach from itself using this method will lead to + * an unresolvable circular reference between the instance role and the instance. + * Use {@link IVolume.grantDetachVolumeFromSelf} to grant an instance permission to detach this + * volume from itself. + * + * @param grantee the principal being granted permission. + * @param instances the instances to which permission is being granted to detach this + * volume from. If not specified, then permission is granted to detach + * from all instances in this account. + */ + grantDetachVolume(grantee: IGrantable, instances?: IInstance[]): Grant; + + /** + * Grants permission to detach the Volume by a ResourceTag condition. + * + * This is implemented via the same mechanism as {@link IVolume.grantAttachVolumeByResourceTag}, + * and is subject to the same conditions. + * + * @param grantee the principal being granted permission. + * @param constructs The list of constructs that will have the generated resource tag applied to them. + * @param tagKeySuffix A suffix to use on the generated Tag key in place of the generated hash value. + * Defaults to a hash calculated from this volume. + */ + grantDetachVolumeByResourceTag(grantee: IGrantable, constructs: Construct[], tagKeySuffix?: string): Grant; +} + +/** + * Properties of an EBS Volume + */ +export interface VolumeProps { + /** + * The value of the physicalName property of this resource. + * + * @default The physical name will be allocated by CloudFormation at deployment time + */ + readonly volumeName?: string; + + /** + * The Availability Zone in which to create the volume. + */ + readonly availabilityZone: string; + + /** + * The size of the volume, in GiBs. You must specify either a snapshot ID or a volume size. + * See {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html#ebs-volume-characteristics|Volume Characteristics} + * for details on the allowable size for each type of volume. + * + * @default If you're creating the volume from a snapshot and don't specify a volume size, the default is the snapshot size. + */ + readonly size?: Size; + + /** + * The snapshot from which to create the volume. You must specify either a snapshot ID or a volume size. + * + * @default The EBS volume is not created from a snapshot. + */ + readonly snapshotId?: string; + + /** + * Indicates whether Amazon EBS Multi-Attach is enabled. + * See {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volumes-multi.html#considerations|Considerations and limitations} + * for the constraints of multi-attach. + * + * @default false + */ + readonly enableMultiAttach?: boolean; + + /** + * Specifies whether the volume should be encrypted. The effect of setting the encryption state to true depends on the volume origin + * (new or from a snapshot), starting encryption state, ownership, and whether encryption by default is enabled. For more information, + * see {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default|Encryption by Default} + * in the Amazon Elastic Compute Cloud User Guide. + * + * Encrypted Amazon EBS volumes must be attached to instances that support Amazon EBS encryption. For more information, see + * {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#EBSEncryption_supported_instances|Supported Instance Types.} + * + * @default false + */ + readonly encrypted?: boolean; + + /** + * The customer-managed encryption key that is used to encrypt the Volume. The encrypted property must + * be true if this is provided. + * + * Note: If using an {@link aws-kms.IKey} created from a {@link aws-kms.Key.fromKeyArn()} here, + * then the KMS key **must** have the following in its Key policy; otherwise, the Volume + * will fail to create. + * + * { + * "Effect": "Allow", + * "Principal": { "AWS": " ex: arn:aws:iam::00000000000:root" }, + * "Resource": "*", + * "Action": [ + * "kms:DescribeKey", + * "kms:GenerateDataKeyWithoutPlainText", + * ], + * "Condition": { + * "StringEquals": { + * "kms:ViaService": "ec2..amazonaws.com", (eg: ec2.us-east-1.amazonaws.com) + * "kms:CallerAccount": "0000000000" (your account ID) + * } + * } + * } + * + * @default The default KMS key for the account, region, and EC2 service is used. + */ + readonly encryptionKey?: IKey; + + /** + * Indicates whether the volume is auto-enabled for I/O operations. By default, Amazon EBS disables I/O to the volume from attached EC2 + * instances when it determines that a volume's data is potentially inconsistent. If the consistency of the volume is not a concern, and + * you prefer that the volume be made available immediately if it's impaired, you can configure the volume to automatically enable I/O. + * + * @default false + */ + readonly autoEnableIo?: boolean; + + /** + * The type of the volume; what type of storage to use to form the EBS Volume. + * + * @default {@link EbsDeviceVolumeType.GENERAL_PURPOSE_SSD} + */ + readonly volumeType?: EbsDeviceVolumeType; + + /** + * The number of I/O operations per second (IOPS) to provision for the volume, with a maximum ratio of 50 IOPS/GiB. + * See {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html#EBSVolumeTypes_piops|Provisioned IOPS SSD (io1) volumes} + * for more information. + * + * This parameter is valid only for PROVISIONED_IOPS_SSD volumes. + * + * @default None -- Required for {@link EbsDeviceVolumeType.PROVISIONED_IOPS_SSD} + */ + readonly iops?: number; +} + +/** + * Attributes required to import an existing EBS Volume into the Stack. + */ +export interface VolumeAttributes { + /** + * The EBS Volume's ID + */ + readonly volumeId: string; + + /** + * The availability zone that the EBS Volume is contained within (ex: us-west-2a) + */ + readonly availabilityZone: string; + + /** + * The customer-managed encryption key that is used to encrypt the Volume. + * + * @default None -- The EBS Volume is not using a customer-managed KMS key for encryption. + */ + readonly encryptionKey?: IKey; +} + +/** + * Common behavior of Volumes. Users should not use this class directly, and instead use ``Volume``. + */ +abstract class VolumeBase extends Resource implements IVolume { + public abstract readonly volumeId: string; + public abstract readonly availabilityZone: string; + public abstract readonly encryptionKey?: IKey; + + public grantAttachVolume(grantee: IGrantable, instances?: IInstance[]): Grant { + const result = Grant.addToPrincipal({ + grantee, + actions: [ 'ec2:AttachVolume' ], + resourceArns : this.collectGrantResourceArns(instances), + }); + + if (this.encryptionKey) { + // When attaching a volume, the EC2 Service will need to grant to itself permission + // to be able to decrypt the encryption key. We restrict the CreateGrant for principle + // of least privilege, in accordance with best practices. + // See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#ebs-encryption-permissions + const kmsGrant: Grant = this.encryptionKey.grant(grantee, 'kms:CreateGrant'); + kmsGrant.principalStatement!.addConditions( + { + Bool: { 'kms:GrantIsForAWSResource': true }, + StringEquals: { + 'kms:ViaService': `ec2.${Stack.of(this).region}.amazonaws.com`, + 'kms:GrantConstraintType': 'EncryptionContextSubset', + }, + }, + ); + } + + return result; + } + + public grantAttachVolumeByResourceTag(grantee: IGrantable, constructs: Construct[], tagKeySuffix?: string): Grant { + const tagKey = `VolumeGrantAttach-${tagKeySuffix ?? this.stringHash(this.node.uniqueId)}`; + const tagValue = this.calculateResourceTagValue(constructs); + const grantCondition: { [key: string]: string } = {}; + grantCondition[`ec2:ResourceTag/${tagKey}`] = tagValue; + + const result = this.grantAttachVolume(grantee); + result.principalStatement!.addCondition( + 'ForAnyValue:StringEquals', grantCondition, + ); + + // The ResourceTag condition requires that all resources involved in the operation have + // the given tag, so we tag this and all constructs given. + Tag.add(this, tagKey, tagValue); + constructs.forEach(construct => Tag.add(construct, tagKey, tagValue)); + + return result; + } + + public grantDetachVolume(grantee: IGrantable, instances?: IInstance[]): Grant { + const result = Grant.addToPrincipal({ + grantee, + actions: [ 'ec2:DetachVolume' ], + resourceArns : this.collectGrantResourceArns(instances), + }); + // Note: No encryption key permissions are required to detach an encrypted volume. + return result; + } + + public grantDetachVolumeByResourceTag(grantee: IGrantable, constructs: Construct[], tagKeySuffix?: string): Grant { + const tagKey = `VolumeGrantDetach-${tagKeySuffix ?? this.stringHash(this.node.uniqueId)}`; + const tagValue = this.calculateResourceTagValue(constructs); + const grantCondition: { [key: string]: string } = {}; + grantCondition[`ec2:ResourceTag/${tagKey}`] = tagValue; + + const result = this.grantDetachVolume(grantee); + result.principalStatement!.addCondition( + 'ForAnyValue:StringEquals', grantCondition, + ); + + // The ResourceTag condition requires that all resources involved in the operation have + // the given tag, so we tag this and all constructs given. + Tag.add(this, tagKey, tagValue); + constructs.forEach(construct => Tag.add(construct, tagKey, tagValue)); + + return result; + } + + private collectGrantResourceArns(instances?: IInstance[]): string[] { + const stack = Stack.of(this); + const resourceArns: string[] = [ + `arn:${stack.partition}:ec2:${stack.region}:${stack.account}:volume/${this.volumeId}`, + ]; + const instanceArnPrefix = `arn:${stack.partition}:ec2:${stack.region}:${stack.account}:instance`; + if (instances) { + instances.forEach(instance => resourceArns.push(`${instanceArnPrefix}/${instance?.instanceId}`)); + } else { + resourceArns.push(`${instanceArnPrefix}/*`); + } + return resourceArns; + } + + private stringHash(value: string): string { + const md5 = crypto.createHash('md5').update(value).digest('hex'); + return md5.slice(0, 8).toUpperCase(); + } + + private calculateResourceTagValue(constructs: Construct[]): string { + const md5 = crypto.createHash('md5'); + constructs.forEach(construct => md5.update(construct.node.uniqueId)); + return md5.digest('hex'); + } +} + +/** + * Creates a new EBS Volume in AWS EC2. + */ +export class Volume extends VolumeBase { + /** + * Import an existing EBS Volume into the Stack. + * + * @param scope the scope of the import. + * @param id the ID of the imported Volume in the construct tree. + * @param attrs the attributes of the imported Volume + */ + public static fromVolumeAttributes(scope: Construct, id: string, attrs: VolumeAttributes): IVolume { + class Import extends VolumeBase { + public readonly volumeId = attrs.volumeId; + public readonly availabilityZone = attrs.availabilityZone; + public readonly encryptionKey = attrs.encryptionKey; + } + // Check that the provided volumeId looks like it could be valid. + if (!Token.isUnresolved(attrs.volumeId) && !/^vol-[0-9a-fA-F]+$/.test(attrs.volumeId)) { + throw new Error('`volumeId` does not match expected pattern. Expected `vol-` (ex: `vol-05abe246af`) or a Token'); + } + return new Import(scope, id); + } + + public readonly volumeId: string; + public readonly availabilityZone: string; + public readonly encryptionKey?: IKey; + + constructor(scope: Construct, id: string, props: VolumeProps) { + super(scope, id, { + physicalName: props.volumeName, + }); + + this.validateProps(props); + + const resource = new CfnVolume(this, 'Resource', { + availabilityZone: props.availabilityZone, + autoEnableIo: props.autoEnableIo, + encrypted: props.encrypted, + kmsKeyId: props.encryptionKey?.keyArn, + iops: props.iops, + multiAttachEnabled: props.enableMultiAttach ?? false, + size: props.size?.toGibibytes({rounding: SizeRoundingBehavior.FAIL}), + snapshotId: props.snapshotId, + volumeType: props.volumeType ?? EbsDeviceVolumeType.GENERAL_PURPOSE_SSD, + }); + + this.volumeId = resource.ref; + this.availabilityZone = props.availabilityZone; + this.encryptionKey = props.encryptionKey; + + if (this.encryptionKey) { + // Per: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#ebs-encryption-requirements + const principal = + new ViaServicePrincipal(`ec2.${Stack.of(this).region}.amazonaws.com`, new AccountRootPrincipal()).withConditions({ + StringEquals: { + 'kms:CallerAccount': Stack.of(this).account, + }, + }); + const grant = this.encryptionKey.grant(principal, + // Describe & Generate are required to be able to create the CMK-encrypted Volume. + 'kms:DescribeKey', + 'kms:GenerateDataKeyWithoutPlainText', + ); + if (props.snapshotId) { + // ReEncrypt is required for when re-encrypting from an encrypted snapshot. + grant.principalStatement?.addActions('kms:ReEncrypt*'); + } + } + } + + protected validateProps(props: VolumeProps) { + if (!Token.isUnresolved(props.availabilityZone) && !/^[a-z]{2}-[a-z]+-[1-9]+[a-z]$/.test(props.availabilityZone)) { + throw new Error('`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); + } + + if (!(props.size || props.snapshotId)) { + throw new Error('Must provide at least one of `size` or `snapshotId`'); + } + + if (props.snapshotId && !Token.isUnresolved(props.snapshotId) && !/^snap-[0-9a-fA-F]+$/.test(props.snapshotId)) { + throw new Error('`snapshotId` does match expected pattern. Expected `snap-` (ex: `snap-05abe246af`) or Token'); + } + + if (props.encryptionKey && !props.encrypted) { + throw new Error('`encrypted` must be true when providing an `encryptionKey`.'); + } + + if (props.iops) { + if (props.volumeType !== EbsDeviceVolumeType.PROVISIONED_IOPS_SSD) { + throw new Error('`iops` may only be specified if the `volumeType` is `PROVISIONED_IOPS_SSD`/`IO1`'); + } + + if (props.iops < 100 || props.iops > 64000) { + throw new Error('`iops` must be in the range 100 to 64,000, inclusive.'); + } + + if (props.size && (props.iops > 50 * props.size.toGibibytes({rounding: SizeRoundingBehavior.FAIL}))) { + throw new Error('`iops` has a maximum ratio of 50 IOPS/GiB.'); + } + } + + if (props.enableMultiAttach && props.volumeType !== EbsDeviceVolumeType.PROVISIONED_IOPS_SSD) { + throw new Error('multi-attach is supported exclusively on `PROVISIONED_IOPS_SSD` volumes.'); + } + + if (props.size) { + const size = props.size.toGibibytes({rounding: SizeRoundingBehavior.FAIL}); + // Enforce maximum volume size: + // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html#ebs-volume-characteristics + const sizeRanges: { [key: string]: { Min: number, Max: number } } = {}; + sizeRanges[EbsDeviceVolumeType.GENERAL_PURPOSE_SSD] = { Min: 1, Max: 16000 }; + sizeRanges[EbsDeviceVolumeType.PROVISIONED_IOPS_SSD] = { Min: 4, Max: 16000 }; + sizeRanges[EbsDeviceVolumeType.THROUGHPUT_OPTIMIZED_HDD] = { Min: 500, Max: 16000 }; + sizeRanges[EbsDeviceVolumeType.COLD_HDD] = { Min: 500, Max: 16000 }; + sizeRanges[EbsDeviceVolumeType.MAGNETIC] = { Min: 1, Max: 1000 }; + const volumeType = props.volumeType ?? EbsDeviceVolumeType.GENERAL_PURPOSE_SSD; + const { Min, Max } = sizeRanges[volumeType]; + if (size < Min || size > Max) { + throw new Error(`\`${volumeType}\` volumes must be between ${Min} GiB and ${Max} GiB in size.`); + } + } + } +} diff --git a/packages/@aws-cdk/aws-ec2/package.json b/packages/@aws-cdk/aws-ec2/package.json index b49f8b3d00007..eadb31460c21d 100644 --- a/packages/@aws-cdk/aws-ec2/package.json +++ b/packages/@aws-cdk/aws-ec2/package.json @@ -74,6 +74,7 @@ "dependencies": { "@aws-cdk/aws-cloudwatch": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", + "@aws-cdk/aws-kms": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-ssm": "0.0.0", @@ -87,6 +88,7 @@ "peerDependencies": { "@aws-cdk/aws-cloudwatch": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", + "@aws-cdk/aws-kms": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-ssm": "0.0.0", diff --git a/packages/@aws-cdk/aws-ec2/test/test.volume.ts b/packages/@aws-cdk/aws-ec2/test/test.volume.ts new file mode 100644 index 0000000000000..dbef8b6ecfebe --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/test.volume.ts @@ -0,0 +1,1487 @@ +import { + expect as cdkExpect, + haveResource, + haveResourceLike, + ResourcePart, +} from '@aws-cdk/assert'; +import { + AccountRootPrincipal, + Role, +} from '@aws-cdk/aws-iam'; +import * as kms from '@aws-cdk/aws-kms'; +import * as cdk from '@aws-cdk/core'; +import { Test } from 'nodeunit'; +import { + AmazonLinuxGeneration, + EbsDeviceVolumeType, + Instance, + InstanceType, + MachineImage, + Volume, + Vpc, +} from '../lib'; + +export = { + 'basic volume'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + + // THEN + cdkExpect(stack).to(haveResource('AWS::EC2::Volume', { + AvailabilityZone: 'us-east-1a', + MultiAttachEnabled: false, + Size: 8, + VolumeType: 'gp2', + }, ResourcePart.Properties)); + + test.done(); + }, + + 'fromVolumeAttributes'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const encryptionKey = new kms.Key(stack, 'Key'); + const volumeId = 'vol-000000'; + const availabilityZone = 'us-east-1a'; + + // WHEN + const volume = Volume.fromVolumeAttributes(stack, 'Volume', { + volumeId, + availabilityZone, + encryptionKey, + }); + + // THEN + test.strictEqual(volume.volumeId, volumeId); + test.strictEqual(volume.availabilityZone, availabilityZone); + test.strictEqual(volume.encryptionKey, encryptionKey); + test.done(); + }, + + 'tagged volume'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + + // WHEN + cdk.Tag.add(volume, 'TagKey', 'TagValue'); + + // THEN + cdkExpect(stack).to(haveResource('AWS::EC2::Volume', { + AvailabilityZone: 'us-east-1a', + MultiAttachEnabled: false, + Size: 8, + VolumeType: 'gp2', + Tags: [{ + Key: 'TagKey', + Value: 'TagValue', + }], + }, ResourcePart.Properties)); + + test.done(); + }, + + 'autoenableIO'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + autoEnableIo: true, + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + AutoEnableIO: true, + }, ResourcePart.Properties)); + + test.done(); + }, + + 'encryption'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + encrypted: true, + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + Encrypted: true, + }, ResourcePart.Properties)); + + test.done(); + }, + + 'encryption with kms'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const encryptionKey = new kms.Key(stack, 'Key'); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + encrypted: true, + encryptionKey, + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + Encrypted: true, + KmsKeyId: { + 'Fn::GetAtt': [ + 'Key961B73FD', + 'Arn', + ], + }, + }, ResourcePart.Properties)); + cdkExpect(stack).to(haveResourceLike('AWS::KMS::Key', { + KeyPolicy: { + Statement: [ + {}, + { + Effect: 'Allow', + Principal: { + AWS: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':iam::', + { + Ref: 'AWS::AccountId', + }, + ':root', + ], + ], + }, + }, + Resource: '*', + Action: [ + 'kms:DescribeKey', + 'kms:GenerateDataKeyWithoutPlainText', + ], + Condition: { + StringEquals: { + 'kms:ViaService': { + 'Fn::Join': [ + '', + [ + 'ec2.', + { + Ref: 'AWS::Region', + }, + '.amazonaws.com', + ], + ], + }, + 'kms:CallerAccount': { + Ref: 'AWS::AccountId', + }, + }, + }, + }, + ], + }, + })); + + test.done(); + }, + + 'encryption with kms from snapshot'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const encryptionKey = new kms.Key(stack, 'Key'); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + encrypted: true, + encryptionKey, + snapshotId: 'snap-1234567890', + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::KMS::Key', { + KeyPolicy: { + Statement: [ + {}, + { + Action: [ + 'kms:DescribeKey', + 'kms:GenerateDataKeyWithoutPlainText', + 'kms:ReEncrypt*', + ], + }, + ], + }, + })); + + test.done(); + }, + + 'iops'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + iops: 500, + volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + Iops: 500, + VolumeType: 'io1', + }, ResourcePart.Properties)); + + test.done(); + }, + + 'multi-attach'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + iops: 500, + volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, + enableMultiAttach: true, + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + MultiAttachEnabled: true, + }, ResourcePart.Properties)); + + test.done(); + }, + + 'snapshotId'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + snapshotId: 'snap-00000000', + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + SnapshotId: 'snap-00000000', + }, ResourcePart.Properties)); + + test.done(); + }, + + 'volume: standard'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + volumeType: EbsDeviceVolumeType.MAGNETIC, + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + VolumeType: 'standard', + }, ResourcePart.Properties)); + + test.done(); + }, + + 'volume: io1'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + VolumeType: 'io1', + }, ResourcePart.Properties)); + + test.done(); + }, + + 'volume: gp2'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + volumeType: EbsDeviceVolumeType.GENERAL_PURPOSE_SSD, + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + VolumeType: 'gp2', + }, ResourcePart.Properties)); + + test.done(); + }, + + 'volume: st1'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + volumeType: EbsDeviceVolumeType.THROUGHPUT_OPTIMIZED_HDD, + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + VolumeType: 'st1', + }, ResourcePart.Properties)); + + test.done(); + }, + + 'volume: sc1'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + volumeType: EbsDeviceVolumeType.COLD_HDD, + }); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + VolumeType: 'sc1', + }, ResourcePart.Properties)); + + test.done(); + }, + + 'grantAttachVolume to any instance'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const role = new Role(stack, 'Role', { assumedBy: new AccountRootPrincipal() }); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + + // WHEN + volume.grantAttachVolume(role); + + // THEN + cdkExpect(stack).to(haveResource('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [{ + Action: 'ec2:AttachVolume', + Effect: 'Allow', + Resource: [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':volume/', + { + Ref: 'VolumeA92988D3', + }, + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':instance/*', + ], + ], + }, + ], + }], + }, + })); + test.done(); + }, + + 'grantAttachVolume to any instance with encryption'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const role = new Role(stack, 'Role', { assumedBy: new AccountRootPrincipal() }); + const encryptionKey = new kms.Key(stack, 'Key'); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + encrypted: true, + encryptionKey, + }); + + // WHEN + volume.grantAttachVolume(role); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::KMS::Key', { + KeyPolicy: { + Statement: [ + {}, + {}, + { + Effect: 'Allow', + Principal: { + AWS: { + 'Fn::GetAtt': [ + 'Role1ABCC5F0', + 'Arn', + ], + }, + }, + Action: 'kms:CreateGrant', + Condition: { + Bool: { + 'kms:GrantIsForAWSResource': true, + }, + StringEquals: { + 'kms:ViaService': { + 'Fn::Join': [ + '', + [ + 'ec2.', + { + Ref: 'AWS::Region', + }, + '.amazonaws.com', + ], + ], + }, + 'kms:GrantConstraintType': 'EncryptionContextSubset', + }, + }, + Resource: '*', + }, + ], + }, + })); + + test.done(); + }, + + 'grantAttachVolume to any instance with KMS.fromKeyArn() encryption'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const role = new Role(stack, 'Role', { assumedBy: new AccountRootPrincipal() }); + const kmsKey = new kms.Key(stack, 'Key'); + // kmsKey policy is not strictly necessary for the test. + // Demonstrating how to properly construct the Key. + const principal = + new kms.ViaServicePrincipal(`ec2.${stack.region}.amazonaws.com`, new AccountRootPrincipal()).withConditions({ + StringEquals: { + 'kms:CallerAccount': stack.account, + }, + }); + kmsKey.grant(principal, + // Describe & Generate are required to be able to create the CMK-encrypted Volume. + 'kms:DescribeKey', + 'kms:GenerateDataKeyWithoutPlainText', + // ReEncrypt is required for when the CMK is rotated. + 'kms:ReEncrypt*', + ); + + const encryptionKey = kms.Key.fromKeyArn(stack, 'KeyArn', kmsKey.keyArn); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + encrypted: true, + encryptionKey, + }); + + // WHEN + volume.grantAttachVolume(role); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [ + {}, + { + Effect: 'Allow', + Action: 'kms:CreateGrant', + Resource: { + 'Fn::GetAtt': [ + 'Key961B73FD', + 'Arn', + ], + }, + Condition: { + Bool: { + 'kms:GrantIsForAWSResource': true, + }, + StringEquals: { + 'kms:ViaService': { + 'Fn::Join': [ + '', + [ + 'ec2.', + { + Ref: 'AWS::Region', + }, + '.amazonaws.com', + ], + ], + }, + 'kms:GrantConstraintType': 'EncryptionContextSubset', + }, + }, + }, + ], + }, + })); + + test.done(); + }, + + 'grantAttachVolume to specific instances'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const role = new Role(stack, 'Role', { assumedBy: new AccountRootPrincipal() }); + const vpc = new Vpc(stack, 'Vpc'); + const instance1 = new Instance(stack, 'Instance1', { + vpc, + instanceType: new InstanceType('t3.small'), + machineImage: MachineImage.latestAmazonLinux({ generation: AmazonLinuxGeneration.AMAZON_LINUX_2 }), + availabilityZone: 'us-east-1a', + }); + const instance2 = new Instance(stack, 'Instance2', { + vpc, + instanceType: new InstanceType('t3.small'), + machineImage: MachineImage.latestAmazonLinux({ generation: AmazonLinuxGeneration.AMAZON_LINUX_2 }), + availabilityZone: 'us-east-1a', + }); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + + // WHEN + volume.grantAttachVolume(role, [instance1, instance2]); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [{ + Action: 'ec2:AttachVolume', + Effect: 'Allow', + Resource: [ + {}, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':instance/', + { + Ref: 'Instance14BC3991D', + }, + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':instance/', + { + Ref: 'Instance255F35265', + }, + ], + ], + }, + ], + }], + }, + })); + + test.done(); + }, + + 'grantAttachVolume to instance self'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new Vpc(stack, 'Vpc'); + const instance = new Instance(stack, 'Instance', { + vpc, + instanceType: new InstanceType('t3.small'), + machineImage: MachineImage.latestAmazonLinux({ generation: AmazonLinuxGeneration.AMAZON_LINUX_2 }), + availabilityZone: 'us-east-1a', + }); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + + // WHEN + volume.grantAttachVolumeByResourceTag(instance.grantPrincipal, [instance]); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [{ + Action: 'ec2:AttachVolume', + Effect: 'Allow', + Resource: [ + {}, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':instance/*', + ], + ], + }, + ], + Condition: { + 'ForAnyValue:StringEquals': { + 'ec2:ResourceTag/VolumeGrantAttach-BD7A9717': 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + }, + }], + }, + })); + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + Tags: [ + { + Key: 'VolumeGrantAttach-BD7A9717', + Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + ], + }, ResourcePart.Properties)); + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Instance', { + Tags: [ + {}, + { + Key: 'VolumeGrantAttach-BD7A9717', + Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + ], + }, ResourcePart.Properties)); + + test.done(); + }, + + 'grantAttachVolume to instance self with suffix'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new Vpc(stack, 'Vpc'); + const instance = new Instance(stack, 'Instance', { + vpc, + instanceType: new InstanceType('t3.small'), + machineImage: MachineImage.latestAmazonLinux({ generation: AmazonLinuxGeneration.AMAZON_LINUX_2 }), + availabilityZone: 'us-east-1a', + }); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + + // WHEN + volume.grantAttachVolumeByResourceTag(instance.grantPrincipal, [instance], 'TestSuffix'); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [{ + Action: 'ec2:AttachVolume', + Effect: 'Allow', + Resource: [ + {}, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':instance/*', + ], + ], + }, + ], + Condition: { + 'ForAnyValue:StringEquals': { + 'ec2:ResourceTag/VolumeGrantAttach-TestSuffix': 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + }, + }], + }, + })); + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + Tags: [ + { + Key: 'VolumeGrantAttach-TestSuffix', + Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + ], + }, ResourcePart.Properties)); + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Instance', { + Tags: [ + {}, + { + Key: 'VolumeGrantAttach-TestSuffix', + Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + ], + }, ResourcePart.Properties)); + + test.done(); + }, + + 'grantDetachVolume to any instance'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const role = new Role(stack, 'Role', { assumedBy: new AccountRootPrincipal() }); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + + // WHEN + volume.grantDetachVolume(role); + + // THEN + cdkExpect(stack).to(haveResource('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [{ + Action: 'ec2:DetachVolume', + Effect: 'Allow', + Resource: [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':volume/', + { + Ref: 'VolumeA92988D3', + }, + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':instance/*', + ], + ], + }, + ], + }], + }, + })); + test.done(); + }, + + 'grantDetachVolume from specific instance'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const role = new Role(stack, 'Role', { assumedBy: new AccountRootPrincipal() }); + const vpc = new Vpc(stack, 'Vpc'); + const instance1 = new Instance(stack, 'Instance1', { + vpc, + instanceType: new InstanceType('t3.small'), + machineImage: MachineImage.latestAmazonLinux({ generation: AmazonLinuxGeneration.AMAZON_LINUX_2 }), + availabilityZone: 'us-east-1a', + }); + const instance2 = new Instance(stack, 'Instance2', { + vpc, + instanceType: new InstanceType('t3.small'), + machineImage: MachineImage.latestAmazonLinux({ generation: AmazonLinuxGeneration.AMAZON_LINUX_2 }), + availabilityZone: 'us-east-1a', + }); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + + // WHEN + volume.grantDetachVolume(role, [instance1, instance2]); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [{ + Action: 'ec2:DetachVolume', + Effect: 'Allow', + Resource: [ + {}, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':instance/', + { + Ref: 'Instance14BC3991D', + }, + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':instance/', + { + Ref: 'Instance255F35265', + }, + ], + ], + }, + ], + }], + }, + })); + + test.done(); + }, + + 'grantDetachVolume from instance self'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new Vpc(stack, 'Vpc'); + const instance = new Instance(stack, 'Instance', { + vpc, + instanceType: new InstanceType('t3.small'), + machineImage: MachineImage.latestAmazonLinux({ generation: AmazonLinuxGeneration.AMAZON_LINUX_2 }), + availabilityZone: 'us-east-1a', + }); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + + // WHEN + volume.grantDetachVolumeByResourceTag(instance.grantPrincipal, [instance]); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [{ + Action: 'ec2:DetachVolume', + Effect: 'Allow', + Resource: [ + {}, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':instance/*', + ], + ], + }, + ], + Condition: { + 'ForAnyValue:StringEquals': { + 'ec2:ResourceTag/VolumeGrantDetach-BD7A9717': 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + }, + }], + }, + })); + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + Tags: [ + { + Key: 'VolumeGrantDetach-BD7A9717', + Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + ], + }, ResourcePart.Properties)); + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Instance', { + Tags: [ + {}, + { + Key: 'VolumeGrantDetach-BD7A9717', + Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + ], + }, ResourcePart.Properties)); + + test.done(); + }, + + 'grantDetachVolume from instance self with suffix'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new Vpc(stack, 'Vpc'); + const instance = new Instance(stack, 'Instance', { + vpc, + instanceType: new InstanceType('t3.small'), + machineImage: MachineImage.latestAmazonLinux({ generation: AmazonLinuxGeneration.AMAZON_LINUX_2 }), + availabilityZone: 'us-east-1a', + }); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + + // WHEN + volume.grantDetachVolumeByResourceTag(instance.grantPrincipal, [instance], 'TestSuffix'); + + // THEN + cdkExpect(stack).to(haveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [{ + Action: 'ec2:DetachVolume', + Effect: 'Allow', + Resource: [ + {}, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':instance/*', + ], + ], + }, + ], + Condition: { + 'ForAnyValue:StringEquals': { + 'ec2:ResourceTag/VolumeGrantDetach-TestSuffix': 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + }, + }], + }, + })); + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', { + Tags: [ + { + Key: 'VolumeGrantDetach-TestSuffix', + Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + ], + }, ResourcePart.Properties)); + cdkExpect(stack).to(haveResourceLike('AWS::EC2::Instance', { + Tags: [ + {}, + { + Key: 'VolumeGrantDetach-TestSuffix', + Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2', + }, + ], + }, ResourcePart.Properties)); + + test.done(); + }, + + 'validation fromVolumeAttributes'(test: Test) { + // GIVEN + let idx: number = 0; + const stack = new cdk.Stack(); + const volume = new Volume(stack, 'Volume', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + + // THEN + test.doesNotThrow(() => { + Volume.fromVolumeAttributes(stack, `Volume${idx++}`, { + volumeId: volume.volumeId, + availabilityZone: volume.availabilityZone, + }); + }); + test.doesNotThrow(() => { + Volume.fromVolumeAttributes(stack, `Volume${idx++}`, { + volumeId: 'vol-0123456789abcdefABCDEF', + availabilityZone: 'us-east-1a', + }); + }); + test.throws(() => { + Volume.fromVolumeAttributes(stack, `Volume${idx++}`, { + volumeId: ' vol-0123456789abcdefABCDEF', // leading invalid character(s) + availabilityZone: 'us-east-1a', + }); + }, Error, '`volumeId` does not match expected pattern. Expected `vol-` (ex: `vol-05abe246af`) or a Token'); + test.throws(() => { + Volume.fromVolumeAttributes(stack, `Volume${idx++}`, { + volumeId: 'vol-0123456789abcdefABCDEF ', // trailing invalid character(s) + availabilityZone: 'us-east-1a', + }); + }, Error, '`volumeId` does not match expected pattern. Expected `vol-` (ex: `vol-05abe246af`) or a Token'); + test.done(); + }, + + 'validation required props'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const key = new kms.Key(stack, 'Key'); + let idx: number = 0; + + // THEN + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + }); + }, Error, 'Must provide at least one of `size` or `snapshotId`'); + test.doesNotThrow(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + }); + test.doesNotThrow(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + snapshotId: 'snap-000000000', + }); + }); + test.doesNotThrow(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + snapshotId: 'snap-000000000', + }); + }); + + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + encryptionKey: key, + }); + }, Error, '`encrypted` must be true when providing an `encryptionKey`.'); + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + encrypted: false, + encryptionKey: key, + }); + }, Error, '`encrypted` must be true when providing an `encryptionKey`.'); + test.doesNotThrow(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + encrypted: true, + encryptionKey: key, + }); + }); + + test.done(); + }, + + 'validation availabilityZone'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const volume = new Volume(stack, 'ForToken', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + let idx: number = 0; + + // THEN + test.doesNotThrow(() => { + // Should not throw if we provide a token for the AZ + new Volume(stack, `Volume${idx++}`, { + availabilityZone: volume.volumeId, + size: cdk.Size.gibibytes(8), + }); + }); + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1', + }); + }, Error, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'Virginia', + }); + }, Error, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: ' us-east-1a', // leading character(s) + }); + }, Error, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a ', // trailing character(s) + }); + }, Error, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); + + test.done(); + }, + + 'validation snapshotId'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const volume = new Volume(stack, 'ForToken', { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(8), + }); + let idx: number = 0; + + // THEN + test.doesNotThrow(() => { + // Should not throw if we provide a Token for the snapshotId + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + snapshotId: volume.volumeId, + }); + }); + test.doesNotThrow(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + snapshotId: 'snap-0123456789abcdefABCDEF', + }); + }); + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + snapshotId: ' snap-1234', // leading extra character(s) + }); + }, Error, '`snapshotId` does match expected pattern. Expected `snap-` (ex: `snap-05abe246af`) or Token'); + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + snapshotId: 'snap-1234 ', // trailing extra character(s) + }); + }, Error, '`snapshotId` does match expected pattern. Expected `snap-` (ex: `snap-05abe246af`) or Token'); + + test.done(); + }, + + 'validation iops'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + let idx: number = 0; + + // THEN + // Test: Type of volume + for (const volumeType of [ + EbsDeviceVolumeType.GENERAL_PURPOSE_SSD, + EbsDeviceVolumeType.THROUGHPUT_OPTIMIZED_HDD, + EbsDeviceVolumeType.COLD_HDD, + EbsDeviceVolumeType.MAGNETIC, + ]) { + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + iops: 100, + volumeType, + }); + }, Error, '`iops` may only be specified if the `volumeType` is `PROVISIONED_IOPS_SSD`/`IO1`'); + } + + // Test: iops in range + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(10), + iops: 99, + volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, + }); + }, Error, '`iops` must be in the range 100 to 64,000, inclusive.'); + test.doesNotThrow(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(10), + iops: 100, + volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, + }); + }); + test.doesNotThrow(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(1300), + iops: 64000, + volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, + }); + }); + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(1300), + iops: 64001, + volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, + }); + }, Error, '`iops` must be in the range 100 to 64,000, inclusive.'); + + // Test: iops ratio + test.doesNotThrow(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(10), + iops: 500, + volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, + }); + }); + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(10), + iops: 501, + volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, + }); + }, Error, '`iops` has a maximum ratio of 50 IOPS/GiB.'); + + test.done(); + }, + + 'validation multi-attach'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + let idx: number = 0; + + // THEN + for (const volumeType of [ + EbsDeviceVolumeType.GENERAL_PURPOSE_SSD, + EbsDeviceVolumeType.THROUGHPUT_OPTIMIZED_HDD, + EbsDeviceVolumeType.COLD_HDD, + EbsDeviceVolumeType.MAGNETIC, + ]) { + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(500), + iops: 100, + enableMultiAttach: true, + volumeType, + }); + }, Error, 'multi-attach is supported exclusively on `PROVISIONED_IOPS_SSD` volumes.'); + } + + test.done(); + }, + + 'validation size in range'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + let idx: number = 0; + + // THEN + for (const testData of [ + [EbsDeviceVolumeType.GENERAL_PURPOSE_SSD, 1, 16000], + [EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, 4, 16000], + [EbsDeviceVolumeType.THROUGHPUT_OPTIMIZED_HDD, 500, 16000], + [EbsDeviceVolumeType.COLD_HDD, 500, 16000], + [EbsDeviceVolumeType.MAGNETIC, 1, 1000], + ]) { + const volumeType = testData[0] as EbsDeviceVolumeType; + const min = testData[1] as number; + const max = testData[2] as number; + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(min - 1), + volumeType, + }); + }, Error, `\`${volumeType}\` volumes must be between ${min} GiB and ${max} GiB in size.`); + test.doesNotThrow(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(min), + volumeType, + }); + }); + test.doesNotThrow(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(max), + volumeType, + }); + }); + test.throws(() => { + new Volume(stack, `Volume${idx++}`, { + availabilityZone: 'us-east-1a', + size: cdk.Size.gibibytes(max + 1), + volumeType, + }); + }, Error, `\`${volumeType}\` volumes must be between ${min} GiB and ${max} GiB in size.`); + } + + test.done(); + }, + +}; \ No newline at end of file From 127547a8d64c25fef7c330abee06fd890354afec Mon Sep 17 00:00:00 2001 From: Pahud Hsieh Date: Fri, 26 Jun 2020 22:08:01 +0800 Subject: [PATCH 16/55] feat(efs): Filesystem.addAccessPoint() (#8737) feat(efs): addAccessPoint() support for efs FileSystem ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-efs/README.md | 6 ++---- packages/@aws-cdk/aws-efs/lib/access-point.ts | 21 ++++++++++++------- .../@aws-cdk/aws-efs/lib/efs-file-system.ts | 11 ++++++++++ .../aws-efs/test/access-point.test.ts | 9 +++++++- .../aws-efs/test/integ.efs.expected.json | 2 +- packages/@aws-cdk/aws-efs/test/integ.efs.ts | 7 +++---- 6 files changed, 38 insertions(+), 18 deletions(-) diff --git a/packages/@aws-cdk/aws-efs/README.md b/packages/@aws-cdk/aws-efs/README.md index ec2ff3352755a..01d766117a6b1 100644 --- a/packages/@aws-cdk/aws-efs/README.md +++ b/packages/@aws-cdk/aws-efs/README.md @@ -45,12 +45,10 @@ and group override any identity information provided by the NFS client. The file access point's root directory. Applications using the access point can only access data in its own directory and below. To learn more, see [Mounting a File System Using EFS Access Points](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html). -Use `AccessPoint` to create an access point: +Use `addAccessPoint` to create an access point from a fileSystem: ```ts -new AccessPoint(stack, 'AccessPoint', { - fileSystem -}); +fileSystem.addAccessPoint('AccessPoint'); ``` By default, when you create an access point, the root(`/`) directory is exposed to the client connecting to diff --git a/packages/@aws-cdk/aws-efs/lib/access-point.ts b/packages/@aws-cdk/aws-efs/lib/access-point.ts index 39c9fabb68a04..6fd4b6e927bce 100644 --- a/packages/@aws-cdk/aws-efs/lib/access-point.ts +++ b/packages/@aws-cdk/aws-efs/lib/access-point.ts @@ -65,14 +65,9 @@ export interface PosixUser { } /** - * Properties for the AccessPoint + * Options to create an AccessPoint */ -export interface AccessPointProps { - /** - * The efs filesystem - */ - readonly fileSystem: IFileSystem; - +export interface AccessPointOptions { /** * Specifies the POSIX IDs and permissions to apply when creating the access point's root directory. If the * root directory specified by `path` does not exist, EFS creates the root directory and applies the @@ -103,6 +98,16 @@ export interface AccessPointProps { readonly posixUser?: PosixUser; } +/** + * Properties for the AccessPoint + */ +export interface AccessPointProps extends AccessPointOptions { + /** + * The efs filesystem + */ + readonly fileSystem: IFileSystem; +} + /** * Represents the AccessPoint */ @@ -137,7 +142,7 @@ export class AccessPoint extends Resource implements IAccessPoint { constructor(scope: Construct, id: string, props: AccessPointProps) { super(scope, id); - const resource = new CfnAccessPoint(scope, 'Resource', { + const resource = new CfnAccessPoint(this, 'Resource', { fileSystemId: props.fileSystem.fileSystemId, rootDirectory: { creationInfo: props.createAcl ? { diff --git a/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts b/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts index aa42acb2b6372..35c6ef381a8d5 100644 --- a/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts +++ b/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts @@ -1,6 +1,7 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as kms from '@aws-cdk/aws-kms'; import { Construct, IResource, RemovalPolicy, Resource, Size, Tag } from '@aws-cdk/core'; +import { AccessPoint, AccessPointOptions } from './access-point'; import { CfnFileSystem, CfnMountTarget } from './efs.generated'; // tslint:disable:max-line-length @@ -272,4 +273,14 @@ export class FileSystem extends Resource implements IFileSystem { }); }); } + + /** + * create access point from this filesystem + */ + public addAccessPoint(id: string, accessPointOptions: AccessPointOptions = {}): AccessPoint { + return new AccessPoint(this, id, { + fileSystem: this, + ...accessPointOptions, + }); + } } diff --git a/packages/@aws-cdk/aws-efs/test/access-point.test.ts b/packages/@aws-cdk/aws-efs/test/access-point.test.ts index 6b7343b1e5f52..761594507c779 100644 --- a/packages/@aws-cdk/aws-efs/test/access-point.test.ts +++ b/packages/@aws-cdk/aws-efs/test/access-point.test.ts @@ -15,7 +15,14 @@ beforeEach(() => { }); }); -test('default access point is created correctly', () => { +test('addAccessPoint correctly', () => { + // WHEN + fileSystem.addAccessPoint('MyAccessPoint'); + // THEN + expectCDK(stack).to(haveResource('AWS::EFS::AccessPoint')); +}); + +test('new AccessPoint correctly', () => { // WHEN new AccessPoint(stack, 'MyAccessPoint', { fileSystem, diff --git a/packages/@aws-cdk/aws-efs/test/integ.efs.expected.json b/packages/@aws-cdk/aws-efs/test/integ.efs.expected.json index f5eeff3153703..8c1fa47948791 100644 --- a/packages/@aws-cdk/aws-efs/test/integ.efs.expected.json +++ b/packages/@aws-cdk/aws-efs/test/integ.efs.expected.json @@ -542,7 +542,7 @@ } } }, - "Resource": { + "FileSystemAccessPointF8178182": { "Type": "AWS::EFS::AccessPoint", "Properties": { "FileSystemId": { diff --git a/packages/@aws-cdk/aws-efs/test/integ.efs.ts b/packages/@aws-cdk/aws-efs/test/integ.efs.ts index 3906e374b8130..0afad3e6f4a29 100644 --- a/packages/@aws-cdk/aws-efs/test/integ.efs.ts +++ b/packages/@aws-cdk/aws-efs/test/integ.efs.ts @@ -1,6 +1,6 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as cdk from '@aws-cdk/core'; -import { AccessPoint, FileSystem } from '../lib'; +import { FileSystem } from '../lib'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'test-efs-integ'); @@ -11,8 +11,7 @@ const fileSystem = new FileSystem(stack, 'FileSystem', { vpc, }); -new AccessPoint(stack, 'AccessPoint', { - fileSystem, +fileSystem.addAccessPoint('AccessPoint', { createAcl: { ownerGid: '1000', ownerUid: '1000', @@ -23,4 +22,4 @@ new AccessPoint(stack, 'AccessPoint', { gid: '1000', uid: '1000', }, -}); +}); \ No newline at end of file From fa4196b11a4b843af1401cbcfd3fe075986ec5c0 Mon Sep 17 00:00:00 2001 From: Romain Marcadier Date: Fri, 26 Jun 2020 16:25:57 +0200 Subject: [PATCH 17/55] feat(cli): support multiple verbosity levels (#8749) Adds support for a "trace" verbosity level (achieved by passing `--verbose` or `-v` multiple times); and use this new verbosity for the AWS SDK logging, which is otherwise a little too present. --- packages/aws-cdk/bin/cdk.ts | 9 ++++---- packages/aws-cdk/lib/api/aws-auth/sdk.ts | 4 ++-- .../cloudformation/stack-activity-monitor.ts | 22 +++++++++---------- packages/aws-cdk/lib/logging.ts | 22 +++++++++++++++---- packages/aws-cdk/test/api/exec.test.ts | 8 ++++--- .../aws-cdk/test/api/sdk-provider.test.ts | 7 ++++-- 6 files changed, 46 insertions(+), 26 deletions(-) diff --git a/packages/aws-cdk/bin/cdk.ts b/packages/aws-cdk/bin/cdk.ts index b30b6346ada84..c40c914714187 100644 --- a/packages/aws-cdk/bin/cdk.ts +++ b/packages/aws-cdk/bin/cdk.ts @@ -13,7 +13,7 @@ import { execProgram } from '../lib/api/cxapp/exec'; import { CdkToolkit } from '../lib/cdk-toolkit'; import { RequireApproval } from '../lib/diff'; import { availableInitLanguages, cliInit, printAvailableTemplates } from '../lib/init'; -import { data, debug, error, setVerbose } from '../lib/logging'; +import { data, debug, error, setLogLevel } from '../lib/logging'; import { PluginHost } from '../lib/plugin'; import { serializeStructure } from '../lib/serialize'; import { Configuration, Settings } from '../lib/settings'; @@ -45,7 +45,8 @@ async function parseCommandLineArguments() { .option('strict', { type: 'boolean', desc: 'Do not construct stacks with warnings' }) .option('ignore-errors', { type: 'boolean', default: false, desc: 'Ignores synthesis errors, which will likely produce an invalid output' }) .option('json', { type: 'boolean', alias: 'j', desc: 'Use JSON output instead of YAML when templates are printed to STDOUT', default: false }) - .option('verbose', { type: 'boolean', alias: 'v', desc: 'Show debug logs', default: false }) + .option('verbose', { type: 'boolean', alias: 'v', desc: 'Show debug logs (specify multiple times to increase verbosity)', default: false }) + .count('verbose') .option('profile', { type: 'string', desc: 'Use the indicated AWS profile as the default environment', requiresArg: true }) .option('proxy', { type: 'string', desc: 'Use the indicated proxy. Will read from HTTPS_PROXY environment variable if not specified.', requiresArg: true }) .option('ca-bundle-path', { type: 'string', desc: 'Path to CA certificate to use when validating HTTPS requests. Will read from AWS_CA_BUNDLE environment variable if not specified.', requiresArg: true }) @@ -122,7 +123,7 @@ if (!process.stdout.isTTY) { async function initCommandLine() { const argv = await parseCommandLineArguments(); if (argv.verbose) { - setVerbose(); + setLogLevel(argv.verbose); } debug('CDK toolkit version:', version.DISPLAY_VERSION); debug('Command line arguments:', argv); @@ -203,7 +204,7 @@ async function initCommandLine() { const cli = new CdkToolkit({ cloudExecutable, cloudFormation, - verbose: argv.trace || argv.verbose, + verbose: argv.trace || argv.verbose > 0, ignoreErrors: argv['ignore-errors'], strict: argv.strict, configuration, diff --git a/packages/aws-cdk/lib/api/aws-auth/sdk.ts b/packages/aws-cdk/lib/api/aws-auth/sdk.ts index 871b36c6002d3..d735231836e27 100644 --- a/packages/aws-cdk/lib/api/aws-auth/sdk.ts +++ b/packages/aws-cdk/lib/api/aws-auth/sdk.ts @@ -1,6 +1,6 @@ import * as AWS from 'aws-sdk'; import { ConfigurationOptions } from 'aws-sdk/lib/config'; -import { debug } from '../../logging'; +import { debug, trace } from '../../logging'; import { cached } from '../../util/functions'; import { AccountAccessKeyCache } from './account-cache'; import { Account } from './sdk-provider'; @@ -60,7 +60,7 @@ export class SDK implements ISDK { ...this.retryOptions, credentials, region, - logger: { log: (...messages) => messages.forEach(m => debug('%s', m)) }, + logger: { log: (...messages) => messages.forEach(m => trace('%s', m)) }, }; this.currentRegion = region; } diff --git a/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts b/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts index c1ac8a8194120..7df4680c7fb3c 100644 --- a/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts +++ b/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts @@ -3,7 +3,7 @@ import * as cxapi from '@aws-cdk/cx-api'; import * as aws from 'aws-sdk'; import * as colors from 'colors/safe'; import * as util from 'util'; -import { error, isVerbose, setVerbose } from '../../../logging'; +import { error, logLevel, LogLevel, setLogLevel } from '../../../logging'; import { RewritableBlock } from '../display'; interface StackActivity { @@ -28,13 +28,13 @@ export interface StackActivityMonitorProps { readonly resourcesTotal?: number; /** - * Whether 'verbose' was requested in the CLI + * The log level that was requested in the CLI * - * If verbose is requested, we'll always use the full history printer. + * If verbose or trace is requested, we'll always use the full history printer. * - * @default - Use value from logging.isVerbose + * @default - Use value from logging.logLevel */ - readonly verbose?: boolean; + readonly logLevel?: LogLevel; } export class StackActivityMonitor { @@ -78,7 +78,7 @@ export class StackActivityMonitor { }; const isWindows = process.platform === 'win32'; - const verbose = options.verbose ?? isVerbose; + const verbose = options.logLevel ?? logLevel; const fancyOutputAvailable = !isWindows && stream.isTTY; this.printer = fancyOutputAvailable && !verbose @@ -479,7 +479,7 @@ export class CurrentActivityPrinter extends ActivityPrinterBase { */ public readonly updateSleep: number = 2_000; - private oldVerbose: boolean = false; + private oldLogLevel: LogLevel = LogLevel.DEFAULT; private block = new RewritableBlock(this.stream); constructor(props: PrinterProps) { @@ -520,12 +520,12 @@ export class CurrentActivityPrinter extends ActivityPrinterBase { public start() { // Need to prevent the waiter from printing 'stack not stable' every 5 seconds, it messes // with the output calculations. - this.oldVerbose = isVerbose; - setVerbose(false); + this.oldLogLevel = logLevel; + setLogLevel(LogLevel.DEFAULT); } public stop() { - setVerbose(this.oldVerbose); + setLogLevel(this.oldLogLevel); // Print failures at the end const lines = new Array(); @@ -623,4 +623,4 @@ function shorten(maxWidth: number, p: string) { } const TIMESTAMP_WIDTH = 12; -const STATUS_WIDTH = 20; \ No newline at end of file +const STATUS_WIDTH = 20; diff --git a/packages/aws-cdk/lib/logging.ts b/packages/aws-cdk/lib/logging.ts index 5c23131d1a451..b85881886a84f 100644 --- a/packages/aws-cdk/lib/logging.ts +++ b/packages/aws-cdk/lib/logging.ts @@ -13,15 +13,20 @@ const logger = (stream: Writable, styles?: StyleFn[]) => (fmt: string, ...args: stream.write(str + '\n'); }; -export let isVerbose = false; +export let logLevel = LogLevel.DEFAULT; -export function setVerbose(enabled = true) { - isVerbose = enabled; +export function setLogLevel(newLogLevel: LogLevel) { + logLevel = newLogLevel; +} + +export function increaseVerbosity() { + logLevel += 1; } const _debug = logger(stderr, [colors.gray]); -export const debug = (fmt: string, ...args: any[]) => isVerbose && _debug(fmt, ...args); +export const trace = (fmt: string, ...args: any) => logLevel >= LogLevel.TRACE && _debug(fmt, ...args); +export const debug = (fmt: string, ...args: any[]) => logLevel >= LogLevel.DEBUG && _debug(fmt, ...args); export const error = logger(stderr, [colors.red]); export const warning = logger(stderr, [colors.yellow]); export const success = logger(stderr, [colors.green]); @@ -42,3 +47,12 @@ export type LoggerFunction = (fmt: string, ...args: any[]) => void; export function prefix(prefixString: string, fn: LoggerFunction): LoggerFunction { return (fmt: string, ...args: any[]) => fn(`%s ${fmt}`, prefixString, ...args); } + +export const enum LogLevel { + /** Not verbose at all */ + DEFAULT = 0, + /** Pretty verbose */ + DEBUG = 1, + /** Extremely verbose */ + TRACE = 2 +} diff --git a/packages/aws-cdk/test/api/exec.test.ts b/packages/aws-cdk/test/api/exec.test.ts index ec653da6d6a77..13c5cf9a5f222 100644 --- a/packages/aws-cdk/test/api/exec.test.ts +++ b/packages/aws-cdk/test/api/exec.test.ts @@ -5,18 +5,18 @@ import * as semver from 'semver'; import * as sinon from 'sinon'; import { ImportMock } from 'ts-mock-imports'; import { execProgram } from '../../lib/api/cxapp/exec'; -import { setVerbose } from '../../lib/logging'; +import { LogLevel, setLogLevel } from '../../lib/logging'; import { Configuration } from '../../lib/settings'; import * as bockfs from '../bockfs'; import { testAssembly } from '../util'; import { mockSpawn } from '../util/mock-child_process'; import { MockSdkProvider } from '../util/mock-sdk'; -setVerbose(true); - let sdkProvider: MockSdkProvider; let config: Configuration; beforeEach(() => { + setLogLevel(LogLevel.DEBUG); + sdkProvider = new MockSdkProvider(); config = new Configuration(); @@ -34,6 +34,8 @@ beforeEach(() => { }); afterEach(() => { + setLogLevel(LogLevel.DEFAULT); + sinon.restore(); bockfs.restore(); }); diff --git a/packages/aws-cdk/test/api/sdk-provider.test.ts b/packages/aws-cdk/test/api/sdk-provider.test.ts index 6e6a4f91511c4..0d50a3936053c 100644 --- a/packages/aws-cdk/test/api/sdk-provider.test.ts +++ b/packages/aws-cdk/test/api/sdk-provider.test.ts @@ -9,7 +9,6 @@ import * as logging from '../../lib/logging'; import * as bockfs from '../bockfs'; SDKMock.setSDKInstance(AWS); -logging.setVerbose(true); type AwsCallback = (err: Error | null, val: T) => void; @@ -26,6 +25,8 @@ let defaultEnv: cxapi.Environment; beforeEach(() => { uid = `(${uuid.v4()})`; + logging.setLogLevel(logging.LogLevel.TRACE); + bockfs({ '/home/me/.bxt/credentials': dedent(` [default] @@ -98,6 +99,8 @@ beforeEach(() => { }); afterEach(() => { + logging.setLogLevel(logging.LogLevel.DEFAULT); + SDKMock.restore(); bockfs.restore(); }); @@ -264,4 +267,4 @@ function commonPrefix(a: string, b: string): string { if (a[i] !== b[i]) { return a.substring(0, i); } } return a.substr(N); -} \ No newline at end of file +} From 53c359a06d17d20a645d14d6cd3ff79e80820b83 Mon Sep 17 00:00:00 2001 From: Romain Marcadier Date: Fri, 26 Jun 2020 16:43:04 +0200 Subject: [PATCH 18/55] docs: tweak docstring for ServiceProps.namespace (#8756) It used to confusingly indicate it represents a namespace ID, whereas a whole `INamespace` is expected. --- packages/@aws-cdk/aws-servicediscovery/lib/service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-servicediscovery/lib/service.ts b/packages/@aws-cdk/aws-servicediscovery/lib/service.ts index f81d9fd043376..c41625bf68a7e 100644 --- a/packages/@aws-cdk/aws-servicediscovery/lib/service.ts +++ b/packages/@aws-cdk/aws-servicediscovery/lib/service.ts @@ -123,7 +123,7 @@ export interface DnsServiceProps extends BaseServiceProps { export interface ServiceProps extends DnsServiceProps { /** - * The ID of the namespace that you want to use for DNS configuration. + * The namespace that you want to use for DNS configuration. */ readonly namespace: INamespace; } From 88f8e1e9475c66114796dd2840c67a3f4e11f57f Mon Sep 17 00:00:00 2001 From: Romain Marcadier Date: Fri, 26 Jun 2020 17:54:03 +0200 Subject: [PATCH 19/55] fix(cli): unable to use "legacy" bootstrap with --public-access-block-configuration=false (#8755) Fixes an invalid CloudFormation template generated for the legacy bootstrap stack when opting out of the S3 public access blocking configuration. Fixes #8728 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/lib/api/bootstrap/legacy-template.ts | 2 +- .../aws-cdk/test/integ/cli/bootstrapping.integtest.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk/lib/api/bootstrap/legacy-template.ts b/packages/aws-cdk/lib/api/bootstrap/legacy-template.ts index 67bed3406b07a..0b98ea3a3fbe2 100644 --- a/packages/aws-cdk/lib/api/bootstrap/legacy-template.ts +++ b/packages/aws-cdk/lib/api/bootstrap/legacy-template.ts @@ -33,7 +33,7 @@ export function legacyBootstrapTemplate(params: BootstrappingParameters): any { IgnorePublicAcls: true, RestrictPublicBuckets: true, }, - 'AWS::NoValue', + { Ref: 'AWS::NoValue' }, ]}, }, }, diff --git a/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts b/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts index 93f9a0974aa2a..7c7947acdcae6 100644 --- a/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts +++ b/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts @@ -152,6 +152,17 @@ integTest('deploying new style synthesis to old style bootstrap fails', async () })).rejects.toThrow('exited with error'); }); +integTest('can create a legacy bootstrap stack with --public-access-block-configuration=false', async () => { + const bootstrapStackName = fullStackName('bootstrap-stack-1'); + + await cdk(['bootstrap', '-v', '--toolkit-stack-name', bootstrapStackName, '--public-access-block-configuration', 'false', '--tags', 'Foo=Bar']); + + const response = await cloudFormation('describeStacks', { StackName: bootstrapStackName }); + expect(response.Stacks?.[0].Tags).toEqual([ + { Key: 'Foo', Value: 'Bar' }, + ]); +}); + integTest('can create multiple legacy bootstrap stacks', async () => { const bootstrapStackName1 = fullStackName('bootstrap-stack-1'); const bootstrapStackName2 = fullStackName('bootstrap-stack-2'); From d2ae4bc35b6d79262da037d431e321c77e178524 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2020 19:31:33 +0000 Subject: [PATCH 20/55] chore(deps): bump aws-sdk from 2.705.0 to 2.706.0 (#8758) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.705.0 to 2.706.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.705.0...v2.706.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-cloudfront/package.json | 2 +- packages/@aws-cdk/aws-cloudtrail/package.json | 2 +- packages/@aws-cdk/aws-codebuild/package.json | 2 +- packages/@aws-cdk/aws-codecommit/package.json | 2 +- packages/@aws-cdk/aws-dynamodb/package.json | 2 +- packages/@aws-cdk/aws-eks/package.json | 2 +- packages/@aws-cdk/aws-events-targets/package.json | 2 +- packages/@aws-cdk/aws-lambda/package.json | 2 +- packages/@aws-cdk/aws-route53/package.json | 2 +- packages/@aws-cdk/aws-sqs/package.json | 2 +- packages/@aws-cdk/custom-resources/package.json | 2 +- packages/aws-cdk/package.json | 2 +- packages/cdk-assets/package.json | 2 +- yarn.lock | 8 ++++---- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudfront/package.json b/packages/@aws-cdk/aws-cloudfront/package.json index dc2ec48ec8753..9daff3e256225 100644 --- a/packages/@aws-cdk/aws-cloudfront/package.json +++ b/packages/@aws-cdk/aws-cloudfront/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-cloudtrail/package.json b/packages/@aws-cdk/aws-cloudtrail/package.json index 531fd7e131986..158b50fc11d40 100644 --- a/packages/@aws-cdk/aws-cloudtrail/package.json +++ b/packages/@aws-cdk/aws-cloudtrail/package.json @@ -64,7 +64,7 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/assert": "0.0.0", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codebuild/package.json b/packages/@aws-cdk/aws-codebuild/package.json index f66eab3b0f48a..a3ebadc8e8cee 100644 --- a/packages/@aws-cdk/aws-codebuild/package.json +++ b/packages/@aws-cdk/aws-codebuild/package.json @@ -70,7 +70,7 @@ "@aws-cdk/aws-sns": "0.0.0", "@aws-cdk/aws-sqs": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codecommit/package.json b/packages/@aws-cdk/aws-codecommit/package.json index a3f357f2b8c87..1fb64aef65eaf 100644 --- a/packages/@aws-cdk/aws-codecommit/package.json +++ b/packages/@aws-cdk/aws-codecommit/package.json @@ -70,7 +70,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-dynamodb/package.json b/packages/@aws-cdk/aws-dynamodb/package.json index 58b72c7b4fb6d..833c699d5d80e 100644 --- a/packages/@aws-cdk/aws-dynamodb/package.json +++ b/packages/@aws-cdk/aws-dynamodb/package.json @@ -65,7 +65,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/jest": "^26.0.3", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index 26d7dfdb65bc6..e4cc3e8273dfb 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-events-targets/package.json b/packages/@aws-cdk/aws-events-targets/package.json index 57defe0356aee..01ab709164870 100644 --- a/packages/@aws-cdk/aws-events-targets/package.json +++ b/packages/@aws-cdk/aws-events-targets/package.json @@ -68,7 +68,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-codecommit": "0.0.0", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index ab331d92e4d5c..58f01292c28d3 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -71,7 +71,7 @@ "@types/lodash": "^4.14.157", "@types/nodeunit": "^0.0.31", "@types/sinon": "^9.0.4", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-route53/package.json b/packages/@aws-cdk/aws-route53/package.json index 9c7d9198b8806..b6d65266506ec 100644 --- a/packages/@aws-cdk/aws-route53/package.json +++ b/packages/@aws-cdk/aws-route53/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-sqs/package.json b/packages/@aws-cdk/aws-sqs/package.json index 3af1a42030c88..ebc4924d0ce86 100644 --- a/packages/@aws-cdk/aws-sqs/package.json +++ b/packages/@aws-cdk/aws-sqs/package.json @@ -65,7 +65,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index a909dd267ea5d..00a82b3853228 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -73,7 +73,7 @@ "@types/aws-lambda": "^8.10.39", "@types/fs-extra": "^8.1.0", "@types/sinon": "^9.0.4", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 89818ce157219..886b797adf972 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -71,7 +71,7 @@ "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/region-info": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "camelcase": "^6.0.0", "cdk-assets": "0.0.0", "colors": "^1.4.0", diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index 616082c289000..138a686cc6afb 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -47,7 +47,7 @@ "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.705.0", + "aws-sdk": "^2.706.0", "glob": "^7.1.6", "yargs": "^15.3.1" }, diff --git a/yarn.lock b/yarn.lock index 3ddfd97af1499..6bd8e24a21c4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2124,10 +2124,10 @@ aws-sdk-mock@^5.1.0: sinon "^9.0.1" traverse "^0.6.6" -aws-sdk@^2.637.0, aws-sdk@^2.705.0: - version "2.705.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.705.0.tgz#6c42851f0efdfe2685eb2dab72740a01742468bd" - integrity sha512-eD3YD3UgCdFIYlkAVYW1rbriKSNHm7nsZbYsBuo91pbyq4XYT56w2oTyNECorYPoq//Y4LQTTx8cbOuEjsNi3w== +aws-sdk@^2.637.0, aws-sdk@^2.706.0: + version "2.706.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.706.0.tgz#09f65e9a91ecac5a635daf934082abae30eca953" + integrity sha512-7GT+yrB5Wb/zOReRdv/Pzkb2Qt+hz6B/8FGMVaoysX3NryHvQUdz7EQWi5yhg9CxOjKxdw5lFwYSs69YlSp1KA== dependencies: buffer "4.9.2" events "1.1.1" From 87e265114590d8fcc69e18b42d777b8ca201307c Mon Sep 17 00:00:00 2001 From: Bryan Pan Date: Fri, 26 Jun 2020 16:38:57 -0700 Subject: [PATCH 21/55] fix(route53-targets): A/AAAA Alias Record to ELB cannot resolve IPv6 addresses (#8747) **[ISSUE]** Route53 A/AAAA Alias Record created by CDK didn't add prefix 'dualstack' to the dnsName of ElasticLoadBalancer as suggested in [documentation](https://aws.amazon.com/de/premiumsupport/knowledge-center/alias-resource-record-set-route53-cli/), resulting in inability to resolve IPv6 records (outcome consistent with these [docs](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-internet-facing-load-balancers.html)). **[APPROACH]** Joined prefix: _dualstack_ to DNS of ELB targets to resolve IPv6 records. Example: > If ELB DNS name is `ALB-xxxxxxxx.us-west-2.elb.amazonaws.com`, > Route53 A/AAAA Alias Record will create Alias Target `dualstack.ALB-xxxxxxxx.us-west-2.elb.amazonaws.com` **[NOTE]** Ignoring the case of using `ApiGatewayDomain(domainName)` because the prefix of 'dualstack' should be added in the `domainName` parameter. ``` new route53.ARecord(this, 'AliasRecord', { zone, target: route53.RecordTarget.fromAlias(new alias.ApiGatewayDomain(domainName)), }); ``` If creating an ApiGatewayDomain for ELB, endpoint for ELB with prefix 'dualstack' should be declared there, not within route53 package. Fixes #6271 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-ecs-patterns/test/ec2/test.l3s.ts | 4 ++-- ...eg.load-balanced-fargate-service.expected.json | 15 ++++++++++++--- packages/@aws-cdk/aws-route53-targets/README.md | 11 ++++++++--- .../lib/classic-load-balancer-target.ts | 2 +- .../lib/load-balancer-target.ts | 2 +- .../test/classic-load-balancer-target.test.ts | 2 +- .../test/integ.alb-alias-target.expected.json | 14 +++++++++++--- .../test/load-balancer-target.test.ts | 2 +- 8 files changed, 37 insertions(+), 15 deletions(-) diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/ec2/test.l3s.ts b/packages/@aws-cdk/aws-ecs-patterns/test/ec2/test.l3s.ts index 17693856ed8fd..09f786c2ea760 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/ec2/test.l3s.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/ec2/test.l3s.ts @@ -436,7 +436,7 @@ export = { Type: 'A', AliasTarget: { HostedZoneId: { 'Fn::GetAtt': ['ServiceLBE9A1ADBC', 'CanonicalHostedZoneID'] }, - DNSName: { 'Fn::GetAtt': ['ServiceLBE9A1ADBC', 'DNSName'] }, + DNSName: { 'Fn::Join': ['', [ 'dualstack.', { 'Fn::GetAtt': ['ServiceLBE9A1ADBC', 'DNSName'] } ] ] }, }, })); @@ -501,7 +501,7 @@ export = { Type: 'A', AliasTarget: { HostedZoneId: { 'Fn::GetAtt': ['ServiceLBE9A1ADBC', 'CanonicalHostedZoneID'] }, - DNSName: { 'Fn::GetAtt': ['ServiceLBE9A1ADBC', 'DNSName'] }, + DNSName: { 'Fn::Join': [ '', [ 'dualstack.', { 'Fn::GetAtt': ['ServiceLBE9A1ADBC', 'DNSName'] } ] ] }, }, })); diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.load-balanced-fargate-service.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.load-balanced-fargate-service.expected.json index 3f560edd9c37a..e7434c8e2eafc 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.load-balanced-fargate-service.expected.json +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.load-balanced-fargate-service.expected.json @@ -618,9 +618,18 @@ "Type": "A", "AliasTarget": { "DNSName": { - "Fn::GetAtt": [ - "myServiceLB168895E1", - "DNSName" + "Fn::Join": + [ + "", + [ + "dualstack.", + { + "Fn::GetAtt": [ + "myServiceLB168895E1", + "DNSName" + ] + } + ] ] }, "HostedZoneId": { diff --git a/packages/@aws-cdk/aws-route53-targets/README.md b/packages/@aws-cdk/aws-route53-targets/README.md index e3e8f99a0e5ba..3bd36f68ba46f 100644 --- a/packages/@aws-cdk/aws-route53-targets/README.md +++ b/packages/@aws-cdk/aws-route53-targets/README.md @@ -13,7 +13,7 @@ This library contains Route53 Alias Record targets for: new route53.ARecord(this, 'AliasRecord', { zone, target: route53.RecordTarget.fromAlias(new alias.ApiGateway(restApi)), - // or - route53.RecordTarget.fromAlias(new alias.ApiGatewayDomainName(domainName)), + // or - route53.RecordTarget.fromAlias(new alias.ApiGatewayDomain(domainName)), }); ``` * CloudFront distributions @@ -28,7 +28,7 @@ This library contains Route53 Alias Record targets for: new route53.ARecord(this, 'AliasRecord', { zone, target: route53.RecordTarget.fromAlias(new alias.LoadBalancerTarget(elbv2)), - // or - route53.RecordTarget.fromAlias(new alias.ApiGatewayDomainName(domainName)), + // or - route53.RecordTarget.fromAlias(new alias.ApiGatewayDomain(domainName)), }); ``` * Classic load balancers @@ -36,9 +36,14 @@ This library contains Route53 Alias Record targets for: new route53.ARecord(this, 'AliasRecord', { zone, target: route53.RecordTarget.fromAlias(new alias.ClassicLoadBalancerTarget(elb)), - // or - route53.RecordTarget.fromAlias(new alias.ApiGatewayDomainName(domainName)), + // or - route53.RecordTarget.fromAlias(new alias.ApiGatewayDomain(domainName)), }); ``` + +**Important:** Based on [AWS documentation](https://aws.amazon.com/de/premiumsupport/knowledge-center/alias-resource-record-set-route53-cli/), all alias record in Route 53 that points to a Elastic Load Balancer will always include *dualstack* for the DNSName to resolve IPv4/IPv6 addresses (without *dualstack* IPv6 will not resolve). + +For example, if the Amazon-provided DNS for the load balancer is `ALB-xxxxxxx.us-west-2.elb.amazonaws.com`, CDK will create alias target in Route 53 will be `dualstack.ALB-xxxxxxx.us-west-2.elb.amazonaws.com`. + * InterfaceVpcEndpoints **Important:** Based on the CFN docs for VPCEndpoints - [see here](attrDnsEntries) - the attributes returned for DnsEntries in CloudFormation is a combination of the hosted zone ID and the DNS name. The entries are ordered as follows: regional public DNS, zonal public DNS, private DNS, and wildcard DNS. This order is not enforced for AWS Marketplace services, and therefore this CDK construct is ONLY guaranteed to work with non-marketplace services. diff --git a/packages/@aws-cdk/aws-route53-targets/lib/classic-load-balancer-target.ts b/packages/@aws-cdk/aws-route53-targets/lib/classic-load-balancer-target.ts index 076c390e8f704..8b25fbe4f331e 100644 --- a/packages/@aws-cdk/aws-route53-targets/lib/classic-load-balancer-target.ts +++ b/packages/@aws-cdk/aws-route53-targets/lib/classic-load-balancer-target.ts @@ -11,7 +11,7 @@ export class ClassicLoadBalancerTarget implements route53.IAliasRecordTarget { public bind(_record: route53.IRecordSet): route53.AliasRecordTargetConfig { return { hostedZoneId: this.loadBalancer.loadBalancerCanonicalHostedZoneNameId, - dnsName: this.loadBalancer.loadBalancerDnsName, + dnsName: `dualstack.${this.loadBalancer.loadBalancerDnsName}`, }; } } diff --git a/packages/@aws-cdk/aws-route53-targets/lib/load-balancer-target.ts b/packages/@aws-cdk/aws-route53-targets/lib/load-balancer-target.ts index c8902b98c0daa..d398256c57f8b 100644 --- a/packages/@aws-cdk/aws-route53-targets/lib/load-balancer-target.ts +++ b/packages/@aws-cdk/aws-route53-targets/lib/load-balancer-target.ts @@ -11,7 +11,7 @@ export class LoadBalancerTarget implements route53.IAliasRecordTarget { public bind(_record: route53.IRecordSet): route53.AliasRecordTargetConfig { return { hostedZoneId: this.loadBalancer.loadBalancerCanonicalHostedZoneId, - dnsName: this.loadBalancer.loadBalancerDnsName, + dnsName: `dualstack.${this.loadBalancer.loadBalancerDnsName}`, }; } } diff --git a/packages/@aws-cdk/aws-route53-targets/test/classic-load-balancer-target.test.ts b/packages/@aws-cdk/aws-route53-targets/test/classic-load-balancer-target.test.ts index 6aea222305741..59e9326e7b23e 100644 --- a/packages/@aws-cdk/aws-route53-targets/test/classic-load-balancer-target.test.ts +++ b/packages/@aws-cdk/aws-route53-targets/test/classic-load-balancer-target.test.ts @@ -28,7 +28,7 @@ test('use classic ELB as record target', () => { // THEN expect(stack).toHaveResource('AWS::Route53::RecordSet', { AliasTarget: { - DNSName: { 'Fn::GetAtt': [ 'LB8A12904C', 'DNSName' ] }, + DNSName: { 'Fn::Join': [ '', [ 'dualstack.', { 'Fn::GetAtt': [ 'LB8A12904C', 'DNSName' ] } ] ] }, HostedZoneId: { 'Fn::GetAtt': [ 'LB8A12904C', 'CanonicalHostedZoneNameID' ] }, }, }); diff --git a/packages/@aws-cdk/aws-route53-targets/test/integ.alb-alias-target.expected.json b/packages/@aws-cdk/aws-route53-targets/test/integ.alb-alias-target.expected.json index 828c0d7f4b6a5..746f62cc9acc7 100644 --- a/packages/@aws-cdk/aws-route53-targets/test/integ.alb-alias-target.expected.json +++ b/packages/@aws-cdk/aws-route53-targets/test/integ.alb-alias-target.expected.json @@ -413,9 +413,17 @@ "Type": "A", "AliasTarget": { "DNSName": { - "Fn::GetAtt": [ - "LB8A12904C", - "DNSName" + "Fn::Join": [ + "", + [ + "dualstack.", + { + "Fn::GetAtt": [ + "LB8A12904C", + "DNSName" + ] + } + ] ] }, "HostedZoneId": { diff --git a/packages/@aws-cdk/aws-route53-targets/test/load-balancer-target.test.ts b/packages/@aws-cdk/aws-route53-targets/test/load-balancer-target.test.ts index 50ff50a1a122e..396d2d457bb85 100644 --- a/packages/@aws-cdk/aws-route53-targets/test/load-balancer-target.test.ts +++ b/packages/@aws-cdk/aws-route53-targets/test/load-balancer-target.test.ts @@ -28,7 +28,7 @@ test('use ALB as record target', () => { // THEN expect(stack).toHaveResource('AWS::Route53::RecordSet', { AliasTarget: { - DNSName: { 'Fn::GetAtt': [ 'LB8A12904C', 'DNSName' ] }, + DNSName: { 'Fn::Join': [ '', [ 'dualstack.', { 'Fn::GetAtt': [ 'LB8A12904C', 'DNSName' ] } ] ] }, HostedZoneId: { 'Fn::GetAtt': [ 'LB8A12904C', 'CanonicalHostedZoneID' ] }, }, }); From 3d5d2b22a0a8419c60a6fcd46839a36ad2961bda Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 27 Jun 2020 07:14:08 +0000 Subject: [PATCH 22/55] chore(deps): bump eslint-plugin-import from 2.21.2 to 2.22.0 (#8761) Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.21.2 to 2.22.0. - [Release notes](https://github.com/benmosher/eslint-plugin-import/releases) - [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md) - [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.21.2...v2.22.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- tools/cdk-build-tools/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/cdk-build-tools/package.json b/tools/cdk-build-tools/package.json index 443b9649bec1c..7913098fa397a 100644 --- a/tools/cdk-build-tools/package.json +++ b/tools/cdk-build-tools/package.json @@ -46,7 +46,7 @@ "eslint": "^6.8.0", "eslint-import-resolver-node": "^0.3.4", "eslint-import-resolver-typescript": "^2.0.0", - "eslint-plugin-import": "^2.21.2", + "eslint-plugin-import": "^2.22.0", "fs-extra": "^9.0.1", "jest": "^25.5.4", "jsii": "^1.7.0", diff --git a/yarn.lock b/yarn.lock index 6bd8e24a21c4f..24e77cc965e49 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3850,10 +3850,10 @@ eslint-module-utils@^2.6.0: debug "^2.6.9" pkg-dir "^2.0.0" -eslint-plugin-import@^2.21.2: - version "2.21.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz#8fef77475cc5510801bedc95f84b932f7f334a7c" - integrity sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA== +eslint-plugin-import@^2.22.0: + version "2.22.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz#92f7736fe1fde3e2de77623c838dd992ff5ffb7e" + integrity sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg== dependencies: array-includes "^3.1.1" array.prototype.flat "^1.2.3" From 991024d7b2b73db5d951a2f36f3c4d9bb395e0b8 Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Sun, 28 Jun 2020 10:12:21 +0200 Subject: [PATCH 23/55] chore(pkglint): ignore cdk.out and .cdk.staging (#8709) Those directories can contain `package.json` files coming for bundled assets (integ tests) that should never be linted. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- tools/pkglint/lib/packagejson.ts | 7 +++++-- tools/pkglint/lib/util.ts | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/pkglint/lib/packagejson.ts b/tools/pkglint/lib/packagejson.ts index 3707a2a29a8ab..1ec46e6b2bdc8 100644 --- a/tools/pkglint/lib/packagejson.ts +++ b/tools/pkglint/lib/packagejson.ts @@ -2,6 +2,9 @@ import * as colors from 'colors/safe'; import * as fs from 'fs-extra'; import * as path from 'path'; +// do not descend into these directories when searching for `package.json` files. +export const PKGLINT_IGNORES = ['node_modules', 'cdk.out', '.cdk.staging']; + /** * Return all package JSONs in the root directory */ @@ -24,8 +27,8 @@ export function findPackageJsons(root: string): PackageJson[] { ret.push(new PackageJson(fullPath)); } - // Recurse into all dirs except node_modules - if (file !== 'node_modules' && (fs.lstatSync(fullPath)).isDirectory()) { + // Recurse into all dirs except ignored dirs + if (!PKGLINT_IGNORES.includes(file) && (fs.lstatSync(fullPath)).isDirectory()) { recurse(fullPath); } } diff --git a/tools/pkglint/lib/util.ts b/tools/pkglint/lib/util.ts index 85f33afb2e7b0..35966d3809b22 100644 --- a/tools/pkglint/lib/util.ts +++ b/tools/pkglint/lib/util.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; import * as path from 'path'; -import { PackageJson } from "./packagejson"; +import { PackageJson, PKGLINT_IGNORES } from "./packagejson"; /** * Expect a particular JSON key to be a given value @@ -168,7 +168,7 @@ export function* findInnerPackages(dir: string): IterableIterator { if (e.code !== 'ENOENT') { throw e; } continue; } - if (fname === 'node_modules') { continue; } + if (PKGLINT_IGNORES.includes(fname)) { continue; } if (fs.existsSync(path.join(dir, fname, 'package.json'))) { yield path.join(dir, fname); From 14e5063d7dd63eb447ce5fa2a2f7093156a29d78 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 28 Jun 2020 17:27:14 +0000 Subject: [PATCH 24/55] chore(deps-dev): bump nock from 12.0.3 to 13.0.0 (#8772) Bumps [nock](https://github.com/nock/nock) from 12.0.3 to 13.0.0. - [Release notes](https://github.com/nock/nock/releases) - [Changelog](https://github.com/nock/nock/blob/master/CHANGELOG.md) - [Commits](https://github.com/nock/nock/compare/v12.0.3...v13.0.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-lambda/package.json | 2 +- packages/@aws-cdk/custom-resources/package.json | 2 +- yarn.lock | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index 58f01292c28d3..1fa918db69d5c 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -77,7 +77,7 @@ "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", "lodash": "^4.17.15", - "nock": "^12.0.3", + "nock": "^13.0.0", "nodeunit": "^0.11.3", "pkglint": "0.0.0", "sinon": "^9.0.2" diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index 00a82b3853228..7907d4568c796 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -79,7 +79,7 @@ "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", "fs-extra": "^9.0.1", - "nock": "^12.0.3", + "nock": "^13.0.0", "pkglint": "0.0.0", "sinon": "^9.0.2" }, diff --git a/yarn.lock b/yarn.lock index 24e77cc965e49..6abcc81885b97 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6918,14 +6918,14 @@ nise@^4.0.1: just-extend "^4.0.2" path-to-regexp "^1.7.0" -nock@^12.0.3: - version "12.0.3" - resolved "https://registry.yarnpkg.com/nock/-/nock-12.0.3.tgz#83f25076dbc4c9aa82b5cdf54c9604c7a778d1c9" - integrity sha512-QNb/j8kbFnKCiyqi9C5DD0jH/FubFGj5rt9NQFONXwQm3IPB0CULECg/eS3AU1KgZb/6SwUa4/DTRKhVxkGABw== +nock@^13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/nock/-/nock-13.0.0.tgz#e07276d558245386a2872cebf4d5570583c0d225" + integrity sha512-FiW8t91Je5yG5MVT1r+go1Z9bX3rCYIEjenUYeZrEl2v8aTWdIX336itrmQaKUO8Ske5Z7RHR7OIzr/9p0Ujjg== dependencies: debug "^4.1.0" json-stringify-safe "^5.0.1" - lodash "^4.17.13" + lodash.set "^4.3.2" propagate "^2.0.0" node-fetch-npm@^2.0.2: From 3a6353e5953e6adf841bce93eadbaea531eba409 Mon Sep 17 00:00:00 2001 From: Pahud Hsieh Date: Mon, 29 Jun 2020 07:42:23 +0800 Subject: [PATCH 25/55] chore(eks): support Inf1 instances (#8379) chore(eks): support inf1 instances Amazon EKS supports Inferentia Instances today(see [Infrerentia Support](https://docs.aws.amazon.com/eks/latest/userguide/inferentia-support.html) and the doc [update](https://twitter.com/aws_doc/status/1268567994394968066)). This PR allows to create Amazon EKS worker nodes with `Inf1` instances. - Add `Inf1` instances support ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- package.json | 2 + .../lib/addons/neuron-device-plugin.yaml | 66 ++ packages/@aws-cdk/aws-eks/lib/cluster.ts | 34 +- packages/@aws-cdk/aws-eks/package.json | 7 +- .../test/integ.eks-cluster.expected.json | 651 ++++++++++++------ .../aws-eks/test/integ.eks-cluster.ts | 12 +- .../@aws-cdk/aws-eks/test/test.cluster.ts | 22 + 7 files changed, 597 insertions(+), 197 deletions(-) create mode 100644 packages/@aws-cdk/aws-eks/lib/addons/neuron-device-plugin.yaml diff --git a/package.json b/package.json index 65f78e85c6d42..6442b77109e93 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,8 @@ "@aws-cdk/aws-codepipeline-actions/case/**", "@aws-cdk/aws-ecr-assets/minimatch", "@aws-cdk/aws-ecr-assets/minimatch/**", + "@aws-cdk/aws-eks/yaml", + "@aws-cdk/aws-eks/yaml/**", "@aws-cdk/aws-lambda-nodejs/parcel-bundler", "@aws-cdk/aws-lambda-nodejs/parcel-bundler/**", "@aws-cdk/cloud-assembly-schema/jsonschema", diff --git a/packages/@aws-cdk/aws-eks/lib/addons/neuron-device-plugin.yaml b/packages/@aws-cdk/aws-eks/lib/addons/neuron-device-plugin.yaml new file mode 100644 index 0000000000000..48d66be1c8343 --- /dev/null +++ b/packages/@aws-cdk/aws-eks/lib/addons/neuron-device-plugin.yaml @@ -0,0 +1,66 @@ +# source: https://github.com/aws/aws-neuron-sdk/blob/master/docs/neuron-container-tools/k8s-neuron-device-plugin.yml +# https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: neuron-device-plugin-daemonset + namespace: kube-system +spec: + selector: + matchLabels: + name: neuron-device-plugin-ds + updateStrategy: + type: RollingUpdate + template: + metadata: + annotations: + scheduler.alpha.kubernetes.io/critical-pod: "" + labels: + name: neuron-device-plugin-ds + spec: + tolerations: + - key: CriticalAddonsOnly + operator: Exists + - key: aws.amazon.com/neuron + operator: Exists + effect: NoSchedule + # Mark this pod as a critical add-on; when enabled, the critical add-on + # scheduler reserves resources for critical add-on pods so that they can + # be rescheduled after a failure. + # See https://kubernetes.io/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/ + priorityClassName: "system-node-critical" + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: "beta.kubernetes.io/instance-type" + operator: In + values: + - inf1.xlarge + - inf1.2xlarge + - inf1.6xlarge + - inf1.4xlarge + - matchExpressions: + - key: "node.kubernetes.io/instance-type" + operator: In + values: + - inf1.xlarge + - inf1.2xlarge + - inf1.6xlarge + - inf1.24xlarge + containers: + - image: 790709498068.dkr.ecr.us-west-2.amazonaws.com/neuron-device-plugin:1.0.9043.0 + imagePullPolicy: Always + name: k8s-neuron-device-plugin-ctr + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + volumeMounts: + - name: device-plugin + mountPath: /var/lib/kubelet/device-plugins + volumes: + - name: device-plugin + hostPath: + path: /var/lib/kubelet/device-plugins \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks/lib/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster.ts index 491d357387073..5cf344f067f75 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster.ts @@ -3,6 +3,9 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as ssm from '@aws-cdk/aws-ssm'; import { CfnOutput, Construct, IResource, Resource, Stack, Tag, Token } from '@aws-cdk/core'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as YAML from 'yaml'; import { AwsAuth } from './aws-auth'; import { clusterArnComponents, ClusterResource } from './cluster-resource'; import { CfnCluster, CfnClusterProps } from './eks.generated'; @@ -385,6 +388,8 @@ export class Cluster extends Resource implements ICluster { private _spotInterruptHandler?: HelmChart; + private _neuronDevicePlugin?: KubernetesResource; + private readonly version: string | undefined; /** @@ -537,6 +542,10 @@ export class Cluster extends Resource implements ICluster { machineImageType: options.machineImageType, }); + if (nodeTypeForInstanceType(options.instanceType) === NodeType.INFERENTIA) { + this.addNeuronDevicePlugin(); + } + return asg; } @@ -834,6 +843,20 @@ export class Cluster extends Resource implements ICluster { return this._spotInterruptHandler; } + /** + * Installs the Neuron device plugin on the cluster if it's not + * already added. + */ + private addNeuronDevicePlugin() { + if (!this._neuronDevicePlugin) { + const fileContents = fs.readFileSync(path.join(__dirname, 'addons/neuron-device-plugin.yaml'), 'utf8'); + const sanitized = YAML.parse(fileContents); + this._neuronDevicePlugin = this.addResource('NeuronDevicePlugin', sanitized); + } + + return this._neuronDevicePlugin; + } + /** * Opportunistically tag subnets with the required tags. * @@ -1112,6 +1135,7 @@ export class EksOptimizedImage implements ec2.IMachineImage { this.amiParameterName = `/aws/service/eks/optimized-ami/${this.kubernetesVersion}/` + ( this.nodeType === NodeType.STANDARD ? 'amazon-linux-2/' : '' ) + ( this.nodeType === NodeType.GPU ? 'amazon-linux-2-gpu/' : '' ) + + (this.nodeType === NodeType.INFERENTIA ? 'amazon-linux-2-gpu/' : '') + 'recommended/image_id'; } @@ -1176,6 +1200,11 @@ export enum NodeType { * GPU instances */ GPU = 'GPU', + + /** + * Inferentia instances + */ + INFERENTIA = 'INFERENTIA', } /** @@ -1222,7 +1251,10 @@ export enum MachineImageType { } const GPU_INSTANCETYPES = ['p2', 'p3', 'g4']; +const INFERENTIA_INSTANCETYPES = ['inf1']; function nodeTypeForInstanceType(instanceType: ec2.InstanceType) { - return GPU_INSTANCETYPES.includes(instanceType.toString().substring(0, 2)) ? NodeType.GPU : NodeType.STANDARD; + return GPU_INSTANCETYPES.includes(instanceType.toString().substring(0, 2)) ? NodeType.GPU : + INFERENTIA_INSTANCETYPES.includes(instanceType.toString().substring(0, 4)) ? NodeType.INFERENTIA : + NodeType.STANDARD; } diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index e4cc3e8273dfb..df01d4bdbe553 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -64,6 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", + "@types/yaml": "1.2.0", "aws-sdk": "^2.706.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", @@ -80,8 +81,12 @@ "@aws-cdk/aws-ssm": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/custom-resources": "0.0.0", - "constructs": "^3.0.2" + "constructs": "^3.0.2", + "yaml": "1.10.0" }, + "bundledDependencies": [ + "yaml" + ], "homepage": "https://github.com/aws/aws-cdk", "peerDependencies": { "@aws-cdk/aws-autoscaling": "0.0.0", diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json index 4278bee450139..a787602404c54 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json @@ -28,7 +28,7 @@ } } }, - "ClusterDefaultVpcFA9F2722": { + "Vpc8378EB38": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": "10.0.0.0/16", @@ -38,17 +38,17 @@ "Tags": [ { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc" + "Value": "aws-cdk-eks-cluster-test/Vpc" } ] } }, - "ClusterDefaultVpcPublicSubnet1Subnet3BFE1BDA": { + "VpcPublicSubnet1Subnet5C2D37C4": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.0.0/19", "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "AvailabilityZone": "test-region-1a", "MapPublicIpOnLaunch": true, @@ -67,16 +67,16 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet1" + "Value": "aws-cdk-eks-cluster-test/Vpc/PublicSubnet1" } ] } }, - "ClusterDefaultVpcPublicSubnet1RouteTable1DCCDD98": { + "VpcPublicSubnet1RouteTable6C95E38E": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "Tags": [ { @@ -85,38 +85,38 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet1" + "Value": "aws-cdk-eks-cluster-test/Vpc/PublicSubnet1" } ] } }, - "ClusterDefaultVpcPublicSubnet1RouteTableAssociationAFBE6789": { + "VpcPublicSubnet1RouteTableAssociation97140677": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPublicSubnet1RouteTable1DCCDD98" + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" }, "SubnetId": { - "Ref": "ClusterDefaultVpcPublicSubnet1Subnet3BFE1BDA" + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" } } }, - "ClusterDefaultVpcPublicSubnet1DefaultRouteCF22EF6E": { + "VpcPublicSubnet1DefaultRoute3DA9E72A": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPublicSubnet1RouteTable1DCCDD98" + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { - "Ref": "ClusterDefaultVpcIGW756BE43E" + "Ref": "VpcIGWD7BA715C" } }, "DependsOn": [ - "ClusterDefaultVpcVPCGWC1D00388" + "VpcVPCGWBF912B6E" ] }, - "ClusterDefaultVpcPublicSubnet1EIP498E2BD2": { + "VpcPublicSubnet1EIPD7E02669": { "Type": "AWS::EC2::EIP", "Properties": { "Domain": "vpc", @@ -127,22 +127,22 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet1" + "Value": "aws-cdk-eks-cluster-test/Vpc/PublicSubnet1" } ] } }, - "ClusterDefaultVpcPublicSubnet1NATGateway6E21013E": { + "VpcPublicSubnet1NATGateway4D7517AA": { "Type": "AWS::EC2::NatGateway", "Properties": { "AllocationId": { "Fn::GetAtt": [ - "ClusterDefaultVpcPublicSubnet1EIP498E2BD2", + "VpcPublicSubnet1EIPD7E02669", "AllocationId" ] }, "SubnetId": { - "Ref": "ClusterDefaultVpcPublicSubnet1Subnet3BFE1BDA" + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" }, "Tags": [ { @@ -151,17 +151,17 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet1" + "Value": "aws-cdk-eks-cluster-test/Vpc/PublicSubnet1" } ] } }, - "ClusterDefaultVpcPublicSubnet2SubnetC4E9A966": { + "VpcPublicSubnet2Subnet691E08A3": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.32.0/19", "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "AvailabilityZone": "test-region-1b", "MapPublicIpOnLaunch": true, @@ -180,16 +180,16 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet2" + "Value": "aws-cdk-eks-cluster-test/Vpc/PublicSubnet2" } ] } }, - "ClusterDefaultVpcPublicSubnet2RouteTable6F1F5F47": { + "VpcPublicSubnet2RouteTable94F7E489": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "Tags": [ { @@ -198,83 +198,43 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet2" + "Value": "aws-cdk-eks-cluster-test/Vpc/PublicSubnet2" } ] } }, - "ClusterDefaultVpcPublicSubnet2RouteTableAssociationA8539C50": { + "VpcPublicSubnet2RouteTableAssociationDD5762D8": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPublicSubnet2RouteTable6F1F5F47" + "Ref": "VpcPublicSubnet2RouteTable94F7E489" }, "SubnetId": { - "Ref": "ClusterDefaultVpcPublicSubnet2SubnetC4E9A966" + "Ref": "VpcPublicSubnet2Subnet691E08A3" } } }, - "ClusterDefaultVpcPublicSubnet2DefaultRoute1FA8621E": { + "VpcPublicSubnet2DefaultRoute97F91067": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPublicSubnet2RouteTable6F1F5F47" + "Ref": "VpcPublicSubnet2RouteTable94F7E489" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { - "Ref": "ClusterDefaultVpcIGW756BE43E" + "Ref": "VpcIGWD7BA715C" } }, "DependsOn": [ - "ClusterDefaultVpcVPCGWC1D00388" + "VpcVPCGWBF912B6E" ] }, - "ClusterDefaultVpcPublicSubnet2EIP265F4810": { - "Type": "AWS::EC2::EIP", - "Properties": { - "Domain": "vpc", - "Tags": [ - { - "Key": "kubernetes.io/role/elb", - "Value": "1" - }, - { - "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet2" - } - ] - } - }, - "ClusterDefaultVpcPublicSubnet2NATGateway4AF4B728": { - "Type": "AWS::EC2::NatGateway", - "Properties": { - "AllocationId": { - "Fn::GetAtt": [ - "ClusterDefaultVpcPublicSubnet2EIP265F4810", - "AllocationId" - ] - }, - "SubnetId": { - "Ref": "ClusterDefaultVpcPublicSubnet2SubnetC4E9A966" - }, - "Tags": [ - { - "Key": "kubernetes.io/role/elb", - "Value": "1" - }, - { - "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet2" - } - ] - } - }, - "ClusterDefaultVpcPublicSubnet3Subnet1A46184A": { + "VpcPublicSubnet3SubnetBE12F0B6": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.64.0/19", "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "AvailabilityZone": "test-region-1c", "MapPublicIpOnLaunch": true, @@ -293,16 +253,16 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet3" + "Value": "aws-cdk-eks-cluster-test/Vpc/PublicSubnet3" } ] } }, - "ClusterDefaultVpcPublicSubnet3RouteTableC81F99EF": { + "VpcPublicSubnet3RouteTable93458DBB": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "Tags": [ { @@ -311,83 +271,43 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet3" + "Value": "aws-cdk-eks-cluster-test/Vpc/PublicSubnet3" } ] } }, - "ClusterDefaultVpcPublicSubnet3RouteTableAssociation7C5D21CC": { + "VpcPublicSubnet3RouteTableAssociation1F1EDF02": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPublicSubnet3RouteTableC81F99EF" + "Ref": "VpcPublicSubnet3RouteTable93458DBB" }, "SubnetId": { - "Ref": "ClusterDefaultVpcPublicSubnet3Subnet1A46184A" + "Ref": "VpcPublicSubnet3SubnetBE12F0B6" } } }, - "ClusterDefaultVpcPublicSubnet3DefaultRouteB6080504": { + "VpcPublicSubnet3DefaultRoute4697774F": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPublicSubnet3RouteTableC81F99EF" + "Ref": "VpcPublicSubnet3RouteTable93458DBB" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { - "Ref": "ClusterDefaultVpcIGW756BE43E" + "Ref": "VpcIGWD7BA715C" } }, "DependsOn": [ - "ClusterDefaultVpcVPCGWC1D00388" + "VpcVPCGWBF912B6E" ] }, - "ClusterDefaultVpcPublicSubnet3EIP0CBF6D05": { - "Type": "AWS::EC2::EIP", - "Properties": { - "Domain": "vpc", - "Tags": [ - { - "Key": "kubernetes.io/role/elb", - "Value": "1" - }, - { - "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet3" - } - ] - } - }, - "ClusterDefaultVpcPublicSubnet3NATGatewayEF4BA49A": { - "Type": "AWS::EC2::NatGateway", - "Properties": { - "AllocationId": { - "Fn::GetAtt": [ - "ClusterDefaultVpcPublicSubnet3EIP0CBF6D05", - "AllocationId" - ] - }, - "SubnetId": { - "Ref": "ClusterDefaultVpcPublicSubnet3Subnet1A46184A" - }, - "Tags": [ - { - "Key": "kubernetes.io/role/elb", - "Value": "1" - }, - { - "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PublicSubnet3" - } - ] - } - }, - "ClusterDefaultVpcPrivateSubnet1Subnet03F39409": { + "VpcPrivateSubnet1Subnet536B997A": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.96.0/19", "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "AvailabilityZone": "test-region-1a", "MapPublicIpOnLaunch": false, @@ -406,16 +326,16 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PrivateSubnet1" + "Value": "aws-cdk-eks-cluster-test/Vpc/PrivateSubnet1" } ] } }, - "ClusterDefaultVpcPrivateSubnet1RouteTable7844020C": { + "VpcPrivateSubnet1RouteTableB2C5B500": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "Tags": [ { @@ -424,40 +344,40 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PrivateSubnet1" + "Value": "aws-cdk-eks-cluster-test/Vpc/PrivateSubnet1" } ] } }, - "ClusterDefaultVpcPrivateSubnet1RouteTableAssociationF8A67D95": { + "VpcPrivateSubnet1RouteTableAssociation70C59FA6": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPrivateSubnet1RouteTable7844020C" + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" }, "SubnetId": { - "Ref": "ClusterDefaultVpcPrivateSubnet1Subnet03F39409" + "Ref": "VpcPrivateSubnet1Subnet536B997A" } } }, - "ClusterDefaultVpcPrivateSubnet1DefaultRouteD624C8BD": { + "VpcPrivateSubnet1DefaultRouteBE02A9ED": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPrivateSubnet1RouteTable7844020C" + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { - "Ref": "ClusterDefaultVpcPublicSubnet1NATGateway6E21013E" + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" } } }, - "ClusterDefaultVpcPrivateSubnet2SubnetA526AEA7": { + "VpcPrivateSubnet2Subnet3788AAA1": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.128.0/19", "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "AvailabilityZone": "test-region-1b", "MapPublicIpOnLaunch": false, @@ -476,16 +396,16 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PrivateSubnet2" + "Value": "aws-cdk-eks-cluster-test/Vpc/PrivateSubnet2" } ] } }, - "ClusterDefaultVpcPrivateSubnet2RouteTable1F9A5298": { + "VpcPrivateSubnet2RouteTableA678073B": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "Tags": [ { @@ -494,40 +414,40 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PrivateSubnet2" + "Value": "aws-cdk-eks-cluster-test/Vpc/PrivateSubnet2" } ] } }, - "ClusterDefaultVpcPrivateSubnet2RouteTableAssociationE1240DF2": { + "VpcPrivateSubnet2RouteTableAssociationA89CAD56": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPrivateSubnet2RouteTable1F9A5298" + "Ref": "VpcPrivateSubnet2RouteTableA678073B" }, "SubnetId": { - "Ref": "ClusterDefaultVpcPrivateSubnet2SubnetA526AEA7" + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" } } }, - "ClusterDefaultVpcPrivateSubnet2DefaultRouteAB55737C": { + "VpcPrivateSubnet2DefaultRoute060D2087": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPrivateSubnet2RouteTable1F9A5298" + "Ref": "VpcPrivateSubnet2RouteTableA678073B" }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { - "Ref": "ClusterDefaultVpcPublicSubnet2NATGateway4AF4B728" + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" } } }, - "ClusterDefaultVpcPrivateSubnet3SubnetB64BC839": { + "VpcPrivateSubnet3SubnetF258B56E": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.160.0/19", "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "AvailabilityZone": "test-region-1c", "MapPublicIpOnLaunch": false, @@ -546,16 +466,16 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PrivateSubnet3" + "Value": "aws-cdk-eks-cluster-test/Vpc/PrivateSubnet3" } ] } }, - "ClusterDefaultVpcPrivateSubnet3RouteTableF71314D0": { + "VpcPrivateSubnet3RouteTableD98824C7": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "Tags": [ { @@ -564,53 +484,53 @@ }, { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc/PrivateSubnet3" + "Value": "aws-cdk-eks-cluster-test/Vpc/PrivateSubnet3" } ] } }, - "ClusterDefaultVpcPrivateSubnet3RouteTableAssociation3007DC36": { + "VpcPrivateSubnet3RouteTableAssociation16BDDC43": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPrivateSubnet3RouteTableF71314D0" + "Ref": "VpcPrivateSubnet3RouteTableD98824C7" }, "SubnetId": { - "Ref": "ClusterDefaultVpcPrivateSubnet3SubnetB64BC839" + "Ref": "VpcPrivateSubnet3SubnetF258B56E" } } }, - "ClusterDefaultVpcPrivateSubnet3DefaultRoute932EDFF0": { + "VpcPrivateSubnet3DefaultRoute94B74F0D": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { - "Ref": "ClusterDefaultVpcPrivateSubnet3RouteTableF71314D0" + "Ref": "VpcPrivateSubnet3RouteTableD98824C7" }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { - "Ref": "ClusterDefaultVpcPublicSubnet3NATGatewayEF4BA49A" + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" } } }, - "ClusterDefaultVpcIGW756BE43E": { + "VpcIGWD7BA715C": { "Type": "AWS::EC2::InternetGateway", "Properties": { "Tags": [ { "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Cluster/DefaultVpc" + "Value": "aws-cdk-eks-cluster-test/Vpc" } ] } }, - "ClusterDefaultVpcVPCGWC1D00388": { + "VpcVPCGWBF912B6E": { "Type": "AWS::EC2::VPCGatewayAttachment", "Properties": { "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" }, "InternetGatewayId": { - "Ref": "ClusterDefaultVpcIGW756BE43E" + "Ref": "VpcIGWD7BA715C" } } }, @@ -657,7 +577,7 @@ } ], "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" } } }, @@ -724,6 +644,27 @@ "ToPort": 443 } }, + "ClusterControlPlaneSecurityGroupfromawscdkeksclustertestClusterInferenceInstancesInstanceSecurityGroup42C57C51443E3176F85": { + "Type": "AWS::EC2::SecurityGroupIngress", + "Properties": { + "IpProtocol": "tcp", + "Description": "from awscdkeksclustertestClusterInferenceInstancesInstanceSecurityGroup42C57C51:443", + "FromPort": 443, + "GroupId": { + "Fn::GetAtt": [ + "ClusterControlPlaneSecurityGroupD274242C", + "GroupId" + ] + }, + "SourceSecurityGroupId": { + "Fn::GetAtt": [ + "ClusterInferenceInstancesInstanceSecurityGroupECB3FC45", + "GroupId" + ] + }, + "ToPort": 443 + } + }, "ClusterCreationRole360249B6": { "Type": "AWS::IAM::Role", "Properties": { @@ -873,22 +814,22 @@ ], "subnetIds": [ { - "Ref": "ClusterDefaultVpcPublicSubnet1Subnet3BFE1BDA" + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" }, { - "Ref": "ClusterDefaultVpcPublicSubnet2SubnetC4E9A966" + "Ref": "VpcPublicSubnet2Subnet691E08A3" }, { - "Ref": "ClusterDefaultVpcPublicSubnet3Subnet1A46184A" + "Ref": "VpcPublicSubnet3SubnetBE12F0B6" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet1Subnet03F39409" + "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet2SubnetA526AEA7" + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet3SubnetB64BC839" + "Ref": "VpcPrivateSubnet3SubnetF258B56E" } ] } @@ -963,6 +904,13 @@ "Arn" ] }, + "\\\",\\\"username\\\":\\\"system:node:{{EC2PrivateDNSName}}\\\",\\\"groups\\\":[\\\"system:bootstrappers\\\",\\\"system:nodes\\\"]},{\\\"rolearn\\\":\\\"", + { + "Fn::GetAtt": [ + "ClusterInferenceInstancesInstanceRole59AC6F56", + "Arn" + ] + }, "\\\",\\\"username\\\":\\\"system:node:{{EC2PrivateDNSName}}\\\",\\\"groups\\\":[\\\"system:bootstrappers\\\",\\\"system:nodes\\\"]}]\",\"mapUsers\":\"[]\",\"mapAccounts\":\"[]\"}}]" ] ] @@ -1059,13 +1007,13 @@ }, "Subnets": [ { - "Ref": "ClusterDefaultVpcPrivateSubnet1Subnet03F39409" + "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet2SubnetA526AEA7" + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet3SubnetB64BC839" + "Ref": "VpcPrivateSubnet3SubnetF258B56E" } ], "ForceUpdateEnabled": true, @@ -1177,7 +1125,7 @@ } ], "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" } } }, @@ -1406,13 +1354,13 @@ ], "VPCZoneIdentifier": [ { - "Ref": "ClusterDefaultVpcPrivateSubnet1Subnet03F39409" + "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet2SubnetA526AEA7" + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet3SubnetB64BC839" + "Ref": "VpcPrivateSubnet3SubnetF258B56E" } ] }, @@ -1465,7 +1413,7 @@ } ], "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" } } }, @@ -1708,13 +1656,13 @@ ], "VPCZoneIdentifier": [ { - "Ref": "ClusterDefaultVpcPrivateSubnet1Subnet03F39409" + "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet2SubnetA526AEA7" + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet3SubnetB64BC839" + "Ref": "VpcPrivateSubnet3SubnetF258B56E" } ] }, @@ -1767,7 +1715,7 @@ } ], "VpcId": { - "Ref": "ClusterDefaultVpcFA9F2722" + "Ref": "Vpc8378EB38" } } }, @@ -1997,13 +1945,13 @@ ], "VPCZoneIdentifier": [ { - "Ref": "ClusterDefaultVpcPrivateSubnet1Subnet03F39409" + "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet2SubnetA526AEA7" + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet3SubnetB64BC839" + "Ref": "VpcPrivateSubnet3SubnetF258B56E" } ] }, @@ -2053,6 +2001,317 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "ClusterInferenceInstancesInstanceSecurityGroupECB3FC45": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-cdk-eks-cluster-test/Cluster/InferenceInstances/InstanceSecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "Tags": [ + { + "Key": { + "Fn::Join": [ + "", + [ + "kubernetes.io/cluster/", + { + "Ref": "Cluster9EE0221C" + } + ] + ] + }, + "Value": "owned" + }, + { + "Key": "Name", + "Value": "aws-cdk-eks-cluster-test/Cluster/InferenceInstances" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "ClusterInferenceInstancesInstanceSecurityGroupfromawscdkeksclustertestClusterInferenceInstancesInstanceSecurityGroup42C57C51ALLTRAFFICB6138869": { + "Type": "AWS::EC2::SecurityGroupIngress", + "Properties": { + "IpProtocol": "-1", + "Description": "from awscdkeksclustertestClusterInferenceInstancesInstanceSecurityGroup42C57C51:ALL TRAFFIC", + "GroupId": { + "Fn::GetAtt": [ + "ClusterInferenceInstancesInstanceSecurityGroupECB3FC45", + "GroupId" + ] + }, + "SourceSecurityGroupId": { + "Fn::GetAtt": [ + "ClusterInferenceInstancesInstanceSecurityGroupECB3FC45", + "GroupId" + ] + } + } + }, + "ClusterInferenceInstancesInstanceSecurityGroupfromawscdkeksclustertestClusterControlPlaneSecurityGroup2F1301344437B48FD33": { + "Type": "AWS::EC2::SecurityGroupIngress", + "Properties": { + "IpProtocol": "tcp", + "Description": "from awscdkeksclustertestClusterControlPlaneSecurityGroup2F130134:443", + "FromPort": 443, + "GroupId": { + "Fn::GetAtt": [ + "ClusterInferenceInstancesInstanceSecurityGroupECB3FC45", + "GroupId" + ] + }, + "SourceSecurityGroupId": { + "Fn::GetAtt": [ + "ClusterControlPlaneSecurityGroupD274242C", + "GroupId" + ] + }, + "ToPort": 443 + } + }, + "ClusterInferenceInstancesInstanceSecurityGroupfromawscdkeksclustertestClusterControlPlaneSecurityGroup2F130134102565535A460F673": { + "Type": "AWS::EC2::SecurityGroupIngress", + "Properties": { + "IpProtocol": "tcp", + "Description": "from awscdkeksclustertestClusterControlPlaneSecurityGroup2F130134:1025-65535", + "FromPort": 1025, + "GroupId": { + "Fn::GetAtt": [ + "ClusterInferenceInstancesInstanceSecurityGroupECB3FC45", + "GroupId" + ] + }, + "SourceSecurityGroupId": { + "Fn::GetAtt": [ + "ClusterControlPlaneSecurityGroupD274242C", + "GroupId" + ] + }, + "ToPort": 65535 + } + }, + "ClusterInferenceInstancesInstanceRole59AC6F56": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "ec2.", + { + "Ref": "AWS::URLSuffix" + } + ] + ] + } + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/AmazonEKSWorkerNodePolicy" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/AmazonEKS_CNI_Policy" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" + ] + ] + } + ], + "Tags": [ + { + "Key": { + "Fn::Join": [ + "", + [ + "kubernetes.io/cluster/", + { + "Ref": "Cluster9EE0221C" + } + ] + ] + }, + "Value": "owned" + }, + { + "Key": "Name", + "Value": "aws-cdk-eks-cluster-test/Cluster/InferenceInstances" + } + ] + } + }, + "ClusterInferenceInstancesInstanceProfile5A1209B4": { + "Type": "AWS::IAM::InstanceProfile", + "Properties": { + "Roles": [ + { + "Ref": "ClusterInferenceInstancesInstanceRole59AC6F56" + } + ] + } + }, + "ClusterInferenceInstancesLaunchConfig03BF48FE": { + "Type": "AWS::AutoScaling::LaunchConfiguration", + "Properties": { + "ImageId": { + "Ref": "SsmParameterValueawsserviceeksoptimizedami116amazonlinux2gpurecommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" + }, + "InstanceType": "inf1.2xlarge", + "IamInstanceProfile": { + "Ref": "ClusterInferenceInstancesInstanceProfile5A1209B4" + }, + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "ClusterInferenceInstancesInstanceSecurityGroupECB3FC45", + "GroupId" + ] + } + ], + "UserData": { + "Fn::Base64": { + "Fn::Join": [ + "", + [ + "#!/bin/bash\nset -o xtrace\n/etc/eks/bootstrap.sh ", + { + "Ref": "Cluster9EE0221C" + }, + " --kubelet-extra-args \"--node-labels lifecycle=OnDemand\" --use-max-pods true\n/opt/aws/bin/cfn-signal --exit-code $? --stack aws-cdk-eks-cluster-test --resource ClusterInferenceInstancesASGE90717C7 --region test-region" + ] + ] + } + } + }, + "DependsOn": [ + "ClusterInferenceInstancesInstanceRole59AC6F56" + ] + }, + "ClusterInferenceInstancesASGE90717C7": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": "1", + "MinSize": "1", + "LaunchConfigurationName": { + "Ref": "ClusterInferenceInstancesLaunchConfig03BF48FE" + }, + "Tags": [ + { + "Key": { + "Fn::Join": [ + "", + [ + "kubernetes.io/cluster/", + { + "Ref": "Cluster9EE0221C" + } + ] + ] + }, + "PropagateAtLaunch": true, + "Value": "owned" + }, + { + "Key": "Name", + "PropagateAtLaunch": true, + "Value": "aws-cdk-eks-cluster-test/Cluster/InferenceInstances" + } + ], + "VPCZoneIdentifier": [ + { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + }, + { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + }, + { + "Ref": "VpcPrivateSubnet3SubnetF258B56E" + } + ] + }, + "UpdatePolicy": { + "AutoScalingRollingUpdate": { + "WaitOnResourceSignals": false, + "PauseTime": "PT0S", + "SuspendProcesses": [ + "HealthCheck", + "ReplaceUnhealthy", + "AZRebalance", + "AlarmNotification", + "ScheduledActions" + ] + }, + "AutoScalingScheduledAction": { + "IgnoreUnmodifiedGroupSizeProperties": true + } + } + }, + "ClustermanifestNeuronDevicePlugin0B3E0D17": { + "Type": "Custom::AWSCDK-EKS-KubernetesResource", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "awscdkawseksKubectlProviderNestedStackawscdkawseksKubectlProviderNestedStackResourceA7AEBA6B", + "Outputs.awscdkeksclustertestawscdkawseksKubectlProviderframeworkonEventC681B49AArn" + ] + }, + "Manifest": "[{\"apiVersion\":\"apps/v1\",\"kind\":\"DaemonSet\",\"metadata\":{\"name\":\"neuron-device-plugin-daemonset\",\"namespace\":\"kube-system\"},\"spec\":{\"selector\":{\"matchLabels\":{\"name\":\"neuron-device-plugin-ds\"}},\"updateStrategy\":{\"type\":\"RollingUpdate\"},\"template\":{\"metadata\":{\"annotations\":{\"scheduler.alpha.kubernetes.io/critical-pod\":\"\"},\"labels\":{\"name\":\"neuron-device-plugin-ds\"}},\"spec\":{\"tolerations\":[{\"key\":\"CriticalAddonsOnly\",\"operator\":\"Exists\"},{\"key\":\"aws.amazon.com/neuron\",\"operator\":\"Exists\",\"effect\":\"NoSchedule\"}],\"priorityClassName\":\"system-node-critical\",\"affinity\":{\"nodeAffinity\":{\"requiredDuringSchedulingIgnoredDuringExecution\":{\"nodeSelectorTerms\":[{\"matchExpressions\":[{\"key\":\"beta.kubernetes.io/instance-type\",\"operator\":\"In\",\"values\":[\"inf1.xlarge\",\"inf1.2xlarge\",\"inf1.6xlarge\",\"inf1.4xlarge\"]}]},{\"matchExpressions\":[{\"key\":\"node.kubernetes.io/instance-type\",\"operator\":\"In\",\"values\":[\"inf1.xlarge\",\"inf1.2xlarge\",\"inf1.6xlarge\",\"inf1.24xlarge\"]}]}]}}},\"containers\":[{\"image\":\"790709498068.dkr.ecr.us-west-2.amazonaws.com/neuron-device-plugin:1.0.9043.0\",\"imagePullPolicy\":\"Always\",\"name\":\"k8s-neuron-device-plugin-ctr\",\"securityContext\":{\"allowPrivilegeEscalation\":false,\"capabilities\":{\"drop\":[\"ALL\"]}},\"volumeMounts\":[{\"name\":\"device-plugin\",\"mountPath\":\"/var/lib/kubelet/device-plugins\"}]}],\"volumes\":[{\"name\":\"device-plugin\",\"hostPath\":{\"path\":\"/var/lib/kubelet/device-plugins\"}}]}}}}]", + "ClusterName": { + "Ref": "Cluster9EE0221C" + }, + "RoleArn": { + "Fn::GetAtt": [ + "ClusterCreationRole360249B6", + "Arn" + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, "ClusterNodegroupextrangNodeGroupRole23AE23D0": { "Type": "AWS::IAM::Role", "Properties": { @@ -2132,13 +2391,13 @@ }, "Subnets": [ { - "Ref": "ClusterDefaultVpcPrivateSubnet1Subnet03F39409" + "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet2SubnetA526AEA7" + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" }, { - "Ref": "ClusterDefaultVpcPrivateSubnet3SubnetB64BC839" + "Ref": "VpcPrivateSubnet3SubnetF258B56E" } ], "ForceUpdateEnabled": true, @@ -2832,6 +3091,10 @@ "SsmParameterValueawsservicebottlerocketawsk8s115x8664latestimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { "Type": "AWS::SSM::Parameter::Value", "Default": "/aws/service/bottlerocket/aws-k8s-1.15/x86_64/latest/image_id" + }, + "SsmParameterValueawsserviceeksoptimizedami116amazonlinux2gpurecommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/aws/service/eks/optimized-ami/1.16/amazon-linux-2-gpu/recommended/image_id" } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts index ff6d62e74c20f..122efbdd9ecc6 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts @@ -14,14 +14,18 @@ class EksClusterStack extends TestStack { assumedBy: new iam.AccountRootPrincipal(), }); + // just need one nat gateway to simplify the test + const vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 3, natGateways: 1 }); + // create the cluster with a default nodegroup capacity const cluster = new eks.Cluster(this, 'Cluster', { + vpc, mastersRole, defaultCapacity: 2, version: '1.16', }); - // // fargate profile for resources in the "default" namespace + // fargate profile for resources in the "default" namespace cluster.addFargateProfile('default', { selectors: [{ namespace: 'default' }], }); @@ -51,6 +55,12 @@ class EksClusterStack extends TestStack { }, }); + // inference instances + cluster.addCapacity('InferenceInstances', { + instanceType: new ec2.InstanceType('inf1.2xlarge'), + minCapacity: 1, + }); + // add a extra nodegroup cluster.addNodegroup('extra-ng', { instanceType: new ec2.InstanceType('t3.small'), diff --git a/packages/@aws-cdk/aws-eks/test/test.cluster.ts b/packages/@aws-cdk/aws-eks/test/test.cluster.ts index 4b00ac1ec6e36..c7a09d794e7cc 100644 --- a/packages/@aws-cdk/aws-eks/test/test.cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/test.cluster.ts @@ -2,7 +2,10 @@ import { countResources, expect, haveResource, haveResourceLike, not } from '@aw import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; +import * as fs from 'fs'; import { Test } from 'nodeunit'; +import * as path from 'path'; +import * as YAML from 'yaml'; import * as eks from '../lib'; import { KubectlLayer } from '../lib/kubectl-layer'; import { testFixture, testFixtureNoVpc } from './util'; @@ -1156,4 +1159,23 @@ export = { })); test.done(); }, + 'inference instances are supported'(test: Test) { + // GIVEN + const { stack } = testFixtureNoVpc(); + const cluster = new eks.Cluster(stack, 'Cluster', { defaultCapacity: 0 }); + + // WHEN + cluster.addCapacity('InferenceInstances', { + instanceType: new ec2.InstanceType('inf1.2xlarge'), + minCapacity: 1, + }); + const fileContents = fs.readFileSync(path.join(__dirname, '../lib', 'addons/neuron-device-plugin.yaml'), 'utf8'); + const sanitized = YAML.parse(fileContents); + + // THEN + expect(stack).to(haveResource(eks.KubernetesResource.RESOURCE_TYPE, { + Manifest: JSON.stringify([sanitized]), + })); + test.done(); + }, }}; From bb514c1eb1098ccbe5cee4d7570d11bc8d9155c3 Mon Sep 17 00:00:00 2001 From: Neta Nir Date: Sun, 28 Jun 2020 22:09:48 -0700 Subject: [PATCH 26/55] fix(rewrite): script ignores list of files (#8777) * fix(rewrite): script ignores files Co-authored-by: Neta Nir --- .../rewrite-imports/bin/rewrite-imports.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/@monocdk-experiment/rewrite-imports/bin/rewrite-imports.ts b/packages/@monocdk-experiment/rewrite-imports/bin/rewrite-imports.ts index a79f833d5e71c..6193a04f5715e 100644 --- a/packages/@monocdk-experiment/rewrite-imports/bin/rewrite-imports.ts +++ b/packages/@monocdk-experiment/rewrite-imports/bin/rewrite-imports.ts @@ -18,12 +18,15 @@ async function main() { 'node_modules/**', ]; - const files = await glob(process.argv[2], { ignore, matchBase: true }); - for (const file of files) { - const input = await fs.promises.readFile(file, { encoding: 'utf8' }); - const output = rewriteImports(input, file); - if (output.trim() !== input.trim()) { - await fs.promises.writeFile(file, output); + const args = process.argv.slice(2); + for (const arg of args) { + const files = await glob(arg, { ignore, matchBase: true }); + for (const file of files) { + const input = await fs.promises.readFile(file, { encoding: 'utf8' }); + const output = rewriteImports(input, file); + if (output.trim() !== input.trim()) { + await fs.promises.writeFile(file, output); + } } } } From 401594ea6cd1c9dc7c4f62ffeee95a720a0ec337 Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Mon, 29 Jun 2020 07:29:42 +0200 Subject: [PATCH 27/55] feat(lambda-nodejs): external and install modules (#8681) Add support for: * external modules: modules that should not be bundled. Defaults to `aws-sdk`. * install modules: modules that should not be bundled but included in the `node_modules` folder of the Lambda package. Those modules are installed in a Lambda compatible Docker image with the right installer (`npm` or `yarn`) based on lock file detection. Closes #6323 Closes #7912 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .gitignore | 3 + .../@aws-cdk/aws-lambda-nodejs/.gitignore | 4 - packages/@aws-cdk/aws-lambda-nodejs/README.md | 35 ++- .../aws-lambda-nodejs/lib/bundling.ts | 247 ++++++++++++------ .../aws-lambda-nodejs/lib/function.ts | 116 ++------ .../@aws-cdk/aws-lambda-nodejs/lib/index.ts | 1 + .../lib/package-json-manager.ts | 71 +++++ .../@aws-cdk/aws-lambda-nodejs/lib/util.ts | 16 +- .../@aws-cdk/aws-lambda-nodejs/package.json | 2 +- .../parcel-bundler/Dockerfile | 10 - .../aws-lambda-nodejs/parcel/Dockerfile | 19 ++ .../aws-lambda-nodejs/test/bundling.test.ts | 120 +++++++-- .../aws-lambda-nodejs/test/function.test.ts | 5 +- .../test/integ-handlers/dependencies.ts | 10 + .../test/integ.dependencies.expected.json | 103 ++++++++ .../test/integ.dependencies.ts | 25 ++ .../test/integ.function.expected.json | 38 +-- .../app/javascript/.template.gitignore | 5 +- .../app/typescript/.template.gitignore | 5 +- .../lib/typescript/.template.gitignore | 5 +- .../sample-app/javascript/.template.gitignore | 5 +- .../sample-app/typescript/.template.gitignore | 5 +- yarn.lock | 5 + 23 files changed, 584 insertions(+), 271 deletions(-) create mode 100644 packages/@aws-cdk/aws-lambda-nodejs/lib/package-json-manager.ts delete mode 100644 packages/@aws-cdk/aws-lambda-nodejs/parcel-bundler/Dockerfile create mode 100644 packages/@aws-cdk/aws-lambda-nodejs/parcel/Dockerfile create mode 100644 packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/dependencies.ts create mode 100644 packages/@aws-cdk/aws-lambda-nodejs/test/integ.dependencies.expected.json create mode 100644 packages/@aws-cdk/aws-lambda-nodejs/test/integ.dependencies.ts diff --git a/.gitignore b/.gitignore index 2cb016405e016..36d6e15a83ab0 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ cdk.out/ # Yarn error log yarn-error.log + +# Parcel default cache directory +.parcel-cache diff --git a/packages/@aws-cdk/aws-lambda-nodejs/.gitignore b/packages/@aws-cdk/aws-lambda-nodejs/.gitignore index 7be76e8fa94c1..ce811676a5cb2 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/.gitignore +++ b/packages/@aws-cdk/aws-lambda-nodejs/.gitignore @@ -14,10 +14,6 @@ nyc.config.js .LAST_PACKAGE *.snk -# Parcel -.build -.cache - !test/integ-handlers/js-handler.js !test/function.test.handler2.js !.eslintrc.js diff --git a/packages/@aws-cdk/aws-lambda-nodejs/README.md b/packages/@aws-cdk/aws-lambda-nodejs/README.md index 84b938347b6f1..b4e4579991f9e 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/README.md +++ b/packages/@aws-cdk/aws-lambda-nodejs/README.md @@ -53,10 +53,41 @@ new lambda.NodejsFunction(this, 'my-handler', { ``` ### Configuring Parcel -The `NodejsFunction` construct exposes some [Parcel](https://parceljs.org/) options via properties: `minify`, `sourceMaps`, -`buildDir` and `cacheDir`. +The `NodejsFunction` construct exposes some [Parcel](https://parceljs.org/) options via properties: `minify`, `sourceMaps` and `cacheDir`. Parcel transpiles your code (every internal module) with [@babel/preset-env](https://babeljs.io/docs/en/babel-preset-env) and uses the runtime version of your Lambda function as target. Configuring Babel with Parcel is possible via a `.babelrc` or a `babel` config in `package.json`. + +### Working with modules + +#### Externals +By default, all node modules are bundled except for `aws-sdk`. This can be configured by specifying +the `externalModules` prop. + +```ts +new lambda.NodejsFunction(this, 'my-handler', { + externalModules: [ + 'aws-sdk', // Use the 'aws-sdk' available in the Lambda runtime + 'cool-module', // 'cool-module' is already available in a Layer + ], +}); +``` + +#### Install modules +By default, all node modules referenced in your Lambda code will be bundled by Parcel. +Use the `nodeModules` prop to specify a list of modules that should not be bundled +but instead included in the `node_modules` folder of the Lambda package. This is useful +when working with native dependencies or when Parcel fails to bundle a module. + +```ts +new lambda.NodejsFunction(this, 'my-handler', { + nodeModules: ['native-module', 'other-module'] +}); +``` + +The modules listed in `nodeModules` must be present in the `package.json`'s dependencies. The +same version will be used for installation. If a lock file is detected (`package-lock.json` or +`yarn.lock`) it will be used along with the right installer (`npm` or `yarn`). The modules are +installed in a [Lambda compatible Docker container](https://github.com/lambci/docker-lambda). diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts index 15457bcf45869..274e043bf11a3 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts @@ -2,136 +2,213 @@ import * as lambda from '@aws-cdk/aws-lambda'; import * as cdk from '@aws-cdk/core'; import * as fs from 'fs'; import * as path from 'path'; -import { findPkgPath } from './util'; +import { PackageJsonManager } from './package-json-manager'; +import { findClosestPathContaining } from './util'; /** - * Options for Parcel bundling + * Base options for Parcel bundling */ -export interface ParcelOptions { +export interface ParcelBaseOptions { /** - * Entry file + * Whether to minify files when bundling. + * + * @default false */ - readonly entry: string; + readonly minify?: boolean; /** - * Expose modules as UMD under this name + * Whether to include source maps when bundling. + * + * @default false */ - readonly global: string; + readonly sourceMaps?: boolean; /** - * Minify + * The cache directory + * + * Parcel uses a filesystem cache for fast rebuilds. + * + * @default - `.cache` in the root directory */ - readonly minify?: boolean; + readonly cacheDir?: string; /** - * Include source maps + * The root of the project. This will be used as the source for the volume + * mounted in the Docker container. If you specify this prop, ensure that + * this path includes `entry` and any module/dependencies used by your + * function otherwise bundling will not be possible. + * + * @default - the closest path containing a .git folder */ - readonly sourceMaps?: boolean; + readonly projectRoot?: string; /** - * The cache directory + * Environment variables defined when Parcel runs. + * + * @default - no environment variables are defined. */ - readonly cacheDir?: string; + readonly parcelEnvironment?: { [key: string]: string; }; /** - * The node version to use as target for Babel + * A list of modules that should be considered as externals (already available + * in the runtime). + * + * @default ['aws-sdk'] */ - readonly nodeVersion: string; + readonly externalModules?: string[]; /** - * The docker tag of the node base image to use in the parcel-bundler docker image + * A list of modules that should be installed instead of bundled. Modules are + * installed in a Lambda compatible environnment. * - * @see https://hub.docker.com/_/node/?tab=tags + * @default - all modules are bundled */ - readonly nodeDockerTag: string; + readonly nodeModules?: string[]; /** - * The root of the project. This will be used as the source for the volume - * mounted in the Docker container. + * The version of Parcel to use. + * + * @default - 2.0.0-beta.1 + */ + readonly parcelVersion?: string; +} + +/** + * Options for Parcel bundling + */ +export interface ParcelOptions extends ParcelBaseOptions { + /** + * Entry file */ - readonly projectRoot: string; + readonly entry: string; /** - * The environment variables to pass to the container running Parcel. - * - * @default - no environment variables are passed to the container + * The runtime of the lambda function */ - readonly environment?: { [key: string]: string; }; + readonly runtime: lambda.Runtime; } /** - * Parcel code + * Bundling */ export class Bundling { + /** + * Parcel bundled Lambda asset code + */ public static parcel(options: ParcelOptions): lambda.AssetCode { - // Original package.json path and content - let pkgPath = findPkgPath(); - if (!pkgPath) { - throw new Error('Cannot find a `package.json` in this project.'); + // Find project root + const projectRoot = options.projectRoot ?? findClosestPathContaining(`.git${path.sep}`); + if (!projectRoot) { + throw new Error('Cannot find project root. Please specify it with `projectRoot`.'); } - pkgPath = path.join(pkgPath, 'package.json'); - const originalPkg = fs.readFileSync(pkgPath); - const originalPkgJson = JSON.parse(originalPkg.toString()); - // Update engines.node in package.json to set the right Babel target - setEngines(options.nodeVersion, pkgPath, originalPkgJson); + // Bundling image derived from runtime bundling image (lambci) + const image = cdk.BundlingDockerImage.fromAsset(path.join(__dirname, '../parcel'), { + buildArgs: { + IMAGE: options.runtime.bundlingDockerImage.image, + PARCEL_VERSION: options.parcelVersion ?? '2.0.0-beta.1', + }, + }); + + const packageJsonManager = new PackageJsonManager(); + + // Collect external and install modules + let includeNodeModules: { [key: string]: boolean } | undefined; + let dependencies: { [key: string]: string } | undefined; + const externalModules = options.externalModules ?? ['aws-sdk']; + if (externalModules || options.nodeModules) { + const modules = [...externalModules, ...options.nodeModules ?? []]; + includeNodeModules = {}; + for (const mod of modules) { + includeNodeModules[mod] = false; + } + if (options.nodeModules) { + dependencies = packageJsonManager.getVersions(options.nodeModules); + } + } - // Entry file path relative to container path - const containerEntryPath = path.join(cdk.AssetStaging.BUNDLING_INPUT_DIR, path.relative(options.projectRoot, path.resolve(options.entry))); - - try { - const command = [ - 'parcel', 'build', containerEntryPath.replace(/\\/g, '/'), // Always use POSIX paths in the container - '--out-dir', cdk.AssetStaging.BUNDLING_OUTPUT_DIR, - '--out-file', 'index.js', - '--global', options.global, - '--target', 'node', - '--bundle-node-modules', - '--log-level', '2', - !options.minify && '--no-minify', - !options.sourceMaps && '--no-source-maps', - ...(options.cacheDir ? ['--cache-dir', '/parcel-cache'] : []), - ].filter(Boolean) as string[]; - - return lambda.Code.fromAsset(options.projectRoot, { - assetHashType: cdk.AssetHashType.BUNDLE, - bundling: { - image: cdk.BundlingDockerImage.fromAsset(path.join(__dirname, '../parcel-bundler'), { - buildArgs: { - NODE_TAG: options.nodeDockerTag ?? `${process.versions.node}-alpine`, - }, - }), - environment: options.environment, - volumes: options.cacheDir - ? [{ containerPath: '/parcel-cache', hostPath: options.cacheDir }] - : [], - workingDirectory: path.dirname(containerEntryPath).replace(/\\/g, '/'), // Always use POSIX paths in the container - command, + // Configure target in package.json for Parcel + packageJsonManager.update({ + 'cdk-lambda': `${cdk.AssetStaging.BUNDLING_OUTPUT_DIR}/index.js`, + 'targets': { + 'cdk-lambda': { + context: 'node', + includeNodeModules: includeNodeModules ?? true, + sourceMap: options.sourceMaps ?? false, + minify: options.minify ?? false, + engines: { + node: `>= ${runtimeVersion(options.runtime)}`, + }, }, - }); - } finally { - restorePkg(pkgPath, originalPkg); + }, + }); + + // Entry file path relative to container path + const containerEntryPath = path.join(cdk.AssetStaging.BUNDLING_INPUT_DIR, path.relative(projectRoot, path.resolve(options.entry))); + const parcelCommand = `parcel build ${containerEntryPath.replace(/\\/g, '/')} --target cdk-lambda${options.cacheDir ? ' --cache-dir /parcel-cache' : ''}`; + + let installer = Installer.NPM; + let lockfile: string | undefined; + let depsCommand = ''; + + if (dependencies) { + // Create a dummy package.json for dependencies that we need to install + fs.writeFileSync( + path.join(projectRoot, '.package.json'), + JSON.stringify({ dependencies }), + ); + + // Use npm unless we have a yarn.lock. + if (fs.existsSync(path.join(projectRoot, LockFile.YARN))) { + installer = Installer.YARN; + lockfile = LockFile.YARN; + } else if (fs.existsSync(path.join(projectRoot, LockFile.NPM))) { + lockfile = LockFile.NPM; + } + + // Move dummy package.json and lock file then install + depsCommand = chain([ + `mv ${cdk.AssetStaging.BUNDLING_INPUT_DIR}/.package.json ${cdk.AssetStaging.BUNDLING_OUTPUT_DIR}/package.json`, + lockfile ? `cp ${cdk.AssetStaging.BUNDLING_INPUT_DIR}/${lockfile} ${cdk.AssetStaging.BUNDLING_OUTPUT_DIR}/${lockfile}` : '', + `cd ${cdk.AssetStaging.BUNDLING_OUTPUT_DIR} && ${installer} install`, + ]); } + + return lambda.Code.fromAsset(projectRoot, { + assetHashType: cdk.AssetHashType.BUNDLE, + bundling: { + image, + command: ['bash', '-c', chain([parcelCommand, depsCommand])], + environment: options.parcelEnvironment, + volumes: options.cacheDir + ? [{ containerPath: '/parcel-cache', hostPath: options.cacheDir }] + : [], + workingDirectory: path.dirname(containerEntryPath).replace(/\\/g, '/'), // Always use POSIX paths in the container + }, + }); } } -function setEngines(nodeVersion: string, pkgPath: string, originalPkgJson: any): void { - // Update engines.node (Babel target) - const updateData = { - engines: { - node: `>= ${nodeVersion}`, - }, - }; - - // Write new package.json - if (Object.keys(updateData).length !== 0) { - fs.writeFileSync(pkgPath, JSON.stringify({ - ...originalPkgJson, - ...updateData, - }, null, 2)); +enum Installer { + NPM = 'npm', + YARN = 'yarn', +} + +enum LockFile { + NPM = 'package-lock.json', + YARN = 'yarn.lock' +} + +function runtimeVersion(runtime: lambda.Runtime): string { + const match = runtime.name.match(/nodejs(\d+)/); + + if (!match) { + throw new Error('Cannot extract version from runtime.'); } + + return match[1]; } -function restorePkg(pkgPath: string, originalPkg: Buffer): void { - fs.writeFileSync(pkgPath, originalPkg); +function chain(commands: string[]): string { + return commands.filter(c => !!c).join(' && '); } diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts index c231eb06d7f84..70cfb8f19b130 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts @@ -2,13 +2,14 @@ import * as lambda from '@aws-cdk/aws-lambda'; import * as cdk from '@aws-cdk/core'; import * as fs from 'fs'; import * as path from 'path'; -import { Bundling } from './bundling'; -import { findGitPath, nodeMajorVersion, parseStackTrace } from './util'; +import { Bundling, ParcelBaseOptions } from './bundling'; +import { PackageJsonManager } from './package-json-manager'; +import { nodeMajorVersion, parseStackTrace } from './util'; /** * Properties for a NodejsFunction */ -export interface NodejsFunctionProps extends lambda.FunctionOptions { +export interface NodejsFunctionProps extends lambda.FunctionOptions, ParcelBaseOptions { /** * Path to the entry file (JavaScript or TypeScript). * @@ -34,62 +35,6 @@ export interface NodejsFunctionProps extends lambda.FunctionOptions { * `NODEJS_10_X` otherwise. */ readonly runtime?: lambda.Runtime; - - /** - * Whether to minify files when bundling. - * - * @default false - */ - readonly minify?: boolean; - - /** - * Whether to include source maps when bundling. - * - * @default false - */ - readonly sourceMaps?: boolean; - - /** - * The build directory - * - * @default - `.build` in the entry file directory - */ - readonly buildDir?: string; - - /** - * The cache directory - * - * Parcel uses a filesystem cache for fast rebuilds. - * - * @default - `.cache` in the root directory - */ - readonly cacheDir?: string; - - /** - * The docker tag of the node base image to use in the parcel-bundler docker image - * - * @see https://hub.docker.com/_/node/?tab=tags - * - * @default - the `process.versions.node` alpine image - */ - readonly nodeDockerTag?: string; - - /** - * The root of the project. This will be used as the source for the volume - * mounted in the Docker container. If you specify this prop, ensure that - * this path includes `entry` and any module/dependencies used by your - * function otherwise bundling will not be possible. - * - * @default - the closest path containing a .git folder - */ - readonly projectRoot?: string; - - /** - * The environment variables to pass to the container running Parcel. - * - * @default - no environment variables are passed to the container - */ - readonly containerEnvironment?: { [key: string]: string; }; } /** @@ -101,34 +46,32 @@ export class NodejsFunction extends lambda.Function { throw new Error('Only `NODEJS` runtimes are supported.'); } + // Entry and defaults const entry = findEntry(id, props.entry); const handler = props.handler ?? 'handler'; const defaultRunTime = nodeMajorVersion() >= 12 ? lambda.Runtime.NODEJS_12_X : lambda.Runtime.NODEJS_10_X; const runtime = props.runtime ?? defaultRunTime; - const projectRoot = props.projectRoot ?? findGitPath(); - if (!projectRoot) { - throw new Error('Cannot find project root. Please specify it with `projectRoot`.'); - } - const nodeDockerTag = props.nodeDockerTag ?? `${process.versions.node}-alpine`; - super(scope, id, { - ...props, - runtime, - code: Bundling.parcel({ - entry, - global: handler, - minify: props.minify, - sourceMaps: props.sourceMaps, - cacheDir: props.cacheDir, - nodeVersion: extractVersion(runtime), - nodeDockerTag, - projectRoot: path.resolve(projectRoot), - environment: props.containerEnvironment, - }), - handler: `index.${handler}`, - }); + // We need to restore the package.json after bundling + const packageJsonManager = new PackageJsonManager(); + + try { + super(scope, id, { + ...props, + runtime, + code: Bundling.parcel({ + entry, + runtime, + ...props, + }), + handler: `index.${handler}`, + }); + } finally { + // We can only restore after the code has been bound to the function + packageJsonManager.restore(); + } } } @@ -178,16 +121,3 @@ function findDefiningFile(): string { return stackTrace[functionIndex + 1].file; } - -/** - * Extracts the version from the runtime - */ -function extractVersion(runtime: lambda.Runtime): string { - const match = runtime.name.match(/nodejs(\d+)/); - - if (!match) { - throw new Error('Cannot extract version from runtime.'); - } - - return match[1]; -} diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/index.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/index.ts index 2653adb2a89e8..bcda298c2f5fe 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/index.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/index.ts @@ -1 +1,2 @@ export * from './function'; +export * from './bundling'; diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/package-json-manager.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/package-json-manager.ts new file mode 100644 index 0000000000000..c43c4b0963351 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/package-json-manager.ts @@ -0,0 +1,71 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { findClosestPathContaining } from './util'; + +/** + * A package.json manager to act on the closest package.json file. + * + * Configuring the bundler requires to manipulate the package.json and then + * restore it. + */ +export class PackageJsonManager { + private readonly pkgPath: string; + private readonly pkg: Buffer; + private readonly pkgJson: PackageJson; + + constructor() { + const pkgPath = findClosestPathContaining('package.json'); + if (!pkgPath) { + throw new Error('Cannot find a `package.json` in this project.'); + } + this.pkgPath = path.join(pkgPath, 'package.json'); + this.pkg = fs.readFileSync(this.pkgPath); + this.pkgJson = JSON.parse(this.pkg.toString()); + } + + /** + * Update the package.json + */ + public update(data: any) { + fs.writeFileSync(this.pkgPath, JSON.stringify({ + ...this.pkgJson, + ...data, + }, null, 2)); + } + + /** + * Restore the package.json to the original + */ + public restore() { + fs.writeFileSync(this.pkgPath, this.pkg); + } + + /** + * Extract versions for a list of modules + */ + public getVersions(modules: string[]): { [key: string]: string } { + const dependencies: { [key: string]: string } = {}; + + const allDependencies = { + ...this.pkgJson.dependencies ?? {}, + ...this.pkgJson.devDependencies ?? {}, + ...this.pkgJson.peerDependencies ?? {}, + }; + + for (const mod of modules) { + if (!allDependencies[mod]) { + throw new Error(`Cannot extract version for ${mod} in package.json`); + } + dependencies[mod] = allDependencies[mod]; + } + + return dependencies; + + } +} + +interface PackageJson { + dependencies?: { [key: string]: string }; + devDependencies?: { [key: string]: string }; + peerDependencies?: { [key: string]: string }; +} diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts index c54b0e3ed56c4..92d61e7f76e1a 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts @@ -53,7 +53,7 @@ export function nodeMajorVersion(): number { /** * Finds the closest path containg a path */ -function findClosestPathContaining(p: string): string | undefined { +export function findClosestPathContaining(p: string): string | undefined { for (const nodeModulesPath of module.paths) { if (fs.existsSync(path.join(path.dirname(nodeModulesPath), p))) { return path.dirname(nodeModulesPath); @@ -62,17 +62,3 @@ function findClosestPathContaining(p: string): string | undefined { return undefined; } - -/** - * Finds closest package.json path - */ -export function findPkgPath(): string | undefined { - return findClosestPathContaining('package.json'); -} - -/** - * Finds closest .git/ - */ -export function findGitPath(): string | undefined { - return findClosestPathContaining(`.git${path.sep}`); -} diff --git a/packages/@aws-cdk/aws-lambda-nodejs/package.json b/packages/@aws-cdk/aws-lambda-nodejs/package.json index 31995f757c849..48c612067a32b 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/package.json +++ b/packages/@aws-cdk/aws-lambda-nodejs/package.json @@ -61,7 +61,7 @@ "@aws-cdk/assert": "0.0.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", - "fs-extra": "^9.0.1", + "delay": "4.3.0", "pkglint": "0.0.0" }, "dependencies": { diff --git a/packages/@aws-cdk/aws-lambda-nodejs/parcel-bundler/Dockerfile b/packages/@aws-cdk/aws-lambda-nodejs/parcel-bundler/Dockerfile deleted file mode 100644 index 0a92746c6464c..0000000000000 --- a/packages/@aws-cdk/aws-lambda-nodejs/parcel-bundler/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -# runs the parcel-bundler npm package to package and install dependencies of nodejs lambda functions -ARG NODE_TAG -FROM node:${NODE_TAG} - -RUN yarn global add parcel-bundler@^1 - -# add the global node_modules folder to NODE_PATH so that plugins can find parcel-bundler -ENV NODE_PATH /usr/local/share/.config/yarn/global/node_modules - -CMD [ "parcel" ] diff --git a/packages/@aws-cdk/aws-lambda-nodejs/parcel/Dockerfile b/packages/@aws-cdk/aws-lambda-nodejs/parcel/Dockerfile new file mode 100644 index 0000000000000..0b91c0df6f600 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/parcel/Dockerfile @@ -0,0 +1,19 @@ +# The correct lambci build image based on the runtime of the function will be +# passed as build arg. The default allows to do `docker build .` when testing. +ARG IMAGE=lambci/lambda:build-nodejs12.x +FROM $IMAGE + +# Ensure npm cache is not owned by root because the image will not run +# as root and can potentially run `npm install`. +RUN mkdir /npm-cache && \ + chown -R 1000:1000 /npm-cache && \ + npm config --global set cache /npm-cache + +# Install yarn +RUN npm install --global yarn + +# Install parcel 2 (fix the version since it's still in beta) +ARG PARCEL_VERSION=2.0.0-beta.1 +RUN yarn global add parcel@$PARCEL_VERSION + +CMD [ "parcel" ] diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts index 9a58350934516..e7129cf5da0c8 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts @@ -1,11 +1,14 @@ -import { Code } from '@aws-cdk/aws-lambda'; +import { Code, Runtime } from '@aws-cdk/aws-lambda'; import { AssetHashType } from '@aws-cdk/core'; +import { version as delayVersion } from 'delay/package.json'; import * as fs from 'fs'; import { Bundling } from '../lib/bundling'; jest.mock('@aws-cdk/aws-lambda'); -const writeFileSyncMock = jest.spyOn(fs, 'writeFileSync'); +const writeFileSyncMock = jest.spyOn(fs, 'writeFileSync').mockReturnValue(); +const existsSyncOriginal = fs.existsSync; +const existsSyncMock = jest.spyOn(fs, 'existsSync'); beforeEach(() => { jest.clearAllMocks(); @@ -14,12 +17,10 @@ beforeEach(() => { test('Parcel bundling', () => { Bundling.parcel({ entry: '/project/folder/entry.ts', - global: 'handler', + runtime: Runtime.NODEJS_12_X, cacheDir: '/cache-dir', - nodeDockerTag: 'lts-alpine', - nodeVersion: '12', projectRoot: '/project', - environment: { + parcelEnvironment: { KEY: 'value', }, }); @@ -34,42 +35,113 @@ test('Parcel bundling', () => { volumes: [{ containerPath: '/parcel-cache', hostPath: '/cache-dir' }], workingDirectory: '/asset-input/folder', command: [ - 'parcel', 'build', '/asset-input/folder/entry.ts', - '--out-dir', '/asset-output', - '--out-file', 'index.js', - '--global', 'handler', - '--target', 'node', - '--bundle-node-modules', - '--log-level', '2', - '--no-minify', - '--no-source-maps', - '--cache-dir', '/parcel-cache', + 'bash', '-c', 'parcel build /asset-input/folder/entry.ts --target cdk-lambda --cache-dir /parcel-cache', ], }), }); // Correctly updates package.json - expect(writeFileSyncMock).toHaveBeenCalledWith( - expect.stringContaining('package.json'), - expect.stringContaining('"node": ">= 12"'), - ); + const call = writeFileSyncMock.mock.calls[0]; + expect(call[0]).toMatch('package.json'); + expect(JSON.parse(call[1])).toEqual(expect.objectContaining({ + 'cdk-lambda': '/asset-output/index.js', + 'targets': { + 'cdk-lambda': { + context: 'node', + includeNodeModules: { + 'aws-sdk': false, + }, + sourceMap: false, + minify: false, + engines: { + node: '>= 12', + }, + }, + }, + })); }); test('Parcel with Windows paths', () => { Bundling.parcel({ entry: 'C:\\my-project\\lib\\entry.ts', - global: 'handler', + runtime: Runtime.NODEJS_12_X, cacheDir: '/cache-dir', - nodeDockerTag: 'lts-alpine', - nodeVersion: '12', projectRoot: 'C:\\my-project', }); expect(Code.fromAsset).toHaveBeenCalledWith('C:\\my-project', expect.objectContaining({ bundling: expect.objectContaining({ command: expect.arrayContaining([ - 'parcel', 'build', expect.stringContaining('/lib/entry.ts'), + expect.stringContaining('/lib/entry.ts'), ]), }), })); }); + +test('Parcel bundling with externals and dependencies', () => { + Bundling.parcel({ + entry: '/project/folder/entry.ts', + runtime: Runtime.NODEJS_12_X, + projectRoot: '/project', + externalModules: ['abc'], + nodeModules: ['delay'], + }); + + // Correctly bundles with parcel + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.BUNDLE, + bundling: expect.objectContaining({ + command: [ + 'bash', '-c', + 'parcel build /asset-input/folder/entry.ts --target cdk-lambda && mv /asset-input/.package.json /asset-output/package.json && cd /asset-output && npm install', + ], + }), + }); + + // Correctly updates package.json + const call = writeFileSyncMock.mock.calls[0]; + expect(call[0]).toMatch('package.json'); + expect(JSON.parse(call[1])).toEqual(expect.objectContaining({ + targets: expect.objectContaining({ + 'cdk-lambda': expect.objectContaining({ + includeNodeModules: { + delay: false, + abc: false, + }, + }), + }), + })); + + // Correctly writes dummy package.json + expect(writeFileSyncMock).toHaveBeenCalledWith('/project/.package.json', JSON.stringify({ + dependencies: { + delay: delayVersion, + }, + })); +}); + +test('Detects yarn.lock', () => { + existsSyncMock.mockImplementation((p: fs.PathLike) => { + if (/yarn.lock/.test(p.toString())) { + return true; + } + return existsSyncOriginal(p); + }); + + Bundling.parcel({ + entry: '/project/folder/entry.ts', + runtime: Runtime.NODEJS_12_X, + projectRoot: '/project', + nodeModules: ['delay'], + }); + + // Correctly bundles with parcel + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.BUNDLE, + bundling: expect.objectContaining({ + command: expect.arrayContaining([ + expect.stringMatching(/yarn\.lock.+yarn install/), + ]), + }), + }); +}); diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts index 25f5589e9e388..200200fdeb1ce 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts @@ -29,7 +29,6 @@ test('NodejsFunction with .ts handler', () => { expect(Bundling.parcel).toHaveBeenCalledWith(expect.objectContaining({ entry: expect.stringContaining('function.test.handler1.ts'), // Automatically finds .ts handler file - global: 'handler', })); expect(stack).toHaveResource('AWS::Lambda::Function', { @@ -50,13 +49,13 @@ test('NodejsFunction with .js handler', () => { test('NodejsFunction with container env vars', () => { // WHEN new NodejsFunction(stack, 'handler1', { - containerEnvironment: { + parcelEnvironment: { KEY: 'VALUE', }, }); expect(Bundling.parcel).toHaveBeenCalledWith(expect.objectContaining({ - environment: { + parcelEnvironment: { KEY: 'VALUE', }, })); diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/dependencies.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/dependencies.ts new file mode 100644 index 0000000000000..31abbb04b4cfe --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/dependencies.ts @@ -0,0 +1,10 @@ +// tslint:disable:no-console +import { S3 } from 'aws-sdk'; // eslint-disable-line import/no-extraneous-dependencies +import * as delay from 'delay'; + +const s3 = new S3(); + +export async function handler() { + console.log(s3); + await delay(5); +} diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.dependencies.expected.json b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.dependencies.expected.json new file mode 100644 index 0000000000000..d67505788c16c --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.dependencies.expected.json @@ -0,0 +1,103 @@ +{ + "Resources": { + "externalServiceRole85A00A90": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "external068F12D1": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParametersf3a8dacfae15c18a4397faeaae668d7170beb89acf2fd97e47f260f73587bde4S3BucketC81DD688" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParametersf3a8dacfae15c18a4397faeaae668d7170beb89acf2fd97e47f260f73587bde4S3VersionKeyDA9CBF67" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParametersf3a8dacfae15c18a4397faeaae668d7170beb89acf2fd97e47f260f73587bde4S3VersionKeyDA9CBF67" + } + ] + } + ] + } + ] + ] + } + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "externalServiceRole85A00A90", + "Arn" + ] + }, + "Runtime": "nodejs12.x" + }, + "DependsOn": [ + "externalServiceRole85A00A90" + ] + } + }, + "Parameters": { + "AssetParametersf3a8dacfae15c18a4397faeaae668d7170beb89acf2fd97e47f260f73587bde4S3BucketC81DD688": { + "Type": "String", + "Description": "S3 bucket for asset \"f3a8dacfae15c18a4397faeaae668d7170beb89acf2fd97e47f260f73587bde4\"" + }, + "AssetParametersf3a8dacfae15c18a4397faeaae668d7170beb89acf2fd97e47f260f73587bde4S3VersionKeyDA9CBF67": { + "Type": "String", + "Description": "S3 key for asset version \"f3a8dacfae15c18a4397faeaae668d7170beb89acf2fd97e47f260f73587bde4\"" + }, + "AssetParametersf3a8dacfae15c18a4397faeaae668d7170beb89acf2fd97e47f260f73587bde4ArtifactHash0E6684C0": { + "Type": "String", + "Description": "Artifact hash for asset \"f3a8dacfae15c18a4397faeaae668d7170beb89acf2fd97e47f260f73587bde4\"" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.dependencies.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.dependencies.ts new file mode 100644 index 0000000000000..acd55e7f6e8c7 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.dependencies.ts @@ -0,0 +1,25 @@ +import { Runtime } from '@aws-cdk/aws-lambda'; +import { App, Construct, Stack, StackProps } from '@aws-cdk/core'; +import * as path from 'path'; +import * as lambda from '../lib'; + +class TestStack extends Stack { + constructor(scope: Construct, id: string, props?: StackProps) { + super(scope, id, props); + + // This function uses aws-sdk but it will not be included + new lambda.NodejsFunction(this, 'external', { + entry: path.join(__dirname, 'integ-handlers/dependencies.ts'), + runtime: Runtime.NODEJS_12_X, + minify: true, + // Will be installed, not bundled + // (delay is a zero dependency package and its version is fixed + // in the package.json to ensure a stable hash for this integ test) + nodeModules: ['delay'], + }); + } +} + +const app = new App(); +new TestStack(app, 'cdk-integ-lambda-nodejs-dependencies'); +app.synth(); diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.expected.json b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.expected.json index 6633fb1402bf7..b88a7e8503886 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.expected.json +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.function.expected.json @@ -36,7 +36,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParameters20afe351e391b62b260d621490f511b5a25bc8bceb71127d3784c5d8e62aa5e9S3Bucket7F316AC2" + "Ref": "AssetParameters9003cb217f859844be0ac9b0b22c7eb387ac397607197d29b624cbf8dc872a88S3BucketD344F833" }, "S3Key": { "Fn::Join": [ @@ -49,7 +49,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters20afe351e391b62b260d621490f511b5a25bc8bceb71127d3784c5d8e62aa5e9S3VersionKeyEEDC3772" + "Ref": "AssetParameters9003cb217f859844be0ac9b0b22c7eb387ac397607197d29b624cbf8dc872a88S3VersionKeyEB3332E0" } ] } @@ -62,7 +62,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters20afe351e391b62b260d621490f511b5a25bc8bceb71127d3784c5d8e62aa5e9S3VersionKeyEEDC3772" + "Ref": "AssetParameters9003cb217f859844be0ac9b0b22c7eb387ac397607197d29b624cbf8dc872a88S3VersionKeyEB3332E0" } ] } @@ -121,7 +121,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParameters39c8a0dc659dd89e6876d7d8447b17176396320962e88fb69ea7d7feb9a23990S3Bucket88C76A86" + "Ref": "AssetParameters0a35a944532d281b38e1ee670488bc40e0c813140eb0a41371db4c5a32202be0S3Bucket3B0DF548" }, "S3Key": { "Fn::Join": [ @@ -134,7 +134,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters39c8a0dc659dd89e6876d7d8447b17176396320962e88fb69ea7d7feb9a23990S3VersionKey1E5E4562" + "Ref": "AssetParameters0a35a944532d281b38e1ee670488bc40e0c813140eb0a41371db4c5a32202be0S3VersionKey1D84CC0E" } ] } @@ -147,7 +147,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters39c8a0dc659dd89e6876d7d8447b17176396320962e88fb69ea7d7feb9a23990S3VersionKey1E5E4562" + "Ref": "AssetParameters0a35a944532d281b38e1ee670488bc40e0c813140eb0a41371db4c5a32202be0S3VersionKey1D84CC0E" } ] } @@ -172,29 +172,29 @@ } }, "Parameters": { - "AssetParameters20afe351e391b62b260d621490f511b5a25bc8bceb71127d3784c5d8e62aa5e9S3Bucket7F316AC2": { + "AssetParameters9003cb217f859844be0ac9b0b22c7eb387ac397607197d29b624cbf8dc872a88S3BucketD344F833": { "Type": "String", - "Description": "S3 bucket for asset \"20afe351e391b62b260d621490f511b5a25bc8bceb71127d3784c5d8e62aa5e9\"" + "Description": "S3 bucket for asset \"9003cb217f859844be0ac9b0b22c7eb387ac397607197d29b624cbf8dc872a88\"" }, - "AssetParameters20afe351e391b62b260d621490f511b5a25bc8bceb71127d3784c5d8e62aa5e9S3VersionKeyEEDC3772": { + "AssetParameters9003cb217f859844be0ac9b0b22c7eb387ac397607197d29b624cbf8dc872a88S3VersionKeyEB3332E0": { "Type": "String", - "Description": "S3 key for asset version \"20afe351e391b62b260d621490f511b5a25bc8bceb71127d3784c5d8e62aa5e9\"" + "Description": "S3 key for asset version \"9003cb217f859844be0ac9b0b22c7eb387ac397607197d29b624cbf8dc872a88\"" }, - "AssetParameters20afe351e391b62b260d621490f511b5a25bc8bceb71127d3784c5d8e62aa5e9ArtifactHash8387A82E": { + "AssetParameters9003cb217f859844be0ac9b0b22c7eb387ac397607197d29b624cbf8dc872a88ArtifactHash079EA103": { "Type": "String", - "Description": "Artifact hash for asset \"20afe351e391b62b260d621490f511b5a25bc8bceb71127d3784c5d8e62aa5e9\"" + "Description": "Artifact hash for asset \"9003cb217f859844be0ac9b0b22c7eb387ac397607197d29b624cbf8dc872a88\"" }, - "AssetParameters39c8a0dc659dd89e6876d7d8447b17176396320962e88fb69ea7d7feb9a23990S3Bucket88C76A86": { + "AssetParameters0a35a944532d281b38e1ee670488bc40e0c813140eb0a41371db4c5a32202be0S3Bucket3B0DF548": { "Type": "String", - "Description": "S3 bucket for asset \"39c8a0dc659dd89e6876d7d8447b17176396320962e88fb69ea7d7feb9a23990\"" + "Description": "S3 bucket for asset \"0a35a944532d281b38e1ee670488bc40e0c813140eb0a41371db4c5a32202be0\"" }, - "AssetParameters39c8a0dc659dd89e6876d7d8447b17176396320962e88fb69ea7d7feb9a23990S3VersionKey1E5E4562": { + "AssetParameters0a35a944532d281b38e1ee670488bc40e0c813140eb0a41371db4c5a32202be0S3VersionKey1D84CC0E": { "Type": "String", - "Description": "S3 key for asset version \"39c8a0dc659dd89e6876d7d8447b17176396320962e88fb69ea7d7feb9a23990\"" + "Description": "S3 key for asset version \"0a35a944532d281b38e1ee670488bc40e0c813140eb0a41371db4c5a32202be0\"" }, - "AssetParameters39c8a0dc659dd89e6876d7d8447b17176396320962e88fb69ea7d7feb9a23990ArtifactHash37B9CB08": { + "AssetParameters0a35a944532d281b38e1ee670488bc40e0c813140eb0a41371db4c5a32202be0ArtifactHash7545DAEB": { "Type": "String", - "Description": "Artifact hash for asset \"39c8a0dc659dd89e6876d7d8447b17176396320962e88fb69ea7d7feb9a23990\"" + "Description": "Artifact hash for asset \"0a35a944532d281b38e1ee670488bc40e0c813140eb0a41371db4c5a32202be0\"" } } -} +} \ No newline at end of file diff --git a/packages/aws-cdk/lib/init-templates/app/javascript/.template.gitignore b/packages/aws-cdk/lib/init-templates/app/javascript/.template.gitignore index 599776985b7ff..a2da1bef05b07 100644 --- a/packages/aws-cdk/lib/init-templates/app/javascript/.template.gitignore +++ b/packages/aws-cdk/lib/init-templates/app/javascript/.template.gitignore @@ -4,6 +4,5 @@ node_modules .cdk.staging cdk.out -# Parcel build directories -.cache -.build +# Parcel default cache directory +.parcel-cache diff --git a/packages/aws-cdk/lib/init-templates/app/typescript/.template.gitignore b/packages/aws-cdk/lib/init-templates/app/typescript/.template.gitignore index 96eba04a818de..305c7fbcc4d89 100644 --- a/packages/aws-cdk/lib/init-templates/app/typescript/.template.gitignore +++ b/packages/aws-cdk/lib/init-templates/app/typescript/.template.gitignore @@ -7,6 +7,5 @@ node_modules .cdk.staging cdk.out -# Parcel build directories -.cache -.build +# Parcel default cache directory +.parcel-cache diff --git a/packages/aws-cdk/lib/init-templates/lib/typescript/.template.gitignore b/packages/aws-cdk/lib/init-templates/lib/typescript/.template.gitignore index 96eba04a818de..305c7fbcc4d89 100644 --- a/packages/aws-cdk/lib/init-templates/lib/typescript/.template.gitignore +++ b/packages/aws-cdk/lib/init-templates/lib/typescript/.template.gitignore @@ -7,6 +7,5 @@ node_modules .cdk.staging cdk.out -# Parcel build directories -.cache -.build +# Parcel default cache directory +.parcel-cache diff --git a/packages/aws-cdk/lib/init-templates/sample-app/javascript/.template.gitignore b/packages/aws-cdk/lib/init-templates/sample-app/javascript/.template.gitignore index 599776985b7ff..a2da1bef05b07 100644 --- a/packages/aws-cdk/lib/init-templates/sample-app/javascript/.template.gitignore +++ b/packages/aws-cdk/lib/init-templates/sample-app/javascript/.template.gitignore @@ -4,6 +4,5 @@ node_modules .cdk.staging cdk.out -# Parcel build directories -.cache -.build +# Parcel default cache directory +.parcel-cache diff --git a/packages/aws-cdk/lib/init-templates/sample-app/typescript/.template.gitignore b/packages/aws-cdk/lib/init-templates/sample-app/typescript/.template.gitignore index 96eba04a818de..305c7fbcc4d89 100644 --- a/packages/aws-cdk/lib/init-templates/sample-app/typescript/.template.gitignore +++ b/packages/aws-cdk/lib/init-templates/sample-app/typescript/.template.gitignore @@ -7,6 +7,5 @@ node_modules .cdk.staging cdk.out -# Parcel build directories -.cache -.build +# Parcel default cache directory +.parcel-cache diff --git a/yarn.lock b/yarn.lock index 6abcc81885b97..3ad380188332a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3528,6 +3528,11 @@ degenerator@^1.0.4: escodegen "1.x.x" esprima "3.x.x" +delay@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-4.3.0.tgz#efeebfb8f545579cb396b3a722443ec96d14c50e" + integrity sha512-Lwaf3zVFDMBop1yDuFZ19F9WyGcZcGacsbdlZtWjQmM50tOcMntm1njF/Nb/Vjij3KaSvCF+sEYGKrrjObu2NA== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" From 75e6d255e8a6f3a45f0c65905e23bf058c8ced27 Mon Sep 17 00:00:00 2001 From: Shiv Lakshminarayan Date: Sun, 28 Jun 2020 22:53:39 -0700 Subject: [PATCH 28/55] chore(stepfunctions): make renderTask internal for the task state and derived classes (#8768) `renderTask()` has been marked internal and renamed to `_renderTask()` to align with naming convention of internal APIs Motivation: users do not directly need to interact or use this API. It's responsible for rendering all Amazon States Language (ASL) properties for service integrations to Step Functions. the `toStateJson()` API is public on the `State` class and can be used in tests for users that want to look at a task state's configuration. the partial configuration that comes from `_renderTask()` is included in the `toStateJson()` API. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-stepfunctions-tasks/lib/batch/submit-job.ts | 5 ++++- .../aws-stepfunctions-tasks/lib/dynamodb/delete-item.ts | 5 ++++- .../aws-stepfunctions-tasks/lib/dynamodb/get-item.ts | 5 ++++- .../aws-stepfunctions-tasks/lib/dynamodb/put-item.ts | 5 ++++- .../aws-stepfunctions-tasks/lib/dynamodb/update-item.ts | 5 ++++- .../aws-stepfunctions-tasks/lib/emr/emr-add-step.ts | 5 ++++- .../aws-stepfunctions-tasks/lib/emr/emr-cancel-step.ts | 5 ++++- .../aws-stepfunctions-tasks/lib/emr/emr-create-cluster.ts | 5 ++++- .../lib/emr/emr-modify-instance-fleet-by-name.ts | 5 ++++- .../lib/emr/emr-modify-instance-group-by-name.ts | 5 ++++- .../lib/emr/emr-set-cluster-termination-protection.ts | 5 ++++- .../lib/emr/emr-terminate-cluster.ts | 5 ++++- .../aws-stepfunctions-tasks/lib/glue/start-job-run.ts | 5 ++++- .../@aws-cdk/aws-stepfunctions-tasks/lib/lambda/invoke.ts | 5 ++++- .../lib/sagemaker/create-training-job.ts | 5 ++++- .../lib/sagemaker/create-transform-job.ts | 5 ++++- .../@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts | 5 ++++- .../aws-stepfunctions-tasks/lib/sqs/send-message.ts | 5 ++++- .../lib/stepfunctions/start-execution.ts | 5 ++++- .../@aws-cdk/aws-stepfunctions/lib/states/task-base.ts | 7 +++++-- packages/@aws-cdk/aws-stepfunctions/test/task-base.test.ts | 5 ++++- 21 files changed, 85 insertions(+), 22 deletions(-) diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/batch/submit-job.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/batch/submit-job.ts index ee9577cbd6ac1..c376a4ce91d26 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/batch/submit-job.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/batch/submit-job.ts @@ -213,7 +213,10 @@ export class BatchSubmitJob extends sfn.TaskStateBase { this.taskPolicies = this.configurePolicyStatements(); } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('batch', 'submitJob', this.integrationPattern), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/delete-item.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/delete-item.ts index 174698241a1f8..f79c40d46f964 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/delete-item.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/delete-item.ts @@ -105,7 +105,10 @@ export class DynamoDeleteItem extends sfn.TaskStateBase { ]; } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: getDynamoResourceArn(DynamoMethod.DELETE), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/get-item.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/get-item.ts index 3cef6bd994fdc..ac361b8c9cb1b 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/get-item.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/get-item.ts @@ -87,7 +87,10 @@ export class DynamoGetItem extends sfn.TaskStateBase { ]; } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: getDynamoResourceArn(DynamoMethod.GET), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/put-item.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/put-item.ts index c23842bf5d98f..4d238765f2247 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/put-item.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/put-item.ts @@ -103,7 +103,10 @@ export class DynamoPutItem extends sfn.TaskStateBase { ]; } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: getDynamoResourceArn(DynamoMethod.PUT), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/update-item.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/update-item.ts index 63c424beb7b20..5e5f871737221 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/update-item.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/dynamodb/update-item.ts @@ -115,7 +115,10 @@ export class DynamoUpdateItem extends sfn.TaskStateBase { ]; } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: getDynamoResourceArn(DynamoMethod.UPDATE), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-add-step.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-add-step.ts index 2faef1a7c978e..a745bfccd6205 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-add-step.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-add-step.ts @@ -122,7 +122,10 @@ export class EmrAddStep extends sfn.TaskStateBase { this.taskPolicies = this.createPolicyStatements(); } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('elasticmapreduce', 'addStep', this.integrationPattern), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-cancel-step.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-cancel-step.ts index 4252056e1cb50..bf14e86085118 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-cancel-step.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-cancel-step.ts @@ -40,7 +40,10 @@ export class EmrCancelStep extends sfn.TaskStateBase { ]; } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('elasticmapreduce', 'cancelStep', sfn.IntegrationPattern.REQUEST_RESPONSE), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-create-cluster.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-create-cluster.ts index b33f12e5d8863..e291448e92019 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-create-cluster.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-create-cluster.ts @@ -230,7 +230,10 @@ export class EmrCreateCluster extends sfn.TaskStateBase { return this._autoScalingRole; } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('elasticmapreduce', 'createCluster', this.integrationPattern), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-modify-instance-fleet-by-name.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-modify-instance-fleet-by-name.ts index cdb6bc8f3f4fd..d4ed7436adba7 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-modify-instance-fleet-by-name.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-modify-instance-fleet-by-name.ts @@ -62,7 +62,10 @@ export class EmrModifyInstanceFleetByName extends sfn.TaskStateBase { ]; } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('elasticmapreduce', 'modifyInstanceFleetByName', sfn.IntegrationPattern.REQUEST_RESPONSE), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-modify-instance-group-by-name.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-modify-instance-group-by-name.ts index 30cfc572b262e..805f59dc52518 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-modify-instance-group-by-name.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-modify-instance-group-by-name.ts @@ -50,7 +50,10 @@ export class EmrModifyInstanceGroupByName extends sfn.TaskStateBase { ]; } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('elasticmapreduce', 'modifyInstanceGroupByName', sfn.IntegrationPattern.REQUEST_RESPONSE), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-set-cluster-termination-protection.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-set-cluster-termination-protection.ts index c2b52f0cc9a4f..ff983869b8b67 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-set-cluster-termination-protection.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-set-cluster-termination-protection.ts @@ -41,7 +41,10 @@ export class EmrSetClusterTerminationProtection extends sfn.TaskStateBase { ]; } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('elasticmapreduce', 'setClusterTerminationProtection', sfn.IntegrationPattern.REQUEST_RESPONSE), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-terminate-cluster.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-terminate-cluster.ts index 3aa9d1dc5a138..9e23ee1bdc8b1 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-terminate-cluster.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/emr/emr-terminate-cluster.ts @@ -39,7 +39,10 @@ export class EmrTerminateCluster extends sfn.TaskStateBase { this.taskPolicies = this.createPolicyStatements(); } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('elasticmapreduce', 'terminateCluster', this.integrationPattern), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/glue/start-job-run.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/glue/start-job-run.ts index 9df1a6a5ed852..0618e413ccb9e 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/glue/start-job-run.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/glue/start-job-run.ts @@ -77,7 +77,10 @@ export class GlueStartJobRun extends sfn.TaskStateBase { }; } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { const notificationProperty = this.props.notifyDelayAfter ? { NotifyDelayAfter: this.props.notifyDelayAfter.toMinutes() } : null; return { Resource: integrationResourceArn('glue', 'startJobRun', this.integrationPattern), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/invoke.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/invoke.ts index 8345d12a83011..90ac0c2f0ab33 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/invoke.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/lambda/invoke.ts @@ -96,7 +96,10 @@ export class LambdaInvoke extends sfn.TaskStateBase { /** * Provides the Lambda Invoke service integration task configuration */ - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('lambda', 'invoke', this.integrationPattern), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts index d57b9114dc7e8..f8b4c73d00320 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts @@ -204,7 +204,10 @@ export class SageMakerCreateTrainingJob extends sfn.TaskStateBase implements iam this.securityGroups.push(securityGroup); } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('sagemaker', 'createTrainingJob', this.integrationPattern), Parameters: sfn.FieldUtils.renderObject(this.renderParameters()), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-transform-job.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-transform-job.ts index 111a15500443e..b9bdcbf940d3d 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-transform-job.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/create-transform-job.ts @@ -134,7 +134,10 @@ export class SageMakerCreateTransformJob extends sfn.TaskStateBase { this.taskPolicies = this.makePolicyStatements(); } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('sagemaker', 'createTransformJob', this.integrationPattern), Parameters: sfn.FieldUtils.renderObject(this.renderParameters()), diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts index a9bca94666963..051b217b6d042 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts @@ -88,7 +88,10 @@ export class SnsPublish extends sfn.TaskStateBase { /** * Provides the SNS Publish service integration task configuration */ - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('sns', 'publish', this.integrationPattern), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-message.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-message.ts index c50c41e952c59..e1a2ae6d5118e 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-message.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sqs/send-message.ts @@ -88,7 +88,10 @@ export class SqsSendMessage extends sfn.TaskStateBase { /** * Provides the SQS SendMessage service integration task configuration */ - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: integrationResourceArn('sqs', 'sendMessage', this.integrationPattern), Parameters: sfn.FieldUtils.renderObject({ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/stepfunctions/start-execution.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/stepfunctions/start-execution.ts index 4bae47036558c..405e3be6a74fc 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/stepfunctions/start-execution.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/stepfunctions/start-execution.ts @@ -61,7 +61,10 @@ export class StepFunctionsStartExecution extends sfn.TaskStateBase { this.taskPolicies = this.createScopedAccessPolicy(); } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { // suffix of ':2' indicates that the output of the nested state machine should be JSON // suffix is only applicable when waiting for a nested state machine to complete (RUN_JOB) // https://docs.aws.amazon.com/step-functions/latest/dg/connect-stepfunctions.html diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/states/task-base.ts b/packages/@aws-cdk/aws-stepfunctions/lib/states/task-base.ts index e34875a02fbcc..23b0c4acbb1b3 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/states/task-base.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/states/task-base.ts @@ -140,7 +140,7 @@ export abstract class TaskStateBase extends State implements INextable { ...this.renderNextEnd(), ...this.renderRetryCatch(), ...this.renderTaskBase(), - ...this.renderTask(), + ...this._renderTask(), }; } @@ -247,7 +247,10 @@ export abstract class TaskStateBase extends State implements INextable { } } - protected abstract renderTask(): any; + /** + * @internal + */ + protected abstract _renderTask(): any; private taskMetric(prefix: string | undefined, suffix: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric { if (prefix === undefined) { diff --git a/packages/@aws-cdk/aws-stepfunctions/test/task-base.test.ts b/packages/@aws-cdk/aws-stepfunctions/test/task-base.test.ts index cfda2f109780a..3778eb6716b30 100644 --- a/packages/@aws-cdk/aws-stepfunctions/test/task-base.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions/test/task-base.test.ts @@ -298,7 +298,10 @@ class FakeTask extends sfn.TaskStateBase { this.taskMetrics = props.metrics; } - protected renderTask(): any { + /** + * @internal + */ + protected _renderTask(): any { return { Resource: 'my-resource', Parameters: sfn.FieldUtils.renderObject({ From d1c2ef2fc8a845446c956e5e1eb32745f1810ee9 Mon Sep 17 00:00:00 2001 From: Eduardo de Moura Rodrigues Date: Mon, 29 Jun 2020 09:11:58 +0200 Subject: [PATCH 29/55] fix(eks): Helm chart timeout expects duration (#8773) This resolves a problem with timeout parameter being passed down to Helm. The Helm version used (v3) expects a duration (in our case, in seconds such as `600s`) instead of integer. fixes #8718 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-eks/lib/helm-chart.ts | 2 +- .../aws-eks/test/integ.eks-cluster.expected.json | 3 ++- .../@aws-cdk/aws-eks/test/integ.eks-cluster.ts | 14 ++++++++++---- packages/@aws-cdk/aws-eks/test/test.helm-chart.ts | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/@aws-cdk/aws-eks/lib/helm-chart.ts b/packages/@aws-cdk/aws-eks/lib/helm-chart.ts index 8d5b50d870151..4761e71b0c7a9 100644 --- a/packages/@aws-cdk/aws-eks/lib/helm-chart.ts +++ b/packages/@aws-cdk/aws-eks/lib/helm-chart.ts @@ -100,7 +100,7 @@ export class HelmChart extends Construct { Chart: props.chart, Version: props.version, Wait: props.wait ?? false, - Timeout: timeout, + Timeout: timeout ? `${timeout.toString()}s` : undefined, // Helm v3 expects duration instead of integer Values: (props.values ? stack.toJsonString(props.values) : undefined), Namespace: props.namespace ?? 'default', Repository: props.repository, diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json index a787602404c54..18503376d76d2 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json @@ -2481,7 +2481,8 @@ }, "Release": "awscdkeksclustertestclusterchartnginxingressa7f70129", "Chart": "nginx-ingress", - "Wait": false, + "Wait": true, + "Timeout": "900s", "Namespace": "kube-system", "Repository": "https://helm.nginx.com/stable" }, diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts index 122efbdd9ecc6..929c27f276e97 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts @@ -1,6 +1,6 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; -import { App, CfnOutput } from '@aws-cdk/core'; +import { App, CfnOutput, Duration } from '@aws-cdk/core'; import * as eks from '../lib'; import * as hello from './hello-k8s'; import { TestStack } from './util'; @@ -69,12 +69,18 @@ class EksClusterStack extends TestStack { nodeRole: cluster.defaultCapacity ? cluster.defaultCapacity.role : undefined, }); - // // apply a kubernetes manifest + // apply a kubernetes manifest cluster.addResource('HelloApp', ...hello.resources); - // // add two Helm charts to the cluster. This will be the Kubernetes dashboard and the Nginx Ingress Controller + // add two Helm charts to the cluster. This will be the Kubernetes dashboard and the Nginx Ingress Controller cluster.addChart('dashboard', { chart: 'kubernetes-dashboard', repository: 'https://kubernetes-charts.storage.googleapis.com' }); - cluster.addChart('nginx-ingress', { chart: 'nginx-ingress', repository: 'https://helm.nginx.com/stable', namespace: 'kube-system' }); + cluster.addChart('nginx-ingress', { + chart: 'nginx-ingress', + repository: 'https://helm.nginx.com/stable', + namespace: 'kube-system', + wait: true, + timeout: Duration.minutes(15), + }); // add a service account connected to a IAM role cluster.addServiceAccount('MyServiceAccount'); diff --git a/packages/@aws-cdk/aws-eks/test/test.helm-chart.ts b/packages/@aws-cdk/aws-eks/test/test.helm-chart.ts index 7fed84a2b6185..0528bb27aac54 100644 --- a/packages/@aws-cdk/aws-eks/test/test.helm-chart.ts +++ b/packages/@aws-cdk/aws-eks/test/test.helm-chart.ts @@ -82,7 +82,7 @@ export = { new eks.HelmChart(stack, 'MyChart', { cluster, chart: 'chart', timeout: Duration.minutes(10) }); // THEN - expect(stack).to(haveResource(eks.HelmChart.RESOURCE_TYPE, { Timeout: 600 })); + expect(stack).to(haveResource(eks.HelmChart.RESOURCE_TYPE, { Timeout: '600s' })); test.done(); }, }, From 83fd2aee6389d03cfe69260b996d7d09398bbf99 Mon Sep 17 00:00:00 2001 From: Shiv Lakshminarayan Date: Mon, 29 Jun 2020 01:05:12 -0700 Subject: [PATCH 30/55] feat(stepfunctions-tasks): evaluate expression as a task construct (#8555) Replacement for the current implementation of experimental Evaluate Expression. Merges state and service integration properties and represents them as a construct. Note that the changes to test are only the reordering of elements. Re-ran the integration test and verified that it functions as documented. BREAKING CHANGE: `EvaluateExpression` is now a construct representing a task state rather than an embedded property called `task` ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-stepfunctions-tasks/README.md | 21 +++++------ .../lib/evaluate-expression.ts | 36 ++++++++++++------- .../test/evaluate-expression.test.ts | 30 ++++++---------- .../integ.evaluate-expression.expected.json | 20 +++++------ .../test/integ.evaluate-expression.ts | 26 ++++++-------- 5 files changed, 64 insertions(+), 69 deletions(-) diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md index 6665cc4196b23..239c943674c2e 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md @@ -164,25 +164,22 @@ Use the `EvaluateExpression` to perform simple operations referencing state path Example: convert a wait time from milliseconds to seconds, concat this in a message and wait: ```ts -const convertToSeconds = new sfn.Task(this, 'Convert to seconds', { - task: new tasks.EvaluateExpression({ expression: '$.waitMilliseconds / 1000' }), - resultPath: '$.waitSeconds' +const convertToSeconds = new tasks.EvaluateExpression(this, 'Convert to seconds', { + expression: '$.waitMilliseconds / 1000', + resultPath: '$.waitSeconds', }); -const createMessage = new sfn.Task(this, 'Create message', { +const createMessage = new tasks.EvaluateExpression(this, 'Create message', { // Note: this is a string inside a string. - task: new tasks.EvaluateExpression({ expression: '`Now waiting ${$.waitSeconds} seconds...`', runtime: lambda.Runtime.NODEJS_10_X, - }), - resultPath: '$.message' + resultPath: '$.message', }); -const publishMessage = new sfn.Task(this, 'Publish message', { - task: new tasks.PublishToTopic(topic, { - message: sfn.TaskInput.fromDataAt('$.message'), - }), - resultPath: '$.sns' +const publishMessage = new tasks.SnsPublish(this, 'Publish message', { + topic, + message: sfn.TaskInput.fromDataAt('$.message'), + resultPath: '$.sns', }); const wait = new sfn.Wait(this, 'Wait', { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/evaluate-expression.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/evaluate-expression.ts index 0e13d9d90c1e3..e07da1a16493b 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/evaluate-expression.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/evaluate-expression.ts @@ -9,7 +9,7 @@ import * as path from 'path'; * * @experimental */ -export interface EvaluateExpressionProps { +export interface EvaluateExpressionProps extends sfn.TaskStateBaseProps { /** * The expression to evaluate. The expression may contain state paths. * @@ -49,11 +49,29 @@ export interface Event { * * @experimental */ -export class EvaluateExpression implements sfn.IStepFunctionsTask { - constructor(private readonly props: EvaluateExpressionProps) { +export class EvaluateExpression extends sfn.TaskStateBase { + protected readonly taskMetrics?: sfn.TaskMetricsConfig; + protected readonly taskPolicies?: iam.PolicyStatement[]; + + private readonly evalFn: lambda.SingletonFunction; + + constructor(scope: cdk.Construct, id: string, private readonly props: EvaluateExpressionProps) { + super(scope, id, props); + + this.evalFn = createEvalFn(this.props.runtime || lambda.Runtime.NODEJS_10_X, this); + + this.taskPolicies = [ + new iam.PolicyStatement({ + resources: [this.evalFn.functionArn], + actions: ['lambda:InvokeFunction'], + }), + ]; } - public bind(task: sfn.Task): sfn.StepFunctionsTaskConfig { + /** + * @internal + */ + protected _renderTask(): any { const matches = this.props.expression.match(/\$[.\[][.a-zA-Z[\]0-9]+/g); let expressionAttributeValues = {}; @@ -67,19 +85,13 @@ export class EvaluateExpression implements sfn.IStepFunctionsTask { ); } - const evalFn = createEvalFn(this.props.runtime || lambda.Runtime.NODEJS_10_X, task); - const parameters: Event = { expression: this.props.expression, expressionAttributeValues, }; return { - resourceArn: evalFn.functionArn, - policyStatements: [new iam.PolicyStatement({ - resources: [evalFn.functionArn], - actions: ['lambda:InvokeFunction'], - })], - parameters, + Resource: this.evalFn.functionArn, + Parameters: sfn.FieldUtils.renderObject(parameters), }; } } diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/evaluate-expression.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/evaluate-expression.test.ts index d1235d66a16aa..0bcc3cc3e98c3 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/evaluate-expression.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/evaluate-expression.test.ts @@ -10,10 +10,8 @@ beforeEach(() => { test('Eval with Node.js', () => { // WHEN - const task = new sfn.Task(stack, 'Task', { - task: new tasks.EvaluateExpression({ - expression: '$.a + $.b', - }), + const task = new tasks.EvaluateExpression(stack, 'Task', { + expression: '$.a + $.b', }); new sfn.StateMachine(stack, 'SM', { definition: task, @@ -25,14 +23,11 @@ test('Eval with Node.js', () => { 'Fn::Join': [ '', [ - '{"StartAt":"Task","States":{"Task":{"End":true,"Parameters":{"expression":"$.a + $.b","expressionAttributeValues":{"$.a.$":"$.a","$.b.$":"$.b"}},"Type":"Task","Resource":"', + '{"StartAt":"Task","States":{"Task":{"End":true,"Type":"Task","Resource":"', { - 'Fn::GetAtt': [ - 'Evala0d2ce44871b4e7487a1f5e63d7c3bdc4DAC06E1', - 'Arn', - ], + 'Fn::GetAtt': ['Evala0d2ce44871b4e7487a1f5e63d7c3bdc4DAC06E1', 'Arn'], }, - '"}}}', + '","Parameters":{"expression":"$.a + $.b","expressionAttributeValues":{"$.a.$":"$.a","$.b.$":"$.b"}}}}}', ], ], }, @@ -45,10 +40,8 @@ test('Eval with Node.js', () => { test('expression does not contain paths', () => { // WHEN - const task = new sfn.Task(stack, 'Task', { - task: new tasks.EvaluateExpression({ - expression: '2 + 2', - }), + const task = new tasks.EvaluateExpression(stack, 'Task', { + expression: '2 + 2', }); new sfn.StateMachine(stack, 'SM', { definition: task, @@ -59,14 +52,11 @@ test('expression does not contain paths', () => { 'Fn::Join': [ '', [ - '{"StartAt":"Task","States":{"Task":{"End":true,"Parameters":{"expression":"2 + 2",\"expressionAttributeValues\":{}},"Type":"Task","Resource":"', + '{"StartAt":"Task","States":{"Task":{"End":true,"Type":"Task","Resource":"', { - 'Fn::GetAtt': [ - 'Evala0d2ce44871b4e7487a1f5e63d7c3bdc4DAC06E1', - 'Arn', - ], + 'Fn::GetAtt': ['Evala0d2ce44871b4e7487a1f5e63d7c3bdc4DAC06E1', 'Arn'], }, - '"}}}', + '","Parameters":{"expression":"2 + 2","expressionAttributeValues":{}}}}}', ], ], }, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.evaluate-expression.expected.json b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.evaluate-expression.expected.json index 7c44d5f356e85..efdf3878e67e2 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.evaluate-expression.expected.json +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.evaluate-expression.expected.json @@ -142,40 +142,40 @@ "StateMachine2E01A3A5": { "Type": "AWS::StepFunctions::StateMachine", "Properties": { + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRoleB840431D", + "Arn" + ] + }, "DefinitionString": { "Fn::Join": [ "", [ - "{\"StartAt\":\"Sum\",\"States\":{\"Sum\":{\"Next\":\"Multiply\",\"Parameters\":{\"expression\":\"$.a + $.b\",\"expressionAttributeValues\":{\"$.a.$\":\"$.a\",\"$.b.$\":\"$.b\"}},\"Type\":\"Task\",\"Resource\":\"", + "{\"StartAt\":\"Sum\",\"States\":{\"Sum\":{\"Next\":\"Multiply\",\"Type\":\"Task\",\"ResultPath\":\"$.c\",\"Resource\":\"", { "Fn::GetAtt": [ "Evala0d2ce44871b4e7487a1f5e63d7c3bdc4DAC06E1", "Arn" ] }, - "\",\"ResultPath\":\"$.c\"},\"Multiply\":{\"Next\":\"Wait\",\"Parameters\":{\"expression\":\"$.c * 2\",\"expressionAttributeValues\":{\"$.c.$\":\"$.c\"}},\"Type\":\"Task\",\"Resource\":\"", + "\",\"Parameters\":{\"expression\":\"$.a + $.b\",\"expressionAttributeValues\":{\"$.a.$\":\"$.a\",\"$.b.$\":\"$.b\"}}},\"Multiply\":{\"Next\":\"Wait\",\"Type\":\"Task\",\"ResultPath\":\"$.d\",\"Resource\":\"", { "Fn::GetAtt": [ "Evala0d2ce44871b4e7487a1f5e63d7c3bdc4DAC06E1", "Arn" ] }, - "\",\"ResultPath\":\"$.d\"},\"Wait\":{\"Type\":\"Wait\",\"SecondsPath\":\"$.d\",\"Next\":\"Now\"},\"Now\":{\"End\":true,\"Parameters\":{\"expression\":\"(new Date()).toUTCString()\",\"expressionAttributeValues\":{}},\"Type\":\"Task\",\"Resource\":\"", + "\",\"Parameters\":{\"expression\":\"$.c * 2\",\"expressionAttributeValues\":{\"$.c.$\":\"$.c\"}}},\"Wait\":{\"Type\":\"Wait\",\"SecondsPath\":\"$.d\",\"Next\":\"Now\"},\"Now\":{\"End\":true,\"Type\":\"Task\",\"ResultPath\":\"$.now\",\"Resource\":\"", { "Fn::GetAtt": [ "Evala0d2ce44871b4e7487a1f5e63d7c3bdc4DAC06E1", "Arn" ] }, - "\",\"ResultPath\":\"$.now\"}}}" + "\",\"Parameters\":{\"expression\":\"(new Date()).toUTCString()\",\"expressionAttributeValues\":{}}}}}" ] ] - }, - "RoleArn": { - "Fn::GetAtt": [ - "StateMachineRoleB840431D", - "Arn" - ] } }, "DependsOn": [ diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.evaluate-expression.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.evaluate-expression.ts index 0dac6789aeb7c..8034635352b32 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.evaluate-expression.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.evaluate-expression.ts @@ -12,33 +12,29 @@ import * as tasks from '../lib'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-stepfunctions-integ'); -const sum = new sfn.Task(stack, 'Sum', { - task: new tasks.EvaluateExpression({ - expression: '$.a + $.b', - }), +const sum = new tasks.EvaluateExpression(stack, 'Sum', { + expression: '$.a + $.b', resultPath: '$.c', }); -const multiply = new sfn.Task(stack, 'Multiply', { - task: new tasks.EvaluateExpression({ - expression: '$.c * 2', - }), +const multiply = new tasks.EvaluateExpression(stack, 'Multiply', { + expression: '$.c * 2', resultPath: '$.d', }); -const now = new sfn.Task(stack, 'Now', { - task: new tasks.EvaluateExpression({ - expression: '(new Date()).toUTCString()', - }), +const now = new tasks.EvaluateExpression(stack, 'Now', { + expression: '(new Date()).toUTCString()', resultPath: '$.now', }); const statemachine = new sfn.StateMachine(stack, 'StateMachine', { definition: sum .next(multiply) - .next(new sfn.Wait(stack, 'Wait', { - time: sfn.WaitTime.secondsPath('$.d'), - })) + .next( + new sfn.Wait(stack, 'Wait', { + time: sfn.WaitTime.secondsPath('$.d'), + }), + ) .next(now), }); From b3855ff13c2317a9b74f508c2beda9b829545e86 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Mon, 29 Jun 2020 13:03:33 +0100 Subject: [PATCH 31/55] chore(scripts): buildup should only build (#8782) Skip the test target to speed up building up to the module. This will significantly improve the speed to arrive to a working module after check out. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- scripts/buildup | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/buildup b/scripts/buildup index 59aeff93dcf50..3fea629af9976 100755 --- a/scripts/buildup +++ b/scripts/buildup @@ -19,7 +19,7 @@ else fi fi -${scriptdir}/foreach.sh --up yarn build+test +${scriptdir}/foreach.sh --up yarn build ${scriptdir}/foreach.sh --reset echo "************************************************************" From af69f805f4e937742fc215ea57c7960c44c612ef Mon Sep 17 00:00:00 2001 From: Pahud Hsieh Date: Mon, 29 Jun 2020 21:08:38 +0800 Subject: [PATCH 32/55] chore(eks): kubectl 1.16.8-eks-e16311, aws-cli 1.18.86, helm 3.2.4 (#8739) - bump aws-lambda-layer-kubectl [2.0.0](https://github.com/aws-samples/aws-lambda-layer-kubectl/releases/tag/2.0.0) with kubectl v1.16.8-eks-e16311, awscli 1.18.86 and helm 3.2.4 - update the helm repo of the kubernetes-dashboard in the integ test to `https://kubernetes.github.io/dashboard/` from [Helm Hub](https://hub.helm.sh/charts/k8s-dashboard) as `https://kubernetes-charts.storage.googleapis.com` has been deprecated ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-eks/lib/kubectl-provider.ts | 2 +- .../test/integ.eks-cluster.expected.json | 20 +++++++++---------- .../aws-eks/test/integ.eks-cluster.ts | 6 +++++- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/@aws-cdk/aws-eks/lib/kubectl-provider.ts b/packages/@aws-cdk/aws-eks/lib/kubectl-provider.ts index dd4f2e27f910a..5c144e42abf97 100644 --- a/packages/@aws-cdk/aws-eks/lib/kubectl-provider.ts +++ b/packages/@aws-cdk/aws-eks/lib/kubectl-provider.ts @@ -24,7 +24,7 @@ export class KubectlProvider extends NestedStack { runtime: lambda.Runtime.PYTHON_3_7, handler: 'index.handler', timeout: Duration.minutes(15), - layers: [ KubectlLayer.getOrCreate(this, { version: '2.0.0-beta2' }) ], + layers: [ KubectlLayer.getOrCreate(this, { version: '2.0.0' }) ], memorySize: 256, }); diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json index 18503376d76d2..dd43e4cf0204d 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json @@ -2456,7 +2456,7 @@ "Chart": "kubernetes-dashboard", "Wait": false, "Namespace": "default", - "Repository": "https://kubernetes-charts.storage.googleapis.com" + "Repository": "https://kubernetes.github.io/dashboard/" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -2687,7 +2687,7 @@ }, "/", { - "Ref": "AssetParametersc70286a3d87ecc95aea2ffe7d7723ba303222280fb87f0128b3e83dcdd1d649eS3Bucket5515EF97" + "Ref": "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042S3BucketAE64A22C" }, "/", { @@ -2697,7 +2697,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersc70286a3d87ecc95aea2ffe7d7723ba303222280fb87f0128b3e83dcdd1d649eS3VersionKeyF1C97F67" + "Ref": "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042S3VersionKeyAFF70CF1" } ] } @@ -2710,7 +2710,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersc70286a3d87ecc95aea2ffe7d7723ba303222280fb87f0128b3e83dcdd1d649eS3VersionKeyF1C97F67" + "Ref": "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042S3VersionKeyAFF70CF1" } ] } @@ -3073,17 +3073,17 @@ "Type": "String", "Description": "Artifact hash for asset \"7255958d303a278986617e8d7ce027c96cd00a70fb8f1ca02c1e0da94a571896\"" }, - "AssetParametersc70286a3d87ecc95aea2ffe7d7723ba303222280fb87f0128b3e83dcdd1d649eS3Bucket5515EF97": { + "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042S3BucketAE64A22C": { "Type": "String", - "Description": "S3 bucket for asset \"c70286a3d87ecc95aea2ffe7d7723ba303222280fb87f0128b3e83dcdd1d649e\"" + "Description": "S3 bucket for asset \"5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042\"" }, - "AssetParametersc70286a3d87ecc95aea2ffe7d7723ba303222280fb87f0128b3e83dcdd1d649eS3VersionKeyF1C97F67": { + "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042S3VersionKeyAFF70CF1": { "Type": "String", - "Description": "S3 key for asset version \"c70286a3d87ecc95aea2ffe7d7723ba303222280fb87f0128b3e83dcdd1d649e\"" + "Description": "S3 key for asset version \"5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042\"" }, - "AssetParametersc70286a3d87ecc95aea2ffe7d7723ba303222280fb87f0128b3e83dcdd1d649eArtifactHash88EDABBF": { + "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042ArtifactHashD8735DDD": { "Type": "String", - "Description": "Artifact hash for asset \"c70286a3d87ecc95aea2ffe7d7723ba303222280fb87f0128b3e83dcdd1d649e\"" + "Description": "Artifact hash for asset \"5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042\"" }, "SsmParameterValueawsserviceeksoptimizedami116amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { "Type": "AWS::SSM::Parameter::Value", diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts index 929c27f276e97..ddee987d81d35 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts @@ -73,7 +73,11 @@ class EksClusterStack extends TestStack { cluster.addResource('HelloApp', ...hello.resources); // add two Helm charts to the cluster. This will be the Kubernetes dashboard and the Nginx Ingress Controller - cluster.addChart('dashboard', { chart: 'kubernetes-dashboard', repository: 'https://kubernetes-charts.storage.googleapis.com' }); + cluster.addChart('dashboard', { + chart: 'kubernetes-dashboard', + repository: 'https://kubernetes.github.io/dashboard/', + }); + cluster.addChart('nginx-ingress', { chart: 'nginx-ingress', repository: 'https://helm.nginx.com/stable', From 05aaf422e71e12ea6ec91ea26bfbce81ebfea7f4 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Mon, 29 Jun 2020 15:52:28 +0100 Subject: [PATCH 33/55] fix(apigateway): error defining lambda integration on imported RestApi (#8785) Root cause here was that `LambdaIntegration` used the deprecated `restApi` property on its binding Method. This property does not work on imported RestApi and has been superceded by the property `api`. A further bug that was discovered was that the API `methodArn()` on the Method construct did not work on imported RestApi. This has been fixed up such that if a `deploymentStage` is not defined for the imported RestApi, the ARN will return '*' as its stage (shorthand for 'all stages'). fixes #8679 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-apigateway/lib/integrations/lambda.ts | 2 +- .../@aws-cdk/aws-apigateway/lib/method.ts | 15 ++++------- .../@aws-cdk/aws-apigateway/lib/restapi.ts | 27 ++++++++++++------- .../aws-apigateway/test/test.lambda.ts | 24 +++++++++++++++++ .../aws-apigateway/test/test.method.ts | 24 ++++++++++++++--- 5 files changed, 67 insertions(+), 25 deletions(-) diff --git a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts index d30d786295dc8..fe5e81678e85e 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts @@ -56,7 +56,7 @@ export class LambdaIntegration extends AwsIntegration { super.bind(method); const principal = new iam.ServicePrincipal('apigateway.amazonaws.com'); - const desc = `${method.restApi.node.uniqueId}.${method.httpMethod}.${method.resource.path.replace(/\//g, '.')}`; + const desc = `${method.api.node.uniqueId}.${method.httpMethod}.${method.resource.path.replace(/\//g, '.')}`; this.handler.addPermission(`ApiPermission.${desc}`, { principal, diff --git a/packages/@aws-cdk/aws-apigateway/lib/method.ts b/packages/@aws-cdk/aws-apigateway/lib/method.ts index a7af625a4d121..8721d9e9da114 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/method.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/method.ts @@ -237,19 +237,14 @@ export class Method extends Resource { * arn:aws:execute-api:{region}:{account}:{restApiId}/{stage}/{method}/{path} * * NOTE: {stage} will refer to the `restApi.deploymentStage`, which will - * automatically set if auto-deploy is enabled. + * automatically set if auto-deploy is enabled, or can be explicitly assigned. + * When not configured, {stage} will be set to '*', as a shorthand for 'all stages'. * * @attribute */ public get methodArn(): string { - if (!this.restApi.deploymentStage) { - throw new Error( - `Unable to determine ARN for method "${this.node.id}" since there is no stage associated with this API.\n` + - 'Either use the `deploy` prop or explicitly assign `deploymentStage` on the RestApi'); - } - - const stage = this.restApi.deploymentStage.stageName.toString(); - return this.restApi.arnForExecuteApi(this.httpMethod, pathForArn(this.resource.path), stage); + const stage = this.api.deploymentStage?.stageName; + return this.api.arnForExecuteApi(this.httpMethod, pathForArn(this.resource.path), stage); } /** @@ -257,7 +252,7 @@ export class Method extends Resource { * This stage is used by the AWS Console UI when testing the method. */ public get testMethodArn(): string { - return this.restApi.arnForExecuteApi(this.httpMethod, pathForArn(this.resource.path), 'test-invoke-stage'); + return this.api.arnForExecuteApi(this.httpMethod, pathForArn(this.resource.path), 'test-invoke-stage'); } private renderIntegration(integration?: Integration): CfnMethod.IntegrationProperty { diff --git a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts index 4d08a0b01ce36..9ba3714aed915 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts @@ -38,6 +38,11 @@ export interface IRestApi extends IResourceBase { */ readonly latestDeployment?: Deployment; + /** + * API Gateway stage that points to the latest deployment (if defined). + */ + deploymentStage: Stage; + /** * Represents the root resource ("/") of this API. Use it to define the API model: * @@ -46,6 +51,17 @@ export interface IRestApi extends IResourceBase { * */ readonly root: IResource; + + /** + * Gets the "execute-api" ARN + * @returns The "execute-api" ARN. + * @default "*" returns the execute API ARN for all methods/resources in + * this API. + * @param method The method (default `*`) + * @param path The resource path. Must start with '/' (default `*`) + * @param stage The stage (default `*`) + */ + arnForExecuteApi(method?: string, path?: string, stage?: string): string; } /** @@ -324,15 +340,6 @@ export abstract class RestApiBase extends Resource implements IRestApi { return new UsagePlan(this, id, props); } - /** - * Gets the "execute-api" ARN - * @returns The "execute-api" ARN. - * @default "*" returns the execute API ARN for all methods/resources in - * this API. - * @param method The method (default `*`) - * @param path The resource path. Must start with '/' (default `*`) - * @param stage The stage (default `*`) - */ public arnForExecuteApi(method: string = '*', path: string = '/*', stage: string = '*') { if (!path.startsWith('/')) { throw new Error(`"path" must begin with a "/": '${path}'`); @@ -496,7 +503,7 @@ export class RestApi extends RestApiBase { * Import an existing RestApi. */ public static fromRestApiId(scope: Construct, id: string, restApiId: string): IRestApi { - class Import extends Resource implements IRestApi { + class Import extends RestApiBase { public readonly restApiId = restApiId; public get root(): IResource { diff --git a/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts b/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts index 542ab030a6269..4a979e7671f85 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts @@ -191,4 +191,28 @@ export = { test.done(); }, + + 'works for imported RestApi'(test: Test) { + const stack = new cdk.Stack(); + const api = apigateway.RestApi.fromRestApiAttributes(stack, 'RestApi', { + restApiId: 'imported-rest-api-id', + rootResourceId: 'imported-root-resource-id', + }); + + const handler = new lambda.Function(stack, 'MyFunc', { + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'index.handler', + code: lambda.Code.fromInline('loo'), + }); + + api.root.addMethod('ANY', new apigateway.LambdaIntegration(handler)); + + expect(stack).to(haveResource('AWS::ApiGateway::Method', { + RestApiId: 'imported-rest-api-id', + ResourceId: 'imported-root-resource-id', + HttpMethod: 'ANY', + })); + + test.done(); + }, }; diff --git a/packages/@aws-cdk/aws-apigateway/test/test.method.ts b/packages/@aws-cdk/aws-apigateway/test/test.method.ts index bb0d28b976094..ba5ab8c1c2c91 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.method.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.method.ts @@ -207,15 +207,31 @@ export = { test.done(); }, - '"methodArn" fails if the API does not have a deployment stage'(test: Test) { + '"methodArn" returns an arn with "*" as its stage when deploymentStage is not set'(test: Test) { // GIVEN const stack = new cdk.Stack(); const api = new apigw.RestApi(stack, 'test-api', { deploy: false }); + + // WHEN const method = new apigw.Method(stack, 'my-method', { httpMethod: 'POST', resource: api.root }); - // WHEN + THEN - test.throws(() => method.methodArn, - /Unable to determine ARN for method "my-method" since there is no stage associated with this API./); + // THEN + test.deepEqual(stack.resolve(method.methodArn), { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':execute-api:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':', + { Ref: 'testapiD6451F70' }, + '/*/POST/', + ], + ], + }); test.done(); }, From 487033a19b328b78648a970b775947288a04feb7 Mon Sep 17 00:00:00 2001 From: Sven Efftinge Date: Mon, 29 Jun 2020 17:29:43 +0200 Subject: [PATCH 34/55] chore(build): Increase yarn install network-timeout (#8751) This change increases the timeout to `yarn install` to stabilize the Gitpod prebuilds. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index b58fa80e1c563..6a90f93fbbcbe 100755 --- a/build.sh +++ b/build.sh @@ -31,7 +31,7 @@ export NODE_OPTIONS="--max-old-space-size=4096 ${NODE_OPTIONS:-}" echo "=============================================================================================" echo "installing..." -yarn install --frozen-lockfile +yarn install --frozen-lockfile --network-timeout 1000000 fail() { echo "❌ Last command failed. Scroll up to see errors in log (search for '!!!!!!!!')." From a216739ea058cc77e75246b06e9888310fb9e0d2 Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Mon, 29 Jun 2020 16:54:42 +0100 Subject: [PATCH 35/55] chore(scripts): builddown should use foreach to support resuming builds (#8784) buildup and builddown currently use two entirely different approaches. This fix makes the builddown mirror the current buildup script, and alters foreach to support a --down flag in addition to --up. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- scripts/builddown | 29 +++++++++++++++++++++-------- scripts/foreach.sh | 26 ++++++++++++++++++-------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/scripts/builddown b/scripts/builddown index 6d75589573fff..181f08dbca389 100755 --- a/scripts/builddown +++ b/scripts/builddown @@ -1,14 +1,27 @@ #!/bin/bash set -euo pipefail +scriptdir=$(cd $(dirname $0) && pwd) + +echo "************************************************************" +echo " builddown usage:" +echo " - execute 'builddown --resume' to resume after failure" +echo " - execute 'builddown' to restart the build from the start" +echo "" +echo " for advanced usage, see ${scriptdir}/foreach.sh" +echo "************************************************************" -if ! [ -x "$(command -v yarn)" ]; then - echo "yarn is not installed. Follow the guide to install yarn - https://yarnpkg.com/en/docs/install." - exit 1 +if [ "$#" -eq 0 ]; then + ${scriptdir}/foreach.sh --reset +else + if [ "$1" != "--resume" ]; then + echo "Unknown option: $1" + exit 1 + fi fi -export NODE_OPTIONS="--max-old-space-size=4096 ${NODE_OPTIONS:-}" +${scriptdir}/foreach.sh --down yarn build +${scriptdir}/foreach.sh --reset -scriptdir=$(cd $(dirname $0) && pwd) -export PATH=$(cd $scriptdir && npm bin):$PATH -scope=$(${scriptdir}/current-scope) -exec lerna run ${1:-build} --scope ${scope} --include-dependents +echo "************************************************************" +echo "builddown done" +echo "************************************************************" diff --git a/scripts/foreach.sh b/scripts/foreach.sh index 39fcb574be7e8..1a389a5d60a3a 100755 --- a/scripts/foreach.sh +++ b/scripts/foreach.sh @@ -18,6 +18,9 @@ # to run the command only against the current module and its dependencies: # foreach.sh --up COMMAND # +# to run the command only against the current module and its consumers: +# foreach.sh --down COMMAND +# # -------------------------------------------------------------------------------------------------- set -euo pipefail scriptdir=$(cd $(dirname $0) && pwd) @@ -61,17 +64,24 @@ if [[ "${1:-}" == "--skip" ]]; then exit 0 fi -up="" -up_desc="" -if [[ "${1:-}" == "--up" ]]; then +direction="" +direction_desc="" +if [[ "${1:-}" == "--up" || "${1:-}" == "--down" ]]; then if [ ! -f package.json ]; then - echo "--up can only be executed from within a module directory (looking for package.json)" + echo "--up or --down can only be executed from within a module directory (looking for package.json)" exit 1 fi scope=$(node -p "require('./package.json').name") - up=" --scope ${scope} --include-dependencies" - up_desc="('${scope}' and its dependencies)" + + if [[ "${1:-}" == "--up" ]]; then + direction=" --scope ${scope} --include-dependencies" + direction_desc="('${scope}' and its dependencies)" + else # --down + direction=" --scope ${scope} --include-dependents" + direction_desc="('${scope}' and its consumers)" + fi + shift fi @@ -89,8 +99,8 @@ fi if [ ! -f "${statefile}" ] && [ ! -f "${commandfile}" ]; then if [ ! -z "${command_arg}" ]; then command="${command_arg}" - success "starting new session ${up_desc}" - ${scriptdir}/../node_modules/.bin/lerna ls --all ${up} --toposort -p > ${statefile} + success "starting new session ${direction_desc}" + ${scriptdir}/../node_modules/.bin/lerna ls --all ${direction} --toposort -p > ${statefile} echo "${command}" > ${commandfile} else error "no active session, use \"$(basename $0) COMMAND\" to start a new session" From d8c5959d0b5c6dc092b5e8b2c9294aef6a80e95c Mon Sep 17 00:00:00 2001 From: ufoo68 Date: Tue, 30 Jun 2020 01:19:31 +0900 Subject: [PATCH 36/55] chore(appsync): Fix sample code on README (#8765) ### Commit Message chore(appsync): Fix sample code on README - Add comma on `new UserPool()` #8764 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-appsync/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-appsync/README.md b/packages/@aws-cdk/aws-appsync/README.md index 0c0b27c8e6f92..378a5a4c8bd7d 100644 --- a/packages/@aws-cdk/aws-appsync/README.md +++ b/packages/@aws-cdk/aws-appsync/README.md @@ -65,7 +65,7 @@ export class ApiStack extends Stack { constructor(scope: Construct, id: string) { super(scope, id); - const userPool = new UserPool(this, 'UserPool'{ + const userPool = new UserPool(this, 'UserPool', { userPoolName: 'myPool', }); From 07b330cf39be2a98fbee93915f07c2c34136e105 Mon Sep 17 00:00:00 2001 From: Andrew Gacek Date: Mon, 29 Jun 2020 13:21:42 -0500 Subject: [PATCH 37/55] fix(backup): correctly validate Vault name (#8689) AWS Backup Vault names must be between 2 and 50 characters. The characters must be alphanumeric, a hyphen, or an underscore. Fixes: #8689 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-backup/lib/vault.ts | 4 ++-- packages/@aws-cdk/aws-backup/test/vault.test.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-backup/lib/vault.ts b/packages/@aws-cdk/aws-backup/lib/vault.ts index 6f109306ce1c3..e9f85d8b160b1 100644 --- a/packages/@aws-cdk/aws-backup/lib/vault.ts +++ b/packages/@aws-cdk/aws-backup/lib/vault.ts @@ -133,8 +133,8 @@ export class BackupVault extends Resource implements IBackupVault { constructor(scope: Construct, id: string, props: BackupVaultProps = {}) { super(scope, id); - if (props.backupVaultName && !/^[a-zA-Z0-9\-_\.]{1,50}$/.test(props.backupVaultName)) { - throw new Error('Expected vault name to match pattern `^[a-zA-Z0-9\-\_\.]{1,50}$`'); + if (props.backupVaultName && !/^[a-zA-Z0-9\-_]{2,50}$/.test(props.backupVaultName)) { + throw new Error('Expected vault name to match pattern `^[a-zA-Z0-9\-_]{2,50}$`'); } let notifications: CfnBackupVault.NotificationObjectTypeProperty | undefined; diff --git a/packages/@aws-cdk/aws-backup/test/vault.test.ts b/packages/@aws-cdk/aws-backup/test/vault.test.ts index b8291be0e74ff..dd1800c5b831e 100644 --- a/packages/@aws-cdk/aws-backup/test/vault.test.ts +++ b/packages/@aws-cdk/aws-backup/test/vault.test.ts @@ -140,3 +140,15 @@ test('throws with invalid name', () => { backupVaultName: 'Hello!Inv@lid', })).toThrow(/Expected vault name to match pattern/); }); + +test('throws with whitespace in name', () => { + expect(() => new BackupVault(stack, 'Vault', { + backupVaultName: 'Hello Invalid', + })).toThrow(/Expected vault name to match pattern/); +}); + +test('throws with too short name', () => { + expect(() => new BackupVault(stack, 'Vault', { + backupVaultName: 'x', + })).toThrow(/Expected vault name to match pattern/); +}); From 293a937a6c24681319ae7ca210ffdd0b2ba7d88a Mon Sep 17 00:00:00 2001 From: comcalvi <66279577+comcalvi@users.noreply.github.com> Date: Mon, 29 Jun 2020 14:41:26 -0400 Subject: [PATCH 38/55] feat(cfn-include): add support for YAML templates (#8746) Fixes #8745 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/cloudformation-include/README.md | 20 +- .../cloudformation-include/lib/cfn-include.ts | 4 +- .../cloudformation-include/lib/file-utils.ts | 60 ++++ .../functions-and-conditions.json | 2 +- .../yaml/invalid/short-form-transform.yaml | 12 + .../test-templates/yaml/long-form-subnet.yaml | 45 +++ .../test-templates/yaml/long-form-vpc.yaml | 44 +++ .../yaml/short-form-base64.yaml | 6 + .../test-templates/yaml/short-form-cidr.yaml | 14 + .../yaml/short-form-conditionals.yaml | 14 + .../yaml/short-form-find-in-map.yaml | 19 + .../yaml/short-form-get-att.yaml | 24 ++ .../yaml/short-form-import-value.yaml | 6 + .../test-templates/yaml/short-form-join.yaml | 11 + .../yaml/short-form-select.yaml | 17 + .../test-templates/yaml/short-form-split.yaml | 15 + .../test/yaml-templates.test.ts | 340 ++++++++++++++++++ 17 files changed, 649 insertions(+), 4 deletions(-) create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/invalid/short-form-transform.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/long-form-subnet.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/long-form-vpc.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-base64.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-cidr.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-conditionals.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-find-in-map.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-get-att.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-import-value.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-join.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-select.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-split.yaml create mode 100644 packages/@aws-cdk/cloudformation-include/test/yaml-templates.test.ts diff --git a/packages/@aws-cdk/cloudformation-include/README.md b/packages/@aws-cdk/cloudformation-include/README.md index 188f9989075ea..68f7b0e2a8b12 100644 --- a/packages/@aws-cdk/cloudformation-include/README.md +++ b/packages/@aws-cdk/cloudformation-include/README.md @@ -17,7 +17,7 @@ It can be thought of as an extension of the capabilities of the ## Basic usage -Assume we have a file `my-template.json`, that contains the following CloudFormation template: +Assume we have a file with an existing template. It could be in JSON format, in a file `my-template.json`: ```json { @@ -32,6 +32,16 @@ Assume we have a file `my-template.json`, that contains the following CloudForma } ``` +Or it could by in YAML format, in a file `my-template.yaml`: + +```yaml +Resources: + Bucket: + Type: AWS::S3::Bucket + Properties: + BucketName: some-bucket-name +``` + It can be included in a CDK application with the following code: ```typescript @@ -42,6 +52,14 @@ const cfnTemplate = new cfn_inc.CfnInclude(this, 'Template', { }); ``` +Or, if our template is YAML, we can use + +```typescript +const cfnTemplate = new cfn_inc.CfnInclude(this, 'Template', { + templateFile: 'my-template.yaml', +}); +``` + This will add all resources from `my-template.json` into the CDK application, preserving their original logical IDs from the template file. diff --git a/packages/@aws-cdk/cloudformation-include/lib/cfn-include.ts b/packages/@aws-cdk/cloudformation-include/lib/cfn-include.ts index b5cabdb9d9d01..49c5a769de73e 100644 --- a/packages/@aws-cdk/cloudformation-include/lib/cfn-include.ts +++ b/packages/@aws-cdk/cloudformation-include/lib/cfn-include.ts @@ -10,7 +10,7 @@ export interface CfnIncludeProps { /** * Path to the template file. * - * Currently, only JSON templates are supported. + * Both JSON and YAML template formats are supported. */ readonly templateFile: string; } @@ -31,7 +31,7 @@ export class CfnInclude extends core.CfnElement { super(scope, id); // read the template into a JS object - this.template = futils.readJsonSync(props.templateFile); + this.template = futils.readYamlSync(props.templateFile); // ToDo implement preserveLogicalIds=false this.preserveLogicalIds = true; diff --git a/packages/@aws-cdk/cloudformation-include/lib/file-utils.ts b/packages/@aws-cdk/cloudformation-include/lib/file-utils.ts index aff2d3255f842..dd58b76777d5d 100644 --- a/packages/@aws-cdk/cloudformation-include/lib/file-utils.ts +++ b/packages/@aws-cdk/cloudformation-include/lib/file-utils.ts @@ -1,6 +1,66 @@ import * as fs from 'fs'; +import * as yaml from 'yaml'; +import * as yaml_cst from 'yaml/parse-cst'; +import * as yaml_types from 'yaml/types'; export function readJsonSync(filePath: string): any { const fileContents = fs.readFileSync(filePath); return JSON.parse(fileContents.toString()); } + +export function readYamlSync(filePath: string): any { + const fileContents = fs.readFileSync(filePath); + return parseYamlStrWithCfnTags(fileContents.toString()); +} + +function makeTagForCfnIntrinsic( + intrinsicName: string, addFnPrefix: boolean = true, + resolveFun?: (_doc: yaml.Document, cstNode: yaml_cst.CST.Node) => any): yaml_types.Schema.CustomTag { + + return { + identify(value: any) { return typeof value === 'string'; }, + tag: `!${intrinsicName}`, + resolve: resolveFun || ((_doc: yaml.Document, cstNode: yaml_cst.CST.Node) => { + const ret: any = {}; + ret[addFnPrefix ? `Fn::${intrinsicName}` : intrinsicName] = + // the +1 is to account for the ! the short form begins with + parseYamlStrWithCfnTags(cstNode.toString().substring(intrinsicName.length + 1)); + return ret; + }), + }; +} + +const shortForms: yaml_types.Schema.CustomTag[] = [ + 'Base64', 'Cidr', 'FindInMap', 'GetAZs', 'ImportValue', 'Join', + 'Select', 'Split', 'Transform', 'And', 'Equals', 'If', 'Not', 'Or', +].map(name => makeTagForCfnIntrinsic(name)).concat( + // ToDo: special logic for ImportValue will be needed when support for Fn::Sub is added. See + // https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html + makeTagForCfnIntrinsic('Ref', false), + makeTagForCfnIntrinsic('GetAtt', true, (_doc: yaml.Document, cstNode: yaml_cst.CST.Node): any => { + // The position of the leftmost period and opening bracket tell us what syntax is being used + // If no brackets are found, then the dot notation is being used; the leftmost dot separates the + // logical ID from the attribute. + // + // If a bracket is found, then the list notation is being used; if present, the leftmost dot separates the + // logical ID from the attribute. + const firstDot = cstNode.toString().indexOf('.'); + const firstBracket = cstNode.toString().indexOf('['); + + return { + 'Fn::GetAtt': firstDot !== -1 && firstBracket === -1 + ? [ + cstNode.toString().substring('!GetAtt '.length, firstDot), + parseYamlStrWithCfnTags((cstNode.toString().substring(firstDot + 1))), + ] + : parseYamlStrWithCfnTags(cstNode.toString().substring('!GetAtt'.length)), + }; + }), +); + +function parseYamlStrWithCfnTags(text: string): any { + return yaml.parse(text, { + customTags: shortForms, + schema: 'yaml-1.1', + }); +} diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/functions-and-conditions.json b/packages/@aws-cdk/cloudformation-include/test/test-templates/functions-and-conditions.json index ce57b3e1a8b9f..e36cef5796891 100644 --- a/packages/@aws-cdk/cloudformation-include/test/test-templates/functions-and-conditions.json +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/functions-and-conditions.json @@ -147,7 +147,7 @@ "Parameters": { "Location": "location", "AnotherParameter": { - "Fn:Base64": "AnotherValue" + "Fn::Base64": "AnotherValue" } } } diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/invalid/short-form-transform.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/invalid/short-form-transform.yaml new file mode 100644 index 0000000000000..d1bb1598365f1 --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/invalid/short-form-transform.yaml @@ -0,0 +1,12 @@ +Resources: + Bucket: + Type: AWS::S3::Bucket + Properties: + BucketName: + !Transform { + "Name": "SomeMacroName", + "Parameters": { + key1: value1, + key2: value2, + } + } \ No newline at end of file diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/long-form-subnet.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/long-form-subnet.yaml new file mode 100644 index 0000000000000..34fbe929fca1f --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/long-form-subnet.yaml @@ -0,0 +1,45 @@ +Conditions: + AlwaysTrueCond: + Fn::Not: + - Fn::Equals: + - Ref: AWS::Region + - completely-made-up-region +Resources: + Bucket1: + Type: AWS::S3::Bucket + Properties: + BucketName: SomeBucketName + Bucket2: + Type: AWS::S3::Bucket + Properties: + BucketName: + Fn::GetAtt: [ Bucket1, Arn ] + CorsConfiguration: + CorsRules: + - AllowedMethods: + - GET + - POST + AllowedOrigins: + - Fn::Join: ['', [{ Ref: Bucket1 }, '1']] + - origin2 + MaxAge: + 2 + Subnet: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Fn::If: + - AlwaysTrueCond + - Fn::Select: + - 0 + - Fn::Split: + - "," + - Fn::ImportValue: ImportedVpcId + - Fn::Select: + - 0 + - Fn::GetAZs: eu-west-2 + CidrBlock: 10.0.0.0/24 + AvailabilityZone: + Fn::Select: + - '0' + - Fn::GetAZs: '' diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/long-form-vpc.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/long-form-vpc.yaml new file mode 100644 index 0000000000000..de8b072887d23 --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/long-form-vpc.yaml @@ -0,0 +1,44 @@ +Mappings: + RegionMap: + region-1: + HVM64: name1 + HVMG2: name2 +Conditions: + AlwaysTrueCond: + Fn::And: + - Fn::Not: + - Fn::Equals: [ Ref: "AWS::Region", completely-made-up-region] + - Fn::Or: + - Fn::Equals: [ Ref: "AWS::Region", completely-made-up-region] + - Fn::Equals: [ Ref: "AWS::Region", completely-made-up-region] +Resources: + Vpc: + Type: AWS::EC2::VPC + Properties: + CidrBlock: + Fn::If: + - AlwaysTrueCond + - Fn::Cidr: + - 192.168.1.1/24 + - 2 + - 5 + - Fn::Cidr: + - 10.0.0.0/24 + - '6' + - '5' + Bucket: + Type: AWS::S3::Bucket + Properties: + BucketName: + Fn::If: + - AlwaysTrueCond + - Fn::FindInMap: + - RegionMap + - region-1 + - HVM64 + - Fn::Transform: + Name: AWS::Include + Parameters: + Location: location, + AnotherParameter: + Fn::Base64: AnotherValue diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-base64.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-base64.yaml new file mode 100644 index 0000000000000..5047abd64962d --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-base64.yaml @@ -0,0 +1,6 @@ +Resources: + Base64Bucket: + Type: AWS::S3::Bucket + Properties: + BucketName: + !Base64 NonBase64BucketName diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-cidr.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-cidr.yaml new file mode 100644 index 0000000000000..ed77a78548925 --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-cidr.yaml @@ -0,0 +1,14 @@ +Resources: + CidrVpc1: + Type: AWS::EC2::VPC + Properties: + CidrBlock: + !Cidr [ 192.168.1.1/24, 2, 5 ] + CidrVpc2: + Type: AWS::EC2::VPC + Properties: + CidrBlock: + !Cidr + - "192.168.1.1/24" + - "2" + - "5" diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-conditionals.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-conditionals.yaml new file mode 100644 index 0000000000000..0eb44349d1775 --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-conditionals.yaml @@ -0,0 +1,14 @@ +Conditions: + AlwaysTrueCond: + !And + - !Not [ !Equals [ !Ref "AWS::Region", completely-made-up-region ] ] + - !Or [ !Equals [ !Ref "AWS::Region", completely-made-up-region ], !Equals [ !Ref "AWS::Region", completely-made-up-region] ] +Resources: + Bucket: + Type: AWS::S3::Bucket + Properties: + BucketName: + !If + - AlwaysTrueCond + - MyBucketName + - !Ref AWS::NoValue \ No newline at end of file diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-find-in-map.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-find-in-map.yaml new file mode 100644 index 0000000000000..39d8e582473f6 --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-find-in-map.yaml @@ -0,0 +1,19 @@ +Mappings: + RegionMap: + region-1: + HVM64: name1 + HVMG2: name2 +Resources: + Bucket1: + Type: AWS::S3::Bucket + Properties: + BucketName: + !FindInMap + - RegionMap + - region-1 + - HVM64 + Bucket2: + Type: AWS::S3::Bucket + Properties: + BucketName: + !FindInMap [ RegionMap, region-1, HVMG2 ] diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-get-att.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-get-att.yaml new file mode 100644 index 0000000000000..ede387067361a --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-get-att.yaml @@ -0,0 +1,24 @@ +Resources: + ELB: + Type: AWS::ElasticLoadBalancing::LoadBalancer + Properties: + AvailabilityZones: + - us-east-1a + Listeners: + - LoadBalancerPort: '80' + InstancePort: '80' + Protocol: HTTP + Bucket0: + Type: AWS::S3::Bucket + Properties: + BucketName: some-bucket + Bucket1: + Type: AWS::S3::Bucket + Properties: + BucketName: !GetAtt Bucket0.Arn + AccessControl: !GetAtt [ ELB, SourceSecurityGroup.GroupName ] + Bucket2: + Type: AWS::S3::Bucket + Properties: + BucketName: !GetAtt [ Bucket1, Arn ] + AccessControl: !GetAtt ELB.SourceSecurityGroup.GroupName diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-import-value.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-import-value.yaml new file mode 100644 index 0000000000000..1d5d4dabea4bc --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-import-value.yaml @@ -0,0 +1,6 @@ +Resources: + Bucket1: + Type: AWS::S3::Bucket + Properties: + BucketName: + !ImportValue SomeSharedValue diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-join.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-join.yaml new file mode 100644 index 0000000000000..ca9ab12b6521d --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-join.yaml @@ -0,0 +1,11 @@ +Resources: + Bucket: + Type: AWS::S3::Bucket + Properties: + BucketName: !Join [ + ' ', + [ + "NamePart1 ", + !ImportValue SomeSharedValue + ] + ] diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-select.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-select.yaml new file mode 100644 index 0000000000000..8e0374a8413e3 --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-select.yaml @@ -0,0 +1,17 @@ +Resources: + Subnet1: + Type: AWS::EC2::Subnet + Properties: + VpcId: + !Select [ 0, !GetAZs "" ] + CidrBlock: 10.0.0.0/24 + AvailabilityZone: + !Select [ '0', !GetAZs eu-west-2 ] + Subnet2: + Type: AWS::EC2::Subnet + Properties: + VpcId: + !Ref Subnet1 + CidrBlock: 10.0.0.0/24 + AvailabilityZone: + !Select [ 0, !GetAZs eu-west-2 ] diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-split.yaml b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-split.yaml new file mode 100644 index 0000000000000..17661580f0246 --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/yaml/short-form-split.yaml @@ -0,0 +1,15 @@ +Resources: + Bucket1: + Type: AWS::S3::Bucket + Properties: + BucketName: !Split [ + ' ', + !ImportValue SomeSharedBucketName + ] + Bucket2: + Type: AWS::S3::Bucket + Properties: + BucketName: + !Split + - ' ' + - !ImportValue SomeSharedBucketName diff --git a/packages/@aws-cdk/cloudformation-include/test/yaml-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/yaml-templates.test.ts new file mode 100644 index 0000000000000..19b7551c50876 --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/yaml-templates.test.ts @@ -0,0 +1,340 @@ +import '@aws-cdk/assert/jest'; +import * as core from '@aws-cdk/core'; +import * as path from 'path'; +import * as inc from '../lib'; +import * as futils from '../lib/file-utils'; + +// tslint:disable:object-literal-key-quotes +/* eslint-disable quotes */ + +describe('CDK Include', () => { + let stack: core.Stack; + + beforeEach(() => { + stack = new core.Stack(); + }); + + test('can ingest a template with all long-form CloudFormation functions and output it unchanged', () => { + includeTestTemplate(stack, 'long-form-vpc.yaml'); + + expect(stack).toMatchTemplate( + loadTestFileToJsObject('long-form-vpc.yaml'), + ); + }); + + test('can ingest a template with the short form Base64 function', () => { + includeTestTemplate(stack, 'short-form-base64.yaml'); + + expect(stack).toMatchTemplate({ + "Resources": { + "Base64Bucket": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { + "Fn::Base64": "NonBase64BucketName", + }, + }, + }, + }, + }); + }); + + test('can ingest a template with the short form !Cidr function', () => { + includeTestTemplate(stack, 'short-form-cidr.yaml'); + + expect(stack).toMatchTemplate({ + "Resources": { + "CidrVpc1": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": { + "Fn::Cidr": [ + "192.168.1.1/24", + 2, + 5, + ], + }, + }, + }, + "CidrVpc2": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": { + "Fn::Cidr": [ + "192.168.1.1/24", + "2", + "5", + ], + }, + }, + }, + }, + }); + }); + + test('can ingest a template with the short form !FindInMap function, in both hyphen and bracket notation', () => { + includeTestTemplate(stack, 'short-form-find-in-map.yaml'); + + expect(stack).toMatchTemplate({ + "Mappings": { + "RegionMap": { + "region-1": { + "HVM64": "name1", + "HVMG2": "name2", + }, + }, + }, + "Resources": { + "Bucket1": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { + "Fn::FindInMap": [ + "RegionMap", + "region-1", + "HVM64", + ], + }, + }, + }, + "Bucket2": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { + "Fn::FindInMap": [ + "RegionMap", + "region-1", + "HVMG2", + ], + }, + }, + }, + }, + }); + }); + + test('can ingest a template with the short form !GetAtt function', () => { + includeTestTemplate(stack, 'short-form-get-att.yaml'); + + expect(stack).toMatchTemplate({ + "Resources": { + "ELB": { + "Type": "AWS::ElasticLoadBalancing::LoadBalancer", + "Properties": { + "AvailabilityZones": [ + "us-east-1a", + ], + "Listeners": [ + { + "LoadBalancerPort": "80", + "InstancePort": "80", + "Protocol": "HTTP", + }, + ], + }, + }, + "Bucket0": { + "Type": "AWS::S3::Bucket", + "Properties": { "BucketName": "some-bucket" }, + }, + "Bucket1": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { "Fn::GetAtt": ["Bucket0", "Arn"] }, + "AccessControl": { "Fn::GetAtt": ["ELB", "SourceSecurityGroup.GroupName"] }, + }, + }, + "Bucket2": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { "Fn::GetAtt": ["Bucket1", "Arn"] }, + "AccessControl": { "Fn::GetAtt": ["ELB", "SourceSecurityGroup.GroupName"] }, + }, + }, + }, + }); + }); + + test('can ingest a template with short form Select, GetAZs, and Ref functions', () => { + includeTestTemplate(stack, 'short-form-select.yaml'); + + expect(stack).toMatchTemplate({ + "Resources": { + "Subnet1": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Fn::Select": [0, { "Fn::GetAZs": "" }], + }, + "CidrBlock": "10.0.0.0/24", + "AvailabilityZone": { + "Fn::Select": ["0", { "Fn::GetAZs": "eu-west-2" }], + }, + }, + }, + "Subnet2": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "Subnet1", + }, + "CidrBlock": "10.0.0.0/24", + "AvailabilityZone": { + "Fn::Select": [0, { "Fn::GetAZs": "eu-west-2" }], + }, + }, + }, + }, + }); + }); + + test('can ingest a template with the short form !ImportValue function', () => { + includeTestTemplate(stack, 'short-form-import-value.yaml'); + + expect(stack).toMatchTemplate({ + "Resources": { + "Bucket1": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { + "Fn::ImportValue": "SomeSharedValue", + }, + }, + }, + }, + }); + }); + + test('can ingest a template with the short form !Join function', () => { + includeTestTemplate(stack, 'short-form-join.yaml'); + + expect(stack).toMatchTemplate({ + "Resources": { + "Bucket": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { + "Fn::Join": [' ', [ + "NamePart1 ", + { "Fn::ImportValue": "SomeSharedValue" }, + ]], + }, + }, + }, + }, + }); + }); + + test('can ingest a template with the short form !Split function that uses both brackets and hyphens', () => { + includeTestTemplate(stack, 'short-form-split.yaml'); + + expect(stack).toMatchTemplate({ + "Resources": { + "Bucket1": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { + "Fn::Split": [' ', { + "Fn::ImportValue": "SomeSharedBucketName", + }], + }, + }, + }, + "Bucket2": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { + "Fn::Split": [' ', { + "Fn::ImportValue": "SomeSharedBucketName", + }], + }, + }, + }, + }, + }); + }); + + // Note that this yaml template fails validation. It is unclear how to invoke !Transform. + test('can ingest a template with the short form !Transform function', () => { + includeTestTemplate(stack, 'invalid/short-form-transform.yaml'); + + expect(stack).toMatchTemplate({ + "Resources": { + "Bucket": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { + "Fn::Transform": { + "Name": "SomeMacroName", + "Parameters": { + "key1": "value1", + "key2": "value2", + }, + }, + }, + }, + }, + }, + }); + }); + + test('can ingest a template with the short form conditionals', () => { + includeTestTemplate(stack, 'short-form-conditionals.yaml'); + + expect(stack).toMatchTemplate({ + "Conditions": { + "AlwaysTrueCond": { + "Fn::And": [ + { + "Fn::Not": [ + { "Fn::Equals": [{ "Ref": "AWS::Region" }, "completely-made-up-region"] }, + ], + }, + { + "Fn::Or": [ + { "Fn::Equals": [{ "Ref": "AWS::Region" }, "completely-made-up-region"] }, + { "Fn::Equals": [{ "Ref": "AWS::Region" }, "completely-made-up-region"] }, + ], + }, + ], + }, + }, + "Resources": { + "Bucket": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { + "Fn::If": [ + "AlwaysTrueCond", + "MyBucketName", + { "Ref": "AWS::NoValue" }, + ], + }, + }, + }, + }, + }); + }); + + test('can ingest a yaml with long-form functions and output it unchanged', () => { + includeTestTemplate(stack, 'long-form-subnet.yaml'); + + expect(stack).toMatchTemplate( + loadTestFileToJsObject('long-form-subnet.yaml'), + ); + }); +}); + +function includeTestTemplate(scope: core.Construct, testTemplate: string): inc.CfnInclude { + return new inc.CfnInclude(scope, 'MyScope', { + templateFile: _testTemplateFilePath(testTemplate), + }); +} + +function loadTestFileToJsObject(testTemplate: string): any { + return futils.readYamlSync(_testTemplateFilePath(testTemplate)); +} + +function _testTemplateFilePath(testTemplate: string) { + return path.join(__dirname, 'test-templates/yaml', testTemplate); +} From 18421686c4109deb018cc77429ec6deefb7d5689 Mon Sep 17 00:00:00 2001 From: Josh K Date: Mon, 29 Jun 2020 14:04:13 -0600 Subject: [PATCH 39/55] fix(core): bundling directory access permission is too restrictive (#8767) The new bundler uses `mkdtempSync` to pre-create uniquely named directories for asset staging. But, `mkdtempSync` creates the staging directories with a restrictive `0700 & ~umask` mode, rather than `mkdir`'s usual `0777 & ~umask` mode. In Bitbucket Pipelines, these restrictive permissions prevent the bundler from accessing its `/asset-output` volume. And, if the bundler can't access `/asset-output`, bundling fails. This fix chmods the asset staging directory to 0777. This change fixes my Bitbucket Pipelines issue. Closes #8757 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/core/lib/asset-staging.ts | 2 ++ packages/@aws-cdk/core/test/test.staging.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/@aws-cdk/core/lib/asset-staging.ts b/packages/@aws-cdk/core/lib/asset-staging.ts index e25994beeb821..2a0702c20d76f 100644 --- a/packages/@aws-cdk/core/lib/asset-staging.ts +++ b/packages/@aws-cdk/core/lib/asset-staging.ts @@ -144,6 +144,8 @@ export class AssetStaging extends Construct { // Create temp directory for bundling inside the temp staging directory const bundleDir = path.resolve(fs.mkdtempSync(path.join(stagingTmp, 'asset-bundle-'))); + // Chmod the bundleDir to full access. + fs.chmodSync(bundleDir, 0o777); let user: string; if (options.user) { diff --git a/packages/@aws-cdk/core/test/test.staging.ts b/packages/@aws-cdk/core/test/test.staging.ts index 81766f8a34879..e229d29ed1e8b 100644 --- a/packages/@aws-cdk/core/test/test.staging.ts +++ b/packages/@aws-cdk/core/test/test.staging.ts @@ -107,6 +107,7 @@ export = { const directory = path.join(__dirname, 'fs', 'fixtures', 'test1'); const ensureDirSyncSpy = sinon.spy(fs, 'ensureDirSync'); const mkdtempSyncSpy = sinon.spy(fs, 'mkdtempSync'); + const chmodSyncSpy = sinon.spy(fs, 'chmodSync'); // WHEN new AssetStaging(stack, 'Asset', { @@ -135,6 +136,7 @@ export = { const stagingTmp = path.join('.', '.cdk.staging'); test.ok(ensureDirSyncSpy.calledWith(stagingTmp)); test.ok(mkdtempSyncSpy.calledWith(sinon.match(path.join(stagingTmp, 'asset-bundle-')))); + test.ok(chmodSyncSpy.calledWith(sinon.match(path.join(stagingTmp, 'asset-bundle-')), 0o777)); test.done(); }, From fa281c8db378d437840f5c1cf5e8a359720f128b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2020 21:07:44 +0000 Subject: [PATCH 40/55] chore(deps): bump @typescript-eslint/eslint-plugin from 3.4.0 to 3.5.0 (#8796) Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 3.4.0 to 3.5.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v3.5.0/packages/eslint-plugin) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- tools/cdk-build-tools/package.json | 2 +- yarn.lock | 44 ++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/tools/cdk-build-tools/package.json b/tools/cdk-build-tools/package.json index 7913098fa397a..68e05b186710f 100644 --- a/tools/cdk-build-tools/package.json +++ b/tools/cdk-build-tools/package.json @@ -39,7 +39,7 @@ "pkglint": "0.0.0" }, "dependencies": { - "@typescript-eslint/eslint-plugin": "^3.4.0", + "@typescript-eslint/eslint-plugin": "^3.5.0", "@typescript-eslint/parser": "^2.19.2", "awslint": "0.0.0", "colors": "^1.4.0", diff --git a/yarn.lock b/yarn.lock index 3ad380188332a..76ac18b33851a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1647,12 +1647,12 @@ resolved "https://registry.yarnpkg.com/@types/yarnpkg__lockfile/-/yarnpkg__lockfile-1.1.3.tgz#38fb31d82ed07dea87df6bd565721d11979fd761" integrity sha512-mhdQq10tYpiNncMkg1vovCud5jQm+rWeRVz6fxjCJlY6uhDlAn9GnMSmBa2DQwqPf/jS5YR0K/xChDEh1jdOQg== -"@typescript-eslint/eslint-plugin@^3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.4.0.tgz#8378062e6be8a1d049259bdbcf27ce5dfbeee62b" - integrity sha512-wfkpiqaEVhZIuQRmudDszc01jC/YR7gMSxa6ulhggAe/Hs0KVIuo9wzvFiDbG3JD5pRFQoqnf4m7REDsUvBnMQ== +"@typescript-eslint/eslint-plugin@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.5.0.tgz#e7736e0808b5fb947a5f9dd949ae6736a7226b84" + integrity sha512-m4erZ8AkSjoIUOf8s4k2V1xdL2c1Vy0D3dN6/jC9d7+nEqjY3gxXCkgi3gW/GAxPaA4hV8biaCoTVdQmfAeTCQ== dependencies: - "@typescript-eslint/experimental-utils" "3.4.0" + "@typescript-eslint/experimental-utils" "3.5.0" debug "^4.1.1" functional-red-black-tree "^1.0.1" regexpp "^3.0.0" @@ -1669,13 +1669,14 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/experimental-utils@3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.4.0.tgz#8a44dfc6fb7f1d071937b390fe27608ebda122b8" - integrity sha512-rHPOjL43lOH1Opte4+dhC0a/+ks+8gOBwxXnyrZ/K4OTAChpSjP76fbI8Cglj7V5GouwVAGaK+xVwzqTyE/TPw== +"@typescript-eslint/experimental-utils@3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.5.0.tgz#d09f9ffb890d1b15a7ffa9975fae92eee05597c4" + integrity sha512-zGNOrVi5Wz0jcjUnFZ6QUD0MCox5hBuVwemGCew2qJzUX5xPoyR+0EzS5qD5qQXL/vnQ8Eu+nv03tpeFRwLrDg== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "3.4.0" + "@typescript-eslint/types" "3.5.0" + "@typescript-eslint/typescript-estree" "3.5.0" eslint-scope "^5.0.0" eslint-utils "^2.0.0" @@ -1689,6 +1690,11 @@ "@typescript-eslint/typescript-estree" "2.28.0" eslint-visitor-keys "^1.1.0" +"@typescript-eslint/types@3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.5.0.tgz#4e3d2a2272268d8ec3e3e4a37152a64956682639" + integrity sha512-Dreqb5idi66VVs1QkbAwVeDmdJG+sDtofJtKwKCZXIaBsINuCN7Jv5eDIHrS0hFMMiOvPH9UuOs4splW0iZe4Q== + "@typescript-eslint/typescript-estree@2.28.0": version "2.28.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.28.0.tgz#d34949099ff81092c36dc275b6a1ea580729ba00" @@ -1702,19 +1708,27 @@ semver "^6.3.0" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.4.0.tgz#6a787eb70b48969e4cd1ea67b057083f96dfee29" - integrity sha512-zKwLiybtt4uJb4mkG5q2t6+W7BuYx2IISiDNV+IY68VfoGwErDx/RfVI7SWL4gnZ2t1A1ytQQwZ+YOJbHHJ2rw== +"@typescript-eslint/typescript-estree@3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.5.0.tgz#dfc895db21a381b84f24c2a719f5bf9c600dcfdc" + integrity sha512-Na71ezI6QP5WVR4EHxwcBJgYiD+Sre9BZO5iJK2QhrmRPo/42+b0no/HZIrdD1sjghzlYv7t+7Jis05M1uMxQg== dependencies: + "@typescript-eslint/types" "3.5.0" + "@typescript-eslint/visitor-keys" "3.5.0" debug "^4.1.1" - eslint-visitor-keys "^1.1.0" glob "^7.1.6" is-glob "^4.0.1" lodash "^4.17.15" semver "^7.3.2" tsutils "^3.17.1" +"@typescript-eslint/visitor-keys@3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.5.0.tgz#73c1ea2582f814735e4afdc1cf6f5e3af78db60a" + integrity sha512-7cTp9rcX2sz9Z+zua9MCOX4cqp5rYyFD5o8LlbSpXrMTXoRdngTtotRZEkm8+FNMHPWYFhitFK+qt/brK8BVJQ== + dependencies: + eslint-visitor-keys "^1.1.0" + "@yarnpkg/lockfile@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" From 9adf55f27a87ba4fd2c69b446557b1cf1c0b210e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2020 21:35:05 +0000 Subject: [PATCH 41/55] chore(deps): bump aws-sdk from 2.706.0 to 2.707.0 (#8791) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.706.0 to 2.707.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.706.0...v2.707.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-cloudfront/package.json | 2 +- packages/@aws-cdk/aws-cloudtrail/package.json | 2 +- packages/@aws-cdk/aws-codebuild/package.json | 2 +- packages/@aws-cdk/aws-codecommit/package.json | 2 +- packages/@aws-cdk/aws-dynamodb/package.json | 2 +- packages/@aws-cdk/aws-eks/package.json | 2 +- packages/@aws-cdk/aws-events-targets/package.json | 2 +- packages/@aws-cdk/aws-lambda/package.json | 2 +- packages/@aws-cdk/aws-route53/package.json | 2 +- packages/@aws-cdk/aws-sqs/package.json | 2 +- packages/@aws-cdk/custom-resources/package.json | 2 +- packages/aws-cdk/package.json | 2 +- packages/cdk-assets/package.json | 2 +- yarn.lock | 8 ++++---- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudfront/package.json b/packages/@aws-cdk/aws-cloudfront/package.json index 9daff3e256225..04a707cba841a 100644 --- a/packages/@aws-cdk/aws-cloudfront/package.json +++ b/packages/@aws-cdk/aws-cloudfront/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-cloudtrail/package.json b/packages/@aws-cdk/aws-cloudtrail/package.json index 158b50fc11d40..8d5509c25710a 100644 --- a/packages/@aws-cdk/aws-cloudtrail/package.json +++ b/packages/@aws-cdk/aws-cloudtrail/package.json @@ -64,7 +64,7 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/assert": "0.0.0", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codebuild/package.json b/packages/@aws-cdk/aws-codebuild/package.json index a3ebadc8e8cee..80ca45af9c2e4 100644 --- a/packages/@aws-cdk/aws-codebuild/package.json +++ b/packages/@aws-cdk/aws-codebuild/package.json @@ -70,7 +70,7 @@ "@aws-cdk/aws-sns": "0.0.0", "@aws-cdk/aws-sqs": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codecommit/package.json b/packages/@aws-cdk/aws-codecommit/package.json index 1fb64aef65eaf..6800a63745732 100644 --- a/packages/@aws-cdk/aws-codecommit/package.json +++ b/packages/@aws-cdk/aws-codecommit/package.json @@ -70,7 +70,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-dynamodb/package.json b/packages/@aws-cdk/aws-dynamodb/package.json index 833c699d5d80e..a228be13eaa0b 100644 --- a/packages/@aws-cdk/aws-dynamodb/package.json +++ b/packages/@aws-cdk/aws-dynamodb/package.json @@ -65,7 +65,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/jest": "^26.0.3", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index df01d4bdbe553..1fb958daabfff 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -65,7 +65,7 @@ "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", "@types/yaml": "1.2.0", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-events-targets/package.json b/packages/@aws-cdk/aws-events-targets/package.json index 01ab709164870..7efd7da1b53ca 100644 --- a/packages/@aws-cdk/aws-events-targets/package.json +++ b/packages/@aws-cdk/aws-events-targets/package.json @@ -68,7 +68,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-codecommit": "0.0.0", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index 1fa918db69d5c..3b70a1aa61194 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -71,7 +71,7 @@ "@types/lodash": "^4.14.157", "@types/nodeunit": "^0.0.31", "@types/sinon": "^9.0.4", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-route53/package.json b/packages/@aws-cdk/aws-route53/package.json index b6d65266506ec..a4ce73f9ac44f 100644 --- a/packages/@aws-cdk/aws-route53/package.json +++ b/packages/@aws-cdk/aws-route53/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-sqs/package.json b/packages/@aws-cdk/aws-sqs/package.json index ebc4924d0ce86..3612521f3a8a2 100644 --- a/packages/@aws-cdk/aws-sqs/package.json +++ b/packages/@aws-cdk/aws-sqs/package.json @@ -65,7 +65,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index 7907d4568c796..8b5141d4c5676 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -73,7 +73,7 @@ "@types/aws-lambda": "^8.10.39", "@types/fs-extra": "^8.1.0", "@types/sinon": "^9.0.4", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 886b797adf972..9a014953a895a 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -71,7 +71,7 @@ "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/region-info": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "camelcase": "^6.0.0", "cdk-assets": "0.0.0", "colors": "^1.4.0", diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index 138a686cc6afb..c233fed3eea17 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -47,7 +47,7 @@ "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.706.0", + "aws-sdk": "^2.707.0", "glob": "^7.1.6", "yargs": "^15.3.1" }, diff --git a/yarn.lock b/yarn.lock index 76ac18b33851a..19e878bfb3ea9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2138,10 +2138,10 @@ aws-sdk-mock@^5.1.0: sinon "^9.0.1" traverse "^0.6.6" -aws-sdk@^2.637.0, aws-sdk@^2.706.0: - version "2.706.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.706.0.tgz#09f65e9a91ecac5a635daf934082abae30eca953" - integrity sha512-7GT+yrB5Wb/zOReRdv/Pzkb2Qt+hz6B/8FGMVaoysX3NryHvQUdz7EQWi5yhg9CxOjKxdw5lFwYSs69YlSp1KA== +aws-sdk@^2.637.0, aws-sdk@^2.707.0: + version "2.707.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.707.0.tgz#c7506dadd1d60a73920ade9027645e166f444e25" + integrity sha512-nt55Z9wQKFodOuwElF3222Thc3kDVnaC4rwemPEHIM1cVGPQe6E5yBfc6AwtYmSo6eoMMEWd6XO5wG2am9PW0w== dependencies: buffer "4.9.2" events "1.1.1" From 13deb266f030a28890b5672a0c12b658d253f57e Mon Sep 17 00:00:00 2001 From: Shiv Lakshminarayan Date: Tue, 30 Jun 2020 00:21:56 -0700 Subject: [PATCH 42/55] feat(stepfunctions-tasks): task construct to call `RunJob` on ECS (#8451) Replacement for the current implementation of `ECS` service integration. Merges state and service integration properties and represents them as a construct. The notable differences from the current implementation are: * single implementation class`runTask` with an added `launchTarget` required property where the properties specific to the launch type are specified * linter disable of `ref-via-interface` as we need to use `TaskDefinition` because properties that are not known for imported task definitions are required * older implementations have been marked deprecated with direction to the replacement. Left all of the unit tests (except fargate platform version which was not previously honored) and integ test expectations verbatim to ensure that we have not lost fidelity. BREAKING CHANGE: * `containerName` is not supported as an override anymore and has been replaced by `containerDefinition` Closes #8610 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-stepfunctions-tasks/README.md | 112 ++- .../lib/ecs/run-ecs-ec2-task.ts | 2 + .../lib/ecs/run-ecs-fargate-task.ts | 2 + .../lib/ecs/run-ecs-task-base-types.ts | 4 +- .../lib/ecs/run-ecs-task-base.ts | 4 +- .../lib/ecs/run-task.ts | 383 ++++++++++ .../aws-stepfunctions-tasks/lib/index.ts | 1 + .../test/ecs/ecs-tasks.test.ts | 111 ++- .../test/ecs/integ.ec2-run-task.expected.json | 719 ++++++++++++++++++ .../test/ecs/integ.ec2-run-task.ts | 75 ++ .../test/ecs/integ.ec2-task.ts | 32 +- .../ecs/integ.fargate-run-task.expected.json | 305 ++++++++ .../test/ecs/integ.fargate-run-task.ts | 77 ++ .../test/ecs/integ.fargate-task.ts | 33 +- .../test/ecs/run-tasks.test.ts | 377 +++++++++ 15 files changed, 2130 insertions(+), 107 deletions(-) create mode 100644 packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-task.ts create mode 100644 packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-run-task.expected.json create mode 100644 packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-run-task.ts create mode 100644 packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-run-task.expected.json create mode 100644 packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-run-task.ts create mode 100644 packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/run-tasks.test.ts diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md index 239c943674c2e..d5142e2159d2b 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md @@ -37,6 +37,8 @@ This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aw - [UpdateItem](#updateitem) - [ECS](#ecs) - [RunTask](#runtask) + - [EC2](#ec2) + - [Fargate](#fargate) - [EMR](#emr) - [Create Cluster](#create-cluster) - [Termination Protection](#termination-protection) @@ -305,31 +307,105 @@ Step Functions supports [ECS/Fargate](https://docs.aws.amazon.com/step-functions [RunTask](https://docs.aws.amazon.com/step-functions/latest/dg/connect-ecs.html) starts a new task using the specified task definition. +#### EC2 + +The EC2 launch type allows you to run your containerized applications on a cluster +of Amazon EC2 instances that you manage. + +When a task that uses the EC2 launch type is launched, Amazon ECS must determine where +to place the task based on the requirements specified in the task definition, such as +CPU and memory. Similarly, when you scale down the task count, Amazon ECS must determine +which tasks to terminate. You can apply task placement strategies and constraints to +customize how Amazon ECS places and terminates tasks. Learn more about [task placement](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement.html) + +The following example runs a job from a task definition on EC2 + ```ts import * as ecs from '@aws-cdk/aws-ecs'; +import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; +import * as sfn from '@aws-cdk/aws-stepfunctions'; -// See examples in ECS library for initialization of 'cluster' and 'taskDefinition' +const vpc = ec2.Vpc.fromLookup(stack, 'Vpc', { + isDefault: true, +}); -new ecs.RunEcsFargateTask({ - cluster, - taskDefinition, - containerOverrides: [ - { - containerName: 'TheContainer', - environment: [ - { - name: 'CONTAINER_INPUT', - value: JsonPath.stringAt('$.valueFromStateData'), - } - ] - } - ] +const cluster = new ecs.Cluster(stack, 'Ec2Cluster', { vpc }); +cluster.addCapacity('DefaultAutoScalingGroup', { + instanceType: new ec2.InstanceType('t2.micro'), + vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC }, +}); + +const taskDefinition = new ecs.TaskDefinition(stack, 'TD', { + compatibility: ecs.Compatibility.EC2, +}); + +taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromRegistry('foo/bar'), + memoryLimitMiB: 256, +}); + +const runTask = new tasks.EcsRunTask(stack, 'Run', { + integrationPattern: sfn.IntegrationPattern.RUN_JOB, + cluster, + taskDefinition, + launchTarget: new tasks.EcsEc2LaunchTarget({ + placementStrategies: [ + ecs.PlacementStrategy.spreadAcrossInstances(), + ecs.PlacementStrategy.packedByCpu(), + ecs.PlacementStrategy.randomly(), + ], + placementConstraints: [ + ecs.PlacementConstraint.memberOf('blieptuut') + ], + }), + }); +``` + +#### Fargate + +AWS Fargate is a serverless compute engine for containers that works with Amazon +Elastic Container Service (ECS). Fargate makes it easy for you to focus on building +your applications. Fargate removes the need to provision and manage servers, lets you +specify and pay for resources per application, and improves security through application +isolation by design. Learn more about [Fargate](https://aws.amazon.com/fargate/) + +The Fargate launch type allows you to run your containerized applications without the need +to provision and manage the backend infrastructure. Just register your task definition and +Fargate launches the container for you. + +The following example runs a job from a task definition on Fargate + +```ts +import * as ecs from '@aws-cdk/aws-ecs'; +import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; +import * as sfn from '@aws-cdk/aws-stepfunctions'; + +const vpc = ec2.Vpc.fromLookup(stack, 'Vpc', { + isDefault: true, }); -fargateTask.connections.allowToDefaultPort(rdsCluster, 'Read the database'); +const cluster = new ecs.Cluster(stack, 'FargateCluster', { vpc }); -new sfn.Task(this, 'CallFargate', { - task: fargateTask +const taskDefinition = new ecs.TaskDefinition(stack, 'TD', { + memoryMiB: '512', + cpu: '256', + compatibility: ecs.Compatibility.FARGATE, +}); + +const containerDefinition = taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromRegistry('foo/bar'), + memoryLimitMiB: 256, +}); + +const runTask = new tasks.EcsRunTask(stack, 'RunFargate', { + integrationPattern: sfn.IntegrationPattern.RUN_JOB, + cluster, + taskDefinition, + containerOverrides: [{ + containerDefinition, + environment: [{ name: 'SOME_KEY', value: sfn.JsonPath.stringAt('$.SomeKey') }], + }], + launchTarget: new tasks.EcsFargateLaunchTarget(), }); ``` diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-ec2-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-ec2-task.ts index 8fc7105c9ae0b..a14778d306e62 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-ec2-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-ec2-task.ts @@ -41,6 +41,8 @@ export interface RunEcsEc2TaskProps extends CommonEcsRunTaskProps { /** * Run an ECS/EC2 Task in a StepFunctions workflow + * + * @deprecated - replaced by `EcsEc2RunTask` */ export class RunEcsEc2Task extends EcsRunTaskBase { constructor(props: RunEcsEc2TaskProps) { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-fargate-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-fargate-task.ts index 63526106757bf..2910613c4d2c5 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-fargate-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-fargate-task.ts @@ -40,6 +40,8 @@ export interface RunEcsFargateTaskProps extends CommonEcsRunTaskProps { /** * Start a service on an ECS cluster + * + * @deprecated - replaced by `EcsFargateRunTask` */ export class RunEcsFargateTask extends EcsRunTaskBase { constructor(props: RunEcsFargateTaskProps) { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base-types.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base-types.ts index aee94c1af0af7..107f86362543b 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base-types.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base-types.ts @@ -1,3 +1,5 @@ +import { ContainerDefinition } from '@aws-cdk/aws-ecs'; + /** * A list of container overrides that specify the name of a container * and the overrides it should receive. @@ -6,7 +8,7 @@ export interface ContainerOverride { /** * Name of the container inside the task definition */ - readonly containerName: string; + readonly containerDefinition: ContainerDefinition; /** * Command to run inside the container diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base.ts index fc4d5f6efc448..12d1c71665577 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-ecs-task-base.ts @@ -87,7 +87,7 @@ export class EcsRunTaskBase implements ec2.IConnectable, sfn.IStepFunctionsTask } for (const override of this.props.containerOverrides || []) { - const name = override.containerName; + const name = override.containerDefinition.containerName; if (!cdk.Token.isUnresolved(name)) { const cont = this.props.taskDefinition.node.tryFindChild(name); if (!cont) { @@ -191,7 +191,7 @@ function renderOverrides(containerOverrides?: ContainerOverride[]) { const ret = new Array(); for (const override of containerOverrides) { ret.push({ - Name: override.containerName, + Name: override.containerDefinition.containerName, Command: override.command, Cpu: override.cpu, Memory: override.memoryLimit, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-task.ts new file mode 100644 index 0000000000000..d06d204641653 --- /dev/null +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/ecs/run-task.ts @@ -0,0 +1,383 @@ +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as ecs from '@aws-cdk/aws-ecs'; +import * as iam from '@aws-cdk/aws-iam'; +import * as sfn from '@aws-cdk/aws-stepfunctions'; +import * as cdk from '@aws-cdk/core'; +import { ContainerOverride } from '..'; +import { integrationResourceArn, validatePatternSupported } from '../private/task-utils'; + +/** + * Properties for ECS Tasks + */ +export interface EcsRunTaskProps extends sfn.TaskStateBaseProps { + /** + * The ECS cluster to run the task on + */ + readonly cluster: ecs.ICluster; + + /** + * [disable-awslint:ref-via-interface] + * Task Definition used for running tasks in the service. + * + * Note: this must be TaskDefinition, and not ITaskDefinition, + * as it requires properties that are not known for imported task definitions + */ + readonly taskDefinition: ecs.TaskDefinition; + + /** + * Container setting overrides + * + * Specify the container to use and the overrides to apply. + * + * @default - No overrides + */ + readonly containerOverrides?: ContainerOverride[]; + + /** + * Subnets to place the task's ENIs + * + * @default - Public subnets if assignPublicIp is set. Private subnets otherwise. + */ + readonly subnets?: ec2.SubnetSelection; + + /** + * Existing security groups to use for the tasks + * + * @default - A new security group is created + */ + readonly securityGroups?: ec2.ISecurityGroup[]; + + /** + * Assign public IP addresses to each task + * + * @default false + */ + readonly assignPublicIp?: boolean; + + /** + * An Amazon ECS launch type determines the type of infrastructure on which your + * tasks and services are hosted. + * + * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html + */ + readonly launchTarget: IEcsLaunchTarget; +} + +/** + * An Amazon ECS launch type determines the type of infrastructure on which your tasks and services are hosted. + * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html + */ +export interface IEcsLaunchTarget { + /** + * called when the ECS launch target is configured on RunTask + */ + bind(task: EcsRunTask, launchTargetOptions: LaunchTargetBindOptions): EcsLaunchTargetConfig; +} + +/** + * Options for binding a launch target to an ECS run job task + */ +export interface LaunchTargetBindOptions { + /** + * Task definition to run Docker containers in Amazon ECS + */ + readonly taskDefinition: ecs.ITaskDefinition; + + /** + * A regional grouping of one or more container instances on which you can run + * tasks and services. + * + * @default - No cluster + */ + readonly cluster?: ecs.ICluster; +} + +/** + * Configuration options for the ECS launch type + */ +export interface EcsLaunchTargetConfig { + /** + * Additional parameters to pass to the base task + * + * @default - No additional parameters passed + */ + readonly parameters?: { [key: string]: any }; +} + +/** + * Properties to define an ECS service + */ +export interface EcsFargateLaunchTargetOptions { + /** + * Refers to a specific runtime environment for Fargate task infrastructure. + * Fargate platform version is a combination of the kernel and container runtime versions. + * + * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/platform_versions.html + */ + readonly platformVersion: ecs.FargatePlatformVersion; +} + +/** + * Options to run an ECS task on EC2 in StepFunctions and ECS + */ +export interface EcsEc2LaunchTargetOptions { + /** + * Placement constraints + * + * @default - None + */ + readonly placementConstraints?: ecs.PlacementConstraint[]; + + /** + * Placement strategies + * + * @default - None + */ + readonly placementStrategies?: ecs.PlacementStrategy[]; +} + +/** + * Configuration for running an ECS task on Fargate + * + * @see https://docs.aws.amazon.com/AmazonECS/latest/userguide/launch_types.html#launch-type-fargate + */ +export class EcsFargateLaunchTarget implements IEcsLaunchTarget { + constructor(private readonly options?: EcsFargateLaunchTargetOptions) {} + + /** + * Called when the Fargate launch type configured on RunTask + */ + public bind(_task: EcsRunTask, launchTargetOptions: LaunchTargetBindOptions): EcsLaunchTargetConfig { + if (!launchTargetOptions.taskDefinition.isFargateCompatible) { + throw new Error('Supplied TaskDefinition is not compatible with Fargate'); + } + + return { + parameters: { + LaunchType: 'FARGATE', + PlatformVersion: this.options?.platformVersion, + }, + }; + } +} + +/** + * Configuration for running an ECS task on EC2 + * + * @see https://docs.aws.amazon.com/AmazonECS/latest/userguide/launch_types.html#launch-type-ec2 + */ +export class EcsEc2LaunchTarget implements IEcsLaunchTarget { + constructor(private readonly options?: EcsEc2LaunchTargetOptions) {} + /** + * Called when the EC2 launch type is configured on RunTask + */ + public bind(_task: EcsRunTask, launchTargetOptions: LaunchTargetBindOptions): EcsLaunchTargetConfig { + if (!launchTargetOptions.taskDefinition.isEc2Compatible) { + throw new Error('Supplied TaskDefinition is not compatible with EC2'); + } + + if (!launchTargetOptions.cluster?.hasEc2Capacity) { + throw new Error('Cluster for this service needs Ec2 capacity. Call addCapacity() on the cluster.'); + } + + return { + parameters: { + LaunchType: 'EC2', + // takes an array of placement constraints each of which contain a single item array of constraints, flattens it + // and renders the Json to be passed as a parameter in the state machine. + // input: [ecs.PlacementConstraint.distinctInstances()] - distinctInstances() returns [{ type: 'distinctInstance' }] + // output: {Type: 'distinctInstance'} + PlacementConstraints: noEmpty(flatten((this.options?.placementConstraints ?? []).map((c) => c.toJson().map(uppercaseKeys)))), + PlacementStrategy: noEmpty(flatten((this.options?.placementStrategies ?? []).map((c) => c.toJson().map(uppercaseKeys)))), + }, + }; + + function uppercaseKeys(obj: { [key: string]: any }): { [key: string]: any } { + const ret: { [key: string]: any } = {}; + for (const key of Object.keys(obj)) { + ret[key.slice(0, 1).toUpperCase() + key.slice(1)] = obj[key]; + } + return ret; + } + + function flatten(xs: A[][]): A[] { + return Array.prototype.concat([], ...xs); + } + + function noEmpty(xs: A[]): A[] | undefined { + if (xs.length === 0) { + return undefined; + } + return xs; + } + } +} + +/** + * Run a Task on ECS or Fargate + */ +export class EcsRunTask extends sfn.TaskStateBase implements ec2.IConnectable { + private static readonly SUPPORTED_INTEGRATION_PATTERNS: sfn.IntegrationPattern[] = [ + sfn.IntegrationPattern.REQUEST_RESPONSE, + sfn.IntegrationPattern.RUN_JOB, + sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, + ]; + + /** + * Manage allowed network traffic for this service + */ + public readonly connections: ec2.Connections = new ec2.Connections(); + + protected readonly taskMetrics?: sfn.TaskMetricsConfig; + protected readonly taskPolicies?: iam.PolicyStatement[]; + + private securityGroups: ec2.ISecurityGroup[] = []; + private networkConfiguration?: any; + private readonly integrationPattern: sfn.IntegrationPattern; + + constructor(scope: cdk.Construct, id: string, private readonly props: EcsRunTaskProps) { + super(scope, id, props); + this.integrationPattern = props.integrationPattern ?? sfn.IntegrationPattern.REQUEST_RESPONSE; + + validatePatternSupported(this.integrationPattern, EcsRunTask.SUPPORTED_INTEGRATION_PATTERNS); + + if (this.integrationPattern === sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN && !sfn.FieldUtils.containsTaskToken(props.containerOverrides)) { + throw new Error('Task Token is required in `containerOverrides` for callback. Use Context.taskToken to set the token.'); + } + + if (!this.props.taskDefinition.defaultContainer) { + throw new Error('A TaskDefinition must have at least one essential container'); + } + + if (this.props.taskDefinition.networkMode === ecs.NetworkMode.AWS_VPC) { + this.configureAwsVpcNetworking(); + } else { + // Either None, Bridge or Host networking. Copy SecurityGroup from ASG. + this.validateNoNetworkingProps(); + this.connections.addSecurityGroup(...this.props.cluster.connections.securityGroups); + } + + for (const override of this.props.containerOverrides ?? []) { + const name = override.containerDefinition.containerName; + if (!cdk.Token.isUnresolved(name)) { + const cont = this.props.taskDefinition.node.tryFindChild(name); + if (!cont) { + throw new Error(`Overrides mention container with name '${name}', but no such container in task definition`); + } + } + } + + this.taskPolicies = this.makePolicyStatements(); + } + + /** + * @internal + */ + protected _renderTask(): any { + return { + Resource: integrationResourceArn('ecs', 'runTask', this.integrationPattern), + Parameters: sfn.FieldUtils.renderObject({ + Cluster: this.props.cluster.clusterArn, + TaskDefinition: this.props.taskDefinition.taskDefinitionArn, + NetworkConfiguration: this.networkConfiguration, + Overrides: renderOverrides(this.props.containerOverrides), + ...this.props.launchTarget.bind(this, {taskDefinition: this.props.taskDefinition, cluster: this.props.cluster}).parameters, + }), + }; + } + + private configureAwsVpcNetworking() { + const subnetSelection = this.props.subnets ?? { subnetType: this.props.assignPublicIp ? ec2.SubnetType.PUBLIC : ec2.SubnetType.PRIVATE }; + + this.networkConfiguration = { + AwsvpcConfiguration: { + AssignPublicIp: this.props.assignPublicIp ? (this.props.assignPublicIp ? 'ENABLED' : 'DISABLED') : undefined, + Subnets: this.props.cluster.vpc.selectSubnets(subnetSelection).subnetIds, + SecurityGroups: cdk.Lazy.listValue({ produce: () => this.securityGroups?.map(sg => sg.securityGroupId) }), + }, + }; + + // Make sure we have a security group if we're using AWSVPC networking + this.securityGroups = this.props.securityGroups ?? [new ec2.SecurityGroup(this, 'SecurityGroup', { vpc: this.props.cluster.vpc })]; + this.connections.addSecurityGroup(...this.securityGroups); + } + + private validateNoNetworkingProps() { + if (this.props.subnets !== undefined || this.props.securityGroups !== undefined) { + throw new Error( + `Supplied TaskDefinition must have 'networkMode' of 'AWS_VPC' to use 'vpcSubnets' and 'securityGroup'. Received: ${this.props.taskDefinition.networkMode}`, + ); + } + } + + private makePolicyStatements(): iam.PolicyStatement[] { + const stack = cdk.Stack.of(this); + + // https://docs.aws.amazon.com/step-functions/latest/dg/ecs-iam.html + const policyStatements = [ + new iam.PolicyStatement({ + actions: ['ecs:RunTask'], + resources: [this.props.taskDefinition.taskDefinitionArn], + }), + new iam.PolicyStatement({ + actions: ['ecs:StopTask', 'ecs:DescribeTasks'], + resources: ['*'], + }), + new iam.PolicyStatement({ + actions: ['iam:PassRole'], + resources: this.taskExecutionRoles().map((r) => r.roleArn), + }), + ]; + + if (this.integrationPattern === sfn.IntegrationPattern.RUN_JOB) { + policyStatements.push( + new iam.PolicyStatement({ + actions: ['events:PutTargets', 'events:PutRule', 'events:DescribeRule'], + resources: [ + stack.formatArn({ + service: 'events', + resource: 'rule', + resourceName: 'StepFunctionsGetEventsForECSTaskRule', + }), + ], + }), + ); + } + + return policyStatements; + } + + private taskExecutionRoles(): iam.IRole[] { + // Need to be able to pass both Task and Execution role, apparently + const ret = new Array(); + ret.push(this.props.taskDefinition.taskRole); + if (this.props.taskDefinition.executionRole) { + ret.push(this.props.taskDefinition.executionRole); + } + return ret; + } +} + +function renderOverrides(containerOverrides?: ContainerOverride[]) { + if (!containerOverrides || containerOverrides.length === 0) { + return undefined; + } + + const ret = new Array(); + for (const override of containerOverrides) { + ret.push({ + Name: override.containerDefinition.containerName, + Command: override.command, + Cpu: override.cpu, + Memory: override.memoryLimit, + MemoryReservation: override.memoryReservation, + Environment: + override.environment?.map((e) => ({ + Name: e.name, + Value: e.value, + })), + }); + } + + return { ContainerOverrides: ret }; +} diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/index.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/index.ts index ec24d7f518d9c..68d8c30b93997 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/index.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/index.ts @@ -10,6 +10,7 @@ export * from './sqs/send-to-queue'; export * from './sqs/send-message'; export * from './ecs/run-ecs-ec2-task'; export * from './ecs/run-ecs-fargate-task'; +export * from './ecs/run-task'; export * from './sagemaker/base-types'; export * from './sagemaker/create-training-job'; export * from './sagemaker/create-transform-job'; diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/ecs-tasks.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/ecs-tasks.test.ts index a644363a9c077..e87d5a6a66163 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/ecs-tasks.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/ecs-tasks.test.ts @@ -30,8 +30,7 @@ test('Cannot create a Fargate task with a fargate-incompatible task definition', memoryLimitMiB: 256, }); - expect(() => new tasks.RunEcsFargateTask({ cluster, taskDefinition })) - .toThrowError(/not configured for compatibility with Fargate/); + expect(() => new tasks.RunEcsFargateTask({ cluster, taskDefinition })).toThrowError(/not configured for compatibility with Fargate/); }); test('Cannot create a Fargate task without a default container', () => { @@ -40,8 +39,7 @@ test('Cannot create a Fargate task without a default container', () => { cpu: '256', compatibility: ecs.Compatibility.FARGATE, }); - expect(() => new tasks.RunEcsFargateTask({ cluster, taskDefinition })) - .toThrowError(/must have at least one essential container/); + expect(() => new tasks.RunEcsFargateTask({ cluster, taskDefinition })).toThrowError(/must have at least one essential container/); }); test('Running a Fargate Task', () => { @@ -50,7 +48,7 @@ test('Running a Fargate Task', () => { cpu: '256', compatibility: ecs.Compatibility.FARGATE, }); - taskDefinition.addContainer('TheContainer', { + const containerDefinition = taskDefinition.addContainer('TheContainer', { image: ecs.ContainerImage.fromRegistry('foo/bar'), memoryLimitMiB: 256, }); @@ -62,7 +60,7 @@ test('Running a Fargate Task', () => { taskDefinition, containerOverrides: [ { - containerName: 'TheContainer', + containerDefinition, environment: [ {name: 'SOME_KEY', value: sfn.JsonPath.stringAt('$.SomeKey')}, ], @@ -78,18 +76,15 @@ test('Running a Fargate Task', () => { expect(stack.resolve(runTask.toStateJson())).toEqual({ End: true, Parameters: { - Cluster: {'Fn::GetAtt': ['ClusterEB0386A7', 'Arn']}, + Cluster: { 'Fn::GetAtt': ['ClusterEB0386A7', 'Arn'] }, LaunchType: 'FARGATE', NetworkConfiguration: { AwsvpcConfiguration: { - SecurityGroups: [{'Fn::GetAtt': ['RunFargateSecurityGroup709740F2', 'GroupId']}], - Subnets: [ - {Ref: 'VpcPrivateSubnet1Subnet536B997A'}, - {Ref: 'VpcPrivateSubnet2Subnet3788AAA1'}, - ], + SecurityGroups: [{ 'Fn::GetAtt': ['RunFargateSecurityGroup709740F2', 'GroupId'] }], + Subnets: [{ Ref: 'VpcPrivateSubnet1Subnet536B997A' }, { Ref: 'VpcPrivateSubnet2Subnet3788AAA1' }], }, }, - TaskDefinition: {Ref: 'TD49C78F36'}, + TaskDefinition: { Ref: 'TD49C78F36' }, Overrides: { ContainerOverrides: [ { @@ -125,7 +120,7 @@ test('Running a Fargate Task', () => { { Action: 'ecs:RunTask', Effect: 'Allow', - Resource: {Ref: 'TD49C78F36'}, + Resource: { Ref: 'TD49C78F36' }, }, { Action: ['ecs:StopTask', 'ecs:DescribeTasks'], @@ -135,20 +130,25 @@ test('Running a Fargate Task', () => { { Action: 'iam:PassRole', Effect: 'Allow', - Resource: [{'Fn::GetAtt': ['TDTaskRoleC497AFFC', 'Arn']}], + Resource: [{ 'Fn::GetAtt': ['TDTaskRoleC497AFFC', 'Arn'] }], }, { Action: ['events:PutTargets', 'events:PutRule', 'events:DescribeRule'], Effect: 'Allow', - Resource: {'Fn::Join': ['', [ - 'arn:', - {Ref: 'AWS::Partition'}, - ':events:', - {Ref: 'AWS::Region'}, - ':', - {Ref: 'AWS::AccountId'}, - ':rule/StepFunctionsGetEventsForECSTaskRule', - ]]}, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':events:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':rule/StepFunctionsGetEventsForECSTaskRule', + ], + ], + }, }, ], }, @@ -159,7 +159,7 @@ test('Running an EC2 Task with bridge network', () => { const taskDefinition = new ecs.TaskDefinition(stack, 'TD', { compatibility: ecs.Compatibility.EC2, }); - taskDefinition.addContainer('TheContainer', { + const containerDefinition = taskDefinition.addContainer('TheContainer', { image: ecs.ContainerImage.fromRegistry('foo/bar'), memoryLimitMiB: 256, }); @@ -171,7 +171,7 @@ test('Running an EC2 Task with bridge network', () => { taskDefinition, containerOverrides: [ { - containerName: 'TheContainer', + containerDefinition, environment: [ {name: 'SOME_KEY', value: sfn.JsonPath.stringAt('$.SomeKey')}, ], @@ -187,9 +187,9 @@ test('Running an EC2 Task with bridge network', () => { expect(stack.resolve(runTask.toStateJson())).toEqual({ End: true, Parameters: { - Cluster: {'Fn::GetAtt': ['ClusterEB0386A7', 'Arn']}, + Cluster: { 'Fn::GetAtt': ['ClusterEB0386A7', 'Arn'] }, LaunchType: 'EC2', - TaskDefinition: {Ref: 'TD49C78F36'}, + TaskDefinition: { Ref: 'TD49C78F36' }, Overrides: { ContainerOverrides: [ { @@ -225,7 +225,7 @@ test('Running an EC2 Task with bridge network', () => { { Action: 'ecs:RunTask', Effect: 'Allow', - Resource: {Ref: 'TD49C78F36'}, + Resource: { Ref: 'TD49C78F36' }, }, { Action: ['ecs:StopTask', 'ecs:DescribeTasks'], @@ -235,20 +235,25 @@ test('Running an EC2 Task with bridge network', () => { { Action: 'iam:PassRole', Effect: 'Allow', - Resource: [{'Fn::GetAtt': ['TDTaskRoleC497AFFC', 'Arn']}], + Resource: [{ 'Fn::GetAtt': ['TDTaskRoleC497AFFC', 'Arn'] }], }, { Action: ['events:PutTargets', 'events:PutRule', 'events:DescribeRule'], Effect: 'Allow', - Resource: {'Fn::Join': ['', [ - 'arn:', - {Ref: 'AWS::Partition'}, - ':events:', - {Ref: 'AWS::Region'}, - ':', - {Ref: 'AWS::AccountId'}, - ':rule/StepFunctionsGetEventsForECSTaskRule', - ]]}, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':events:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':rule/StepFunctionsGetEventsForECSTaskRule', + ], + ], + }, }, ], }, @@ -268,11 +273,7 @@ test('Running an EC2 Task with placement strategies', () => { integrationPattern: sfn.ServiceIntegrationPattern.SYNC, cluster, taskDefinition, - placementStrategies: [ - ecs.PlacementStrategy.spreadAcrossInstances(), - ecs.PlacementStrategy.packedByCpu(), - ecs.PlacementStrategy.randomly(), - ], + placementStrategies: [ecs.PlacementStrategy.spreadAcrossInstances(), ecs.PlacementStrategy.packedByCpu(), ecs.PlacementStrategy.randomly()], placementConstraints: [ecs.PlacementConstraint.memberOf('blieptuut')], }); @@ -287,17 +288,11 @@ test('Running an EC2 Task with placement strategies', () => { expect(stack.resolve(runTask.toStateJson())).toEqual({ End: true, Parameters: { - Cluster: {'Fn::GetAtt': ['ClusterEB0386A7', 'Arn']}, + Cluster: { 'Fn::GetAtt': ['ClusterEB0386A7', 'Arn'] }, LaunchType: 'EC2', - TaskDefinition: {Ref: 'TD49C78F36'}, - PlacementConstraints: [ - { Type: 'memberOf', Expression: 'blieptuut' }, - ], - PlacementStrategy: [ - { Field: 'instanceId', Type: 'spread' }, - { Field: 'cpu', Type: 'binpack' }, - { Type: 'random' }, - ], + TaskDefinition: { Ref: 'TD49C78F36' }, + PlacementConstraints: [{ Type: 'memberOf', Expression: 'blieptuut' }], + PlacementStrategy: [{ Field: 'instanceId', Type: 'spread' }, { Field: 'cpu', Type: 'binpack' }, { Type: 'random' }], }, Resource: { 'Fn::Join': [ @@ -319,7 +314,7 @@ test('Running an EC2 Task with overridden number values', () => { const taskDefinition = new ecs.TaskDefinition(stack, 'TD', { compatibility: ecs.Compatibility.EC2, }); - taskDefinition.addContainer('TheContainer', { + const containerDefinition = taskDefinition.addContainer('TheContainer', { image: ecs.ContainerImage.fromRegistry('foo/bar'), memoryLimitMiB: 256, }); @@ -330,7 +325,7 @@ test('Running an EC2 Task with overridden number values', () => { taskDefinition, containerOverrides: [ { - containerName: 'TheContainer', + containerDefinition, command: sfn.JsonPath.listAt('$.TheCommand'), cpu: 5, memoryLimit: sfn.JsonPath.numberAt('$.MemoryLimit'), @@ -345,9 +340,9 @@ test('Running an EC2 Task with overridden number values', () => { expect(stack.resolve(runTask.toStateJson())).toEqual({ End: true, Parameters: { - Cluster: {'Fn::GetAtt': ['ClusterEB0386A7', 'Arn']}, + Cluster: { 'Fn::GetAtt': ['ClusterEB0386A7', 'Arn'] }, LaunchType: 'EC2', - TaskDefinition: {Ref: 'TD49C78F36'}, + TaskDefinition: { Ref: 'TD49C78F36' }, Overrides: { ContainerOverrides: [ { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-run-task.expected.json b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-run-task.expected.json new file mode 100644 index 0000000000000..634506837f8d5 --- /dev/null +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-run-task.expected.json @@ -0,0 +1,719 @@ +{ + "Resources": { + "Ec2ClusterEE43E89D": { + "Type": "AWS::ECS::Cluster" + }, + "Ec2ClusterDefaultAutoScalingGroupInstanceSecurityGroup149B0A9E": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-sfn-tasks-ecs-ec2-integ/Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "aws-sfn-tasks-ecs-ec2-integ/Ec2Cluster/DefaultAutoScalingGroup" + } + ], + "VpcId": "vpc-60900905" + } + }, + "Ec2ClusterDefaultAutoScalingGroupInstanceRole73D80898": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "ec2.", + { + "Ref": "AWS::URLSuffix" + } + ] + ] + } + } + } + ], + "Version": "2012-10-17" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-sfn-tasks-ecs-ec2-integ/Ec2Cluster/DefaultAutoScalingGroup" + } + ] + } + }, + "Ec2ClusterDefaultAutoScalingGroupInstanceRoleDefaultPolicy6D2DC2FD": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ecs:CreateCluster", + "ecs:DeregisterContainerInstance", + "ecs:DiscoverPollEndpoint", + "ecs:Poll", + "ecs:RegisterContainerInstance", + "ecs:StartTelemetrySession", + "ecs:Submit*", + "ecr:GetAuthorizationToken", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "Ec2ClusterDefaultAutoScalingGroupInstanceRoleDefaultPolicy6D2DC2FD", + "Roles": [ + { + "Ref": "Ec2ClusterDefaultAutoScalingGroupInstanceRole73D80898" + } + ] + } + }, + "Ec2ClusterDefaultAutoScalingGroupInstanceProfileDB232471": { + "Type": "AWS::IAM::InstanceProfile", + "Properties": { + "Roles": [ + { + "Ref": "Ec2ClusterDefaultAutoScalingGroupInstanceRole73D80898" + } + ] + } + }, + "Ec2ClusterDefaultAutoScalingGroupLaunchConfig7B2FED3A": { + "Type": "AWS::AutoScaling::LaunchConfiguration", + "Properties": { + "ImageId": { + "Ref": "SsmParameterValueawsserviceecsoptimizedamiamazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" + }, + "InstanceType": "t2.micro", + "IamInstanceProfile": { + "Ref": "Ec2ClusterDefaultAutoScalingGroupInstanceProfileDB232471" + }, + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "Ec2ClusterDefaultAutoScalingGroupInstanceSecurityGroup149B0A9E", + "GroupId" + ] + } + ], + "UserData": { + "Fn::Base64": { + "Fn::Join": [ + "", + [ + "#!/bin/bash\necho ECS_CLUSTER=", + { + "Ref": "Ec2ClusterEE43E89D" + }, + " >> /etc/ecs/ecs.config\nsudo iptables --insert FORWARD 1 --in-interface docker+ --destination 169.254.169.254/32 --jump DROP\nsudo service iptables save\necho ECS_AWSVPC_BLOCK_IMDS=true >> /etc/ecs/ecs.config" + ] + ] + } + } + }, + "DependsOn": [ + "Ec2ClusterDefaultAutoScalingGroupInstanceRoleDefaultPolicy6D2DC2FD", + "Ec2ClusterDefaultAutoScalingGroupInstanceRole73D80898" + ] + }, + "Ec2ClusterDefaultAutoScalingGroupASGC5A6D4C0": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": "1", + "MinSize": "1", + "LaunchConfigurationName": { + "Ref": "Ec2ClusterDefaultAutoScalingGroupLaunchConfig7B2FED3A" + }, + "Tags": [ + { + "Key": "Name", + "PropagateAtLaunch": true, + "Value": "aws-sfn-tasks-ecs-ec2-integ/Ec2Cluster/DefaultAutoScalingGroup" + } + ], + "VPCZoneIdentifier": [ + "subnet-e19455ca", + "subnet-e0c24797", + "subnet-ccd77395" + ] + }, + "UpdatePolicy": { + "AutoScalingReplacingUpdate": { + "WillReplace": true + }, + "AutoScalingScheduledAction": { + "IgnoreUnmodifiedGroupSizeProperties": true + } + } + }, + "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRole23116FA3": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "aws-sfn-tasks-ecs-ec2-integ/Ec2Cluster/DefaultAutoScalingGroup" + } + ] + } + }, + "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRoleDefaultPolicy638C9E33": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ec2:DescribeInstances", + "ec2:DescribeInstanceAttribute", + "ec2:DescribeInstanceStatus", + "ec2:DescribeHosts" + ], + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "autoscaling:CompleteLifecycleAction", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":autoscaling:test-region:12345678:autoScalingGroup:*:autoScalingGroupName/", + { + "Ref": "Ec2ClusterDefaultAutoScalingGroupASGC5A6D4C0" + } + ] + ] + } + }, + { + "Action": [ + "ecs:DescribeContainerInstances", + "ecs:DescribeTasks" + ], + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "ecs:ListContainerInstances", + "ecs:SubmitContainerStateChange", + "ecs:SubmitTaskStateChange" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Ec2ClusterEE43E89D", + "Arn" + ] + } + }, + { + "Action": [ + "ecs:UpdateContainerInstancesState", + "ecs:ListTasks" + ], + "Condition": { + "ArnEquals": { + "ecs:cluster": { + "Fn::GetAtt": [ + "Ec2ClusterEE43E89D", + "Arn" + ] + } + } + }, + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRoleDefaultPolicy638C9E33", + "Roles": [ + { + "Ref": "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRole23116FA3" + } + ] + } + }, + "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionE0DEFB31": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "import boto3, json, os, time\n\necs = boto3.client('ecs')\nautoscaling = boto3.client('autoscaling')\n\n\ndef lambda_handler(event, context):\n print(json.dumps(event))\n cluster = os.environ['CLUSTER']\n snsTopicArn = event['Records'][0]['Sns']['TopicArn']\n lifecycle_event = json.loads(event['Records'][0]['Sns']['Message'])\n instance_id = lifecycle_event.get('EC2InstanceId')\n if not instance_id:\n print('Got event without EC2InstanceId: %s', json.dumps(event))\n return\n\n instance_arn = container_instance_arn(cluster, instance_id)\n print('Instance %s has container instance ARN %s' % (lifecycle_event['EC2InstanceId'], instance_arn))\n\n if not instance_arn:\n return\n\n while has_tasks(cluster, instance_arn):\n time.sleep(10)\n\n try:\n print('Terminating instance %s' % instance_id)\n autoscaling.complete_lifecycle_action(\n LifecycleActionResult='CONTINUE',\n **pick(lifecycle_event, 'LifecycleHookName', 'LifecycleActionToken', 'AutoScalingGroupName'))\n except Exception as e:\n # Lifecycle action may have already completed.\n print(str(e))\n\n\ndef container_instance_arn(cluster, instance_id):\n \"\"\"Turn an instance ID into a container instance ARN.\"\"\"\n arns = ecs.list_container_instances(cluster=cluster, filter='ec2InstanceId==' + instance_id)['containerInstanceArns']\n if not arns:\n return None\n return arns[0]\n\n\ndef has_tasks(cluster, instance_arn):\n \"\"\"Return True if the instance is running tasks for the given cluster.\"\"\"\n instances = ecs.describe_container_instances(cluster=cluster, containerInstances=[instance_arn])['containerInstances']\n if not instances:\n return False\n instance = instances[0]\n\n if instance['status'] == 'ACTIVE':\n # Start draining, then try again later\n set_container_instance_to_draining(cluster, instance_arn)\n return True\n\n tasks = instance['runningTasksCount'] + instance['pendingTasksCount']\n print('Instance %s has %s tasks' % (instance_arn, tasks))\n\n return tasks > 0\n\n\ndef set_container_instance_to_draining(cluster, instance_arn):\n ecs.update_container_instances_state(\n cluster=cluster,\n containerInstances=[instance_arn], status='DRAINING')\n\n\ndef pick(dct, *keys):\n \"\"\"Pick a subset of a dict.\"\"\"\n return {k: v for k, v in dct.items() if k in keys}\n" + }, + "Handler": "index.lambda_handler", + "Role": { + "Fn::GetAtt": [ + "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRole23116FA3", + "Arn" + ] + }, + "Runtime": "python3.6", + "Environment": { + "Variables": { + "CLUSTER": { + "Ref": "Ec2ClusterEE43E89D" + } + } + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-sfn-tasks-ecs-ec2-integ/Ec2Cluster/DefaultAutoScalingGroup" + } + ], + "Timeout": 310 + }, + "DependsOn": [ + "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRoleDefaultPolicy638C9E33", + "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRole23116FA3" + ] + }, + "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionAllowInvokeawssfntasksecsec2integEc2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookTopicEE9E39A29ACCEEA3": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionE0DEFB31", + "Arn" + ] + }, + "Principal": "sns.amazonaws.com", + "SourceArn": { + "Ref": "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookTopicF7263B30" + } + } + }, + "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionTopic4795E0F6": { + "Type": "AWS::SNS::Subscription", + "Properties": { + "Protocol": "lambda", + "TopicArn": { + "Ref": "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookTopicF7263B30" + }, + "Endpoint": { + "Fn::GetAtt": [ + "Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionE0DEFB31", + "Arn" + ] + } + } + }, + "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRole71045ED7": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "autoscaling.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-sfn-tasks-ecs-ec2-integ/Ec2Cluster/DefaultAutoScalingGroup" + } + ] + } + }, + "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRoleDefaultPolicyE499974B": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "sns:Publish", + "Effect": "Allow", + "Resource": { + "Ref": "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookTopicF7263B30" + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRoleDefaultPolicyE499974B", + "Roles": [ + { + "Ref": "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRole71045ED7" + } + ] + } + }, + "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookTopicF7263B30": { + "Type": "AWS::SNS::Topic", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-sfn-tasks-ecs-ec2-integ/Ec2Cluster/DefaultAutoScalingGroup" + } + ] + } + }, + "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHook5CB1467E": { + "Type": "AWS::AutoScaling::LifecycleHook", + "Properties": { + "AutoScalingGroupName": { + "Ref": "Ec2ClusterDefaultAutoScalingGroupASGC5A6D4C0" + }, + "LifecycleTransition": "autoscaling:EC2_INSTANCE_TERMINATING", + "DefaultResult": "CONTINUE", + "HeartbeatTimeout": 300, + "NotificationTargetARN": { + "Ref": "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookTopicF7263B30" + }, + "RoleARN": { + "Fn::GetAtt": [ + "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRole71045ED7", + "Arn" + ] + } + }, + "DependsOn": [ + "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRoleDefaultPolicyE499974B", + "Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRole71045ED7" + ] + }, + "TaskDefTaskRole1EDB4A67": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "TaskDef54694570": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": { + "Fn::Join": [ + "", + [ + "12345678.dkr.ecr.test-region.", + { + "Ref": "AWS::URLSuffix" + }, + "/aws-cdk/assets:1f37178655533422f6654c973b99eadec99a723c7181c912e4fb0976187c687c" + ] + ] + }, + "LogConfiguration": { + "LogDriver": "awslogs", + "Options": { + "awslogs-group": { + "Ref": "TaskDefTheContainerLogGroupD94C8EF5" + }, + "awslogs-stream-prefix": "EventDemo", + "awslogs-region": "test-region" + } + }, + "Memory": 256, + "Name": "TheContainer" + } + ], + "ExecutionRoleArn": { + "Fn::GetAtt": [ + "TaskDefExecutionRoleB4775C97", + "Arn" + ] + }, + "Family": "awssfntasksecsec2integTaskDefFAFE2BE7", + "NetworkMode": "bridge", + "RequiresCompatibilities": [ + "EC2" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "TaskDefTaskRole1EDB4A67", + "Arn" + ] + } + } + }, + "TaskDefTheContainerLogGroupD94C8EF5": { + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "TaskDefExecutionRoleB4775C97": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "TaskDefExecutionRoleDefaultPolicy0DBB737A": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ecr:test-region:12345678:repository/aws-cdk/assets" + ] + ] + } + }, + { + "Action": "ecr:GetAuthorizationToken", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TaskDefTheContainerLogGroupD94C8EF5", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "TaskDefExecutionRoleDefaultPolicy0DBB737A", + "Roles": [ + { + "Ref": "TaskDefExecutionRoleB4775C97" + } + ] + } + }, + "StateMachineRoleB840431D": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.test-region.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "StateMachineRoleDefaultPolicyDF1E6607": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "ecs:RunTask", + "Effect": "Allow", + "Resource": { + "Ref": "TaskDef54694570" + } + }, + { + "Action": [ + "ecs:StopTask", + "ecs:DescribeTasks" + ], + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "TaskDefTaskRole1EDB4A67", + "Arn" + ] + }, + { + "Fn::GetAtt": [ + "TaskDefExecutionRoleB4775C97", + "Arn" + ] + } + ] + }, + { + "Action": [ + "events:PutTargets", + "events:PutRule", + "events:DescribeRule" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":events:test-region:12345678:rule/StepFunctionsGetEventsForECSTaskRule" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "StateMachineRoleDefaultPolicyDF1E6607", + "Roles": [ + { + "Ref": "StateMachineRoleB840431D" + } + ] + } + }, + "StateMachine2E01A3A5": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRoleB840431D", + "Arn" + ] + }, + "DefinitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"Start\",\"States\":{\"Start\":{\"Type\":\"Pass\",\"Result\":{\"SomeKey\":\"SomeValue\"},\"Next\":\"Run\"},\"Run\":{\"End\":true,\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::ecs:runTask.sync\",\"Parameters\":{\"Cluster\":\"", + { + "Fn::GetAtt": [ + "Ec2ClusterEE43E89D", + "Arn" + ] + }, + "\",\"TaskDefinition\":\"", + { + "Ref": "TaskDef54694570" + }, + "\",\"Overrides\":{\"ContainerOverrides\":[{\"Name\":\"TheContainer\",\"Environment\":[{\"Name\":\"SOME_KEY\",\"Value.$\":\"$.SomeKey\"}]}]},\"LaunchType\":\"EC2\"}}}}" + ] + ] + } + }, + "DependsOn": [ + "StateMachineRoleDefaultPolicyDF1E6607", + "StateMachineRoleB840431D" + ] + } + }, + "Parameters": { + "SsmParameterValueawsserviceecsoptimizedamiamazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id" + } + }, + "Outputs": { + "stateMachineArn": { + "Value": { + "Ref": "StateMachine2E01A3A5" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-run-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-run-task.ts new file mode 100644 index 0000000000000..7713e04363465 --- /dev/null +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-run-task.ts @@ -0,0 +1,75 @@ +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as ecs from '@aws-cdk/aws-ecs'; +import * as sfn from '@aws-cdk/aws-stepfunctions'; +import * as cdk from '@aws-cdk/core'; +import * as path from 'path'; +import * as tasks from '../../lib'; + +/* + * * Creates a state machine with a task state to run a job with ECS on EC2 + * + * Stack verification steps: + * The generated State Machine can be executed from the CLI (or Step Functions console) + * and runs with an execution status of `Succeeded`. + * + * -- aws stepfunctions start-execution --state-machine-arn provides execution arn + * -- aws stepfunctions describe-execution --execution-arn returns a status of `Succeeded` + */ +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-sfn-tasks-ecs-ec2-integ', { + env: { + account: process.env.CDK_INTEG_ACCOUNT || process.env.CDK_DEFAULT_ACCOUNT, + region: process.env.CDK_INTEG_REGION || process.env.CDK_DEFAULT_REGION, + }, +}); + +const vpc = ec2.Vpc.fromLookup(stack, 'Vpc', { + isDefault: true, +}); + +const cluster = new ecs.Cluster(stack, 'Ec2Cluster', { vpc }); +cluster.addCapacity('DefaultAutoScalingGroup', { + instanceType: new ec2.InstanceType('t2.micro'), + vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC }, +}); + +// Build task definition +const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); +const containerDefinition = taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromAsset(path.resolve(__dirname, 'eventhandler-image')), + memoryLimitMiB: 256, + logging: new ecs.AwsLogDriver({ streamPrefix: 'EventDemo' }), +}); + +// Build state machine +const definition = new sfn.Pass(stack, 'Start', { + result: sfn.Result.fromObject({ SomeKey: 'SomeValue' }), +}).next( + new tasks.EcsRunTask(stack, 'Run', { + integrationPattern: sfn.IntegrationPattern.RUN_JOB, + cluster, + taskDefinition, + containerOverrides: [ + { + containerDefinition, + environment: [ + { + name: 'SOME_KEY', + value: sfn.JsonPath.stringAt('$.SomeKey'), + }, + ], + }, + ], + launchTarget: new tasks.EcsEc2LaunchTarget(), + }), +); + +const sm = new sfn.StateMachine(stack, 'StateMachine', { + definition, +}); + +new cdk.CfnOutput(stack, 'stateMachineArn', { + value: sm.stateMachineArn, +}); + +app.synth(); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-task.ts index dc0a42c1d7bd8..9da3a9e76b72f 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.ec2-task.ts @@ -25,7 +25,7 @@ cluster.addCapacity('DefaultAutoScalingGroup', { // Build task definition const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); -taskDefinition.addContainer('TheContainer', { +const containerDefinition = taskDefinition.addContainer('TheContainer', { image: ecs.ContainerImage.fromAsset(path.resolve(__dirname, 'eventhandler-image')), memoryLimitMiB: 256, logging: new ecs.AwsLogDriver({ streamPrefix: 'EventDemo' }), @@ -34,22 +34,26 @@ taskDefinition.addContainer('TheContainer', { // Build state machine const definition = new sfn.Pass(stack, 'Start', { result: sfn.Result.fromObject({ SomeKey: 'SomeValue' }), -}).next(new sfn.Task(stack, 'Run', { task: new tasks.RunEcsEc2Task({ - integrationPattern: sfn.ServiceIntegrationPattern.SYNC, - cluster, - taskDefinition, - containerOverrides: [ - { - containerName: 'TheContainer', - environment: [ +}).next( + new sfn.Task(stack, 'Run', { + task: new tasks.RunEcsEc2Task({ + integrationPattern: sfn.ServiceIntegrationPattern.SYNC, + cluster, + taskDefinition, + containerOverrides: [ { - name: 'SOME_KEY', - value: sfn.JsonPath.stringAt('$.SomeKey'), + containerDefinition, + environment: [ + { + name: 'SOME_KEY', + value: sfn.JsonPath.stringAt('$.SomeKey'), + }, + ], }, ], - }, - ], -})})); + }), + }), +); new sfn.StateMachine(stack, 'StateMachine', { definition, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-run-task.expected.json b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-run-task.expected.json new file mode 100644 index 0000000000000..3d131dd24f6cf --- /dev/null +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-run-task.expected.json @@ -0,0 +1,305 @@ +{ + "Resources": { + "FargateCluster7CCD5F93": { + "Type": "AWS::ECS::Cluster" + }, + "TaskDefTaskRole1EDB4A67": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "TaskDef54694570": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": { + "Fn::Join": [ + "", + [ + "12345678.dkr.ecr.test-region.", + { + "Ref": "AWS::URLSuffix" + }, + "/aws-cdk/assets:1f37178655533422f6654c973b99eadec99a723c7181c912e4fb0976187c687c" + ] + ] + }, + "LogConfiguration": { + "LogDriver": "awslogs", + "Options": { + "awslogs-group": { + "Ref": "TaskDefTheContainerLogGroupD94C8EF5" + }, + "awslogs-stream-prefix": "EventDemo", + "awslogs-region": "test-region" + } + }, + "Memory": 256, + "Name": "TheContainer" + } + ], + "Cpu": "256", + "ExecutionRoleArn": { + "Fn::GetAtt": [ + "TaskDefExecutionRoleB4775C97", + "Arn" + ] + }, + "Family": "awssfntasksecsfargateintegTaskDefD0F4AD10", + "Memory": "512", + "NetworkMode": "awsvpc", + "RequiresCompatibilities": [ + "FARGATE" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "TaskDefTaskRole1EDB4A67", + "Arn" + ] + } + } + }, + "TaskDefTheContainerLogGroupD94C8EF5": { + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "TaskDefExecutionRoleB4775C97": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "TaskDefExecutionRoleDefaultPolicy0DBB737A": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ecr:test-region:12345678:repository/aws-cdk/assets" + ] + ] + } + }, + { + "Action": "ecr:GetAuthorizationToken", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TaskDefTheContainerLogGroupD94C8EF5", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "TaskDefExecutionRoleDefaultPolicy0DBB737A", + "Roles": [ + { + "Ref": "TaskDefExecutionRoleB4775C97" + } + ] + } + }, + "FargateTaskSecurityGroup0BBB27CB": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-sfn-tasks-ecs-fargate-integ/FargateTask/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": "vpc-60900905" + } + }, + "StateMachineRoleB840431D": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.test-region.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "StateMachineRoleDefaultPolicyDF1E6607": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "ecs:RunTask", + "Effect": "Allow", + "Resource": { + "Ref": "TaskDef54694570" + } + }, + { + "Action": [ + "ecs:StopTask", + "ecs:DescribeTasks" + ], + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "TaskDefTaskRole1EDB4A67", + "Arn" + ] + }, + { + "Fn::GetAtt": [ + "TaskDefExecutionRoleB4775C97", + "Arn" + ] + } + ] + }, + { + "Action": [ + "events:PutTargets", + "events:PutRule", + "events:DescribeRule" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":events:test-region:12345678:rule/StepFunctionsGetEventsForECSTaskRule" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "StateMachineRoleDefaultPolicyDF1E6607", + "Roles": [ + { + "Ref": "StateMachineRoleB840431D" + } + ] + } + }, + "StateMachine2E01A3A5": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRoleB840431D", + "Arn" + ] + }, + "DefinitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"Start\",\"States\":{\"Start\":{\"Type\":\"Pass\",\"Result\":{\"SomeKey\":\"SomeValue\"},\"Next\":\"FargateTask\"},\"FargateTask\":{\"End\":true,\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::ecs:runTask.sync\",\"Parameters\":{\"Cluster\":\"", + { + "Fn::GetAtt": [ + "FargateCluster7CCD5F93", + "Arn" + ] + }, + "\",\"TaskDefinition\":\"", + { + "Ref": "TaskDef54694570" + }, + "\",\"NetworkConfiguration\":{\"AwsvpcConfiguration\":{\"AssignPublicIp\":\"ENABLED\",\"Subnets\":[\"subnet-e19455ca\",\"subnet-e0c24797\",\"subnet-ccd77395\"],\"SecurityGroups\":[\"", + { + "Fn::GetAtt": [ + "FargateTaskSecurityGroup0BBB27CB", + "GroupId" + ] + }, + "\"]}},\"Overrides\":{\"ContainerOverrides\":[{\"Name\":\"TheContainer\",\"Environment\":[{\"Name\":\"SOME_KEY\",\"Value.$\":\"$.SomeKey\"}]}]},\"LaunchType\":\"FARGATE\",\"PlatformVersion\":\"1.4.0\"}}}}" + ] + ] + } + }, + "DependsOn": [ + "StateMachineRoleDefaultPolicyDF1E6607", + "StateMachineRoleB840431D" + ] + } + }, + "Outputs": { + "stateMachineArn": { + "Value": { + "Ref": "StateMachine2E01A3A5" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-run-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-run-task.ts new file mode 100644 index 0000000000000..c7cdab910cdf5 --- /dev/null +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-run-task.ts @@ -0,0 +1,77 @@ +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as ecs from '@aws-cdk/aws-ecs'; +import * as sfn from '@aws-cdk/aws-stepfunctions'; +import * as cdk from '@aws-cdk/core'; +import * as path from 'path'; +import * as tasks from '../../lib'; + +/* + * Creates a state machine with a task state to run a job with ECS on Fargate + * + * Stack verification steps: + * The generated State Machine can be executed from the CLI (or Step Functions console) + * and runs with an execution status of `Succeeded`. + * + * -- aws stepfunctions start-execution --state-machine-arn provides execution arn + * -- aws stepfunctions describe-execution --execution-arn returns a status of `Succeeded` + */ +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-sfn-tasks-ecs-fargate-integ', { + env: { + account: process.env.CDK_INTEG_ACCOUNT || process.env.CDK_DEFAULT_ACCOUNT, + region: process.env.CDK_INTEG_REGION || process.env.CDK_DEFAULT_REGION, + }, +}); + +const vpc = ec2.Vpc.fromLookup(stack, 'Vpc', { + isDefault: true, +}); + +const cluster = new ecs.Cluster(stack, 'FargateCluster', { vpc }); + +// Build task definition +const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef', { + memoryLimitMiB: 512, + cpu: 256, +}); +const containerDefinition = taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromAsset(path.resolve(__dirname, 'eventhandler-image')), + memoryLimitMiB: 256, + logging: new ecs.AwsLogDriver({ streamPrefix: 'EventDemo' }), +}); + +// Build state machine +const definition = new sfn.Pass(stack, 'Start', { + result: sfn.Result.fromObject({ SomeKey: 'SomeValue' }), +}).next( + new tasks.EcsRunTask(stack, 'FargateTask', { + integrationPattern: sfn.IntegrationPattern.RUN_JOB, + cluster, + taskDefinition, + assignPublicIp: true, + containerOverrides: [ + { + containerDefinition, + environment: [ + { + name: 'SOME_KEY', + value: sfn.JsonPath.stringAt('$.SomeKey'), + }, + ], + }, + ], + launchTarget: new tasks.EcsFargateLaunchTarget({ + platformVersion: ecs.FargatePlatformVersion.VERSION1_4, + }), + }), +); + +const sm = new sfn.StateMachine(stack, 'StateMachine', { + definition, +}); + +new cdk.CfnOutput(stack, 'stateMachineArn', { + value: sm.stateMachineArn, +}); + +app.synth(); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-task.ts index 4f981dfaa45b8..dbc470d8d283e 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/integ.fargate-task.ts @@ -24,7 +24,7 @@ const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef', { memoryLimitMiB: 512, cpu: 256, }); -taskDefinition.addContainer('TheContainer', { +const containerDefinition = taskDefinition.addContainer('TheContainer', { image: ecs.ContainerImage.fromAsset(path.resolve(__dirname, 'eventhandler-image')), memoryLimitMiB: 256, logging: new ecs.AwsLogDriver({ streamPrefix: 'EventDemo' }), @@ -33,22 +33,27 @@ taskDefinition.addContainer('TheContainer', { // Build state machine const definition = new sfn.Pass(stack, 'Start', { result: sfn.Result.fromObject({ SomeKey: 'SomeValue' }), -}).next(new sfn.Task(stack, 'FargateTask', { task: new tasks.RunEcsFargateTask({ - integrationPattern: sfn.ServiceIntegrationPattern.SYNC, - cluster, taskDefinition, - assignPublicIp: true, - containerOverrides: [ - { - containerName: 'TheContainer', - environment: [ +}).next( + new sfn.Task(stack, 'FargateTask', { + task: new tasks.RunEcsFargateTask({ + integrationPattern: sfn.ServiceIntegrationPattern.SYNC, + cluster, + taskDefinition, + assignPublicIp: true, + containerOverrides: [ { - name: 'SOME_KEY', - value: sfn.JsonPath.stringAt('$.SomeKey'), + containerDefinition, + environment: [ + { + name: 'SOME_KEY', + value: sfn.JsonPath.stringAt('$.SomeKey'), + }, + ], }, ], - }, - ], -})})); + }), + }), +); new sfn.StateMachine(stack, 'StateMachine', { definition, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/run-tasks.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/run-tasks.test.ts new file mode 100644 index 0000000000000..d124b1ac9c6ee --- /dev/null +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs/run-tasks.test.ts @@ -0,0 +1,377 @@ +import '@aws-cdk/assert/jest'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as ecs from '@aws-cdk/aws-ecs'; +import * as sfn from '@aws-cdk/aws-stepfunctions'; +import { Stack } from '@aws-cdk/core'; +import * as tasks from '../../lib'; + +let stack: Stack; +let vpc: ec2.Vpc; +let cluster: ecs.Cluster; + +// tslint:disable: object-literal-key-quotes + +beforeEach(() => { + // GIVEN + stack = new Stack(); + vpc = new ec2.Vpc(stack, 'Vpc'); + cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); + cluster.addCapacity('Capacity', { + instanceType: new ec2.InstanceType('t3.medium'), + }); +}); + +test('Cannot create a Fargate task with a fargate-incompatible task definition', () => { + const taskDefinition = new ecs.TaskDefinition(stack, 'TD', { + memoryMiB: '512', + cpu: '256', + compatibility: ecs.Compatibility.EC2, + }); + taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromRegistry('foo/bar'), + memoryLimitMiB: 256, + }); + + expect(() => + new tasks.EcsRunTask(stack, 'task', { cluster, taskDefinition, launchTarget: new tasks.EcsFargateLaunchTarget() }).toStateJson(), + ).toThrowError(/Supplied TaskDefinition is not compatible with Fargate/); +}); + +test('Cannot create a Fargate task without a default container', () => { + const taskDefinition = new ecs.TaskDefinition(stack, 'TD', { + memoryMiB: '512', + cpu: '256', + compatibility: ecs.Compatibility.FARGATE, + }); + expect(() => + new tasks.EcsRunTask(stack, 'task', { cluster, taskDefinition, launchTarget: new tasks.EcsFargateLaunchTarget() }).toStateJson(), + ).toThrowError(/must have at least one essential container/); +}); + +test('Running a Fargate Task', () => { + const taskDefinition = new ecs.TaskDefinition(stack, 'TD', { + memoryMiB: '512', + cpu: '256', + compatibility: ecs.Compatibility.FARGATE, + }); + const containerDefinition = taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromRegistry('foo/bar'), + memoryLimitMiB: 256, + }); + + // WHEN + const runTask = new tasks.EcsRunTask(stack, 'RunFargate', { + integrationPattern: sfn.IntegrationPattern.RUN_JOB, + cluster, + taskDefinition, + containerOverrides: [ + { + containerDefinition, + environment: [{ name: 'SOME_KEY', value: sfn.JsonPath.stringAt('$.SomeKey') }], + }, + ], + launchTarget: new tasks.EcsFargateLaunchTarget({ + platformVersion: ecs.FargatePlatformVersion.VERSION1_4, + }), + }); + + new sfn.StateMachine(stack, 'SM', { + definition: runTask, + }); + + // THEN + expect(stack.resolve(runTask.toStateJson())).toEqual({ + End: true, + Parameters: { + Cluster: { 'Fn::GetAtt': ['ClusterEB0386A7', 'Arn'] }, + LaunchType: 'FARGATE', + NetworkConfiguration: { + AwsvpcConfiguration: { + SecurityGroups: [{ 'Fn::GetAtt': ['RunFargateSecurityGroup709740F2', 'GroupId'] }], + Subnets: [{ Ref: 'VpcPrivateSubnet1Subnet536B997A' }, { Ref: 'VpcPrivateSubnet2Subnet3788AAA1' }], + }, + }, + PlatformVersion: '1.4.0', + TaskDefinition: { Ref: 'TD49C78F36' }, + Overrides: { + ContainerOverrides: [ + { + Environment: [ + { + Name: 'SOME_KEY', + 'Value.$': '$.SomeKey', + }, + ], + Name: 'TheContainer', + }, + ], + }, + }, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:::ecs:runTask.sync', + ], + ], + }, + Type: 'Task', + }); + + expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'ecs:RunTask', + Effect: 'Allow', + Resource: { Ref: 'TD49C78F36' }, + }, + { + Action: ['ecs:StopTask', 'ecs:DescribeTasks'], + Effect: 'Allow', + Resource: '*', + }, + { + Action: 'iam:PassRole', + Effect: 'Allow', + Resource: { 'Fn::GetAtt': ['TDTaskRoleC497AFFC', 'Arn'] }, + }, + { + Action: ['events:PutTargets', 'events:PutRule', 'events:DescribeRule'], + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':events:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':rule/StepFunctionsGetEventsForECSTaskRule', + ], + ], + }, + }, + ], + }, + }); +}); + +test('Running an EC2 Task with bridge network', () => { + const taskDefinition = new ecs.TaskDefinition(stack, 'TD', { + compatibility: ecs.Compatibility.EC2, + }); + const containerDefinition = taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromRegistry('foo/bar'), + memoryLimitMiB: 256, + }); + + // WHEN + const runTask = new tasks.EcsRunTask(stack, 'Run', { + integrationPattern: sfn.IntegrationPattern.RUN_JOB, + cluster, + taskDefinition, + containerOverrides: [ + { + containerDefinition, + environment: [{ name: 'SOME_KEY', value: sfn.JsonPath.stringAt('$.SomeKey') }], + }, + ], + launchTarget: new tasks.EcsEc2LaunchTarget(), + }); + + new sfn.StateMachine(stack, 'SM', { + definition: runTask, + }); + + // THEN + expect(stack.resolve(runTask.toStateJson())).toEqual({ + End: true, + Parameters: { + Cluster: { 'Fn::GetAtt': ['ClusterEB0386A7', 'Arn'] }, + LaunchType: 'EC2', + TaskDefinition: { Ref: 'TD49C78F36' }, + Overrides: { + ContainerOverrides: [ + { + Environment: [ + { + Name: 'SOME_KEY', + 'Value.$': '$.SomeKey', + }, + ], + Name: 'TheContainer', + }, + ], + }, + }, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:::ecs:runTask.sync', + ], + ], + }, + Type: 'Task', + }); + + expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'ecs:RunTask', + Effect: 'Allow', + Resource: { Ref: 'TD49C78F36' }, + }, + { + Action: ['ecs:StopTask', 'ecs:DescribeTasks'], + Effect: 'Allow', + Resource: '*', + }, + { + Action: 'iam:PassRole', + Effect: 'Allow', + Resource: { 'Fn::GetAtt': ['TDTaskRoleC497AFFC', 'Arn'] }, + }, + { + Action: ['events:PutTargets', 'events:PutRule', 'events:DescribeRule'], + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':events:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':rule/StepFunctionsGetEventsForECSTaskRule', + ], + ], + }, + }, + ], + }, + }); +}); + +test('Running an EC2 Task with placement strategies', () => { + const taskDefinition = new ecs.TaskDefinition(stack, 'TD', { + compatibility: ecs.Compatibility.EC2, + }); + taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromRegistry('foo/bar'), + memoryLimitMiB: 256, + }); + + // WHEN + const runTask = new tasks.EcsRunTask(stack, 'Run', { + integrationPattern: sfn.IntegrationPattern.RUN_JOB, + cluster, + taskDefinition, + launchTarget: new tasks.EcsEc2LaunchTarget({ + placementStrategies: [ecs.PlacementStrategy.spreadAcrossInstances(), ecs.PlacementStrategy.packedByCpu(), ecs.PlacementStrategy.randomly()], + placementConstraints: [ecs.PlacementConstraint.memberOf('blieptuut')], + }), + }); + + new sfn.StateMachine(stack, 'SM', { + definition: runTask, + }); + + // THEN + expect(stack.resolve(runTask.toStateJson())).toEqual({ + End: true, + Parameters: { + Cluster: { 'Fn::GetAtt': ['ClusterEB0386A7', 'Arn'] }, + LaunchType: 'EC2', + TaskDefinition: { Ref: 'TD49C78F36' }, + PlacementConstraints: [{ Type: 'memberOf', Expression: 'blieptuut' }], + PlacementStrategy: [{ Field: 'instanceId', Type: 'spread' }, { Field: 'cpu', Type: 'binpack' }, { Type: 'random' }], + }, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:::ecs:runTask.sync', + ], + ], + }, + Type: 'Task', + }); +}); + +test('Running an EC2 Task with overridden number values', () => { + const taskDefinition = new ecs.TaskDefinition(stack, 'TD', { + compatibility: ecs.Compatibility.EC2, + }); + const containerDefinition = taskDefinition.addContainer('TheContainer', { + image: ecs.ContainerImage.fromRegistry('foo/bar'), + memoryLimitMiB: 256, + }); + + // WHEN + const runTask = new tasks.EcsRunTask(stack, 'Run', { + integrationPattern: sfn.IntegrationPattern.RUN_JOB, + cluster, + taskDefinition, + containerOverrides: [ + { + containerDefinition, + command: sfn.JsonPath.listAt('$.TheCommand'), + cpu: 5, + memoryLimit: sfn.JsonPath.numberAt('$.MemoryLimit'), + }, + ], + launchTarget: new tasks.EcsEc2LaunchTarget(), + }); + + // THEN + expect(stack.resolve(runTask.toStateJson())).toEqual({ + End: true, + Parameters: { + Cluster: { 'Fn::GetAtt': ['ClusterEB0386A7', 'Arn'] }, + LaunchType: 'EC2', + TaskDefinition: { Ref: 'TD49C78F36' }, + Overrides: { + ContainerOverrides: [ + { + 'Command.$': '$.TheCommand', + Cpu: 5, + 'Memory.$': '$.MemoryLimit', + Name: 'TheContainer', + }, + ], + }, + }, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:::ecs:runTask.sync', + ], + ], + }, + Type: 'Task', + }); +}); From 973fa4212cece01e7eb5cbff37265a02d0577aa0 Mon Sep 17 00:00:00 2001 From: Pahud Hsieh Date: Tue, 30 Jun 2020 15:42:13 +0800 Subject: [PATCH 43/55] chore(eks): support create namespace with helm (#8787) chore(eks): support create namespace with helm - add `createNamespace` property for `eks.HelmChart` - set the `wait` flag correctly for HelmChart custom resource Fixes: https://github.com/aws/aws-cdk/issues/7216 https://github.com/aws/aws-cdk/issues/7209 #8713 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-eks/lib/helm-chart.ts | 14 +- .../lib/kubectl-handler/helm/__init__.py | 7 +- .../test/integ.eks-cluster.expected.json | 781 ++++++++---------- .../@aws-cdk/aws-eks/test/test.cluster.ts | 1 - .../@aws-cdk/aws-eks/test/test.helm-chart.ts | 58 +- 5 files changed, 408 insertions(+), 453 deletions(-) diff --git a/packages/@aws-cdk/aws-eks/lib/helm-chart.ts b/packages/@aws-cdk/aws-eks/lib/helm-chart.ts index 4761e71b0c7a9..cb668784129fe 100644 --- a/packages/@aws-cdk/aws-eks/lib/helm-chart.ts +++ b/packages/@aws-cdk/aws-eks/lib/helm-chart.ts @@ -53,6 +53,12 @@ export interface HelmChartOptions { * @default Duration.minutes(5) */ readonly timeout?: Duration; + + /** + * create namespace if not exist + * @default true + */ + readonly createNamespace?: boolean; } /** @@ -90,6 +96,11 @@ export class HelmChart extends Construct { throw new Error('Helm chart timeout cannot be higher than 15 minutes.'); } + // default not to wait + const wait = props.wait ?? false; + // default to create new namespace + const createNamespace = props.createNamespace ?? true; + new CustomResource(this, 'Resource', { serviceToken: provider.serviceToken, resourceType: HelmChart.RESOURCE_TYPE, @@ -99,11 +110,12 @@ export class HelmChart extends Construct { Release: props.release ?? this.node.uniqueId.slice(-53).toLowerCase(), // Helm has a 53 character limit for the name Chart: props.chart, Version: props.version, - Wait: props.wait ?? false, + Wait: wait || undefined, // props are stringified so we encode “false” as undefined Timeout: timeout ? `${timeout.toString()}s` : undefined, // Helm v3 expects duration instead of integer Values: (props.values ? stack.toJsonString(props.values) : undefined), Namespace: props.namespace ?? 'default', Repository: props.repository, + CreateNamespace: createNamespace || undefined, }, }); } diff --git a/packages/@aws-cdk/aws-eks/lib/kubectl-handler/helm/__init__.py b/packages/@aws-cdk/aws-eks/lib/kubectl-handler/helm/__init__.py index 57ea65a2fa3b7..6e740b1cdaca8 100644 --- a/packages/@aws-cdk/aws-eks/lib/kubectl-handler/helm/__init__.py +++ b/packages/@aws-cdk/aws-eks/lib/kubectl-handler/helm/__init__.py @@ -27,6 +27,7 @@ def helm_handler(event, context): wait = props.get('Wait', False) timeout = props.get('Timeout', None) namespace = props.get('Namespace', None) + create_namespace = props.get('CreateNamespace', None) repository = props.get('Repository', None) values_text = props.get('Values', None) @@ -46,14 +47,14 @@ def helm_handler(event, context): f.write(json.dumps(values, indent=2)) if request_type == 'Create' or request_type == 'Update': - helm('upgrade', release, chart, repository, values_file, namespace, version, wait, timeout) + helm('upgrade', release, chart, repository, values_file, namespace, version, wait, timeout, create_namespace) elif request_type == "Delete": try: helm('uninstall', release, namespace=namespace, timeout=timeout) except Exception as e: logger.info("delete error: %s" % e) -def helm(verb, release, chart = None, repo = None, file = None, namespace = None, version = None, wait = False, timeout = None): +def helm(verb, release, chart = None, repo = None, file = None, namespace = None, version = None, wait = False, timeout = None, create_namespace = None): import subprocess cmnd = ['helm', verb, release] @@ -61,6 +62,8 @@ def helm(verb, release, chart = None, repo = None, file = None, namespace = None cmnd.append(chart) if verb == 'upgrade': cmnd.append('--install') + if create_namespace: + cmnd.append('--create-namespace') if not repo is None: cmnd.extend(['--repo', repo]) if not file is None: diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json index dd43e4cf0204d..0329b152b4263 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json @@ -4,26 +4,24 @@ "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::12345678:root" - ] + "Statement": [{ + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::12345678:root" ] - } + ] } } - ], + }], "Version": "2012-10-17" } } @@ -35,12 +33,10 @@ "EnableDnsHostnames": true, "EnableDnsSupport": true, "InstanceTenancy": "default", - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Vpc" - } - ] + "Tags": [{ + "Key": "Name", + "Value": "aws-cdk-eks-cluster-test/Vpc" + }] } }, "VpcPublicSubnet1Subnet5C2D37C4": { @@ -52,8 +48,7 @@ }, "AvailabilityZone": "test-region-1a", "MapPublicIpOnLaunch": true, - "Tags": [ - { + "Tags": [{ "Key": "aws-cdk:subnet-name", "Value": "Public" }, @@ -78,8 +73,7 @@ "VpcId": { "Ref": "Vpc8378EB38" }, - "Tags": [ - { + "Tags": [{ "Key": "kubernetes.io/role/elb", "Value": "1" }, @@ -120,8 +114,7 @@ "Type": "AWS::EC2::EIP", "Properties": { "Domain": "vpc", - "Tags": [ - { + "Tags": [{ "Key": "kubernetes.io/role/elb", "Value": "1" }, @@ -144,8 +137,7 @@ "SubnetId": { "Ref": "VpcPublicSubnet1Subnet5C2D37C4" }, - "Tags": [ - { + "Tags": [{ "Key": "kubernetes.io/role/elb", "Value": "1" }, @@ -165,8 +157,7 @@ }, "AvailabilityZone": "test-region-1b", "MapPublicIpOnLaunch": true, - "Tags": [ - { + "Tags": [{ "Key": "aws-cdk:subnet-name", "Value": "Public" }, @@ -191,8 +182,7 @@ "VpcId": { "Ref": "Vpc8378EB38" }, - "Tags": [ - { + "Tags": [{ "Key": "kubernetes.io/role/elb", "Value": "1" }, @@ -238,8 +228,7 @@ }, "AvailabilityZone": "test-region-1c", "MapPublicIpOnLaunch": true, - "Tags": [ - { + "Tags": [{ "Key": "aws-cdk:subnet-name", "Value": "Public" }, @@ -264,8 +253,7 @@ "VpcId": { "Ref": "Vpc8378EB38" }, - "Tags": [ - { + "Tags": [{ "Key": "kubernetes.io/role/elb", "Value": "1" }, @@ -311,8 +299,7 @@ }, "AvailabilityZone": "test-region-1a", "MapPublicIpOnLaunch": false, - "Tags": [ - { + "Tags": [{ "Key": "aws-cdk:subnet-name", "Value": "Private" }, @@ -337,8 +324,7 @@ "VpcId": { "Ref": "Vpc8378EB38" }, - "Tags": [ - { + "Tags": [{ "Key": "kubernetes.io/role/internal-elb", "Value": "1" }, @@ -381,8 +367,7 @@ }, "AvailabilityZone": "test-region-1b", "MapPublicIpOnLaunch": false, - "Tags": [ - { + "Tags": [{ "Key": "aws-cdk:subnet-name", "Value": "Private" }, @@ -407,8 +392,7 @@ "VpcId": { "Ref": "Vpc8378EB38" }, - "Tags": [ - { + "Tags": [{ "Key": "kubernetes.io/role/internal-elb", "Value": "1" }, @@ -451,8 +435,7 @@ }, "AvailabilityZone": "test-region-1c", "MapPublicIpOnLaunch": false, - "Tags": [ - { + "Tags": [{ "Key": "aws-cdk:subnet-name", "Value": "Private" }, @@ -477,8 +460,7 @@ "VpcId": { "Ref": "Vpc8378EB38" }, - "Tags": [ - { + "Tags": [{ "Key": "kubernetes.io/role/internal-elb", "Value": "1" }, @@ -515,12 +497,10 @@ "VpcIGWD7BA715C": { "Type": "AWS::EC2::InternetGateway", "Properties": { - "Tags": [ - { - "Key": "Name", - "Value": "aws-cdk-eks-cluster-test/Vpc" - } - ] + "Tags": [{ + "Key": "Name", + "Value": "aws-cdk-eks-cluster-test/Vpc" + }] } }, "VpcVPCGWBF912B6E": { @@ -538,44 +518,38 @@ "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "eks.amazonaws.com" - } + "Statement": [{ + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "eks.amazonaws.com" } - ], + }], "Version": "2012-10-17" }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/AmazonEKSClusterPolicy" - ] + "ManagedPolicyArns": [{ + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/AmazonEKSClusterPolicy" ] - } - ] + ] + }] } }, "ClusterControlPlaneSecurityGroupD274242C": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "EKS Control Plane Security Group", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1" - } - ], + "SecurityGroupEgress": [{ + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + }], "VpcId": { "Ref": "Vpc8378EB38" } @@ -669,13 +643,11 @@ "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Statement": [ - { + "Statement": [{ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "AWS": [ - { + "AWS": [{ "Fn::GetAtt": [ "awscdkawseksClusterResourceProviderNestedStackawscdkawseksClusterResourceProviderNestedStackResource9827C454", "Outputs.awscdkeksclustertestawscdkawseksClusterResourceProviderOnEventHandlerServiceRole5B783C71Arn" @@ -711,8 +683,7 @@ "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { - "Statement": [ - { + "Statement": [{ "Action": "iam:PassRole", "Effect": "Allow", "Resource": { @@ -779,11 +750,9 @@ "Version": "2012-10-17" }, "PolicyName": "ClusterCreationRoleDefaultPolicyE8BDFC7B", - "Roles": [ - { - "Ref": "ClusterCreationRole360249B6" - } - ] + "Roles": [{ + "Ref": "ClusterCreationRole360249B6" + }] } }, "Cluster9EE0221C": { @@ -804,16 +773,13 @@ }, "version": "1.16", "resourcesVpcConfig": { - "securityGroupIds": [ - { - "Fn::GetAtt": [ - "ClusterControlPlaneSecurityGroupD274242C", - "GroupId" - ] - } - ], - "subnetIds": [ - { + "securityGroupIds": [{ + "Fn::GetAtt": [ + "ClusterControlPlaneSecurityGroupD274242C", + "GroupId" + ] + }], + "subnetIds": [{ "Ref": "VpcPublicSubnet1Subnet5C2D37C4" }, { @@ -932,29 +898,26 @@ "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": { - "Fn::Join": [ - "", - [ - "ec2.", - { - "Ref": "AWS::URLSuffix" - } - ] + "Statement": [{ + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "ec2.", + { + "Ref": "AWS::URLSuffix" + } ] - } + ] } } - ], + }], "Version": "2012-10-17" }, - "ManagedPolicyArns": [ - { + "ManagedPolicyArns": [{ "Fn::Join": [ "", [ @@ -1005,8 +968,7 @@ "Arn" ] }, - "Subnets": [ - { + "Subnets": [{ "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { @@ -1031,31 +993,27 @@ "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "eks-fargate-pods.amazonaws.com" - } + "Statement": [{ + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "eks-fargate-pods.amazonaws.com" } - ], + }], "Version": "2012-10-17" }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy" - ] + "ManagedPolicyArns": [{ + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy" ] - } - ] + ] + }] } }, "ClusterfargateprofiledefaultEFC59F14": { @@ -1083,11 +1041,9 @@ "Arn" ] }, - "selectors": [ - { - "namespace": "default" - } - ] + "selectors": [{ + "namespace": "default" + }] } }, "UpdateReplacePolicy": "Delete", @@ -1097,15 +1053,12 @@ "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "aws-cdk-eks-cluster-test/Cluster/Nodes/InstanceSecurityGroup", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1" - } - ], - "Tags": [ - { + "SecurityGroupEgress": [{ + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + }], + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -1194,29 +1147,26 @@ "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": { - "Fn::Join": [ - "", - [ - "ec2.", - { - "Ref": "AWS::URLSuffix" - } - ] + "Statement": [{ + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "ec2.", + { + "Ref": "AWS::URLSuffix" + } ] - } + ] } } - ], + }], "Version": "2012-10-17" }, - "ManagedPolicyArns": [ - { + "ManagedPolicyArns": [{ "Fn::Join": [ "", [ @@ -1253,8 +1203,7 @@ ] } ], - "Tags": [ - { + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -1278,11 +1227,9 @@ "ClusterNodesInstanceProfileF2DD0E21": { "Type": "AWS::IAM::InstanceProfile", "Properties": { - "Roles": [ - { - "Ref": "ClusterNodesInstanceRoleC3C01328" - } - ] + "Roles": [{ + "Ref": "ClusterNodesInstanceRoleC3C01328" + }] } }, "ClusterNodesLaunchConfig7C420A27": { @@ -1295,14 +1242,12 @@ "IamInstanceProfile": { "Ref": "ClusterNodesInstanceProfileF2DD0E21" }, - "SecurityGroups": [ - { - "Fn::GetAtt": [ - "ClusterNodesInstanceSecurityGroup899246BD", - "GroupId" - ] - } - ], + "SecurityGroups": [{ + "Fn::GetAtt": [ + "ClusterNodesInstanceSecurityGroup899246BD", + "GroupId" + ] + }], "UserData": { "Fn::Base64": { "Fn::Join": [ @@ -1330,8 +1275,7 @@ "LaunchConfigurationName": { "Ref": "ClusterNodesLaunchConfig7C420A27" }, - "Tags": [ - { + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -1352,8 +1296,7 @@ "Value": "aws-cdk-eks-cluster-test/Cluster/Nodes" } ], - "VPCZoneIdentifier": [ - { + "VPCZoneIdentifier": [{ "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { @@ -1385,15 +1328,12 @@ "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "aws-cdk-eks-cluster-test/Cluster/BottlerocketNodes/InstanceSecurityGroup", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1" - } - ], - "Tags": [ - { + "SecurityGroupEgress": [{ + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + }], + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -1482,29 +1422,26 @@ "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": { - "Fn::Join": [ - "", - [ - "ec2.", - { - "Ref": "AWS::URLSuffix" - } - ] + "Statement": [{ + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "ec2.", + { + "Ref": "AWS::URLSuffix" + } ] - } + ] } } - ], + }], "Version": "2012-10-17" }, - "ManagedPolicyArns": [ - { + "ManagedPolicyArns": [{ "Fn::Join": [ "", [ @@ -1541,8 +1478,7 @@ ] } ], - "Tags": [ - { + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -1566,11 +1502,9 @@ "ClusterBottlerocketNodesInstanceProfileB6E2F25A": { "Type": "AWS::IAM::InstanceProfile", "Properties": { - "Roles": [ - { - "Ref": "ClusterBottlerocketNodesInstanceRole68E4BCFB" - } - ] + "Roles": [{ + "Ref": "ClusterBottlerocketNodesInstanceRole68E4BCFB" + }] } }, "ClusterBottlerocketNodesLaunchConfig76D7BEBE": { @@ -1583,14 +1517,12 @@ "IamInstanceProfile": { "Ref": "ClusterBottlerocketNodesInstanceProfileB6E2F25A" }, - "SecurityGroups": [ - { - "Fn::GetAtt": [ - "ClusterBottlerocketNodesInstanceSecurityGroup3794A94B", - "GroupId" - ] - } - ], + "SecurityGroups": [{ + "Fn::GetAtt": [ + "ClusterBottlerocketNodesInstanceSecurityGroup3794A94B", + "GroupId" + ] + }], "UserData": { "Fn::Base64": { "Fn::Join": [ @@ -1632,8 +1564,7 @@ "LaunchConfigurationName": { "Ref": "ClusterBottlerocketNodesLaunchConfig76D7BEBE" }, - "Tags": [ - { + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -1654,8 +1585,7 @@ "Value": "aws-cdk-eks-cluster-test/Cluster/BottlerocketNodes" } ], - "VPCZoneIdentifier": [ - { + "VPCZoneIdentifier": [{ "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { @@ -1687,15 +1617,12 @@ "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "aws-cdk-eks-cluster-test/Cluster/spot/InstanceSecurityGroup", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1" - } - ], - "Tags": [ - { + "SecurityGroupEgress": [{ + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + }], + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -1784,29 +1711,26 @@ "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": { - "Fn::Join": [ - "", - [ - "ec2.", - { - "Ref": "AWS::URLSuffix" - } - ] + "Statement": [{ + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "ec2.", + { + "Ref": "AWS::URLSuffix" + } ] - } + ] } } - ], + }], "Version": "2012-10-17" }, - "ManagedPolicyArns": [ - { + "ManagedPolicyArns": [{ "Fn::Join": [ "", [ @@ -1843,8 +1767,7 @@ ] } ], - "Tags": [ - { + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -1868,11 +1791,9 @@ "ClusterspotInstanceProfileAB88D077": { "Type": "AWS::IAM::InstanceProfile", "Properties": { - "Roles": [ - { - "Ref": "ClusterspotInstanceRole39043830" - } - ] + "Roles": [{ + "Ref": "ClusterspotInstanceRole39043830" + }] } }, "ClusterspotLaunchConfigCC19F2E6": { @@ -1885,14 +1806,12 @@ "IamInstanceProfile": { "Ref": "ClusterspotInstanceProfileAB88D077" }, - "SecurityGroups": [ - { - "Fn::GetAtt": [ - "ClusterspotInstanceSecurityGroup01F7B1CE", - "GroupId" - ] - } - ], + "SecurityGroups": [{ + "Fn::GetAtt": [ + "ClusterspotInstanceSecurityGroup01F7B1CE", + "GroupId" + ] + }], "SpotPrice": "0.1094", "UserData": { "Fn::Base64": { @@ -1921,8 +1840,7 @@ "LaunchConfigurationName": { "Ref": "ClusterspotLaunchConfigCC19F2E6" }, - "Tags": [ - { + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -1943,8 +1861,7 @@ "Value": "aws-cdk-eks-cluster-test/Cluster/spot" } ], - "VPCZoneIdentifier": [ - { + "VPCZoneIdentifier": [{ "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { @@ -1993,10 +1910,10 @@ "Release": "ksclustertestclusterchartspotinterrupthandlerf41ba997", "Chart": "aws-node-termination-handler", "Version": "0.7.3", - "Wait": false, "Values": "{\"nodeSelector.lifecycle\":\"Ec2Spot\"}", "Namespace": "kube-system", - "Repository": "https://aws.github.io/eks-charts" + "Repository": "https://aws.github.io/eks-charts", + "CreateNamespace": true }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -2005,15 +1922,12 @@ "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "aws-cdk-eks-cluster-test/Cluster/InferenceInstances/InstanceSecurityGroup", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1" - } - ], - "Tags": [ - { + "SecurityGroupEgress": [{ + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + }], + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -2102,29 +2016,26 @@ "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": { - "Fn::Join": [ - "", - [ - "ec2.", - { - "Ref": "AWS::URLSuffix" - } - ] + "Statement": [{ + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "ec2.", + { + "Ref": "AWS::URLSuffix" + } ] - } + ] } } - ], + }], "Version": "2012-10-17" }, - "ManagedPolicyArns": [ - { + "ManagedPolicyArns": [{ "Fn::Join": [ "", [ @@ -2161,8 +2072,7 @@ ] } ], - "Tags": [ - { + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -2186,11 +2096,9 @@ "ClusterInferenceInstancesInstanceProfile5A1209B4": { "Type": "AWS::IAM::InstanceProfile", "Properties": { - "Roles": [ - { - "Ref": "ClusterInferenceInstancesInstanceRole59AC6F56" - } - ] + "Roles": [{ + "Ref": "ClusterInferenceInstancesInstanceRole59AC6F56" + }] } }, "ClusterInferenceInstancesLaunchConfig03BF48FE": { @@ -2203,14 +2111,12 @@ "IamInstanceProfile": { "Ref": "ClusterInferenceInstancesInstanceProfile5A1209B4" }, - "SecurityGroups": [ - { - "Fn::GetAtt": [ - "ClusterInferenceInstancesInstanceSecurityGroupECB3FC45", - "GroupId" - ] - } - ], + "SecurityGroups": [{ + "Fn::GetAtt": [ + "ClusterInferenceInstancesInstanceSecurityGroupECB3FC45", + "GroupId" + ] + }], "UserData": { "Fn::Base64": { "Fn::Join": [ @@ -2238,8 +2144,7 @@ "LaunchConfigurationName": { "Ref": "ClusterInferenceInstancesLaunchConfig03BF48FE" }, - "Tags": [ - { + "Tags": [{ "Key": { "Fn::Join": [ "", @@ -2260,8 +2165,7 @@ "Value": "aws-cdk-eks-cluster-test/Cluster/InferenceInstances" } ], - "VPCZoneIdentifier": [ - { + "VPCZoneIdentifier": [{ "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { @@ -2316,29 +2220,26 @@ "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": { - "Fn::Join": [ - "", - [ - "ec2.", - { - "Ref": "AWS::URLSuffix" - } - ] + "Statement": [{ + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "ec2.", + { + "Ref": "AWS::URLSuffix" + } ] - } + ] } } - ], + }], "Version": "2012-10-17" }, - "ManagedPolicyArns": [ - { + "ManagedPolicyArns": [{ "Fn::Join": [ "", [ @@ -2389,8 +2290,7 @@ "Arn" ] }, - "Subnets": [ - { + "Subnets": [{ "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { @@ -2454,9 +2354,9 @@ }, "Release": "awscdkeksclustertestclusterchartdashboard1f3d83fe", "Chart": "kubernetes-dashboard", - "Wait": false, "Namespace": "default", - "Repository": "https://kubernetes.github.io/dashboard/" + "Repository": "https://kubernetes.github.io/dashboard/", + "CreateNamespace": true }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -2484,7 +2384,8 @@ "Wait": true, "Timeout": "900s", "Namespace": "kube-system", - "Repository": "https://helm.nginx.com/stable" + "Repository": "https://helm.nginx.com/stable", + "CreateNamespace": true }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -2528,25 +2429,23 @@ "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRoleWithWebIdentity", - "Condition": { - "StringEquals": { - "Fn::GetAtt": [ - "ClusterMyServiceAccountConditionJson671C0633", - "Value" - ] - } - }, - "Effect": "Allow", - "Principal": { - "Federated": { - "Ref": "ClusterOpenIdConnectProviderE7EB0530" - } + "Statement": [{ + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "Fn::GetAtt": [ + "ClusterMyServiceAccountConditionJson671C0633", + "Value" + ] + } + }, + "Effect": "Allow", + "Principal": { + "Federated": { + "Ref": "ClusterOpenIdConnectProviderE7EB0530" } } - ], + }], "Version": "2012-10-17" } } @@ -2687,7 +2586,7 @@ }, "/", { - "Ref": "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042S3BucketAE64A22C" + "Ref": "AssetParametersf6c9f832ab537bf67a2e6f11d920c2b7462186e1dc599dc92a7ada76f087b3bfS3BucketAD1A1343" }, "/", { @@ -2697,7 +2596,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042S3VersionKeyAFF70CF1" + "Ref": "AssetParametersf6c9f832ab537bf67a2e6f11d920c2b7462186e1dc599dc92a7ada76f087b3bfS3VersionKeyA6C46C4E" } ] } @@ -2710,7 +2609,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042S3VersionKeyAFF70CF1" + "Ref": "AssetParametersf6c9f832ab537bf67a2e6f11d920c2b7462186e1dc599dc92a7ada76f087b3bfS3VersionKeyA6C46C4E" } ] } @@ -2720,11 +2619,11 @@ ] }, "Parameters": { - "referencetoawscdkeksclustertestAssetParametersca6f286e0d135e22cfefc133659e2f2fe139a4b46b8eef5b8e197606625c9af9S3Bucket973804E9Ref": { - "Ref": "AssetParametersca6f286e0d135e22cfefc133659e2f2fe139a4b46b8eef5b8e197606625c9af9S3BucketC1533EC8" + "referencetoawscdkeksclustertestAssetParameters2d65340a9414c04d1844e421bd328aa3b80015d6a02e74afe9a222168b2ba050S3BucketA41B2C70Ref": { + "Ref": "AssetParameters2d65340a9414c04d1844e421bd328aa3b80015d6a02e74afe9a222168b2ba050S3Bucket0EAA682D" }, - "referencetoawscdkeksclustertestAssetParametersca6f286e0d135e22cfefc133659e2f2fe139a4b46b8eef5b8e197606625c9af9S3VersionKey2F733777Ref": { - "Ref": "AssetParametersca6f286e0d135e22cfefc133659e2f2fe139a4b46b8eef5b8e197606625c9af9S3VersionKey2C834492" + "referencetoawscdkeksclustertestAssetParameters2d65340a9414c04d1844e421bd328aa3b80015d6a02e74afe9a222168b2ba050S3VersionKey4E1E47F7Ref": { + "Ref": "AssetParameters2d65340a9414c04d1844e421bd328aa3b80015d6a02e74afe9a222168b2ba050S3VersionKeyF3400812" }, "referencetoawscdkeksclustertestAssetParameters5d5280180ad87e8a1c2a08423cb5b2dae41281832799cd51db5eff913091ade6S3Bucket8FECC379Ref": { "Ref": "AssetParameters5d5280180ad87e8a1c2a08423cb5b2dae41281832799cd51db5eff913091ade6S3Bucket03CDDE18" @@ -2740,21 +2639,17 @@ "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } + "Statement": [{ + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" } - ] + }] }, - "ManagedPolicyArns": [ - { - "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - } - ] + "ManagedPolicyArns": [{ + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + }] } }, "AWSCDKCfnUtilsProviderCustomResourceProviderHandlerCF82AA57": { @@ -2767,8 +2662,7 @@ "S3Key": { "Fn::Join": [ "", - [ - { + [{ "Fn::Select": [ 0, { @@ -2818,42 +2712,34 @@ "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } + "Statement": [{ + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" } - ] - }, - "ManagedPolicyArns": [ - { - "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - } - ], - "Policies": [ - { - "PolicyName": "Inline", - "PolicyDocument": { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Resource": "*", - "Action": [ - "iam:CreateOpenIDConnectProvider", - "iam:DeleteOpenIDConnectProvider", - "iam:UpdateOpenIDConnectProviderThumbprint", - "iam:AddClientIDToOpenIDConnectProvider", - "iam:RemoveClientIDFromOpenIDConnectProvider" - ] - } + }] + }, + "ManagedPolicyArns": [{ + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + }], + "Policies": [{ + "PolicyName": "Inline", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [{ + "Effect": "Allow", + "Resource": "*", + "Action": [ + "iam:CreateOpenIDConnectProvider", + "iam:DeleteOpenIDConnectProvider", + "iam:UpdateOpenIDConnectProviderThumbprint", + "iam:AddClientIDToOpenIDConnectProvider", + "iam:RemoveClientIDFromOpenIDConnectProvider" ] - } + }] } - ] + }] } }, "CustomAWSCDKOpenIdConnectProviderCustomResourceProviderHandlerF2C543E0": { @@ -2866,8 +2752,7 @@ "S3Key": { "Fn::Join": [ "", - [ - { + [{ "Fn::Select": [ 0, { @@ -3025,17 +2910,17 @@ "Type": "String", "Description": "Artifact hash for asset \"5d5280180ad87e8a1c2a08423cb5b2dae41281832799cd51db5eff913091ade6\"" }, - "AssetParametersca6f286e0d135e22cfefc133659e2f2fe139a4b46b8eef5b8e197606625c9af9S3BucketC1533EC8": { + "AssetParameters2d65340a9414c04d1844e421bd328aa3b80015d6a02e74afe9a222168b2ba050S3Bucket0EAA682D": { "Type": "String", - "Description": "S3 bucket for asset \"ca6f286e0d135e22cfefc133659e2f2fe139a4b46b8eef5b8e197606625c9af9\"" + "Description": "S3 bucket for asset \"2d65340a9414c04d1844e421bd328aa3b80015d6a02e74afe9a222168b2ba050\"" }, - "AssetParametersca6f286e0d135e22cfefc133659e2f2fe139a4b46b8eef5b8e197606625c9af9S3VersionKey2C834492": { + "AssetParameters2d65340a9414c04d1844e421bd328aa3b80015d6a02e74afe9a222168b2ba050S3VersionKeyF3400812": { "Type": "String", - "Description": "S3 key for asset version \"ca6f286e0d135e22cfefc133659e2f2fe139a4b46b8eef5b8e197606625c9af9\"" + "Description": "S3 key for asset version \"2d65340a9414c04d1844e421bd328aa3b80015d6a02e74afe9a222168b2ba050\"" }, - "AssetParametersca6f286e0d135e22cfefc133659e2f2fe139a4b46b8eef5b8e197606625c9af9ArtifactHash51A7CDC3": { + "AssetParameters2d65340a9414c04d1844e421bd328aa3b80015d6a02e74afe9a222168b2ba050ArtifactHashF4CEE19F": { "Type": "String", - "Description": "Artifact hash for asset \"ca6f286e0d135e22cfefc133659e2f2fe139a4b46b8eef5b8e197606625c9af9\"" + "Description": "Artifact hash for asset \"2d65340a9414c04d1844e421bd328aa3b80015d6a02e74afe9a222168b2ba050\"" }, "AssetParameters3b28f4ee261986c158a160900e3042a61238f644fe502199d60bcea592128086S3Bucket57C0655B": { "Type": "String", @@ -3073,17 +2958,17 @@ "Type": "String", "Description": "Artifact hash for asset \"7255958d303a278986617e8d7ce027c96cd00a70fb8f1ca02c1e0da94a571896\"" }, - "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042S3BucketAE64A22C": { + "AssetParametersf6c9f832ab537bf67a2e6f11d920c2b7462186e1dc599dc92a7ada76f087b3bfS3BucketAD1A1343": { "Type": "String", - "Description": "S3 bucket for asset \"5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042\"" + "Description": "S3 bucket for asset \"f6c9f832ab537bf67a2e6f11d920c2b7462186e1dc599dc92a7ada76f087b3bf\"" }, - "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042S3VersionKeyAFF70CF1": { + "AssetParametersf6c9f832ab537bf67a2e6f11d920c2b7462186e1dc599dc92a7ada76f087b3bfS3VersionKeyA6C46C4E": { "Type": "String", - "Description": "S3 key for asset version \"5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042\"" + "Description": "S3 key for asset version \"f6c9f832ab537bf67a2e6f11d920c2b7462186e1dc599dc92a7ada76f087b3bf\"" }, - "AssetParameters5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042ArtifactHashD8735DDD": { + "AssetParametersf6c9f832ab537bf67a2e6f11d920c2b7462186e1dc599dc92a7ada76f087b3bfArtifactHash0C55941B": { "Type": "String", - "Description": "Artifact hash for asset \"5b580ce3f53b1ee1551ac2e759433f10ef9a6a312bf7a501a0753fddcc8a3042\"" + "Description": "Artifact hash for asset \"f6c9f832ab537bf67a2e6f11d920c2b7462186e1dc599dc92a7ada76f087b3bf\"" }, "SsmParameterValueawsserviceeksoptimizedami116amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { "Type": "AWS::SSM::Parameter::Value", @@ -3098,4 +2983,4 @@ "Default": "/aws/service/eks/optimized-ami/1.16/amazon-linux-2-gpu/recommended/image_id" } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-eks/test/test.cluster.ts b/packages/@aws-cdk/aws-eks/test/test.cluster.ts index c7a09d794e7cc..93bf628e83b2a 100644 --- a/packages/@aws-cdk/aws-eks/test/test.cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/test.cluster.ts @@ -685,7 +685,6 @@ export = { expect(stack).to(haveResource(eks.HelmChart.RESOURCE_TYPE, { Release: 'stackclusterchartspotinterrupthandlerdec62e07', Chart: 'aws-node-termination-handler', - Wait: false, Values: '{\"nodeSelector.lifecycle\":\"Ec2Spot\"}', Namespace: 'kube-system', Repository: 'https://aws.github.io/eks-charts', diff --git a/packages/@aws-cdk/aws-eks/test/test.helm-chart.ts b/packages/@aws-cdk/aws-eks/test/test.helm-chart.ts index 0528bb27aac54..5041cc6a17701 100644 --- a/packages/@aws-cdk/aws-eks/test/test.helm-chart.ts +++ b/packages/@aws-cdk/aws-eks/test/test.helm-chart.ts @@ -52,6 +52,39 @@ export = { expect(stack).to(haveResource(eks.HelmChart.RESOURCE_TYPE, { Values: '{\"foo\":123}' })); test.done(); }, + 'should support create namespaces by default'(test: Test) { + // GIVEN + const { stack, cluster } = testFixtureCluster(); + + // WHEN + new eks.HelmChart(stack, 'MyChart', { cluster, chart: 'chart' }); + + // THEN + expect(stack).to(haveResource(eks.HelmChart.RESOURCE_TYPE, { CreateNamespace: true })); + test.done(); + }, + 'should support create namespaces when explicitly specified'(test: Test) { + // GIVEN + const { stack, cluster } = testFixtureCluster(); + + // WHEN + new eks.HelmChart(stack, 'MyChart', { cluster, chart: 'chart', createNamespace: true }); + + // THEN + expect(stack).to(haveResource(eks.HelmChart.RESOURCE_TYPE, { CreateNamespace: true })); + test.done(); + }, + 'should not create namespaces when disabled'(test: Test) { + // GIVEN + const { stack, cluster } = testFixtureCluster(); + + // WHEN + new eks.HelmChart(stack, 'MyChart', { cluster, chart: 'chart', createNamespace: false }); + + // THEN + expect(stack).notTo(haveResource(eks.HelmChart.RESOURCE_TYPE, { CreateNamespace: true })); + test.done(); + }, 'should support waiting until everything is completed before marking release as successful'(test: Test) { // GIVEN const { stack, cluster } = testFixtureCluster(); @@ -71,9 +104,32 @@ export = { new eks.HelmChart(stack, 'MyWaitingChart', { cluster, chart: 'chart' }); // THEN - expect(stack).to(haveResource(eks.HelmChart.RESOURCE_TYPE, { Wait: false })); + expect(stack).notTo(haveResource(eks.HelmChart.RESOURCE_TYPE, { Wait: true })); + test.done(); + }, + 'should enable waiting when specified'(test: Test) { + // GIVEN + const { stack, cluster } = testFixtureCluster(); + + // WHEN + new eks.HelmChart(stack, 'MyWaitingChart', { cluster, chart: 'chart', wait: true }); + + // THEN + expect(stack).to(haveResource(eks.HelmChart.RESOURCE_TYPE, { Wait: true })); test.done(); }, + 'should disable waiting when specified as false'(test: Test) { + // GIVEN + const { stack, cluster } = testFixtureCluster(); + + // WHEN + new eks.HelmChart(stack, 'MyWaitingChart', { cluster, chart: 'chart', wait: false }); + + // THEN + expect(stack).notTo(haveResource(eks.HelmChart.RESOURCE_TYPE, { Wait: true })); + test.done(); + }, + 'should timeout only after 10 minutes'(test: Test) { // GIVEN const { stack, cluster } = testFixtureCluster(); From c337d4a89dfad2080e7efa1d37c751fcbaa21858 Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Tue, 30 Jun 2020 12:23:37 +0300 Subject: [PATCH 44/55] chore(pkglint): dont publish cdk.out directories (#8803) Adds a pkglint validation so that we always include `**/cdk.out` in our `.npmignore` files. This will prevent us from accidentally publishing cdk artifacts that were generated during build/test. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/alexa-ask/.npmignore | 3 ++ packages/@aws-cdk/app-delivery/.npmignore | 3 ++ packages/@aws-cdk/assert/.npmignore | 3 ++ packages/@aws-cdk/assets/.npmignore | 3 ++ .../@aws-cdk/aws-accessanalyzer/.npmignore | 3 ++ packages/@aws-cdk/aws-acmpca/.npmignore | 3 ++ packages/@aws-cdk/aws-amazonmq/.npmignore | 3 ++ packages/@aws-cdk/aws-amplify/.npmignore | 3 ++ packages/@aws-cdk/aws-apigateway/.npmignore | 3 ++ packages/@aws-cdk/aws-apigatewayv2/.npmignore | 3 ++ packages/@aws-cdk/aws-appconfig/.npmignore | 3 ++ .../aws-applicationautoscaling/.npmignore | 3 ++ packages/@aws-cdk/aws-appmesh/.npmignore | 3 ++ packages/@aws-cdk/aws-appstream/.npmignore | 3 ++ packages/@aws-cdk/aws-appsync/.npmignore | 3 ++ packages/@aws-cdk/aws-athena/.npmignore | 3 ++ .../aws-autoscaling-common/.npmignore | 3 ++ .../aws-autoscaling-hooktargets/.npmignore | 3 ++ packages/@aws-cdk/aws-autoscaling/.npmignore | 3 ++ .../@aws-cdk/aws-autoscalingplans/.npmignore | 3 ++ packages/@aws-cdk/aws-backup/.npmignore | 3 ++ packages/@aws-cdk/aws-batch/.npmignore | 3 ++ packages/@aws-cdk/aws-budgets/.npmignore | 3 ++ packages/@aws-cdk/aws-cassandra/.npmignore | 3 ++ packages/@aws-cdk/aws-ce/.npmignore | 3 ++ .../aws-certificatemanager/.npmignore | 3 ++ packages/@aws-cdk/aws-chatbot/.npmignore | 3 ++ packages/@aws-cdk/aws-cloud9/.npmignore | 3 ++ .../@aws-cdk/aws-cloudformation/.npmignore | 3 ++ packages/@aws-cdk/aws-cloudfront/.npmignore | 3 ++ packages/@aws-cdk/aws-cloudtrail/.npmignore | 4 ++- .../aws-cloudwatch-actions/.npmignore | 3 ++ packages/@aws-cdk/aws-cloudwatch/.npmignore | 3 ++ packages/@aws-cdk/aws-codebuild/.npmignore | 3 ++ packages/@aws-cdk/aws-codecommit/.npmignore | 3 ++ packages/@aws-cdk/aws-codedeploy/.npmignore | 3 ++ .../@aws-cdk/aws-codeguruprofiler/.npmignore | 3 ++ .../aws-codepipeline-actions/.npmignore | 3 ++ packages/@aws-cdk/aws-codepipeline/.npmignore | 3 ++ packages/@aws-cdk/aws-codestar/.npmignore | 3 ++ .../aws-codestarconnections/.npmignore | 3 ++ .../aws-codestarnotifications/.npmignore | 3 ++ packages/@aws-cdk/aws-cognito/.npmignore | 3 ++ packages/@aws-cdk/aws-config/.npmignore | 3 ++ packages/@aws-cdk/aws-datapipeline/.npmignore | 3 ++ packages/@aws-cdk/aws-dax/.npmignore | 3 ++ packages/@aws-cdk/aws-detective/.npmignore | 3 ++ .../@aws-cdk/aws-directoryservice/.npmignore | 3 ++ packages/@aws-cdk/aws-dlm/.npmignore | 3 ++ packages/@aws-cdk/aws-dms/.npmignore | 3 ++ packages/@aws-cdk/aws-docdb/.npmignore | 3 ++ .../@aws-cdk/aws-dynamodb-global/.npmignore | 3 ++ packages/@aws-cdk/aws-dynamodb/.npmignore | 3 ++ packages/@aws-cdk/aws-ec2/.npmignore | 3 ++ packages/@aws-cdk/aws-ecr-assets/.npmignore | 3 ++ packages/@aws-cdk/aws-ecr/.npmignore | 3 ++ packages/@aws-cdk/aws-ecs-patterns/.npmignore | 3 ++ packages/@aws-cdk/aws-ecs/.npmignore | 3 ++ packages/@aws-cdk/aws-efs/.npmignore | 3 ++ packages/@aws-cdk/aws-eks-legacy/.npmignore | 3 ++ packages/@aws-cdk/aws-eks/.npmignore | 3 ++ packages/@aws-cdk/aws-elasticache/.npmignore | 3 ++ .../@aws-cdk/aws-elasticbeanstalk/.npmignore | 3 ++ .../aws-elasticloadbalancing/.npmignore | 3 ++ .../.npmignore | 4 ++- .../.npmignore | 3 ++ .../aws-elasticloadbalancingv2/.npmignore | 3 ++ .../@aws-cdk/aws-elasticsearch/.npmignore | 3 ++ packages/@aws-cdk/aws-emr/.npmignore | 3 ++ .../@aws-cdk/aws-events-targets/.npmignore | 3 ++ packages/@aws-cdk/aws-events/.npmignore | 3 ++ packages/@aws-cdk/aws-eventschemas/.npmignore | 3 ++ packages/@aws-cdk/aws-fms/.npmignore | 3 ++ packages/@aws-cdk/aws-fsx/.npmignore | 3 ++ packages/@aws-cdk/aws-gamelift/.npmignore | 3 ++ .../@aws-cdk/aws-globalaccelerator/.npmignore | 3 ++ packages/@aws-cdk/aws-glue/.npmignore | 3 ++ packages/@aws-cdk/aws-greengrass/.npmignore | 3 ++ packages/@aws-cdk/aws-guardduty/.npmignore | 3 ++ packages/@aws-cdk/aws-iam/.npmignore | 3 ++ packages/@aws-cdk/aws-imagebuilder/.npmignore | 3 ++ packages/@aws-cdk/aws-inspector/.npmignore | 3 ++ packages/@aws-cdk/aws-iot/.npmignore | 3 ++ packages/@aws-cdk/aws-iot1click/.npmignore | 3 ++ packages/@aws-cdk/aws-iotanalytics/.npmignore | 3 ++ packages/@aws-cdk/aws-iotevents/.npmignore | 3 ++ .../@aws-cdk/aws-iotthingsgraph/.npmignore | 3 ++ packages/@aws-cdk/aws-kinesis/.npmignore | 3 ++ .../@aws-cdk/aws-kinesisanalytics/.npmignore | 3 ++ .../@aws-cdk/aws-kinesisfirehose/.npmignore | 3 ++ packages/@aws-cdk/aws-kms/.npmignore | 3 ++ .../@aws-cdk/aws-lakeformation/.npmignore | 3 ++ .../aws-lambda-destinations/.npmignore | 3 ++ .../aws-lambda-event-sources/.npmignore | 3 ++ .../@aws-cdk/aws-lambda-nodejs/.npmignore | 3 ++ packages/@aws-cdk/aws-lambda/.npmignore | 3 ++ .../@aws-cdk/aws-logs-destinations/.npmignore | 3 ++ packages/@aws-cdk/aws-logs/.npmignore | 3 ++ packages/@aws-cdk/aws-macie/.npmignore | 3 ++ .../@aws-cdk/aws-managedblockchain/.npmignore | 3 ++ packages/@aws-cdk/aws-mediaconvert/.npmignore | 3 ++ packages/@aws-cdk/aws-medialive/.npmignore | 3 ++ packages/@aws-cdk/aws-mediastore/.npmignore | 3 ++ packages/@aws-cdk/aws-msk/.npmignore | 3 ++ packages/@aws-cdk/aws-neptune/.npmignore | 3 ++ .../@aws-cdk/aws-networkmanager/.npmignore | 3 ++ packages/@aws-cdk/aws-opsworks/.npmignore | 3 ++ packages/@aws-cdk/aws-opsworkscm/.npmignore | 3 ++ packages/@aws-cdk/aws-pinpoint/.npmignore | 3 ++ .../@aws-cdk/aws-pinpointemail/.npmignore | 3 ++ packages/@aws-cdk/aws-qldb/.npmignore | 3 ++ packages/@aws-cdk/aws-ram/.npmignore | 3 ++ packages/@aws-cdk/aws-rds/.npmignore | 3 ++ packages/@aws-cdk/aws-redshift/.npmignore | 3 ++ .../@aws-cdk/aws-resourcegroups/.npmignore | 3 ++ packages/@aws-cdk/aws-robomaker/.npmignore | 3 ++ .../@aws-cdk/aws-route53-patterns/.npmignore | 3 ++ .../@aws-cdk/aws-route53-targets/.npmignore | 3 ++ packages/@aws-cdk/aws-route53/.npmignore | 3 ++ .../@aws-cdk/aws-route53resolver/.npmignore | 3 ++ packages/@aws-cdk/aws-s3-assets/.npmignore | 3 ++ .../@aws-cdk/aws-s3-deployment/.npmignore | 3 ++ .../@aws-cdk/aws-s3-notifications/.npmignore | 3 ++ packages/@aws-cdk/aws-s3/.npmignore | 3 ++ packages/@aws-cdk/aws-sagemaker/.npmignore | 3 ++ packages/@aws-cdk/aws-sam/.npmignore | 3 ++ packages/@aws-cdk/aws-sdb/.npmignore | 3 ++ .../@aws-cdk/aws-secretsmanager/.npmignore | 3 ++ packages/@aws-cdk/aws-securityhub/.npmignore | 3 ++ .../@aws-cdk/aws-servicecatalog/.npmignore | 3 ++ .../@aws-cdk/aws-servicediscovery/.npmignore | 3 ++ packages/@aws-cdk/aws-ses-actions/.npmignore | 3 ++ packages/@aws-cdk/aws-ses/.npmignore | 3 ++ .../@aws-cdk/aws-sns-subscriptions/.npmignore | 3 ++ packages/@aws-cdk/aws-sns/.npmignore | 3 ++ packages/@aws-cdk/aws-sqs/.npmignore | 3 ++ packages/@aws-cdk/aws-ssm/.npmignore | 3 ++ .../aws-stepfunctions-tasks/.npmignore | 3 ++ .../@aws-cdk/aws-stepfunctions/.npmignore | 3 ++ packages/@aws-cdk/aws-synthetics/.npmignore | 4 ++- packages/@aws-cdk/aws-transfer/.npmignore | 3 ++ packages/@aws-cdk/aws-waf/.npmignore | 3 ++ packages/@aws-cdk/aws-wafregional/.npmignore | 3 ++ packages/@aws-cdk/aws-wafv2/.npmignore | 3 ++ packages/@aws-cdk/aws-workspaces/.npmignore | 3 ++ .../@aws-cdk/cdk-assets-schema/.npmignore | 3 ++ .../@aws-cdk/cloud-assembly-schema/.npmignore | 3 ++ .../@aws-cdk/cloudformation-diff/.npmignore | 3 ++ .../cloudformation-include/.npmignore | 3 ++ packages/@aws-cdk/core/.npmignore | 3 ++ packages/@aws-cdk/custom-resources/.npmignore | 3 ++ packages/@aws-cdk/cx-api/.npmignore | 3 ++ .../example-construct-library/.npmignore | 3 ++ packages/@aws-cdk/region-info/.npmignore | 3 ++ .../rewrite-imports/.npmignore | 3 ++ packages/aws-cdk/.npmignore | 3 ++ packages/cdk-assets/.npmignore | 3 ++ packages/monocdk-experiment/.npmignore | 4 ++- packages/monocdk-experiment/package.json | 4 ++- tools/cdk-build-tools/.npmignore | 4 ++- tools/cdk-integ-tools/.npmignore | 3 ++ tools/cfn2ts/.npmignore | 3 ++ tools/pkglint/lib/rules.ts | 31 +++++++++++++++++++ tools/pkgtools/.npmignore | 3 ++ tools/yarn-cling/.npmignore | 4 ++- 165 files changed, 523 insertions(+), 7 deletions(-) diff --git a/packages/@aws-cdk/alexa-ask/.npmignore b/packages/@aws-cdk/alexa-ask/.npmignore index c0fc6f9e7667f..b0edf81a01371 100644 --- a/packages/@aws-cdk/alexa-ask/.npmignore +++ b/packages/@aws-cdk/alexa-ask/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/app-delivery/.npmignore b/packages/@aws-cdk/app-delivery/.npmignore index 8cd0e50359c6b..001499d011563 100644 --- a/packages/@aws-cdk/app-delivery/.npmignore +++ b/packages/@aws-cdk/app-delivery/.npmignore @@ -17,3 +17,6 @@ coverage tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/assert/.npmignore b/packages/@aws-cdk/assert/.npmignore index 18ab2081759df..f5e2864c265a7 100644 --- a/packages/@aws-cdk/assert/.npmignore +++ b/packages/@aws-cdk/assert/.npmignore @@ -15,3 +15,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/assets/.npmignore b/packages/@aws-cdk/assets/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/assets/.npmignore +++ b/packages/@aws-cdk/assets/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-accessanalyzer/.npmignore b/packages/@aws-cdk/aws-accessanalyzer/.npmignore index 8ac959aca8fa5..683e3e0847e1f 100644 --- a/packages/@aws-cdk/aws-accessanalyzer/.npmignore +++ b/packages/@aws-cdk/aws-accessanalyzer/.npmignore @@ -20,3 +20,6 @@ tsconfig.json !.jsii .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-acmpca/.npmignore b/packages/@aws-cdk/aws-acmpca/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-acmpca/.npmignore +++ b/packages/@aws-cdk/aws-acmpca/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-amazonmq/.npmignore b/packages/@aws-cdk/aws-amazonmq/.npmignore index 8afbe60698fb4..ac1c98567f9a5 100644 --- a/packages/@aws-cdk/aws-amazonmq/.npmignore +++ b/packages/@aws-cdk/aws-amazonmq/.npmignore @@ -24,3 +24,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-amplify/.npmignore b/packages/@aws-cdk/aws-amplify/.npmignore index 2b093ce17a11b..5177fc0435bf1 100644 --- a/packages/@aws-cdk/aws-amplify/.npmignore +++ b/packages/@aws-cdk/aws-amplify/.npmignore @@ -24,3 +24,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/.npmignore b/packages/@aws-cdk/aws-apigateway/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-apigateway/.npmignore +++ b/packages/@aws-cdk/aws-apigateway/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigatewayv2/.npmignore b/packages/@aws-cdk/aws-apigatewayv2/.npmignore index 8ac959aca8fa5..683e3e0847e1f 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/.npmignore +++ b/packages/@aws-cdk/aws-apigatewayv2/.npmignore @@ -20,3 +20,6 @@ tsconfig.json !.jsii .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-appconfig/.npmignore b/packages/@aws-cdk/aws-appconfig/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-appconfig/.npmignore +++ b/packages/@aws-cdk/aws-appconfig/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-applicationautoscaling/.npmignore b/packages/@aws-cdk/aws-applicationautoscaling/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-applicationautoscaling/.npmignore +++ b/packages/@aws-cdk/aws-applicationautoscaling/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-appmesh/.npmignore b/packages/@aws-cdk/aws-appmesh/.npmignore index dd7e4908d99e4..af5cffcab06c1 100644 --- a/packages/@aws-cdk/aws-appmesh/.npmignore +++ b/packages/@aws-cdk/aws-appmesh/.npmignore @@ -22,3 +22,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-appstream/.npmignore b/packages/@aws-cdk/aws-appstream/.npmignore index c0fc6f9e7667f..b0edf81a01371 100644 --- a/packages/@aws-cdk/aws-appstream/.npmignore +++ b/packages/@aws-cdk/aws-appstream/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-appsync/.npmignore b/packages/@aws-cdk/aws-appsync/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-appsync/.npmignore +++ b/packages/@aws-cdk/aws-appsync/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-athena/.npmignore b/packages/@aws-cdk/aws-athena/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-athena/.npmignore +++ b/packages/@aws-cdk/aws-athena/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling-common/.npmignore b/packages/@aws-cdk/aws-autoscaling-common/.npmignore index 4af9e55a2f0e6..9e5af6ca8e34d 100644 --- a/packages/@aws-cdk/aws-autoscaling-common/.npmignore +++ b/packages/@aws-cdk/aws-autoscaling-common/.npmignore @@ -22,3 +22,6 @@ lambda/*.sh tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling-hooktargets/.npmignore b/packages/@aws-cdk/aws-autoscaling-hooktargets/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-autoscaling-hooktargets/.npmignore +++ b/packages/@aws-cdk/aws-autoscaling-hooktargets/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling/.npmignore b/packages/@aws-cdk/aws-autoscaling/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-autoscaling/.npmignore +++ b/packages/@aws-cdk/aws-autoscaling/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscalingplans/.npmignore b/packages/@aws-cdk/aws-autoscalingplans/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-autoscalingplans/.npmignore +++ b/packages/@aws-cdk/aws-autoscalingplans/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-backup/.npmignore b/packages/@aws-cdk/aws-backup/.npmignore index d04d75fba5945..2e1e60862c02c 100644 --- a/packages/@aws-cdk/aws-backup/.npmignore +++ b/packages/@aws-cdk/aws-backup/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-batch/.npmignore b/packages/@aws-cdk/aws-batch/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-batch/.npmignore +++ b/packages/@aws-cdk/aws-batch/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-budgets/.npmignore b/packages/@aws-cdk/aws-budgets/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-budgets/.npmignore +++ b/packages/@aws-cdk/aws-budgets/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cassandra/.npmignore b/packages/@aws-cdk/aws-cassandra/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-cassandra/.npmignore +++ b/packages/@aws-cdk/aws-cassandra/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ce/.npmignore b/packages/@aws-cdk/aws-ce/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-ce/.npmignore +++ b/packages/@aws-cdk/aws-ce/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-certificatemanager/.npmignore b/packages/@aws-cdk/aws-certificatemanager/.npmignore index 7af62da222de0..13e93138e8461 100644 --- a/packages/@aws-cdk/aws-certificatemanager/.npmignore +++ b/packages/@aws-cdk/aws-certificatemanager/.npmignore @@ -22,3 +22,6 @@ lambda-packages/dns_validated_certificate_handler/node_modules tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-chatbot/.npmignore b/packages/@aws-cdk/aws-chatbot/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-chatbot/.npmignore +++ b/packages/@aws-cdk/aws-chatbot/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloud9/.npmignore b/packages/@aws-cdk/aws-cloud9/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-cloud9/.npmignore +++ b/packages/@aws-cdk/aws-cloud9/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudformation/.npmignore b/packages/@aws-cdk/aws-cloudformation/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-cloudformation/.npmignore +++ b/packages/@aws-cdk/aws-cloudformation/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudfront/.npmignore b/packages/@aws-cdk/aws-cloudfront/.npmignore index 789857384bbe8..eb063bd7f38c8 100644 --- a/packages/@aws-cdk/aws-cloudfront/.npmignore +++ b/packages/@aws-cdk/aws-cloudfront/.npmignore @@ -20,3 +20,6 @@ coverage tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/.npmignore b/packages/@aws-cdk/aws-cloudtrail/.npmignore index 181217cf5ba43..57328c980bcca 100644 --- a/packages/@aws-cdk/aws-cloudtrail/.npmignore +++ b/packages/@aws-cdk/aws-cloudtrail/.npmignore @@ -20,4 +20,6 @@ dist tsconfig.json .eslintrc.js -jest.config.js \ No newline at end of file +jest.config.js +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudwatch-actions/.npmignore b/packages/@aws-cdk/aws-cloudwatch-actions/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-cloudwatch-actions/.npmignore +++ b/packages/@aws-cdk/aws-cloudwatch-actions/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudwatch/.npmignore b/packages/@aws-cdk/aws-cloudwatch/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-cloudwatch/.npmignore +++ b/packages/@aws-cdk/aws-cloudwatch/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codebuild/.npmignore b/packages/@aws-cdk/aws-codebuild/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-codebuild/.npmignore +++ b/packages/@aws-cdk/aws-codebuild/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codecommit/.npmignore b/packages/@aws-cdk/aws-codecommit/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-codecommit/.npmignore +++ b/packages/@aws-cdk/aws-codecommit/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codedeploy/.npmignore b/packages/@aws-cdk/aws-codedeploy/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-codedeploy/.npmignore +++ b/packages/@aws-cdk/aws-codedeploy/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codeguruprofiler/.npmignore b/packages/@aws-cdk/aws-codeguruprofiler/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-codeguruprofiler/.npmignore +++ b/packages/@aws-cdk/aws-codeguruprofiler/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codepipeline-actions/.npmignore b/packages/@aws-cdk/aws-codepipeline-actions/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/.npmignore +++ b/packages/@aws-cdk/aws-codepipeline-actions/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codepipeline/.npmignore b/packages/@aws-cdk/aws-codepipeline/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-codepipeline/.npmignore +++ b/packages/@aws-cdk/aws-codepipeline/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codestar/.npmignore b/packages/@aws-cdk/aws-codestar/.npmignore index d04d75fba5945..2e1e60862c02c 100644 --- a/packages/@aws-cdk/aws-codestar/.npmignore +++ b/packages/@aws-cdk/aws-codestar/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codestarconnections/.npmignore b/packages/@aws-cdk/aws-codestarconnections/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-codestarconnections/.npmignore +++ b/packages/@aws-cdk/aws-codestarconnections/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codestarnotifications/.npmignore b/packages/@aws-cdk/aws-codestarnotifications/.npmignore index 8ac959aca8fa5..683e3e0847e1f 100644 --- a/packages/@aws-cdk/aws-codestarnotifications/.npmignore +++ b/packages/@aws-cdk/aws-codestarnotifications/.npmignore @@ -20,3 +20,6 @@ tsconfig.json !.jsii .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/.npmignore b/packages/@aws-cdk/aws-cognito/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-cognito/.npmignore +++ b/packages/@aws-cdk/aws-cognito/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-config/.npmignore b/packages/@aws-cdk/aws-config/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-config/.npmignore +++ b/packages/@aws-cdk/aws-config/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-datapipeline/.npmignore b/packages/@aws-cdk/aws-datapipeline/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-datapipeline/.npmignore +++ b/packages/@aws-cdk/aws-datapipeline/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dax/.npmignore b/packages/@aws-cdk/aws-dax/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-dax/.npmignore +++ b/packages/@aws-cdk/aws-dax/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-detective/.npmignore b/packages/@aws-cdk/aws-detective/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-detective/.npmignore +++ b/packages/@aws-cdk/aws-detective/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-directoryservice/.npmignore b/packages/@aws-cdk/aws-directoryservice/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-directoryservice/.npmignore +++ b/packages/@aws-cdk/aws-directoryservice/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dlm/.npmignore b/packages/@aws-cdk/aws-dlm/.npmignore index c0fc6f9e7667f..b0edf81a01371 100644 --- a/packages/@aws-cdk/aws-dlm/.npmignore +++ b/packages/@aws-cdk/aws-dlm/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dms/.npmignore b/packages/@aws-cdk/aws-dms/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-dms/.npmignore +++ b/packages/@aws-cdk/aws-dms/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-docdb/.npmignore b/packages/@aws-cdk/aws-docdb/.npmignore index c0fc6f9e7667f..b0edf81a01371 100644 --- a/packages/@aws-cdk/aws-docdb/.npmignore +++ b/packages/@aws-cdk/aws-docdb/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb-global/.npmignore b/packages/@aws-cdk/aws-dynamodb-global/.npmignore index d5182ba051a16..92e94b941656e 100644 --- a/packages/@aws-cdk/aws-dynamodb-global/.npmignore +++ b/packages/@aws-cdk/aws-dynamodb-global/.npmignore @@ -20,3 +20,6 @@ lambda-packages/aws-global-table-coordinator/node_modules tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/.npmignore b/packages/@aws-cdk/aws-dynamodb/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-dynamodb/.npmignore +++ b/packages/@aws-cdk/aws-dynamodb/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/.npmignore b/packages/@aws-cdk/aws-ec2/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-ec2/.npmignore +++ b/packages/@aws-cdk/aws-ec2/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecr-assets/.npmignore b/packages/@aws-cdk/aws-ecr-assets/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-ecr-assets/.npmignore +++ b/packages/@aws-cdk/aws-ecr-assets/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecr/.npmignore b/packages/@aws-cdk/aws-ecr/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-ecr/.npmignore +++ b/packages/@aws-cdk/aws-ecr/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecs-patterns/.npmignore b/packages/@aws-cdk/aws-ecs-patterns/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/.npmignore +++ b/packages/@aws-cdk/aws-ecs-patterns/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecs/.npmignore b/packages/@aws-cdk/aws-ecs/.npmignore index 9dbc8260e16f3..047d5ca251254 100644 --- a/packages/@aws-cdk/aws-ecs/.npmignore +++ b/packages/@aws-cdk/aws-ecs/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-efs/.npmignore b/packages/@aws-cdk/aws-efs/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-efs/.npmignore +++ b/packages/@aws-cdk/aws-efs/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks-legacy/.npmignore b/packages/@aws-cdk/aws-eks-legacy/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-eks-legacy/.npmignore +++ b/packages/@aws-cdk/aws-eks-legacy/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks/.npmignore b/packages/@aws-cdk/aws-eks/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-eks/.npmignore +++ b/packages/@aws-cdk/aws-eks/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticache/.npmignore b/packages/@aws-cdk/aws-elasticache/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-elasticache/.npmignore +++ b/packages/@aws-cdk/aws-elasticache/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticbeanstalk/.npmignore b/packages/@aws-cdk/aws-elasticbeanstalk/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-elasticbeanstalk/.npmignore +++ b/packages/@aws-cdk/aws-elasticbeanstalk/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/.npmignore b/packages/@aws-cdk/aws-elasticloadbalancing/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/.npmignore +++ b/packages/@aws-cdk/aws-elasticloadbalancing/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2-actions/.npmignore b/packages/@aws-cdk/aws-elasticloadbalancingv2-actions/.npmignore index 6112f38ab3d62..837d590e98218 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2-actions/.npmignore +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2-actions/.npmignore @@ -19,4 +19,6 @@ dist tsconfig.json .eslintrc.js -jest.config.js \ No newline at end of file +jest.config.js +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/.npmignore b/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/.npmignore index 34ff973619988..36fe3528aa4c6 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/.npmignore +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/.npmignore b/packages/@aws-cdk/aws-elasticloadbalancingv2/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/.npmignore +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticsearch/.npmignore b/packages/@aws-cdk/aws-elasticsearch/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-elasticsearch/.npmignore +++ b/packages/@aws-cdk/aws-elasticsearch/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-emr/.npmignore b/packages/@aws-cdk/aws-emr/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-emr/.npmignore +++ b/packages/@aws-cdk/aws-emr/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-events-targets/.npmignore b/packages/@aws-cdk/aws-events-targets/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-events-targets/.npmignore +++ b/packages/@aws-cdk/aws-events-targets/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-events/.npmignore b/packages/@aws-cdk/aws-events/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-events/.npmignore +++ b/packages/@aws-cdk/aws-events/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eventschemas/.npmignore b/packages/@aws-cdk/aws-eventschemas/.npmignore index 8ac959aca8fa5..683e3e0847e1f 100644 --- a/packages/@aws-cdk/aws-eventschemas/.npmignore +++ b/packages/@aws-cdk/aws-eventschemas/.npmignore @@ -20,3 +20,6 @@ tsconfig.json !.jsii .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-fms/.npmignore b/packages/@aws-cdk/aws-fms/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-fms/.npmignore +++ b/packages/@aws-cdk/aws-fms/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-fsx/.npmignore b/packages/@aws-cdk/aws-fsx/.npmignore index c0fc6f9e7667f..b0edf81a01371 100644 --- a/packages/@aws-cdk/aws-fsx/.npmignore +++ b/packages/@aws-cdk/aws-fsx/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-gamelift/.npmignore b/packages/@aws-cdk/aws-gamelift/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-gamelift/.npmignore +++ b/packages/@aws-cdk/aws-gamelift/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-globalaccelerator/.npmignore b/packages/@aws-cdk/aws-globalaccelerator/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-globalaccelerator/.npmignore +++ b/packages/@aws-cdk/aws-globalaccelerator/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-glue/.npmignore b/packages/@aws-cdk/aws-glue/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-glue/.npmignore +++ b/packages/@aws-cdk/aws-glue/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-greengrass/.npmignore b/packages/@aws-cdk/aws-greengrass/.npmignore index c0fc6f9e7667f..b0edf81a01371 100644 --- a/packages/@aws-cdk/aws-greengrass/.npmignore +++ b/packages/@aws-cdk/aws-greengrass/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-guardduty/.npmignore b/packages/@aws-cdk/aws-guardduty/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-guardduty/.npmignore +++ b/packages/@aws-cdk/aws-guardduty/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iam/.npmignore b/packages/@aws-cdk/aws-iam/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-iam/.npmignore +++ b/packages/@aws-cdk/aws-iam/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder/.npmignore b/packages/@aws-cdk/aws-imagebuilder/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-imagebuilder/.npmignore +++ b/packages/@aws-cdk/aws-imagebuilder/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-inspector/.npmignore b/packages/@aws-cdk/aws-inspector/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-inspector/.npmignore +++ b/packages/@aws-cdk/aws-inspector/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iot/.npmignore b/packages/@aws-cdk/aws-iot/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-iot/.npmignore +++ b/packages/@aws-cdk/aws-iot/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iot1click/.npmignore b/packages/@aws-cdk/aws-iot1click/.npmignore index 8afbe60698fb4..ac1c98567f9a5 100644 --- a/packages/@aws-cdk/aws-iot1click/.npmignore +++ b/packages/@aws-cdk/aws-iot1click/.npmignore @@ -24,3 +24,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iotanalytics/.npmignore b/packages/@aws-cdk/aws-iotanalytics/.npmignore index c0fc6f9e7667f..b0edf81a01371 100644 --- a/packages/@aws-cdk/aws-iotanalytics/.npmignore +++ b/packages/@aws-cdk/aws-iotanalytics/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iotevents/.npmignore b/packages/@aws-cdk/aws-iotevents/.npmignore index d04d75fba5945..2e1e60862c02c 100644 --- a/packages/@aws-cdk/aws-iotevents/.npmignore +++ b/packages/@aws-cdk/aws-iotevents/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iotthingsgraph/.npmignore b/packages/@aws-cdk/aws-iotthingsgraph/.npmignore index 2b093ce17a11b..5177fc0435bf1 100644 --- a/packages/@aws-cdk/aws-iotthingsgraph/.npmignore +++ b/packages/@aws-cdk/aws-iotthingsgraph/.npmignore @@ -24,3 +24,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-kinesis/.npmignore b/packages/@aws-cdk/aws-kinesis/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-kinesis/.npmignore +++ b/packages/@aws-cdk/aws-kinesis/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-kinesisanalytics/.npmignore b/packages/@aws-cdk/aws-kinesisanalytics/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics/.npmignore +++ b/packages/@aws-cdk/aws-kinesisanalytics/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-kinesisfirehose/.npmignore b/packages/@aws-cdk/aws-kinesisfirehose/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose/.npmignore +++ b/packages/@aws-cdk/aws-kinesisfirehose/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-kms/.npmignore b/packages/@aws-cdk/aws-kms/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-kms/.npmignore +++ b/packages/@aws-cdk/aws-kms/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lakeformation/.npmignore b/packages/@aws-cdk/aws-lakeformation/.npmignore index d04d75fba5945..2e1e60862c02c 100644 --- a/packages/@aws-cdk/aws-lakeformation/.npmignore +++ b/packages/@aws-cdk/aws-lakeformation/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-destinations/.npmignore b/packages/@aws-cdk/aws-lambda-destinations/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-lambda-destinations/.npmignore +++ b/packages/@aws-cdk/aws-lambda-destinations/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-event-sources/.npmignore b/packages/@aws-cdk/aws-lambda-event-sources/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/.npmignore +++ b/packages/@aws-cdk/aws-lambda-event-sources/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-nodejs/.npmignore b/packages/@aws-cdk/aws-lambda-nodejs/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/.npmignore +++ b/packages/@aws-cdk/aws-lambda-nodejs/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/.npmignore b/packages/@aws-cdk/aws-lambda/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-lambda/.npmignore +++ b/packages/@aws-cdk/aws-lambda/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-logs-destinations/.npmignore b/packages/@aws-cdk/aws-logs-destinations/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-logs-destinations/.npmignore +++ b/packages/@aws-cdk/aws-logs-destinations/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-logs/.npmignore b/packages/@aws-cdk/aws-logs/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-logs/.npmignore +++ b/packages/@aws-cdk/aws-logs/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-macie/.npmignore b/packages/@aws-cdk/aws-macie/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-macie/.npmignore +++ b/packages/@aws-cdk/aws-macie/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-managedblockchain/.npmignore b/packages/@aws-cdk/aws-managedblockchain/.npmignore index d04d75fba5945..2e1e60862c02c 100644 --- a/packages/@aws-cdk/aws-managedblockchain/.npmignore +++ b/packages/@aws-cdk/aws-managedblockchain/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-mediaconvert/.npmignore b/packages/@aws-cdk/aws-mediaconvert/.npmignore index 8ac959aca8fa5..683e3e0847e1f 100644 --- a/packages/@aws-cdk/aws-mediaconvert/.npmignore +++ b/packages/@aws-cdk/aws-mediaconvert/.npmignore @@ -20,3 +20,6 @@ tsconfig.json !.jsii .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-medialive/.npmignore b/packages/@aws-cdk/aws-medialive/.npmignore index d04d75fba5945..2e1e60862c02c 100644 --- a/packages/@aws-cdk/aws-medialive/.npmignore +++ b/packages/@aws-cdk/aws-medialive/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-mediastore/.npmignore b/packages/@aws-cdk/aws-mediastore/.npmignore index d04d75fba5945..2e1e60862c02c 100644 --- a/packages/@aws-cdk/aws-mediastore/.npmignore +++ b/packages/@aws-cdk/aws-mediastore/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-msk/.npmignore b/packages/@aws-cdk/aws-msk/.npmignore index 2b093ce17a11b..5177fc0435bf1 100644 --- a/packages/@aws-cdk/aws-msk/.npmignore +++ b/packages/@aws-cdk/aws-msk/.npmignore @@ -24,3 +24,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-neptune/.npmignore b/packages/@aws-cdk/aws-neptune/.npmignore index 8afbe60698fb4..ac1c98567f9a5 100644 --- a/packages/@aws-cdk/aws-neptune/.npmignore +++ b/packages/@aws-cdk/aws-neptune/.npmignore @@ -24,3 +24,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-networkmanager/.npmignore b/packages/@aws-cdk/aws-networkmanager/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-networkmanager/.npmignore +++ b/packages/@aws-cdk/aws-networkmanager/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-opsworks/.npmignore b/packages/@aws-cdk/aws-opsworks/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-opsworks/.npmignore +++ b/packages/@aws-cdk/aws-opsworks/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-opsworkscm/.npmignore b/packages/@aws-cdk/aws-opsworkscm/.npmignore index c0fc6f9e7667f..b0edf81a01371 100644 --- a/packages/@aws-cdk/aws-opsworkscm/.npmignore +++ b/packages/@aws-cdk/aws-opsworkscm/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-pinpoint/.npmignore b/packages/@aws-cdk/aws-pinpoint/.npmignore index 2b093ce17a11b..5177fc0435bf1 100644 --- a/packages/@aws-cdk/aws-pinpoint/.npmignore +++ b/packages/@aws-cdk/aws-pinpoint/.npmignore @@ -24,3 +24,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-pinpointemail/.npmignore b/packages/@aws-cdk/aws-pinpointemail/.npmignore index d04d75fba5945..2e1e60862c02c 100644 --- a/packages/@aws-cdk/aws-pinpointemail/.npmignore +++ b/packages/@aws-cdk/aws-pinpointemail/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-qldb/.npmignore b/packages/@aws-cdk/aws-qldb/.npmignore index d04d75fba5945..2e1e60862c02c 100644 --- a/packages/@aws-cdk/aws-qldb/.npmignore +++ b/packages/@aws-cdk/aws-qldb/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ram/.npmignore b/packages/@aws-cdk/aws-ram/.npmignore index c0fc6f9e7667f..b0edf81a01371 100644 --- a/packages/@aws-cdk/aws-ram/.npmignore +++ b/packages/@aws-cdk/aws-ram/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-rds/.npmignore b/packages/@aws-cdk/aws-rds/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-rds/.npmignore +++ b/packages/@aws-cdk/aws-rds/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/.npmignore b/packages/@aws-cdk/aws-redshift/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-redshift/.npmignore +++ b/packages/@aws-cdk/aws-redshift/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-resourcegroups/.npmignore b/packages/@aws-cdk/aws-resourcegroups/.npmignore index fb37683c5a457..2f1ff45adc883 100644 --- a/packages/@aws-cdk/aws-resourcegroups/.npmignore +++ b/packages/@aws-cdk/aws-resourcegroups/.npmignore @@ -21,3 +21,6 @@ tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-robomaker/.npmignore b/packages/@aws-cdk/aws-robomaker/.npmignore index c0fc6f9e7667f..b0edf81a01371 100644 --- a/packages/@aws-cdk/aws-robomaker/.npmignore +++ b/packages/@aws-cdk/aws-robomaker/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-patterns/.npmignore b/packages/@aws-cdk/aws-route53-patterns/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-route53-patterns/.npmignore +++ b/packages/@aws-cdk/aws-route53-patterns/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-targets/.npmignore b/packages/@aws-cdk/aws-route53-targets/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-route53-targets/.npmignore +++ b/packages/@aws-cdk/aws-route53-targets/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53/.npmignore b/packages/@aws-cdk/aws-route53/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-route53/.npmignore +++ b/packages/@aws-cdk/aws-route53/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53resolver/.npmignore b/packages/@aws-cdk/aws-route53resolver/.npmignore index c0fc6f9e7667f..b0edf81a01371 100644 --- a/packages/@aws-cdk/aws-route53resolver/.npmignore +++ b/packages/@aws-cdk/aws-route53resolver/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-s3-assets/.npmignore b/packages/@aws-cdk/aws-s3-assets/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-s3-assets/.npmignore +++ b/packages/@aws-cdk/aws-s3-assets/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-s3-deployment/.npmignore b/packages/@aws-cdk/aws-s3-deployment/.npmignore index 1ff88035fd2ad..d1bc4d39e6428 100644 --- a/packages/@aws-cdk/aws-s3-deployment/.npmignore +++ b/packages/@aws-cdk/aws-s3-deployment/.npmignore @@ -21,3 +21,6 @@ lambda/*.sh tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-s3-notifications/.npmignore b/packages/@aws-cdk/aws-s3-notifications/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-s3-notifications/.npmignore +++ b/packages/@aws-cdk/aws-s3-notifications/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-s3/.npmignore b/packages/@aws-cdk/aws-s3/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-s3/.npmignore +++ b/packages/@aws-cdk/aws-s3/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-sagemaker/.npmignore b/packages/@aws-cdk/aws-sagemaker/.npmignore index b033e481c6000..2f6c8553a5830 100644 --- a/packages/@aws-cdk/aws-sagemaker/.npmignore +++ b/packages/@aws-cdk/aws-sagemaker/.npmignore @@ -24,3 +24,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-sam/.npmignore b/packages/@aws-cdk/aws-sam/.npmignore index 8afbe60698fb4..ac1c98567f9a5 100644 --- a/packages/@aws-cdk/aws-sam/.npmignore +++ b/packages/@aws-cdk/aws-sam/.npmignore @@ -24,3 +24,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-sdb/.npmignore b/packages/@aws-cdk/aws-sdb/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-sdb/.npmignore +++ b/packages/@aws-cdk/aws-sdb/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-secretsmanager/.npmignore b/packages/@aws-cdk/aws-secretsmanager/.npmignore index dd7e4908d99e4..af5cffcab06c1 100644 --- a/packages/@aws-cdk/aws-secretsmanager/.npmignore +++ b/packages/@aws-cdk/aws-secretsmanager/.npmignore @@ -22,3 +22,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-securityhub/.npmignore b/packages/@aws-cdk/aws-securityhub/.npmignore index d04d75fba5945..2e1e60862c02c 100644 --- a/packages/@aws-cdk/aws-securityhub/.npmignore +++ b/packages/@aws-cdk/aws-securityhub/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalog/.npmignore b/packages/@aws-cdk/aws-servicecatalog/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-servicecatalog/.npmignore +++ b/packages/@aws-cdk/aws-servicecatalog/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicediscovery/.npmignore b/packages/@aws-cdk/aws-servicediscovery/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-servicediscovery/.npmignore +++ b/packages/@aws-cdk/aws-servicediscovery/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ses-actions/.npmignore b/packages/@aws-cdk/aws-ses-actions/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-ses-actions/.npmignore +++ b/packages/@aws-cdk/aws-ses-actions/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ses/.npmignore b/packages/@aws-cdk/aws-ses/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-ses/.npmignore +++ b/packages/@aws-cdk/aws-ses/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-sns-subscriptions/.npmignore b/packages/@aws-cdk/aws-sns-subscriptions/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-sns-subscriptions/.npmignore +++ b/packages/@aws-cdk/aws-sns-subscriptions/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-sns/.npmignore b/packages/@aws-cdk/aws-sns/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-sns/.npmignore +++ b/packages/@aws-cdk/aws-sns/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-sqs/.npmignore b/packages/@aws-cdk/aws-sqs/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-sqs/.npmignore +++ b/packages/@aws-cdk/aws-sqs/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ssm/.npmignore b/packages/@aws-cdk/aws-ssm/.npmignore index 174864d493a79..fe4df9a06d9a9 100644 --- a/packages/@aws-cdk/aws-ssm/.npmignore +++ b/packages/@aws-cdk/aws-ssm/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/.npmignore b/packages/@aws-cdk/aws-stepfunctions-tasks/.npmignore index 34ff973619988..36fe3528aa4c6 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/.npmignore +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/.npmignore @@ -19,3 +19,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-stepfunctions/.npmignore b/packages/@aws-cdk/aws-stepfunctions/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-stepfunctions/.npmignore +++ b/packages/@aws-cdk/aws-stepfunctions/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-synthetics/.npmignore b/packages/@aws-cdk/aws-synthetics/.npmignore index 90dc55901a24e..1bd81793f7aa0 100644 --- a/packages/@aws-cdk/aws-synthetics/.npmignore +++ b/packages/@aws-cdk/aws-synthetics/.npmignore @@ -20,4 +20,6 @@ dist tsconfig.json .eslintrc.js -jest.config.js \ No newline at end of file +jest.config.js +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-transfer/.npmignore b/packages/@aws-cdk/aws-transfer/.npmignore index d04d75fba5945..2e1e60862c02c 100644 --- a/packages/@aws-cdk/aws-transfer/.npmignore +++ b/packages/@aws-cdk/aws-transfer/.npmignore @@ -23,3 +23,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-waf/.npmignore b/packages/@aws-cdk/aws-waf/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-waf/.npmignore +++ b/packages/@aws-cdk/aws-waf/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-wafregional/.npmignore b/packages/@aws-cdk/aws-wafregional/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-wafregional/.npmignore +++ b/packages/@aws-cdk/aws-wafregional/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-wafv2/.npmignore b/packages/@aws-cdk/aws-wafv2/.npmignore index 8ac959aca8fa5..683e3e0847e1f 100644 --- a/packages/@aws-cdk/aws-wafv2/.npmignore +++ b/packages/@aws-cdk/aws-wafv2/.npmignore @@ -20,3 +20,6 @@ tsconfig.json !.jsii .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/aws-workspaces/.npmignore b/packages/@aws-cdk/aws-workspaces/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/aws-workspaces/.npmignore +++ b/packages/@aws-cdk/aws-workspaces/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/cdk-assets-schema/.npmignore b/packages/@aws-cdk/cdk-assets-schema/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/cdk-assets-schema/.npmignore +++ b/packages/@aws-cdk/cdk-assets-schema/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/cloud-assembly-schema/.npmignore b/packages/@aws-cdk/cloud-assembly-schema/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/cloud-assembly-schema/.npmignore +++ b/packages/@aws-cdk/cloud-assembly-schema/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/cloudformation-diff/.npmignore b/packages/@aws-cdk/cloudformation-diff/.npmignore index 18ab2081759df..f5e2864c265a7 100644 --- a/packages/@aws-cdk/cloudformation-diff/.npmignore +++ b/packages/@aws-cdk/cloudformation-diff/.npmignore @@ -15,3 +15,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/cloudformation-include/.npmignore b/packages/@aws-cdk/cloudformation-include/.npmignore index 72d17ee76a860..b4fa4a2dc1486 100644 --- a/packages/@aws-cdk/cloudformation-include/.npmignore +++ b/packages/@aws-cdk/cloudformation-include/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/core/.npmignore b/packages/@aws-cdk/core/.npmignore index 18605ad3c26cd..d021dc7ac0182 100644 --- a/packages/@aws-cdk/core/.npmignore +++ b/packages/@aws-cdk/core/.npmignore @@ -22,3 +22,6 @@ dist tsconfig.json .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/custom-resources/.npmignore b/packages/@aws-cdk/custom-resources/.npmignore index d21f4808a6c14..8e6cd9397a51c 100644 --- a/packages/@aws-cdk/custom-resources/.npmignore +++ b/packages/@aws-cdk/custom-resources/.npmignore @@ -21,3 +21,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/cx-api/.npmignore b/packages/@aws-cdk/cx-api/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/cx-api/.npmignore +++ b/packages/@aws-cdk/cx-api/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/example-construct-library/.npmignore b/packages/@aws-cdk/example-construct-library/.npmignore index 4e4f173de8358..9a6e1c30b51b7 100644 --- a/packages/@aws-cdk/example-construct-library/.npmignore +++ b/packages/@aws-cdk/example-construct-library/.npmignore @@ -20,3 +20,6 @@ dist tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@aws-cdk/region-info/.npmignore b/packages/@aws-cdk/region-info/.npmignore index 3655c2f7c965a..563a051f5ad88 100644 --- a/packages/@aws-cdk/region-info/.npmignore +++ b/packages/@aws-cdk/region-info/.npmignore @@ -18,3 +18,6 @@ coverage tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/@monocdk-experiment/rewrite-imports/.npmignore b/packages/@monocdk-experiment/rewrite-imports/.npmignore index 8e89ca26ab028..5b887f0a51fee 100644 --- a/packages/@monocdk-experiment/rewrite-imports/.npmignore +++ b/packages/@monocdk-experiment/rewrite-imports/.npmignore @@ -10,3 +10,6 @@ tsconfig.json !*.d.ts .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/aws-cdk/.npmignore b/packages/aws-cdk/.npmignore index 49b9729723982..bb0195dca43a2 100644 --- a/packages/aws-cdk/.npmignore +++ b/packages/aws-cdk/.npmignore @@ -28,3 +28,6 @@ jest.config.js !test/integ/cli-regression-patches/**/* .DS_Store + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/cdk-assets/.npmignore b/packages/cdk-assets/.npmignore index 538c9e1ccc614..8a58a12181aaa 100644 --- a/packages/cdk-assets/.npmignore +++ b/packages/cdk-assets/.npmignore @@ -23,3 +23,6 @@ tsconfig.json !lib/init-templates/**/tsconfig.json .eslintrc.js jest.config.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/monocdk-experiment/.npmignore b/packages/monocdk-experiment/.npmignore index 85a5b1ed52c6b..c044a328472e1 100644 --- a/packages/monocdk-experiment/.npmignore +++ b/packages/monocdk-experiment/.npmignore @@ -20,4 +20,6 @@ tsconfig.json *.tsbuildinfo !.jsii -.eslintrc.js \ No newline at end of file +.eslintrc.js +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/packages/monocdk-experiment/package.json b/packages/monocdk-experiment/package.json index 435d045416c85..71a5dd88067b3 100644 --- a/packages/monocdk-experiment/package.json +++ b/packages/monocdk-experiment/package.json @@ -24,7 +24,9 @@ "compat": "cdk-compat" }, "awslint": { - "exclude": ["*:*"] + "exclude": [ + "*:*" + ] }, "cdk-build": { "eslint": { diff --git a/tools/cdk-build-tools/.npmignore b/tools/cdk-build-tools/.npmignore index db3a4c220e7e6..e73fa5f97606e 100644 --- a/tools/cdk-build-tools/.npmignore +++ b/tools/cdk-build-tools/.npmignore @@ -6,4 +6,6 @@ coverage *.tgz *.snk -.eslintrc.js \ No newline at end of file +.eslintrc.js +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/tools/cdk-integ-tools/.npmignore b/tools/cdk-integ-tools/.npmignore index c996786130653..7025b934b52f4 100644 --- a/tools/cdk-integ-tools/.npmignore +++ b/tools/cdk-integ-tools/.npmignore @@ -8,3 +8,6 @@ coverage .LAST_BUILD *.snk .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/tools/cfn2ts/.npmignore b/tools/cfn2ts/.npmignore index c996786130653..7025b934b52f4 100644 --- a/tools/cfn2ts/.npmignore +++ b/tools/cfn2ts/.npmignore @@ -8,3 +8,6 @@ coverage .LAST_BUILD *.snk .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/tools/pkglint/lib/rules.ts b/tools/pkglint/lib/rules.ts index d52dfc9b6a672..f47154f7c1181 100644 --- a/tools/pkglint/lib/rules.ts +++ b/tools/pkglint/lib/rules.ts @@ -47,6 +47,37 @@ export class DescriptionIsRequired extends ValidationRule { } } +/** + * Verify cdk.out directory is included in npmignore since we should not be + * publihsing it. + */ +export class CdkOutMustBeNpmIgnored extends ValidationRule { + + public readonly name = 'package-info/npm-ignore-cdk-out'; + + public validate(pkg: PackageJson): void { + + const npmIgnorePath = path.join(pkg.packageRoot, '.npmignore'); + + if (fs.existsSync(npmIgnorePath)) { + + const npmIgnore = fs.readFileSync(npmIgnorePath); + + if (!npmIgnore.includes('**/cdk.out')) { + pkg.report({ + ruleName: this.name, + message: `${npmIgnorePath}: Must exclude **/cdk.out`, + fix: () => fs.writeFileSync( + npmIgnorePath, + `${npmIgnore}\n# exclude cdk artifacts\n**/cdk.out` + ) + }); + } + } + } + +} + /** * Repository must be our GitHub repo */ diff --git a/tools/pkgtools/.npmignore b/tools/pkgtools/.npmignore index c996786130653..7025b934b52f4 100644 --- a/tools/pkgtools/.npmignore +++ b/tools/pkgtools/.npmignore @@ -8,3 +8,6 @@ coverage .LAST_BUILD *.snk .eslintrc.js + +# exclude cdk artifacts +**/cdk.out \ No newline at end of file diff --git a/tools/yarn-cling/.npmignore b/tools/yarn-cling/.npmignore index af12b026f1401..4d83036ddf1ae 100644 --- a/tools/yarn-cling/.npmignore +++ b/tools/yarn-cling/.npmignore @@ -9,4 +9,6 @@ coverage *.snk jest.config.js -.eslintrc.js \ No newline at end of file +.eslintrc.js +# exclude cdk artifacts +**/cdk.out \ No newline at end of file From 3698f47bad970be6f3765e4f145d64f59ded4276 Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Tue, 30 Jun 2020 11:43:24 +0100 Subject: [PATCH 45/55] feat(autoscaling): bring your own security group Allow specific a Security Group (`ISecurityGroup`) when defining an AutoScalingGroup. This allows passing in a group created in the same stack or passing in an imported group. --- packages/@aws-cdk/aws-autoscaling/README.md | 17 +++++++++++--- .../aws-autoscaling/lib/auto-scaling-group.ts | 9 +++++++- .../test/test.auto-scaling-group.ts | 22 +++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/aws-autoscaling/README.md b/packages/@aws-cdk/aws-autoscaling/README.md index ce55c411671f7..44331a3b5b1c3 100644 --- a/packages/@aws-cdk/aws-autoscaling/README.md +++ b/packages/@aws-cdk/aws-autoscaling/README.md @@ -29,9 +29,20 @@ new autoscaling.AutoScalingGroup(this, 'ASG', { }); ``` -> NOTE: AutoScalingGroup has an property called `allowAllOutbound` (allowing the instances to contact the -> internet) which is set to `true` by default. Be sure to set this to `false` if you don't want -> your instances to be able to start arbitrary connections. +NOTE: AutoScalingGroup has an property called `allowAllOutbound` (allowing the instances to contact the +internet) which is set to `true` by default. Be sure to set this to `false` if you don't want +your instances to be able to start arbitrary connections. Alternatively, you can specify an existing security +group to attach to the instances that are launched, rather than have the group create a new one. + +```ts +const mySecurityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {...}); +new autoscaling.AutoScalingGroup(this, 'ASG', { + vpc, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), + machineImage: new ec2.AmazonLinuxImage(), + securityGroup: mySecurityGroup, +}); +``` ### Machine Images (AMIs) diff --git a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts index 31483d53d40a6..4007b60c7ab3a 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -255,6 +255,13 @@ export interface AutoScalingGroupProps extends CommonAutoScalingGroupProps { */ readonly machineImage: ec2.IMachineImage; + /** + * Security group to launch the instances in. + * + * @default - A SecurityGroup will be created if none is specified. + */ + readonly securityGroup?: ec2.ISecurityGroup; + /** * Specific UserData to use * @@ -475,7 +482,7 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements constructor(scope: Construct, id: string, props: AutoScalingGroupProps) { super(scope, id); - this.securityGroup = new ec2.SecurityGroup(this, 'InstanceSecurityGroup', { + this.securityGroup = props.securityGroup || new ec2.SecurityGroup(this, 'InstanceSecurityGroup', { vpc: props.vpc, allowAllOutbound: props.allowAllOutbound !== false, }); diff --git a/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts index faea5fe7cd8f9..05ac3029b6e4c 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts @@ -658,6 +658,28 @@ export = { test.done(); }, + 'an existing security group can be specified instead of auto-created'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = mockVpc(stack); + const securityGroup = ec2.SecurityGroup.fromSecurityGroupId(stack, 'MySG', 'most-secure'); + + // WHEN + new autoscaling.AutoScalingGroup(stack, 'MyASG', { + vpc, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + machineImage: new ec2.AmazonLinuxImage(), + securityGroup, + }); + + // THEN + expect(stack).to(haveResource('AWS::AutoScaling::LaunchConfiguration', { + SecurityGroups: ['most-secure'], + }, + )); + test.done(); + }, + 'an existing role can be specified instead of auto-created'(test: Test) { // GIVEN const stack = new cdk.Stack(); From 719cd1604925cff0380ec3bc08a3a3b049e81528 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Tue, 30 Jun 2020 17:14:20 +0200 Subject: [PATCH 46/55] chore(ec2): convert tests to Jest (#8811) Turn the `aws-ec2` nodeunit test set into a Jest test set. In order to speed up the conversion, I did not actually rewrite the tests. Instead, I added a shim layer which converts between the two APIs. That means we're free to ditch the nodeunit dependency add future tests in Jest format, while spending minimal effort on the conversion. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ec2/.gitignore | 2 + packages/@aws-cdk/aws-ec2/.npmignore | 3 +- packages/@aws-cdk/aws-ec2/jest.config.js | 2 + packages/@aws-cdk/aws-ec2/package.json | 6 +- ...t.bastion-host.ts => bastion-host.test.ts} | 6 +- ...est.connections.ts => connections.test.ts} | 6 +- .../{test.instance.ts => instance.test.ts} | 6 +- packages/@aws-cdk/aws-ec2/test/l1.test.ts | 14 +++ .../aws-ec2/test/machine-image.test.ts | 94 +++++++++++++++ ...network-utils.ts => network-utils.test.ts} | 9 +- ...curity-group.ts => security-group.test.ts} | 6 +- packages/@aws-cdk/aws-ec2/test/test.l1.ts | 19 ---- .../aws-ec2/test/test.machine-image.ts | 107 ------------------ .../{test.userdata.ts => userdata.test.ts} | 6 +- .../test/{test.volume.ts => volume.test.ts} | 43 ++++--- ...ervice.ts => vpc-endpoint-service.test.ts} | 6 +- ...t.vpc-endpoint.ts => vpc-endpoint.test.ts} | 6 +- ...vpc-flow-logs.ts => vpc-flow-logs.test.ts} | 6 +- ...from-lookup.ts => vpc.from-lookup.test.ts} | 6 +- .../aws-ec2/test/{test.vpc.ts => vpc.test.ts} | 6 +- .../aws-ec2/test/{test.vpn.ts => vpn.test.ts} | 6 +- tools/nodeunit-shim/.gitignore | 13 +++ tools/nodeunit-shim/README.md | 80 +++++++++++++ tools/nodeunit-shim/index.ts | 79 +++++++++++++ tools/nodeunit-shim/package.json | 25 ++++ tools/nodeunit-shim/tsconfig.json | 20 ++++ 26 files changed, 392 insertions(+), 190 deletions(-) create mode 100644 packages/@aws-cdk/aws-ec2/jest.config.js rename packages/@aws-cdk/aws-ec2/test/{test.bastion-host.ts => bastion-host.test.ts} (96%) rename packages/@aws-cdk/aws-ec2/test/{test.connections.ts => connections.test.ts} (99%) rename packages/@aws-cdk/aws-ec2/test/{test.instance.ts => instance.test.ts} (99%) create mode 100644 packages/@aws-cdk/aws-ec2/test/l1.test.ts create mode 100644 packages/@aws-cdk/aws-ec2/test/machine-image.test.ts rename packages/@aws-cdk/aws-ec2/test/{test.network-utils.ts => network-utils.test.ts} (98%) rename packages/@aws-cdk/aws-ec2/test/{test.security-group.ts => security-group.test.ts} (99%) delete mode 100644 packages/@aws-cdk/aws-ec2/test/test.l1.ts delete mode 100644 packages/@aws-cdk/aws-ec2/test/test.machine-image.ts rename packages/@aws-cdk/aws-ec2/test/{test.userdata.ts => userdata.test.ts} (99%) rename packages/@aws-cdk/aws-ec2/test/{test.volume.ts => volume.test.ts} (95%) rename packages/@aws-cdk/aws-ec2/test/{test.vpc-endpoint-service.ts => vpc-endpoint-service.test.ts} (98%) rename packages/@aws-cdk/aws-ec2/test/{test.vpc-endpoint.ts => vpc-endpoint.test.ts} (99%) rename packages/@aws-cdk/aws-ec2/test/{test.vpc-flow-logs.ts => vpc-flow-logs.test.ts} (98%) rename packages/@aws-cdk/aws-ec2/test/{test.vpc.from-lookup.ts => vpc.from-lookup.test.ts} (99%) rename packages/@aws-cdk/aws-ec2/test/{test.vpc.ts => vpc.test.ts} (99%) rename packages/@aws-cdk/aws-ec2/test/{test.vpn.ts => vpn.test.ts} (99%) create mode 100644 tools/nodeunit-shim/.gitignore create mode 100644 tools/nodeunit-shim/README.md create mode 100644 tools/nodeunit-shim/index.ts create mode 100644 tools/nodeunit-shim/package.json create mode 100644 tools/nodeunit-shim/tsconfig.json diff --git a/packages/@aws-cdk/aws-ec2/.gitignore b/packages/@aws-cdk/aws-ec2/.gitignore index 97fd430070d42..1d4a8175e1579 100644 --- a/packages/@aws-cdk/aws-ec2/.gitignore +++ b/packages/@aws-cdk/aws-ec2/.gitignore @@ -14,3 +14,5 @@ nyc.config.js .LAST_PACKAGE *.snk !.eslintrc.js + +!jest.config.js \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/.npmignore b/packages/@aws-cdk/aws-ec2/.npmignore index fe4df9a06d9a9..fba0982f5ee45 100644 --- a/packages/@aws-cdk/aws-ec2/.npmignore +++ b/packages/@aws-cdk/aws-ec2/.npmignore @@ -21,4 +21,5 @@ tsconfig.json .eslintrc.js # exclude cdk artifacts -**/cdk.out \ No newline at end of file +**/cdk.out +jest.config.js \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/jest.config.js b/packages/@aws-cdk/aws-ec2/jest.config.js new file mode 100644 index 0000000000000..cd664e1d069e5 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/jest.config.js @@ -0,0 +1,2 @@ +const baseConfig = require('../../../tools/cdk-build-tools/config/jest.config'); +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-ec2/package.json b/packages/@aws-cdk/aws-ec2/package.json index eadb31460c21d..ad6075cc5ec77 100644 --- a/packages/@aws-cdk/aws-ec2/package.json +++ b/packages/@aws-cdk/aws-ec2/package.json @@ -47,7 +47,8 @@ "compat": "cdk-compat" }, "cdk-build": { - "cloudformation": "AWS::EC2" + "cloudformation": "AWS::EC2", + "jest": true }, "keywords": [ "aws", @@ -63,11 +64,10 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/assert": "0.0.0", - "@types/nodeunit": "^0.0.31", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", - "nodeunit": "^0.11.3", + "nodeunit-shim": "0.0.0", "pkglint": "0.0.0", "@aws-cdk/cloud-assembly-schema": "0.0.0" }, diff --git a/packages/@aws-cdk/aws-ec2/test/test.bastion-host.ts b/packages/@aws-cdk/aws-ec2/test/bastion-host.test.ts similarity index 96% rename from packages/@aws-cdk/aws-ec2/test/test.bastion-host.ts rename to packages/@aws-cdk/aws-ec2/test/bastion-host.test.ts index 4345718952364..738b66c3d82cc 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.bastion-host.ts +++ b/packages/@aws-cdk/aws-ec2/test/bastion-host.test.ts @@ -1,9 +1,9 @@ import { expect, haveResource } from '@aws-cdk/assert'; import { Stack } from '@aws-cdk/core'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; import { BastionHostLinux, BlockDeviceVolume, SubnetType, Vpc } from '../lib'; -export = { +nodeunitShim({ 'default instance is created in basic'(test: Test) { // GIVEN const stack = new Stack(); @@ -85,4 +85,4 @@ export = { test.done(); }, -}; +}); diff --git a/packages/@aws-cdk/aws-ec2/test/test.connections.ts b/packages/@aws-cdk/aws-ec2/test/connections.test.ts similarity index 99% rename from packages/@aws-cdk/aws-ec2/test/test.connections.ts rename to packages/@aws-cdk/aws-ec2/test/connections.test.ts index e49cb7ef4281e..2721f073cf6b0 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.connections.ts +++ b/packages/@aws-cdk/aws-ec2/test/connections.test.ts @@ -1,6 +1,6 @@ import { expect, haveResource } from '@aws-cdk/assert'; import { App, ConstructNode, Stack } from '@aws-cdk/core'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; import { Connections, @@ -10,7 +10,7 @@ import { Vpc, } from '../lib'; -export = { +nodeunitShim({ 'peering between two security groups does not recursive infinitely'(test: Test) { // GIVEN const stack = new Stack(undefined, 'TestStack', { env: { account: '12345678', region: 'dummy' }}); @@ -326,7 +326,7 @@ export = { test.done(); }, -}; +}); class SomethingConnectable implements IConnectable { constructor(public readonly connections: Connections) { diff --git a/packages/@aws-cdk/aws-ec2/test/test.instance.ts b/packages/@aws-cdk/aws-ec2/test/instance.test.ts similarity index 99% rename from packages/@aws-cdk/aws-ec2/test/test.instance.ts rename to packages/@aws-cdk/aws-ec2/test/instance.test.ts index 782585960decd..06afe520cb1aa 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.instance.ts +++ b/packages/@aws-cdk/aws-ec2/test/instance.test.ts @@ -2,10 +2,10 @@ import { expect, haveResource } from '@aws-cdk/assert'; import { StringParameter } from '@aws-cdk/aws-ssm'; import * as cxschema from '@aws-cdk/cloud-assembly-schema'; import { Stack } from '@aws-cdk/core'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; import { AmazonLinuxImage, BlockDeviceVolume, EbsDeviceVolumeType, Instance, InstanceClass, InstanceSize, InstanceType, Vpc } from '../lib'; -export = { +nodeunitShim({ 'instance is created correctly'(test: Test) { // GIVEN const stack = new Stack(); @@ -292,4 +292,4 @@ export = { test.done(); }, -}; +}); diff --git a/packages/@aws-cdk/aws-ec2/test/l1.test.ts b/packages/@aws-cdk/aws-ec2/test/l1.test.ts new file mode 100644 index 0000000000000..0124940b6e3fc --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/l1.test.ts @@ -0,0 +1,14 @@ +import * as cdk from '@aws-cdk/core'; +import * as ec2 from '../lib'; + +test('NetworkAclEntry CidrBlock should be optional', () => { + const stack = new cdk.Stack(); + + new ec2.CfnNetworkAclEntry(stack, 'ACL', { + // Note the conspicuous absence of cidrBlock + networkAclId: 'asdf', + protocol: 5, + ruleAction: 'action', + ruleNumber: 1, + }); +}); diff --git a/packages/@aws-cdk/aws-ec2/test/machine-image.test.ts b/packages/@aws-cdk/aws-ec2/test/machine-image.test.ts new file mode 100644 index 0000000000000..f94de3de356fd --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/machine-image.test.ts @@ -0,0 +1,94 @@ +import { App, Stack } from '@aws-cdk/core'; +import * as ec2 from '../lib'; + +let app: App; +let stack: Stack; + +beforeEach(() => { + app = new App(); + stack = new Stack(app, 'Stack', { + env: { account: '1234', region: 'testregion' }, + }); +}); + +test('can make and use a Windows image', () => { + // WHEN + const image = new ec2.GenericWindowsImage({ + testregion: 'ami-1234', + }); + + // THEN + const details = image.getImage(stack); + expect(details.imageId).toEqual('ami-1234'); + expect(details.osType).toEqual(ec2.OperatingSystemType.WINDOWS); +}); + +test('WindowsImage retains userdata if given', () => { + // WHEN + const ud = ec2.UserData.forWindows(); + + const image = new ec2.GenericWindowsImage({ + testregion: 'ami-1234', + }, { + userData: ud, + }); + + // THEN + const details = image.getImage(stack); + expect(details.userData).toEqual(ud); +}); + +test('WindowsImage creates UserData if not given', () => { + // WHEN + const image = new ec2.GenericWindowsImage({ + testregion: 'ami-1234', + }); + + // THEN + const details = image.getImage(stack); + expect(isWindowsUserData(details.userData)).toBeTruthy(); +}); + +test('LookupMachineImage default search', () => { + // GIVEN + + // WHEN + new ec2.LookupMachineImage({ name: 'bla*', owners: ['amazon'] }).getImage(stack); + + // THEN + const missing = app.synth().manifest.missing || []; + expect(missing).toEqual([ + { + key: 'ami:account=1234:filters.image-type.0=machine:filters.name.0=bla*:filters.state.0=available:owners.0=amazon:region=testregion', + props: { + account: '1234', + region: 'testregion', + owners: [ 'amazon' ], + filters: { + 'name': [ 'bla*' ], + 'state': [ 'available' ], + 'image-type': [ 'machine' ], + }, + }, + provider: 'ami', + }, + ]); +}); + +test('LookupMachineImage creates correct type of UserData', () => { + // WHEN + const linuxDetails = new ec2.LookupMachineImage({ name: 'bla*', owners: ['amazon'] }).getImage(stack); + const windowsDetails = new ec2.LookupMachineImage({ name: 'bla*', owners: ['amazon'], windows: true }).getImage(stack); + + // THEN + expect(isWindowsUserData(windowsDetails.userData)).toBeTruthy(); + expect(isLinuxUserData(linuxDetails.userData)).toBeTruthy(); +}); + +function isWindowsUserData(ud: ec2.UserData) { + return ud.render().indexOf('powershell') > -1; +} + +function isLinuxUserData(ud: ec2.UserData) { + return ud.render().indexOf('bash') > -1; +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/test.network-utils.ts b/packages/@aws-cdk/aws-ec2/test/network-utils.test.ts similarity index 98% rename from packages/@aws-cdk/aws-ec2/test/test.network-utils.ts rename to packages/@aws-cdk/aws-ec2/test/network-utils.test.ts index 55e3433f9fb5e..b1904331644f2 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.network-utils.ts +++ b/packages/@aws-cdk/aws-ec2/test/network-utils.test.ts @@ -1,4 +1,4 @@ -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; import { CidrBlock, InvalidCidrRangeError, @@ -6,8 +6,7 @@ import { NetworkUtils, } from '../lib/network-util'; -export = { - +nodeunitShim({ IP: { 'should convert a valid IP Address to an integer'(test: Test) { test.strictEqual(NetworkUtils.ipToNum('174.66.173.168'), 2923605416); @@ -16,7 +15,7 @@ export = { 'should throw on invalid IP Address'(test: Test) { test.throws(() => { NetworkUtils.ipToNum('174.266.173.168'); - }, Error, 'is not valid'); + }, 'is not valid'); test.done(); }, 'should convert a valid IP integer to a staring'(test: Test) { @@ -188,4 +187,4 @@ export = { test.strictEqual(18, builder5.maskForRemainingSubnets(3)); test.done(); }, }, -}; +}); diff --git a/packages/@aws-cdk/aws-ec2/test/test.security-group.ts b/packages/@aws-cdk/aws-ec2/test/security-group.test.ts similarity index 99% rename from packages/@aws-cdk/aws-ec2/test/test.security-group.ts rename to packages/@aws-cdk/aws-ec2/test/security-group.test.ts index b2ec76bf28e7b..0fb952ea1b36c 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.security-group.ts +++ b/packages/@aws-cdk/aws-ec2/test/security-group.test.ts @@ -1,9 +1,9 @@ import { expect, haveResource, not } from '@aws-cdk/assert'; import { Intrinsic, Lazy, Stack, Token } from '@aws-cdk/core'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; import { Peer, Port, SecurityGroup, Vpc } from '../lib'; -export = { +nodeunitShim({ 'security group can allows all outbound traffic by default'(test: Test) { // GIVEN const stack = new Stack(); @@ -293,4 +293,4 @@ export = { test.done(); }, }, -}; +}); diff --git a/packages/@aws-cdk/aws-ec2/test/test.l1.ts b/packages/@aws-cdk/aws-ec2/test/test.l1.ts deleted file mode 100644 index 8fab621dac5ea..0000000000000 --- a/packages/@aws-cdk/aws-ec2/test/test.l1.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as cdk from '@aws-cdk/core'; -import { Test } from 'nodeunit'; -import * as ec2 from '../lib'; - -export = { - 'NetworkAclEntry CidrBlock should be optional'(test: Test) { - const stack = new cdk.Stack(); - - new ec2.CfnNetworkAclEntry(stack, 'ACL', { - // Note the conspicuous absence of cidrBlock - networkAclId: 'asdf', - protocol: 5, - ruleAction: 'action', - ruleNumber: 1, - }); - - test.done(); - }, -}; diff --git a/packages/@aws-cdk/aws-ec2/test/test.machine-image.ts b/packages/@aws-cdk/aws-ec2/test/test.machine-image.ts deleted file mode 100644 index dce4195a868f8..0000000000000 --- a/packages/@aws-cdk/aws-ec2/test/test.machine-image.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { App, Stack } from '@aws-cdk/core'; -import { Test } from 'nodeunit'; -import * as ec2 from '../lib'; - -let app: App; -let stack: Stack; - -export = { - 'setUp'(cb: () => void) { - app = new App(); - stack = new Stack(app, 'Stack', { - env: { account: '1234', region: 'testregion' }, - }); - - cb(); - }, - 'can make and use a Windows image'(test: Test) { - // WHEN - const image = new ec2.GenericWindowsImage({ - testregion: 'ami-1234', - }); - - // THEN - const details = image.getImage(stack); - test.equals(details.imageId, 'ami-1234'); - test.equals(details.osType, ec2.OperatingSystemType.WINDOWS); - - test.done(); - }, - - 'WindowsImage retains userdata if given'(test: Test) { - // WHEN - const ud = ec2.UserData.forWindows(); - - const image = new ec2.GenericWindowsImage({ - testregion: 'ami-1234', - }, { - userData: ud, - }); - - // THEN - const details = image.getImage(stack); - test.equals(details.userData, ud); - - test.done(); - }, - - 'WindowsImage creates UserData if not given'(test: Test) { - // WHEN - const image = new ec2.GenericWindowsImage({ - testregion: 'ami-1234', - }); - - // THEN - const details = image.getImage(stack); - test.ok(isWindowsUserData(details.userData)); - - test.done(); - }, - - 'LookupMachineImage default search'(test: Test) { - // GIVEN - - // WHEN - new ec2.LookupMachineImage({ name: 'bla*', owners: ['amazon'] }).getImage(stack); - - // THEN - const missing = app.synth().manifest.missing || []; - test.deepEqual(missing, [ - { - key: 'ami:account=1234:filters.image-type.0=machine:filters.name.0=bla*:filters.state.0=available:owners.0=amazon:region=testregion', - props: { - account: '1234', - region: 'testregion', - owners: [ 'amazon' ], - filters: { - 'name': [ 'bla*' ], - 'state': [ 'available' ], - 'image-type': [ 'machine' ], - }, - }, - provider: 'ami', - }, - ]); - - test.done(); - }, - - 'LookupMachineImage creates correct type of UserData'(test: Test) { - // WHEN - const linuxDetails = new ec2.LookupMachineImage({ name: 'bla*', owners: ['amazon'] }).getImage(stack); - const windowsDetails = new ec2.LookupMachineImage({ name: 'bla*', owners: ['amazon'], windows: true }).getImage(stack); - - // THEN - test.ok(isWindowsUserData(windowsDetails.userData)); - test.ok(isLinuxUserData(linuxDetails.userData)); - test.done(); - }, -}; - -function isWindowsUserData(ud: ec2.UserData) { - return ud.render().indexOf('powershell') > -1; -} - -function isLinuxUserData(ud: ec2.UserData) { - return ud.render().indexOf('bash') > -1; -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/test.userdata.ts b/packages/@aws-cdk/aws-ec2/test/userdata.test.ts similarity index 99% rename from packages/@aws-cdk/aws-ec2/test/test.userdata.ts rename to packages/@aws-cdk/aws-ec2/test/userdata.test.ts index d487eb9bb54ed..4f4a357d55e37 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.userdata.ts +++ b/packages/@aws-cdk/aws-ec2/test/userdata.test.ts @@ -1,9 +1,9 @@ import { Bucket } from '@aws-cdk/aws-s3'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; import { Stack } from '../../core/lib'; import * as ec2 from '../lib'; -export = { +nodeunitShim({ 'can create Windows user data'(test: Test) { // GIVEN @@ -273,4 +273,4 @@ export = { test.done(); }, -}; +}); diff --git a/packages/@aws-cdk/aws-ec2/test/test.volume.ts b/packages/@aws-cdk/aws-ec2/test/volume.test.ts similarity index 95% rename from packages/@aws-cdk/aws-ec2/test/test.volume.ts rename to packages/@aws-cdk/aws-ec2/test/volume.test.ts index dbef8b6ecfebe..dbe368285fb40 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.volume.ts +++ b/packages/@aws-cdk/aws-ec2/test/volume.test.ts @@ -10,7 +10,7 @@ import { } from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; import * as cdk from '@aws-cdk/core'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; import { AmazonLinuxGeneration, EbsDeviceVolumeType, @@ -21,7 +21,7 @@ import { Vpc, } from '../lib'; -export = { +nodeunitShim({ 'basic volume'(test: Test) { // GIVEN const stack = new cdk.Stack(); @@ -1182,13 +1182,13 @@ export = { volumeId: ' vol-0123456789abcdefABCDEF', // leading invalid character(s) availabilityZone: 'us-east-1a', }); - }, Error, '`volumeId` does not match expected pattern. Expected `vol-` (ex: `vol-05abe246af`) or a Token'); + }, '`volumeId` does not match expected pattern. Expected `vol-` (ex: `vol-05abe246af`) or a Token'); test.throws(() => { Volume.fromVolumeAttributes(stack, `Volume${idx++}`, { volumeId: 'vol-0123456789abcdefABCDEF ', // trailing invalid character(s) availabilityZone: 'us-east-1a', }); - }, Error, '`volumeId` does not match expected pattern. Expected `vol-` (ex: `vol-05abe246af`) or a Token'); + }, '`volumeId` does not match expected pattern. Expected `vol-` (ex: `vol-05abe246af`) or a Token'); test.done(); }, @@ -1203,7 +1203,7 @@ export = { new Volume(stack, `Volume${idx++}`, { availabilityZone: 'us-east-1a', }); - }, Error, 'Must provide at least one of `size` or `snapshotId`'); + }, 'Must provide at least one of `size` or `snapshotId`'); test.doesNotThrow(() => { new Volume(stack, `Volume${idx++}`, { availabilityZone: 'us-east-1a', @@ -1230,7 +1230,7 @@ export = { size: cdk.Size.gibibytes(8), encryptionKey: key, }); - }, Error, '`encrypted` must be true when providing an `encryptionKey`.'); + }, '`encrypted` must be true when providing an `encryptionKey`.'); test.throws(() => { new Volume(stack, `Volume${idx++}`, { availabilityZone: 'us-east-1a', @@ -1238,7 +1238,7 @@ export = { encrypted: false, encryptionKey: key, }); - }, Error, '`encrypted` must be true when providing an `encryptionKey`.'); + }, '`encrypted` must be true when providing an `encryptionKey`.'); test.doesNotThrow(() => { new Volume(stack, `Volume${idx++}`, { availabilityZone: 'us-east-1a', @@ -1272,22 +1272,22 @@ export = { new Volume(stack, `Volume${idx++}`, { availabilityZone: 'us-east-1', }); - }, Error, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); + }, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); test.throws(() => { new Volume(stack, `Volume${idx++}`, { availabilityZone: 'Virginia', }); - }, Error, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); + }, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); test.throws(() => { new Volume(stack, `Volume${idx++}`, { availabilityZone: ' us-east-1a', // leading character(s) }); - }, Error, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); + }, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); test.throws(() => { new Volume(stack, `Volume${idx++}`, { availabilityZone: 'us-east-1a ', // trailing character(s) }); - }, Error, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); + }, '`availabilityZone` is a region followed by a letter (ex: `us-east-1a`), or a token'); test.done(); }, @@ -1320,13 +1320,13 @@ export = { availabilityZone: 'us-east-1a', snapshotId: ' snap-1234', // leading extra character(s) }); - }, Error, '`snapshotId` does match expected pattern. Expected `snap-` (ex: `snap-05abe246af`) or Token'); + }, '`snapshotId` does match expected pattern. Expected `snap-` (ex: `snap-05abe246af`) or Token'); test.throws(() => { new Volume(stack, `Volume${idx++}`, { availabilityZone: 'us-east-1a', snapshotId: 'snap-1234 ', // trailing extra character(s) }); - }, Error, '`snapshotId` does match expected pattern. Expected `snap-` (ex: `snap-05abe246af`) or Token'); + }, '`snapshotId` does match expected pattern. Expected `snap-` (ex: `snap-05abe246af`) or Token'); test.done(); }, @@ -1351,7 +1351,7 @@ export = { iops: 100, volumeType, }); - }, Error, '`iops` may only be specified if the `volumeType` is `PROVISIONED_IOPS_SSD`/`IO1`'); + }, '`iops` may only be specified if the `volumeType` is `PROVISIONED_IOPS_SSD`/`IO1`'); } // Test: iops in range @@ -1362,7 +1362,7 @@ export = { iops: 99, volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, }); - }, Error, '`iops` must be in the range 100 to 64,000, inclusive.'); + }, '`iops` must be in the range 100 to 64,000, inclusive.'); test.doesNotThrow(() => { new Volume(stack, `Volume${idx++}`, { availabilityZone: 'us-east-1a', @@ -1386,7 +1386,7 @@ export = { iops: 64001, volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, }); - }, Error, '`iops` must be in the range 100 to 64,000, inclusive.'); + }, '`iops` must be in the range 100 to 64,000, inclusive.'); // Test: iops ratio test.doesNotThrow(() => { @@ -1404,7 +1404,7 @@ export = { iops: 501, volumeType: EbsDeviceVolumeType.PROVISIONED_IOPS_SSD, }); - }, Error, '`iops` has a maximum ratio of 50 IOPS/GiB.'); + }, '`iops` has a maximum ratio of 50 IOPS/GiB.'); test.done(); }, @@ -1425,11 +1425,10 @@ export = { new Volume(stack, `Volume${idx++}`, { availabilityZone: 'us-east-1a', size: cdk.Size.gibibytes(500), - iops: 100, enableMultiAttach: true, volumeType, }); - }, Error, 'multi-attach is supported exclusively on `PROVISIONED_IOPS_SSD` volumes.'); + }, 'multi-attach is supported exclusively on `PROVISIONED_IOPS_SSD` volumes.'); } test.done(); @@ -1457,7 +1456,7 @@ export = { size: cdk.Size.gibibytes(min - 1), volumeType, }); - }, Error, `\`${volumeType}\` volumes must be between ${min} GiB and ${max} GiB in size.`); + }, `\`${volumeType}\` volumes must be between ${min} GiB and ${max} GiB in size.`); test.doesNotThrow(() => { new Volume(stack, `Volume${idx++}`, { availabilityZone: 'us-east-1a', @@ -1478,10 +1477,10 @@ export = { size: cdk.Size.gibibytes(max + 1), volumeType, }); - }, Error, `\`${volumeType}\` volumes must be between ${min} GiB and ${max} GiB in size.`); + }, `\`${volumeType}\` volumes must be between ${min} GiB and ${max} GiB in size.`); } test.done(); }, -}; \ No newline at end of file +}); diff --git a/packages/@aws-cdk/aws-ec2/test/test.vpc-endpoint-service.ts b/packages/@aws-cdk/aws-ec2/test/vpc-endpoint-service.test.ts similarity index 98% rename from packages/@aws-cdk/aws-ec2/test/test.vpc-endpoint-service.ts rename to packages/@aws-cdk/aws-ec2/test/vpc-endpoint-service.test.ts index 7d4439bf0bfc2..f7840f14829a2 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.vpc-endpoint-service.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc-endpoint-service.test.ts @@ -1,7 +1,7 @@ import { expect, haveResource } from '@aws-cdk/assert'; import { ArnPrincipal } from '@aws-cdk/aws-iam'; import { Stack } from '@aws-cdk/core'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; // tslint:disable-next-line:max-line-length import { IVpcEndpointServiceLoadBalancer, Vpc, VpcEndpointService } from '../lib'; @@ -19,7 +19,7 @@ class DummyEndpointLoadBalacer implements IVpcEndpointServiceLoadBalancer { } } -export = { +nodeunitShim({ 'test vpc endpoint service': { 'create endpoint service with no principals'(test: Test) { // GIVEN @@ -104,4 +104,4 @@ export = { test.done(); }, }, -}; \ No newline at end of file +}); diff --git a/packages/@aws-cdk/aws-ec2/test/test.vpc-endpoint.ts b/packages/@aws-cdk/aws-ec2/test/vpc-endpoint.test.ts similarity index 99% rename from packages/@aws-cdk/aws-ec2/test/test.vpc-endpoint.ts rename to packages/@aws-cdk/aws-ec2/test/vpc-endpoint.test.ts index 159447c322749..30c6018c961ac 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.vpc-endpoint.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc-endpoint.test.ts @@ -2,11 +2,11 @@ import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert'; import { AnyPrincipal, PolicyStatement } from '@aws-cdk/aws-iam'; import * as cxschema from '@aws-cdk/cloud-assembly-schema'; import { ContextProvider, Stack } from '@aws-cdk/core'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; // tslint:disable-next-line:max-line-length import { GatewayVpcEndpoint, GatewayVpcEndpointAwsService, InterfaceVpcEndpoint, InterfaceVpcEndpointAwsService, InterfaceVpcEndpointService, SecurityGroup, SubnetType, Vpc } from '../lib'; -export = { +nodeunitShim({ 'gateway endpoint': { 'add an endpoint to a vpc'(test: Test) { // GIVEN @@ -473,4 +473,4 @@ export = { test.done(); }, }, -}; +}); diff --git a/packages/@aws-cdk/aws-ec2/test/test.vpc-flow-logs.ts b/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts similarity index 98% rename from packages/@aws-cdk/aws-ec2/test/test.vpc-flow-logs.ts rename to packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts index 65414e376739d..965c538bab5a0 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.vpc-flow-logs.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc-flow-logs.test.ts @@ -3,10 +3,10 @@ import * as iam from '@aws-cdk/aws-iam'; import * as logs from '@aws-cdk/aws-logs'; import * as s3 from '@aws-cdk/aws-s3'; import { Stack } from '@aws-cdk/core'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; import { FlowLog, FlowLogDestination, FlowLogResourceType, Vpc } from '../lib'; -export = { +nodeunitShim({ 'with defaults set, it successfully creates with cloudwatch logs destination'( test: Test, ) { @@ -155,7 +155,7 @@ export = { ); test.done(); }, -}; +}); function getTestStack(): Stack { return new Stack(undefined, 'TestStack', { diff --git a/packages/@aws-cdk/aws-ec2/test/test.vpc.from-lookup.ts b/packages/@aws-cdk/aws-ec2/test/vpc.from-lookup.test.ts similarity index 99% rename from packages/@aws-cdk/aws-ec2/test/test.vpc.from-lookup.ts rename to packages/@aws-cdk/aws-ec2/test/vpc.from-lookup.test.ts index 2cf0fac4a9e33..170f62f6f61a5 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.vpc.from-lookup.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc.from-lookup.test.ts @@ -1,10 +1,10 @@ import * as cxschema from '@aws-cdk/cloud-assembly-schema'; import { Construct, ContextProvider, GetContextValueOptions, GetContextValueResult, Lazy, Stack } from '@aws-cdk/core'; import * as cxapi from '@aws-cdk/cx-api'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; import { GenericLinuxImage, Instance, InstanceType, SubnetType, Vpc } from '../lib'; -export = { +nodeunitShim({ 'Vpc.fromLookup()': { 'requires concrete values'(test: Test) { // GIVEN @@ -210,7 +210,7 @@ export = { test.done(); }, }, -}; +}); interface MockVcpContextResponse { readonly vpcId: string; diff --git a/packages/@aws-cdk/aws-ec2/test/test.vpc.ts b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts similarity index 99% rename from packages/@aws-cdk/aws-ec2/test/test.vpc.ts rename to packages/@aws-cdk/aws-ec2/test/vpc.test.ts index fedf67b95c738..13d6d62c8c6a5 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.vpc.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts @@ -1,11 +1,11 @@ import { countResources, expect, haveResource, haveResourceLike, isSuperObject, MatchStyle } from '@aws-cdk/assert'; import { CfnOutput, Lazy, Stack, Tag } from '@aws-cdk/core'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; import { AclCidr, AclTraffic, CfnSubnet, CfnVPC, DefaultInstanceTenancy, GenericLinuxImage, InstanceType, InterfaceVpcEndpoint, InterfaceVpcEndpointService, NatProvider, NetworkAcl, NetworkAclEntry, Peer, Port, PrivateSubnet, PublicSubnet, RouterType, Subnet, SubnetType, TrafficDirection, Vpc } from '../lib'; -export = { +nodeunitShim({ 'When creating a VPC': { 'with the default CIDR range': { @@ -1244,7 +1244,7 @@ export = { }, }, -}; +}); function getTestStack(): Stack { return new Stack(undefined, 'TestStack', { env: { account: '123456789012', region: 'us-east-1' } }); diff --git a/packages/@aws-cdk/aws-ec2/test/test.vpn.ts b/packages/@aws-cdk/aws-ec2/test/vpn.test.ts similarity index 99% rename from packages/@aws-cdk/aws-ec2/test/test.vpn.ts rename to packages/@aws-cdk/aws-ec2/test/vpn.test.ts index 2e5989cc1f590..69863f933a76d 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.vpn.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpn.test.ts @@ -1,9 +1,9 @@ import { expect, haveResource } from '@aws-cdk/assert'; import { Duration, Stack } from '@aws-cdk/core'; -import { Test } from 'nodeunit'; +import { nodeunitShim, Test } from 'nodeunit-shim'; import { PublicSubnet, Vpc, VpnConnection } from '../lib'; -export = { +nodeunitShim({ 'can add a vpn connection to a vpc with a vpn gateway'(test: Test) { // GIVEN const stack = new Stack(); @@ -322,4 +322,4 @@ export = { })); test.done(); }, -}; +}); diff --git a/tools/nodeunit-shim/.gitignore b/tools/nodeunit-shim/.gitignore new file mode 100644 index 0000000000000..2d8e8a2d36377 --- /dev/null +++ b/tools/nodeunit-shim/.gitignore @@ -0,0 +1,13 @@ +*.js +*.js.map +*.d.ts +dist + +.LAST_BUILD +*.snk +!jest.config.js + +.nyc_output +coverage +nyc.config.js +!.eslintrc.js \ No newline at end of file diff --git a/tools/nodeunit-shim/README.md b/tools/nodeunit-shim/README.md new file mode 100644 index 0000000000000..163e24b3b1eb7 --- /dev/null +++ b/tools/nodeunit-shim/README.md @@ -0,0 +1,80 @@ +nodeunit-shim +============== + +Tiny helper library to move from nodeunit tests to Jest. + +Why? +---- + +Jest tests have a better runner, better error reporting, better matchers, +and nicer syntax. They're just all around nicer. Plus, nodeunit has long +since been deprecated. + +Rewriting our existing codebase of nodeunit tests is kind of a hassle though. +Therefore, a tiny adapter layer between the 2 APIs. + +How to use +---------- + +### Update package.json + +```json +"devDependencies": { + // Remove these: + "@types/nodeunit": "...", + "nodeunit": "...", + + // Add this + "nodeunit-shim": "0.0.0", +}, +"cdk-build": { + // Add this + "jest": true +} +``` + +### Get jest.config.js + +Copy a `jest.config.js` from another package. + +### Update .gitignore/.npmignore + +Run `yarn pkglint --fix`. + +### Rename tests + +Rename all test files `test.*.ts` -> `*.test.ts` (be sure to rename +the `.js` as well, or remove them). + +### Rewrite tests + +Inside every test file: + +Replace + +```ts +import { Test } from 'nodeunit'; +``` + +with + +```ts +import { nodeunitShim, Test } from 'nodeunit-shim'; +``` + +and replace: + +```ts +export = { + // ... +}; +``` + +with: + +```ts +nodeunitShim({ + // ... +}); +``` + diff --git a/tools/nodeunit-shim/index.ts b/tools/nodeunit-shim/index.ts new file mode 100644 index 0000000000000..840c7390ce7ae --- /dev/null +++ b/tools/nodeunit-shim/index.ts @@ -0,0 +1,79 @@ +/** + * Jest/Nodeunit compatibility shim + * + * Use this to mass-convert Nodeunit tests to Jest tests. + */ + +/** + * Compatibility shim test + */ +export class Test { + constructor(private readonly cb: () => void) { + } + + public equal(a: any, b: any, _message?: string) { + expect(a).toEqual(b); + } + + public equals(a: any, b: any, _message?: string) { + expect(a).toEqual(b); + } + + public strictEqual(a: any, b: any, _message?: string) { + expect(a).toEqual(b); + } + + public deepEqual(a: any, b: any) { + expect(a).toEqual(b); + } + + public ok(a: any) { + expect(a).toBeTruthy(); + } + + public throws(block: () => any, error?: string | RegExp | ErrorConstructor) { + expect(block).toThrow(error); + } + + public doesNotThrow(block: () => any, error?: string | RegExp | ErrorConstructor) { + expect(block).not.toThrow(error); + } + + public done() { + this.cb(); + } +} + +export function nodeunitShim(exports: Record) { + if (exports.setUp) { + beforeEach(() => { + return new Promise(ok => { + exports.setUp(ok); + }); + }); + } + if (exports.tearDown) { + afterEach(() => { + return new Promise(ok => { + exports.tearDown(ok); + }); + }); + } + for (const [testName, testObj] of Object.entries(exports)) { + if (testName === 'setUp' || testName === 'tearDown') { continue; } + + if (typeof testObj === 'object') { + // It's a suite + describe(testName, () => { + nodeunitShim(testObj); + }); + } else { + // It's a test + test(testName, () => new Promise(ok => { + testObj(new Test(ok)); + })); + } + } +} + +type ErrorConstructor = new (...args: any[]) => Error; diff --git a/tools/nodeunit-shim/package.json b/tools/nodeunit-shim/package.json new file mode 100644 index 0000000000000..5037cce6b7c15 --- /dev/null +++ b/tools/nodeunit-shim/package.json @@ -0,0 +1,25 @@ +{ + "name": "nodeunit-shim", + "private": true, + "version": "0.0.0", + "description": "A helper package to migrate tests from nodeunit to Jest", + "main": "index.js", + "scripts": { + "build": "tsc", + "watch": "tsc -w", + "test": "echo No tests", + "build+test+package": "npm run build+test", + "build+test": "npm run build && npm test" + }, + "devDependencies": { + "@types/node": "^10.17.26", + "typescript": "~3.9.5", + "@types/jest": "^26.0.3" + }, + "dependencies": { + "jest": "^25.5.4" + }, + "keywords": [], + "author": "", + "license": "ISC" +} diff --git a/tools/nodeunit-shim/tsconfig.json b/tools/nodeunit-shim/tsconfig.json new file mode 100644 index 0000000000000..14499cd2abfaf --- /dev/null +++ b/tools/nodeunit-shim/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2018", + "module": "commonjs", + "lib": ["es2018"], + "strict": true, + "alwaysStrict": true, + "declaration": true, + "inlineSourceMap": true, + "inlineSources": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "resolveJsonModule": true, + "composite": true, + "incremental": true + }, + "include": ["**/*.ts"] +} From 7003a09c4cc5390c4b1c125e79d50cf7ba2c9723 Mon Sep 17 00:00:00 2001 From: Rob Bass Date: Tue, 30 Jun 2020 17:17:45 +0100 Subject: [PATCH 47/55] feat(aws-cloudwatch): add comparison operators (#8812) closes #8808 Co-authored-by: Neta Nir --- packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts b/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts index a422b99daa0db..299220eb8d42f 100644 --- a/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts +++ b/packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts @@ -51,6 +51,18 @@ export enum ComparisonOperator { * Used only for alarms based on anomaly detection models */ LESS_THAN_LOWER_OR_GREATER_THAN_UPPER_THRESHOLD = 'LessThanLowerOrGreaterThanUpperThreshold', + + /** + * Specified statistic is greater than the anomaly model band. + * Used only for alarms based on anomaly detection models + */ + GREATER_THAN_UPPER_THRESHOLD = 'GreaterThanUpperThreshold', + + /** + * Specified statistic is lower than the anomaly model band. + * Used only for alarms based on anomaly detection models + */ + LESS_THAN_LOWER_THRESHOLD = 'LessThanLowerThreshold', } const OPERATOR_SYMBOLS: {[key: string]: string} = { From 034bc354ace24965cd091f423b8f2ef91f487a7a Mon Sep 17 00:00:00 2001 From: Chris McKnight Date: Tue, 30 Jun 2020 11:47:48 -0500 Subject: [PATCH 48/55] fix(batch): Invalid spot fleet service role (#8325) Generated role arn invalid due to missing colons (e.g. arnawsiam) Closes #6706 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-batch/lib/compute-environment.ts | 4 ++-- .../@aws-cdk/aws-batch/test/compute-environment.test.ts | 4 ++-- packages/@aws-cdk/aws-batch/test/integ.batch.expected.json | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/@aws-cdk/aws-batch/lib/compute-environment.ts b/packages/@aws-cdk/aws-batch/lib/compute-environment.ts index 129aa321a135d..5d18ae0ca635e 100644 --- a/packages/@aws-cdk/aws-batch/lib/compute-environment.ts +++ b/packages/@aws-cdk/aws-batch/lib/compute-environment.ts @@ -1,6 +1,6 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; -import { Aws, Construct, IResource, Resource, Stack, Tag } from '@aws-cdk/core'; +import { Construct, IResource, Resource, Stack, Tag } from '@aws-cdk/core'; import { CfnComputeEnvironment } from './batch.generated'; /** @@ -493,7 +493,7 @@ export class ComputeEnvironment extends Resource implements IComputeEnvironment return props.computeResources.spotFleetRole; } else if (props.computeResources.type === ComputeResourceType.SPOT) { return iam.Role.fromRoleArn(this, 'Resource-SpotFleet-Role', - `arn${Aws.PARTITION}iam::${this.stack.account}:role/aws-service-role/spotfleet.amazonaws.com/AWSServiceRoleForEC2SpotFleet`); + `arn:${this.stack.partition}:iam::${this.stack.account}:role/aws-service-role/spotfleet.amazonaws.com/AWSServiceRoleForEC2SpotFleet`); } } diff --git a/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts b/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts index ba450e1ffd79e..f09b30f0129fa 100644 --- a/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts +++ b/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts @@ -104,11 +104,11 @@ describe('Batch Compute Evironment', () => { 'Fn::Join': [ '', [ - 'arn', + 'arn:', { Ref: 'AWS::Partition', }, - 'iam::', + ':iam::', { Ref: 'AWS::AccountId', }, diff --git a/packages/@aws-cdk/aws-batch/test/integ.batch.expected.json b/packages/@aws-cdk/aws-batch/test/integ.batch.expected.json index b1e7863929d12..80d101f22547c 100644 --- a/packages/@aws-cdk/aws-batch/test/integ.batch.expected.json +++ b/packages/@aws-cdk/aws-batch/test/integ.batch.expected.json @@ -1173,11 +1173,11 @@ "Fn::Join": [ "", [ - "arn", + "arn:", { "Ref": "AWS::Partition" }, - "iam::", + ":iam::", { "Ref": "AWS::AccountId" }, @@ -1351,4 +1351,4 @@ } } } -} \ No newline at end of file +} From 4ce27f4195c70bd9e365ec0e0df5c0ede863bc8a Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Tue, 30 Jun 2020 19:07:32 +0200 Subject: [PATCH 49/55] feat(cfnspec): cloudformation spec v16.0.0 (#8807) See [CHANGELOG](https://github.com/aws/aws-cdk/blob/bump/16.0.0/CHANGELOG.md) --- packages/@aws-cdk/cfnspec/CHANGELOG.md | 69 +++ packages/@aws-cdk/cfnspec/cfn.version | 2 +- ...0_CloudFormationResourceSpecification.json | 436 +++++++++++++++--- .../cfnspec/spec-source/000_sam.spec.json | 38 +- 4 files changed, 471 insertions(+), 74 deletions(-) diff --git a/packages/@aws-cdk/cfnspec/CHANGELOG.md b/packages/@aws-cdk/cfnspec/CHANGELOG.md index 85710f5c8e9b3..32390673011c9 100644 --- a/packages/@aws-cdk/cfnspec/CHANGELOG.md +++ b/packages/@aws-cdk/cfnspec/CHANGELOG.md @@ -1,3 +1,72 @@ +# CloudFormation Resource Specification v16.0.0 + +## New Resource Types + +* AWS::AppConfig::HostedConfigurationVersion +* AWS::ECS::CapacityProvider + +## Removed Resource Types + +* AWS::EC2::PrefixList + +## Attribute Changes + +* AWS::EC2::FlowLog Id (__added__) + +## Property Changes + +* AWS::ECS::Cluster CapacityProviders (__added__) +* AWS::ECS::Cluster DefaultCapacityProviderStrategy (__added__) +* AWS::SSM::MaintenanceWindow ScheduleOffset (__added__) +* AWS::SSM::MaintenanceWindowTask TaskType.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::ServiceDiscovery::HttpNamespace Tags (__added__) +* AWS::ServiceDiscovery::PrivateDnsNamespace Tags (__added__) +* AWS::ServiceDiscovery::PublicDnsNamespace Tags (__added__) +* AWS::ServiceDiscovery::Service Tags (__added__) +* AWS::WAFv2::WebACLAssociation ResourceArn.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::WAFv2::WebACLAssociation WebACLArn.UpdateType (__changed__) + * Old: Mutable + * New: Immutable + +## Property Type Changes + +* AWS::AppMesh::Route.GrpcTimeout (__added__) +* AWS::AppMesh::Route.HttpTimeout (__added__) +* AWS::AppMesh::Route.TcpTimeout (__added__) +* AWS::AppMesh::VirtualNode.Duration (__added__) +* AWS::AppMesh::VirtualNode.GrpcTimeout (__added__) +* AWS::AppMesh::VirtualNode.HttpTimeout (__added__) +* AWS::AppMesh::VirtualNode.ListenerTimeout (__added__) +* AWS::AppMesh::VirtualNode.TcpTimeout (__added__) +* AWS::ECS::Cluster.CapacityProviderStrategyItem (__added__) +* AWS::AppMesh::Route.GrpcRoute Timeout (__added__) +* AWS::AppMesh::Route.HttpRoute Timeout (__added__) +* AWS::AppMesh::Route.TcpRoute Timeout (__added__) +* AWS::AppMesh::VirtualNode.Listener Timeout (__added__) +* AWS::FMS::Policy.IEMap ORGUNIT (__added__) + +# Serverless Application Model (SAM) Resource Specification v2016-10-31 + +## New Resource Types + + +## Attribute Changes + + +## Property Changes + +* AWS::Serverless::Api OpenApiVersion (__added__) + +## Property Type Changes + +* AWS::Serverless::Function.EventBridgeRuleEvent (__added__) +* AWS::Serverless::Function.EventSource Properties.Types (__changed__) + * Added EventBridgeRuleEvent + # CloudFormation Resource Specification v15.1.0 ## New Resource Types diff --git a/packages/@aws-cdk/cfnspec/cfn.version b/packages/@aws-cdk/cfnspec/cfn.version index d14dfbac36926..946789e6195a1 100644 --- a/packages/@aws-cdk/cfnspec/cfn.version +++ b/packages/@aws-cdk/cfnspec/cfn.version @@ -1 +1 @@ -15.1.0 +16.0.0 diff --git a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json index 4904014995091..2fda3710b204b 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json +++ b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json @@ -1673,6 +1673,12 @@ "Required": false, "Type": "GrpcRetryPolicy", "UpdateType": "Mutable" + }, + "Timeout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpcroute.html#cfn-appmesh-route-grpcroute-timeout", + "Required": false, + "Type": "GrpcTimeout", + "UpdateType": "Mutable" } } }, @@ -1770,6 +1776,23 @@ } } }, + "AWS::AppMesh::Route.GrpcTimeout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpctimeout.html", + "Properties": { + "Idle": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpctimeout.html#cfn-appmesh-route-grpctimeout-idle", + "Required": false, + "Type": "Duration", + "UpdateType": "Mutable" + }, + "PerRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-grpctimeout.html#cfn-appmesh-route-grpctimeout-perrequest", + "Required": false, + "Type": "Duration", + "UpdateType": "Mutable" + } + } + }, "AWS::AppMesh::Route.HeaderMatchMethod": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-headermatchmethod.html", "Properties": { @@ -1856,6 +1879,12 @@ "Required": false, "Type": "HttpRetryPolicy", "UpdateType": "Mutable" + }, + "Timeout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httproute.html#cfn-appmesh-route-httproute-timeout", + "Required": false, + "Type": "HttpTimeout", + "UpdateType": "Mutable" } } }, @@ -1924,6 +1953,23 @@ } } }, + "AWS::AppMesh::Route.HttpTimeout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httptimeout.html", + "Properties": { + "Idle": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httptimeout.html#cfn-appmesh-route-httptimeout-idle", + "Required": false, + "Type": "Duration", + "UpdateType": "Mutable" + }, + "PerRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-httptimeout.html#cfn-appmesh-route-httptimeout-perrequest", + "Required": false, + "Type": "Duration", + "UpdateType": "Mutable" + } + } + }, "AWS::AppMesh::Route.MatchRange": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-matchrange.html", "Properties": { @@ -1984,6 +2030,12 @@ "Required": true, "Type": "TcpRouteAction", "UpdateType": "Mutable" + }, + "Timeout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcproute.html#cfn-appmesh-route-tcproute-timeout", + "Required": false, + "Type": "TcpTimeout", + "UpdateType": "Mutable" } } }, @@ -1999,6 +2051,17 @@ } } }, + "AWS::AppMesh::Route.TcpTimeout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcptimeout.html", + "Properties": { + "Idle": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-tcptimeout.html#cfn-appmesh-route-tcptimeout-idle", + "Required": false, + "Type": "Duration", + "UpdateType": "Mutable" + } + } + }, "AWS::AppMesh::Route.WeightedTarget": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-route-weightedtarget.html", "Properties": { @@ -2136,6 +2199,23 @@ } } }, + "AWS::AppMesh::VirtualNode.Duration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-duration.html", + "Properties": { + "Unit": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-duration.html#cfn-appmesh-virtualnode-duration-unit", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Value": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-duration.html#cfn-appmesh-virtualnode-duration-value", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::AppMesh::VirtualNode.FileAccessLog": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-fileaccesslog.html", "Properties": { @@ -2147,6 +2227,23 @@ } } }, + "AWS::AppMesh::VirtualNode.GrpcTimeout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-grpctimeout.html", + "Properties": { + "Idle": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-grpctimeout.html#cfn-appmesh-virtualnode-grpctimeout-idle", + "Required": false, + "Type": "Duration", + "UpdateType": "Mutable" + }, + "PerRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-grpctimeout.html#cfn-appmesh-virtualnode-grpctimeout-perrequest", + "Required": false, + "Type": "Duration", + "UpdateType": "Mutable" + } + } + }, "AWS::AppMesh::VirtualNode.HealthCheck": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-healthcheck.html", "Properties": { @@ -2194,6 +2291,23 @@ } } }, + "AWS::AppMesh::VirtualNode.HttpTimeout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-httptimeout.html", + "Properties": { + "Idle": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-httptimeout.html#cfn-appmesh-virtualnode-httptimeout-idle", + "Required": false, + "Type": "Duration", + "UpdateType": "Mutable" + }, + "PerRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-httptimeout.html#cfn-appmesh-virtualnode-httptimeout-perrequest", + "Required": false, + "Type": "Duration", + "UpdateType": "Mutable" + } + } + }, "AWS::AppMesh::VirtualNode.Listener": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listener.html", "Properties": { @@ -2214,6 +2328,41 @@ "Required": false, "Type": "ListenerTls", "UpdateType": "Mutable" + }, + "Timeout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listener.html#cfn-appmesh-virtualnode-listener-timeout", + "Required": false, + "Type": "ListenerTimeout", + "UpdateType": "Mutable" + } + } + }, + "AWS::AppMesh::VirtualNode.ListenerTimeout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertimeout.html", + "Properties": { + "GRPC": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertimeout.html#cfn-appmesh-virtualnode-listenertimeout-grpc", + "Required": false, + "Type": "GrpcTimeout", + "UpdateType": "Mutable" + }, + "HTTP": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertimeout.html#cfn-appmesh-virtualnode-listenertimeout-http", + "Required": false, + "Type": "HttpTimeout", + "UpdateType": "Mutable" + }, + "HTTP2": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertimeout.html#cfn-appmesh-virtualnode-listenertimeout-http2", + "Required": false, + "Type": "HttpTimeout", + "UpdateType": "Mutable" + }, + "TCP": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-listenertimeout.html#cfn-appmesh-virtualnode-listenertimeout-tcp", + "Required": false, + "Type": "TcpTimeout", + "UpdateType": "Mutable" } } }, @@ -2324,6 +2473,17 @@ } } }, + "AWS::AppMesh::VirtualNode.TcpTimeout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tcptimeout.html", + "Properties": { + "Idle": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tcptimeout.html#cfn-appmesh-virtualnode-tcptimeout-idle", + "Required": false, + "Type": "Duration", + "UpdateType": "Mutable" + } + } + }, "AWS::AppMesh::VirtualNode.TlsValidationContext": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appmesh-virtualnode-tlsvalidationcontext.html", "Properties": { @@ -11015,23 +11175,6 @@ } } }, - "AWS::EC2::PrefixList.Entry": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-prefixlist-entry.html", - "Properties": { - "Cidr": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-prefixlist-entry.html#cfn-ec2-prefixlist-entry-cidr", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Mutable" - }, - "Description": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-prefixlist-entry.html#cfn-ec2-prefixlist-entry-description", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - } - } - }, "AWS::EC2::SecurityGroup.Egress": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html", "Properties": { @@ -11801,6 +11944,81 @@ } } }, + "AWS::ECS::CapacityProvider.AutoScalingGroupProvider": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-capacityprovider-autoscalinggroupprovider.html", + "Properties": { + "AutoScalingGroupArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-capacityprovider-autoscalinggroupprovider.html#cfn-ecs-capacityprovider-autoscalinggroupprovider-autoscalinggrouparn", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ManagedScaling": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-capacityprovider-autoscalinggroupprovider.html#cfn-ecs-capacityprovider-autoscalinggroupprovider-managedscaling", + "Required": false, + "Type": "ManagedScaling", + "UpdateType": "Immutable" + }, + "ManagedTerminationProtection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-capacityprovider-autoscalinggroupprovider.html#cfn-ecs-capacityprovider-autoscalinggroupprovider-managedterminationprotection", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::ECS::CapacityProvider.ManagedScaling": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-capacityprovider-managedscaling.html", + "Properties": { + "MaximumScalingStepSize": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-capacityprovider-managedscaling.html#cfn-ecs-capacityprovider-managedscaling-maximumscalingstepsize", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "MinimumScalingStepSize": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-capacityprovider-managedscaling.html#cfn-ecs-capacityprovider-managedscaling-minimumscalingstepsize", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Status": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-capacityprovider-managedscaling.html#cfn-ecs-capacityprovider-managedscaling-status", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "TargetCapacity": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-capacityprovider-managedscaling.html#cfn-ecs-capacityprovider-managedscaling-targetcapacity", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::ECS::Cluster.CapacityProviderStrategyItem": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-capacityproviderstrategyitem.html", + "Properties": { + "Base": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-capacityproviderstrategyitem.html#cfn-ecs-cluster-capacityproviderstrategyitem-base", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "CapacityProvider": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-capacityproviderstrategyitem.html#cfn-ecs-cluster-capacityproviderstrategyitem-capacityprovider", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Weight": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-capacityproviderstrategyitem.html#cfn-ecs-cluster-capacityproviderstrategyitem-weight", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::ECS::Cluster.ClusterSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-cluster-clustersettings.html", "Properties": { @@ -16217,6 +16435,13 @@ "Required": false, "Type": "List", "UpdateType": "Mutable" + }, + "ORGUNIT": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fms-policy-iemap.html#cfn-fms-policy-iemap-orgunit", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" } } }, @@ -32388,7 +32613,7 @@ } } }, - "ResourceSpecificationVersion": "15.1.0", + "ResourceSpecificationVersion": "16.0.0", "ResourceTypes": { "AWS::ACMPCA::Certificate": { "Attributes": { @@ -34629,6 +34854,47 @@ } } }, + "AWS::AppConfig::HostedConfigurationVersion": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appconfig-hostedconfigurationversion.html", + "Properties": { + "ApplicationId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appconfig-hostedconfigurationversion.html#cfn-appconfig-hostedconfigurationversion-applicationid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ConfigurationProfileId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appconfig-hostedconfigurationversion.html#cfn-appconfig-hostedconfigurationversion-configurationprofileid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Content": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appconfig-hostedconfigurationversion.html#cfn-appconfig-hostedconfigurationversion-content", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ContentType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appconfig-hostedconfigurationversion.html#cfn-appconfig-hostedconfigurationversion-contenttype", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appconfig-hostedconfigurationversion.html#cfn-appconfig-hostedconfigurationversion-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "LatestVersionNumber": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appconfig-hostedconfigurationversion.html#cfn-appconfig-hostedconfigurationversion-latestversionnumber", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::AppMesh::Mesh": { "Attributes": { "Arn": { @@ -40736,6 +41002,11 @@ } }, "AWS::EC2::FlowLog": { + "Attributes": { + "Id": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html", "Properties": { "DeliverLogsPermissionArn": { @@ -41454,57 +41725,6 @@ } } }, - "AWS::EC2::PrefixList": { - "Attributes": { - "Arn": { - "PrimitiveType": "String" - }, - "OwnerId": { - "PrimitiveType": "String" - }, - "PrefixListId": { - "PrimitiveType": "String" - }, - "Version": { - "PrimitiveType": "Integer" - } - }, - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html", - "Properties": { - "AddressFamily": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-addressfamily", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Mutable" - }, - "Entries": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-entries", - "ItemType": "Entry", - "Required": false, - "Type": "List", - "UpdateType": "Mutable" - }, - "MaxEntries": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-maxentries", - "PrimitiveType": "Integer", - "Required": true, - "UpdateType": "Mutable" - }, - "PrefixListName": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-prefixlistname", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Mutable" - }, - "Tags": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-tags", - "ItemType": "Tag", - "Required": false, - "Type": "List", - "UpdateType": "Mutable" - } - } - }, "AWS::EC2::Route": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html", "Properties": { @@ -42795,6 +43015,30 @@ } } }, + "AWS::ECS::CapacityProvider": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-capacityprovider.html", + "Properties": { + "AutoScalingGroupProvider": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-capacityprovider.html#cfn-ecs-capacityprovider-autoscalinggroupprovider", + "Required": true, + "Type": "AutoScalingGroupProvider", + "UpdateType": "Immutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-capacityprovider.html#cfn-ecs-capacityprovider-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-capacityprovider.html#cfn-ecs-capacityprovider-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::ECS::Cluster": { "Attributes": { "Arn": { @@ -42803,6 +43047,13 @@ }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-cluster.html", "Properties": { + "CapacityProviders": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-cluster.html#cfn-ecs-cluster-capacityproviders", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "ClusterName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-cluster.html#cfn-ecs-cluster-clustername", "PrimitiveType": "String", @@ -42816,6 +43067,13 @@ "Type": "List", "UpdateType": "Mutable" }, + "DefaultCapacityProviderStrategy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-cluster.html#cfn-ecs-cluster-defaultcapacityproviderstrategy", + "ItemType": "CapacityProviderStrategyItem", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-cluster.html#cfn-ecs-cluster-tags", "ItemType": "Tag", @@ -54951,6 +55209,12 @@ "Required": true, "UpdateType": "Mutable" }, + "ScheduleOffset": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-maintenancewindow.html#cfn-ssm-maintenancewindow-scheduleoffset", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, "ScheduleTimezone": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-maintenancewindow.html#cfn-ssm-maintenancewindow-scheduletimezone", "PrimitiveType": "String", @@ -55088,7 +55352,7 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-maintenancewindowtask.html#cfn-ssm-maintenancewindowtask-tasktype", "PrimitiveType": "String", "Required": true, - "UpdateType": "Mutable" + "UpdateType": "Immutable" }, "WindowId": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-maintenancewindowtask.html#cfn-ssm-maintenancewindowtask-windowid", @@ -56321,6 +56585,13 @@ "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-servicediscovery-httpnamespace.html#cfn-servicediscovery-httpnamespace-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" } } }, @@ -56370,6 +56641,13 @@ "Required": true, "UpdateType": "Immutable" }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-servicediscovery-privatednsnamespace.html#cfn-servicediscovery-privatednsnamespace-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "Vpc": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-servicediscovery-privatednsnamespace.html#cfn-servicediscovery-privatednsnamespace-vpc", "PrimitiveType": "String", @@ -56400,6 +56678,13 @@ "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-servicediscovery-publicdnsnamespace.html#cfn-servicediscovery-publicdnsnamespace-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" } } }, @@ -56452,6 +56737,13 @@ "PrimitiveType": "String", "Required": false, "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-servicediscovery-service.html#cfn-servicediscovery-service-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" } } }, @@ -57364,13 +57656,13 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wafv2-webaclassociation.html#cfn-wafv2-webaclassociation-resourcearn", "PrimitiveType": "String", "Required": true, - "UpdateType": "Mutable" + "UpdateType": "Immutable" }, "WebACLArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wafv2-webaclassociation.html#cfn-wafv2-webaclassociation-webaclarn", "PrimitiveType": "String", "Required": true, - "UpdateType": "Mutable" + "UpdateType": "Immutable" } } }, diff --git a/packages/@aws-cdk/cfnspec/spec-source/000_sam.spec.json b/packages/@aws-cdk/cfnspec/spec-source/000_sam.spec.json index 2dd18618067a8..b6eac7d714e02 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/000_sam.spec.json +++ b/packages/@aws-cdk/cfnspec/spec-source/000_sam.spec.json @@ -304,6 +304,35 @@ "Documentation": "https://github.com/awslabs/serverless-application-model/blob/master/docs/policy_templates.rst", "Properties": {} }, + "AWS::Serverless::Function.EventBridgeRuleEvent": { + "Documentation": "https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#eventbridgerule", + "Properties": { + "EventBusName": { + "Documentation": "https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#eventbridgerule", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Input": { + "Documentation": "https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#eventbridgerule", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "InputPath": { + "Documentation": "https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#eventbridgerule", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Pattern": { + "Documentation": "https://docs.aws.amazon.com/eventbridge/latest/userguide/filtering-examples-structure.html", + "PrimitiveType": "Json", + "Required": true, + "UpdateType": "Immutable" + } + } + }, "AWS::Serverless::Function.EventSource": { "Documentation": "https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#event-source-object", "Properties": { @@ -321,7 +350,8 @@ "CloudWatchEventEvent", "CloudWatchLogsEvent", "IoTRuleEvent", - "AlexaSkillEvent" + "AlexaSkillEvent", + "EventBridgeRuleEvent" ], "UpdateType": "Immutable" }, @@ -963,6 +993,12 @@ "Required": false, "UpdateType": "Immutable" }, + "OpenApiVersion": { + "Documentation": "https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessapi", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, "StageName": { "Documentation": "https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessapi", "PrimitiveType": "String", From 4e72d1e9f00ff464c9e645fe55f9178e30ad44df Mon Sep 17 00:00:00 2001 From: Ian Alford Date: Tue, 30 Jun 2020 13:27:28 -0400 Subject: [PATCH 50/55] feat(secretsmanager): add grantUpdate method (#8600) This creates the `grantUpdate` method to give an `iam.IGrantable` the ability to update a secret in Secrets Manager. I opted to move it out from the `grantWrite` method, as there may be cases where we want something to write an initial value, but not change it later on. This decision could be reversed if it seems too granular or too much of an edge-case. Closes #8491 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-secretsmanager/README.md | 4 ++-- packages/@aws-cdk/aws-secretsmanager/lib/secret.ts | 4 ++-- .../@aws-cdk/aws-secretsmanager/test/test.secret.ts | 10 ++++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/@aws-cdk/aws-secretsmanager/README.md b/packages/@aws-cdk/aws-secretsmanager/README.md index fb3a61e920725..540cc9a7fa0be 100644 --- a/packages/@aws-cdk/aws-secretsmanager/README.md +++ b/packages/@aws-cdk/aws-secretsmanager/README.md @@ -44,8 +44,8 @@ A secret can set `RemovalPolicy`. If it set to `RETAIN`, that removing a secret ### Grant permission to use the secret to a role You must grant permission to a resource for that resource to be allowed to -use a secret. This can be achieved with the `Secret.grantRead` and/or -`Secret.grantWrite` method, depending on your need: +use a secret. This can be achieved with the `Secret.grantRead` and/or `Secret.grantUpdate` + method, depending on your need: ```ts const role = new iam.Role(stack, 'SomeRole', { assumedBy: new iam.AccountRootPrincipal() }); diff --git a/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts b/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts index 91cf18a7a8229..c0abdd48832c8 100644 --- a/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts +++ b/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts @@ -42,7 +42,7 @@ export interface ISecret extends IResource { grantRead(grantee: iam.IGrantable, versionStages?: string[]): iam.Grant; /** - * Grants writing the secret value to some role. + * Grants writing and updating the secret value to some role. * * @param grantee the principal being granted permission. */ @@ -166,7 +166,7 @@ abstract class SecretBase extends Resource implements ISecret { // See https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_identity-based-policies.html const result = iam.Grant.addToPrincipal({ grantee, - actions: ['secretsmanager:PutSecretValue'], + actions: ['secretsmanager:PutSecretValue', 'secretsmanager:UpdateSecret'], resourceArns: [this.secretArn], scope: this, }); diff --git a/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts b/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts index 1b10443ff69e2..89767231ee750 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts +++ b/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts @@ -344,7 +344,10 @@ export = { PolicyDocument: { Version: '2012-10-17', Statement: [{ - Action: 'secretsmanager:PutSecretValue', + Action: [ + 'secretsmanager:PutSecretValue', + 'secretsmanager:UpdateSecret', + ], Effect: 'Allow', Resource: { Ref: 'SecretA720EF05' }, }], @@ -369,7 +372,10 @@ export = { PolicyDocument: { Version: '2012-10-17', Statement: [{ - Action: 'secretsmanager:PutSecretValue', + Action: [ + 'secretsmanager:PutSecretValue', + 'secretsmanager:UpdateSecret', + ], Effect: 'Allow', Resource: { Ref: 'SecretA720EF05' }, }], From 917c5ac89e76100fef17579fdcd0f1101bfd18b7 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2020 22:07:29 +0000 Subject: [PATCH 51/55] chore(deps): bump aws-sdk from 2.707.0 to 2.708.0 (#8819) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.707.0 to 2.708.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.707.0...v2.708.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-cloudfront/package.json | 2 +- packages/@aws-cdk/aws-cloudtrail/package.json | 2 +- packages/@aws-cdk/aws-codebuild/package.json | 2 +- packages/@aws-cdk/aws-codecommit/package.json | 2 +- packages/@aws-cdk/aws-dynamodb/package.json | 2 +- packages/@aws-cdk/aws-eks/package.json | 2 +- packages/@aws-cdk/aws-events-targets/package.json | 2 +- packages/@aws-cdk/aws-lambda/package.json | 2 +- packages/@aws-cdk/aws-route53/package.json | 2 +- packages/@aws-cdk/aws-sqs/package.json | 2 +- packages/@aws-cdk/custom-resources/package.json | 2 +- packages/aws-cdk/package.json | 2 +- packages/cdk-assets/package.json | 2 +- yarn.lock | 8 ++++---- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudfront/package.json b/packages/@aws-cdk/aws-cloudfront/package.json index 04a707cba841a..e71b8ba3b433d 100644 --- a/packages/@aws-cdk/aws-cloudfront/package.json +++ b/packages/@aws-cdk/aws-cloudfront/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-cloudtrail/package.json b/packages/@aws-cdk/aws-cloudtrail/package.json index 8d5509c25710a..b1972d3edc822 100644 --- a/packages/@aws-cdk/aws-cloudtrail/package.json +++ b/packages/@aws-cdk/aws-cloudtrail/package.json @@ -64,7 +64,7 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/assert": "0.0.0", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codebuild/package.json b/packages/@aws-cdk/aws-codebuild/package.json index 80ca45af9c2e4..5ccb74d845fad 100644 --- a/packages/@aws-cdk/aws-codebuild/package.json +++ b/packages/@aws-cdk/aws-codebuild/package.json @@ -70,7 +70,7 @@ "@aws-cdk/aws-sns": "0.0.0", "@aws-cdk/aws-sqs": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codecommit/package.json b/packages/@aws-cdk/aws-codecommit/package.json index 6800a63745732..a065b625b061a 100644 --- a/packages/@aws-cdk/aws-codecommit/package.json +++ b/packages/@aws-cdk/aws-codecommit/package.json @@ -70,7 +70,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-dynamodb/package.json b/packages/@aws-cdk/aws-dynamodb/package.json index a228be13eaa0b..1f19f07b21909 100644 --- a/packages/@aws-cdk/aws-dynamodb/package.json +++ b/packages/@aws-cdk/aws-dynamodb/package.json @@ -65,7 +65,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/jest": "^26.0.3", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index 1fb958daabfff..a3868fe98f31a 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -65,7 +65,7 @@ "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", "@types/yaml": "1.2.0", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-events-targets/package.json b/packages/@aws-cdk/aws-events-targets/package.json index 7efd7da1b53ca..03ac69704b3cb 100644 --- a/packages/@aws-cdk/aws-events-targets/package.json +++ b/packages/@aws-cdk/aws-events-targets/package.json @@ -68,7 +68,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-codecommit": "0.0.0", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index 3b70a1aa61194..1d3425619cb1f 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -71,7 +71,7 @@ "@types/lodash": "^4.14.157", "@types/nodeunit": "^0.0.31", "@types/sinon": "^9.0.4", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-route53/package.json b/packages/@aws-cdk/aws-route53/package.json index a4ce73f9ac44f..88f21d12085a9 100644 --- a/packages/@aws-cdk/aws-route53/package.json +++ b/packages/@aws-cdk/aws-route53/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-sqs/package.json b/packages/@aws-cdk/aws-sqs/package.json index 3612521f3a8a2..d10126166f74d 100644 --- a/packages/@aws-cdk/aws-sqs/package.json +++ b/packages/@aws-cdk/aws-sqs/package.json @@ -65,7 +65,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@types/nodeunit": "^0.0.31", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index 8b5141d4c5676..c7646d329169e 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -73,7 +73,7 @@ "@types/aws-lambda": "^8.10.39", "@types/fs-extra": "^8.1.0", "@types/sinon": "^9.0.4", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 9a014953a895a..1db0de549fd0d 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -71,7 +71,7 @@ "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/region-info": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "camelcase": "^6.0.0", "cdk-assets": "0.0.0", "colors": "^1.4.0", diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index c233fed3eea17..efd4e6bcbb333 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -47,7 +47,7 @@ "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.707.0", + "aws-sdk": "^2.708.0", "glob": "^7.1.6", "yargs": "^15.3.1" }, diff --git a/yarn.lock b/yarn.lock index 19e878bfb3ea9..5116de6fb6ed9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2138,10 +2138,10 @@ aws-sdk-mock@^5.1.0: sinon "^9.0.1" traverse "^0.6.6" -aws-sdk@^2.637.0, aws-sdk@^2.707.0: - version "2.707.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.707.0.tgz#c7506dadd1d60a73920ade9027645e166f444e25" - integrity sha512-nt55Z9wQKFodOuwElF3222Thc3kDVnaC4rwemPEHIM1cVGPQe6E5yBfc6AwtYmSo6eoMMEWd6XO5wG2am9PW0w== +aws-sdk@^2.637.0, aws-sdk@^2.708.0: + version "2.708.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.708.0.tgz#6d4345c6d7a06f3d076ce9f0c54958563b2a721e" + integrity sha512-5xXOvbgBXUUKBaJlJUcJIFc2EVMa4Z4f7ILbKIpApoFonW1kHiwBLMBi0MarY4aco7RaodgbqhaOBar4kmSHKw== dependencies: buffer "4.9.2" events "1.1.1" From dfac0df6575ee65149b109fb82117d02491d545f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 1 Jul 2020 01:17:53 +0000 Subject: [PATCH 52/55] chore(deps-dev): bump nock from 13.0.0 to 13.0.1 (#8825) Bumps [nock](https://github.com/nock/nock) from 13.0.0 to 13.0.1. - [Release notes](https://github.com/nock/nock/releases) - [Changelog](https://github.com/nock/nock/blob/main/CHANGELOG.md) - [Commits](https://github.com/nock/nock/compare/v13.0.0...v13.0.1) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-lambda/package.json | 2 +- packages/@aws-cdk/custom-resources/package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index 1d3425619cb1f..01117df7096bd 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -77,7 +77,7 @@ "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", "lodash": "^4.17.15", - "nock": "^13.0.0", + "nock": "^13.0.1", "nodeunit": "^0.11.3", "pkglint": "0.0.0", "sinon": "^9.0.2" diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index c7646d329169e..f9db67380543a 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -79,7 +79,7 @@ "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", "fs-extra": "^9.0.1", - "nock": "^13.0.0", + "nock": "^13.0.1", "pkglint": "0.0.0", "sinon": "^9.0.2" }, diff --git a/yarn.lock b/yarn.lock index 5116de6fb6ed9..e2f60f0584c1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6937,10 +6937,10 @@ nise@^4.0.1: just-extend "^4.0.2" path-to-regexp "^1.7.0" -nock@^13.0.0: - version "13.0.0" - resolved "https://registry.yarnpkg.com/nock/-/nock-13.0.0.tgz#e07276d558245386a2872cebf4d5570583c0d225" - integrity sha512-FiW8t91Je5yG5MVT1r+go1Z9bX3rCYIEjenUYeZrEl2v8aTWdIX336itrmQaKUO8Ske5Z7RHR7OIzr/9p0Ujjg== +nock@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/nock/-/nock-13.0.1.tgz#6e3db0801ca7595685f69f1e8925e7300c13a68f" + integrity sha512-45qR68yd+izs5D81klZrhDwfHx1wulnKotZZYEuEMjw2K6VWClHg9ROf8hBf0tvxe11hP3m6skQZcCpeGv87zg== dependencies: debug "^4.1.0" json-stringify-safe "^5.0.1" From 7f432ffd2c4755bd0976c1777021dad4c7cf2e26 Mon Sep 17 00:00:00 2001 From: Bryan Pan Date: Wed, 1 Jul 2020 00:54:22 -0700 Subject: [PATCH 53/55] feat(ec2): natGateways=0 disables private subnets (#8817) **[ISSUE]** If `natGateways: 0` in VPC but with no subnet configuration. If 0 NAT gateways, private subnets are effectively isolated subnets so it would be a *nice-to-have* to allow this configuration to construct without errors. **[APPROACH]** Added another default subnet configuration called `DEFAULT_SUBNET_NO_NAT` that does an even split of Public and Isolated Subnets. Added a check before `subnetConfiguration` to determine which is 'default' configuration to use. **[NOTE]** Previous use cases should be untouched, changes adjust for our customers' requests to allow for easy configuration. Closes #4814 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ec2/README.md | 8 +++-- packages/@aws-cdk/aws-ec2/lib/vpc.ts | 19 +++++++++++- packages/@aws-cdk/aws-ec2/test/vpc.test.ts | 34 +++++++++++++++++++++- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2/README.md b/packages/@aws-cdk/aws-ec2/README.md index d3d9e070684f8..49cf5949caa9c 100644 --- a/packages/@aws-cdk/aws-ec2/README.md +++ b/packages/@aws-cdk/aws-ec2/README.md @@ -48,9 +48,11 @@ distinguishes three different subnet types: connected to from other instances in the same VPC. A default VPC configuration will not include isolated subnets, -A default VPC configuration will create public and private subnets, but not -isolated subnets. See *Advanced Subnet Configuration* below for information -on how to change the default subnet configuration. + +A default VPC configuration will create public and **private** subnets. However, if +`natGateways:0` **and** `subnetConfiguration` is undefined, default VPC configuration +will create public and **isolated** subnets. See [*Advanced Subnet Configuration*](#advanced-subnet-configuration) +below for information on how to change the default subnet configuration. Constructs using the VPC will "launch instances" (or more accurately, create Elastic Network Interfaces) into one or more of the subnets. They all accept diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index 49a3af5b19311..509c42daebaf9 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -968,6 +968,22 @@ export class Vpc extends VpcBase { }, ]; + /** + * The default subnet configuration if natGateways specified to be 0 + * + * 1 Public and 1 Isolated Subnet per AZ evenly split + */ + public static readonly DEFAULT_SUBNETS_NO_NAT: SubnetConfiguration[] = [ + { + subnetType: SubnetType.PUBLIC, + name: defaultSubnetName(SubnetType.PUBLIC), + }, + { + subnetType: SubnetType.ISOLATED, + name: defaultSubnetName(SubnetType.ISOLATED), + }, + ]; + /** * Import an exported VPC */ @@ -1152,7 +1168,8 @@ export class Vpc extends VpcBase { this.vpcId = this.resource.ref; - this.subnetConfiguration = ifUndefined(props.subnetConfiguration, Vpc.DEFAULT_SUBNETS); + const defaultSubnet = props.natGateways === 0 ? Vpc.DEFAULT_SUBNETS_NO_NAT : Vpc.DEFAULT_SUBNETS; + this.subnetConfiguration = ifUndefined(props.subnetConfiguration, defaultSubnet); const natGatewayPlacement = props.natGatewaySubnets || { subnetType: SubnetType.PUBLIC }; const natGatewayCount = determineNatGatewayCount(props.natGateways, this.subnetConfiguration, this.availabilityZones.length); diff --git a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts index 13d6d62c8c6a5..280c1e2ac4e11 100644 --- a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts @@ -417,17 +417,49 @@ nodeunitShim({ test.done(); }, - 'natGateways = 0 requires there to be no PRIVATE subnets'(test: Test) { + 'natGateways = 0 throws if no PRIVATE subnets configured'(test: Test) { const stack = getTestStack(); test.throws(() => { new Vpc(stack, 'VPC', { natGateways: 0, + subnetConfiguration: [ + { + name: 'public', + subnetType: SubnetType.PUBLIC, + }, + { + name: 'private', + subnetType: SubnetType.PRIVATE, + }, + ], }); }, /make sure you don't configure any PRIVATE subnets/); test.done(); }, + 'natGateway = 0 defaults with ISOLATED subnet'(test: Test) { + const stack = getTestStack(); + new Vpc(stack, 'VPC', { + natGateways: 0, + }); + expect(stack).to(haveResource('AWS::EC2::Subnet', hasTags([{ + Key: 'aws-cdk:subnet-type', + Value: 'Isolated', + }]))); + test.done(); + }, + + 'unspecified natGateways constructs with PRIVATE subnet'(test: Test) { + const stack = getTestStack(); + new Vpc(stack, 'VPC'); + expect(stack).to(haveResource('AWS::EC2::Subnet', hasTags([{ + Key: 'aws-cdk:subnet-type', + Value: 'Private', + }]))); + test.done(); + }, + 'natGateways = 0 allows RESERVED PRIVATE subnets'(test: Test) { const stack = getTestStack(); new Vpc(stack, 'VPC', { From ed93879b8fa5bb601d51e56b0a0be0fc530f03de Mon Sep 17 00:00:00 2001 From: AWS CDK Team Date: Wed, 1 Jul 2020 08:01:00 +0000 Subject: [PATCH 54/55] chore(release): 1.48.0 --- CHANGELOG.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ lerna.json | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e81140cc1f356..a75fbc0148d89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,52 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.48.0](https://github.com/aws/aws-cdk/compare/v1.47.1...v1.48.0) (2020-07-01) + + +### ⚠ BREAKING CHANGES + +* **stepfunctions-tasks:** * `containerName` is not supported as an override anymore and has been replaced by `containerDefinition` +* **stepfunctions-tasks:** `EvaluateExpression` is now a construct representing a task state rather than an embedded property called `task` +* **backup:** existing vaults that use a generated name will be replaced but +existing recovery points won't be lost. The default vault removal policy is +`RETAIN` and if it was set to `DESTROY` the deployment will fail because +vault with recovery points cannot be deleted. + +### Features + +* **autoscaling:** bring your own security group ([3698f47](https://github.com/aws/aws-cdk/commit/3698f47bad970be6f3765e4f145d64f59ded4276)) +* **aws-cloudwatch:** add comparison operators ([#8812](https://github.com/aws/aws-cdk/issues/8812)) ([7003a09](https://github.com/aws/aws-cdk/commit/7003a09c4cc5390c4b1c125e79d50cf7ba2c9723)), closes [#8808](https://github.com/aws/aws-cdk/issues/8808) +* **cfn-include:** add support for YAML templates ([#8746](https://github.com/aws/aws-cdk/issues/8746)) ([293a937](https://github.com/aws/aws-cdk/commit/293a937a6c24681319ae7ca210ffdd0b2ba7d88a)), closes [#8745](https://github.com/aws/aws-cdk/issues/8745) +* **cfnspec:** cloudformation spec v16.0.0 ([#8807](https://github.com/aws/aws-cdk/issues/8807)) ([4ce27f4](https://github.com/aws/aws-cdk/commit/4ce27f4195c70bd9e365ec0e0df5c0ede863bc8a)) +* **cli:** support multiple verbosity levels ([#8749](https://github.com/aws/aws-cdk/issues/8749)) ([fa4196b](https://github.com/aws/aws-cdk/commit/fa4196b11a4b843af1401cbcfd3fe075986ec5c0)) +* **ec2:** `Volume` construct ([#8219](https://github.com/aws/aws-cdk/issues/8219)) ([7490dee](https://github.com/aws/aws-cdk/commit/7490deef3390f024dede3da8b95bcec6140ce1be)) +* **ec2:** add 6xlarge InstanceSize ([#8701](https://github.com/aws/aws-cdk/issues/8701)) ([4917c04](https://github.com/aws/aws-cdk/commit/4917c04a23852608c4c697bff02a1085fdfd4b8c)) +* **ec2:** natGateways=0 disables private subnets ([#8817](https://github.com/aws/aws-cdk/issues/8817)) ([7f432ff](https://github.com/aws/aws-cdk/commit/7f432ffd2c4755bd0976c1777021dad4c7cf2e26)), closes [#4814](https://github.com/aws/aws-cdk/issues/4814) +* **efs:** Filesystem.addAccessPoint() ([#8737](https://github.com/aws/aws-cdk/issues/8737)) ([127547a](https://github.com/aws/aws-cdk/commit/127547a8d64c25fef7c330abee06fd890354afec)) +* **lambda-nodejs:** external and install modules ([#8681](https://github.com/aws/aws-cdk/issues/8681)) ([401594e](https://github.com/aws/aws-cdk/commit/401594ea6cd1c9dc7c4f62ffeee95a720a0ec337)), closes [#6323](https://github.com/aws/aws-cdk/issues/6323) [#7912](https://github.com/aws/aws-cdk/issues/7912) +* **secretsmanager:** add grantUpdate method ([#8600](https://github.com/aws/aws-cdk/issues/8600)) ([4e72d1e](https://github.com/aws/aws-cdk/commit/4e72d1e9f00ff464c9e645fe55f9178e30ad44df)), closes [#8491](https://github.com/aws/aws-cdk/issues/8491) +* **stepfunctions:** class for working with Json paths to retrieve state machine data and context ([#8647](https://github.com/aws/aws-cdk/issues/8647)) ([67978a1](https://github.com/aws/aws-cdk/commit/67978a1cc92c9e7bea389e533b893efedd204c66)) +* **stepfunctions-tasks:** evaluate expression as a task construct ([#8555](https://github.com/aws/aws-cdk/issues/8555)) ([83fd2ae](https://github.com/aws/aws-cdk/commit/83fd2aee6389d03cfe69260b996d7d09398bbf99)) +* **stepfunctions-tasks:** task construct to call `RunJob` on ECS ([#8451](https://github.com/aws/aws-cdk/issues/8451)) ([13deb26](https://github.com/aws/aws-cdk/commit/13deb266f030a28890b5672a0c12b658d253f57e)), closes [#8610](https://github.com/aws/aws-cdk/issues/8610) + + +### Bug Fixes + +* **apigateway:** error defining lambda integration on imported RestApi ([#8785](https://github.com/aws/aws-cdk/issues/8785)) ([05aaf42](https://github.com/aws/aws-cdk/commit/05aaf422e71e12ea6ec91ea26bfbce81ebfea7f4)), closes [#8679](https://github.com/aws/aws-cdk/issues/8679) +* **backup:** correctly validate Vault name ([#8689](https://github.com/aws/aws-cdk/issues/8689)) ([07b330c](https://github.com/aws/aws-cdk/commit/07b330cf39be2a98fbee93915f07c2c34136e105)) +* **backup:** vault name may exceed 50 characters ([#8653](https://github.com/aws/aws-cdk/issues/8653)) ([d09c121](https://github.com/aws/aws-cdk/commit/d09c121e84c0c106f25a129066b0990fb237b841)), closes [#8627](https://github.com/aws/aws-cdk/issues/8627) +* **batch:** Invalid spot fleet service role ([#8325](https://github.com/aws/aws-cdk/issues/8325)) ([034bc35](https://github.com/aws/aws-cdk/commit/034bc354ace24965cd091f423b8f2ef91f487a7a)), closes [#6706](https://github.com/aws/aws-cdk/issues/6706) +* **cli:** post install warnings are not clearly visible when running cdk init ([#8723](https://github.com/aws/aws-cdk/issues/8723)) ([2662db3](https://github.com/aws/aws-cdk/commit/2662db3218387a6264b37190c231e3b0006eb6b6)), closes [#8720](https://github.com/aws/aws-cdk/issues/8720) +* **cli:** unable to use "legacy" bootstrap with --public-access-block-configuration=false ([#8755](https://github.com/aws/aws-cdk/issues/8755)) ([88f8e1e](https://github.com/aws/aws-cdk/commit/88f8e1e9475c66114796dd2840c67a3f4e11f57f)), closes [#8728](https://github.com/aws/aws-cdk/issues/8728) +* **cognito:** cannot add multiple route53 targets to the same user pool domain ([#8622](https://github.com/aws/aws-cdk/issues/8622)) ([32b54a5](https://github.com/aws/aws-cdk/commit/32b54a504357922e55ac98850a8e4acc9a0349f5)), closes [#8603](https://github.com/aws/aws-cdk/issues/8603) +* **core:** bundling directory access permission is too restrictive ([#8767](https://github.com/aws/aws-cdk/issues/8767)) ([1842168](https://github.com/aws/aws-cdk/commit/18421686c4109deb018cc77429ec6deefb7d5689)), closes [#8757](https://github.com/aws/aws-cdk/issues/8757) +* **eks:** Helm chart timeout expects duration ([#8773](https://github.com/aws/aws-cdk/issues/8773)) ([d1c2ef2](https://github.com/aws/aws-cdk/commit/d1c2ef2fc8a845446c956e5e1eb32745f1810ee9)), closes [#8718](https://github.com/aws/aws-cdk/issues/8718) +* **elbv2:** Add missing accounts to ELBv2 Log Delivery. ([#8715](https://github.com/aws/aws-cdk/issues/8715)) ([8914899](https://github.com/aws/aws-cdk/commit/8914899aafcaa28d8b7ca2d2901f86b016179b50)) +* **rewrite:** script ignores list of files ([#8777](https://github.com/aws/aws-cdk/issues/8777)) ([bb514c1](https://github.com/aws/aws-cdk/commit/bb514c1eb1098ccbe5cee4d7570d11bc8d9155c3)) +* **route53-targets:** A/AAAA Alias Record to ELB cannot resolve IPv6 addresses ([#8747](https://github.com/aws/aws-cdk/issues/8747)) ([87e2651](https://github.com/aws/aws-cdk/commit/87e265114590d8fcc69e18b42d777b8ca201307c)), closes [#6271](https://github.com/aws/aws-cdk/issues/6271) +* **s3-notifications:** broken permissions query in `LambdaDestination` ([#8741](https://github.com/aws/aws-cdk/issues/8741)) ([10bd8e4](https://github.com/aws/aws-cdk/commit/10bd8e49709330624eee5f2c2662dee11e19e130)), closes [#8538](https://github.com/aws/aws-cdk/issues/8538) + ## [1.47.1](https://github.com/aws/aws-cdk/compare/v1.47.0...v1.47.1) (2020-06-30) ### Bug Fixes diff --git a/lerna.json b/lerna.json index 605ee25a0805b..df639ba7af7e5 100644 --- a/lerna.json +++ b/lerna.json @@ -10,5 +10,5 @@ "tools/*" ], "rejectCycles": "true", - "version": "1.47.1" + "version": "1.48.0" } From ff1ab502df156260c91220ff0ba31c0d8279084c Mon Sep 17 00:00:00 2001 From: epolon Date: Wed, 1 Jul 2020 11:05:13 +0300 Subject: [PATCH 55/55] minor CHANGELOG touchup --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a75fbc0148d89..493c58a098f60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. See [standa ### ⚠ BREAKING CHANGES -* **stepfunctions-tasks:** * `containerName` is not supported as an override anymore and has been replaced by `containerDefinition` +* **stepfunctions-tasks:** `containerName` is not supported as an override anymore and has been replaced by `containerDefinition` * **stepfunctions-tasks:** `EvaluateExpression` is now a construct representing a task state rather than an embedded property called `task` * **backup:** existing vaults that use a generated name will be replaced but existing recovery points won't be lost. The default vault removal policy is