From 68efa0443649d897dace22843531f0c373b2fe0e Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Sat, 18 May 2019 14:54:13 +0300 Subject: [PATCH] refactor: remove "export"s and normalize resource names (#2580) Implemented an awslint rule to help identify all "export" methods and remove them. Align all AWS resource constructs (besides `events.EventRule`) to their canonical name. Fixes #2577 Fixes #2578 Fixes #2458 Fixes #2419 Fixes #2579 Fixes #2313 Related #2551 BREAKING CHANGE: All `export` methods from all AWS resources have been removed. CloudFormation Exports are now automatically created when attributes are referenced across stacks within the same app. To export resources manually, you can explicitly define a `CfnOutput`. * `kms.EncryptionKey` renamed to `kms.Key` * `ec2.VpcNetwork` renamed to `ec2.Vpc` * `ec2.VpcSubnet` renamed to `ec2.Subnet` * `cloudtrail.CloudTrail` renamed `to `cloudtrail.Trail` * Deleted a few `XxxAttribute` and `XxxImportProps` interfaces which were no longer in used after their corresponding `export` method was deleted and there was no use for them in imports. * `ecs.ClusterAttributes` now accepts `IVpc` and `ISecurityGroup` instead of attributes. You can use their corresponding `fromXxx` methods to import them as needed. * `servicediscovery.CnameInstance.instanceCname` renamed to `cname`. * `glue.IDatabase.locationUrl` is now only in `glue.Database` (not on the interface) * `ec2.TcpPortFromAttribute` and `UdpPortFromAttribute` removed. Use `TcpPort` and `UdpPort` with `new Token(x).toNumber` instead. * `ec2.VpcNetwork.importFromContext` renamed to `ec2.Vpc.fromLookup` * `iam.IRole.roleId` has been removed from the interface, but `Role.roleId` is still available for owned resources. --- .../@aws-cdk/aws-apigateway/lib/restapi.ts | 29 -- .../aws-apigateway/test/test.method.ts | 2 +- .../aws-apigateway/test/test.restapi.ts | 14 +- .../aws-apigateway/test/test.vpc-link.ts | 2 +- .../aws-autoscaling/lib/auto-scaling-group.ts | 2 +- .../test/integ.amazonlinux2.ts | 2 +- .../test/integ.asg-w-classic-loadbalancer.ts | 2 +- .../aws-autoscaling/test/integ.asg-w-elbv2.ts | 2 +- .../test/integ.custom-scaling.ts | 2 +- .../test/integ.external-role.ts | 2 +- .../test/test.auto-scaling-group.ts | 2 +- .../test/test.lifecyclehooks.ts | 2 +- .../aws-autoscaling/test/test.scaling.ts | 4 +- .../test/test.scheduled-action.ts | 2 +- .../aws-certificatemanager/lib/certificate.ts | 29 +- .../lib/dns-validated-certificate.ts | 11 +- .../test/test.certificate.ts | 10 +- .../test/test.dns-validated-certificate.ts | 16 - packages/@aws-cdk/aws-cloudtrail/lib/index.ts | 26 +- .../test/integ.cloudtrail.lit.ts | 2 +- .../aws-cloudtrail/test/test.cloudtrail.ts | 14 +- .../@aws-cdk/aws-codebuild/lib/project.ts | 48 +-- .../aws-codebuild/test/integ.project-vpc.ts | 2 +- .../aws-codebuild/test/test.codebuild.ts | 6 +- .../@aws-cdk/aws-codecommit/lib/repository.ts | 46 +-- .../aws-codedeploy/lib/lambda/application.ts | 62 +-- .../lib/lambda/deployment-group.ts | 20 +- .../aws-codedeploy/lib/server/application.ts | 61 +-- .../lib/server/deployment-config.ts | 25 -- .../lib/server/deployment-group.ts | 19 +- .../test/server/integ.deployment-group.ts | 2 +- .../test/server/test.deployment-group.ts | 12 +- .../lib/jenkins/jenkins-provider.ts | 26 +- .../test/ecs/test.ecs-deploy-action.ts | 2 +- .../test/integ.lambda-pipeline.ts | 2 +- .../test/integ.pipeline-ecs-deploy.ts | 2 +- .../@aws-cdk/aws-codepipeline/lib/pipeline.ts | 2 +- .../@aws-cdk/aws-cognito/lib/user-pool.ts | 21 +- .../aws-ec2/lib/security-group-rule.ts | 62 +-- .../@aws-cdk/aws-ec2/lib/security-group.ts | 35 +- packages/@aws-cdk/aws-ec2/lib/util.ts | 65 +--- packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts | 186 +++------ .../aws-ec2/lib/vpc-network-provider.ts | 18 +- packages/@aws-cdk/aws-ec2/lib/vpc.ts | 292 ++++++++------- packages/@aws-cdk/aws-ec2/lib/vpn.ts | 4 +- .../@aws-cdk/aws-ec2/test/export-helper.ts | 82 ++++ .../test/integ.import-default-vpc.lit.ts | 2 +- .../aws-ec2/test/integ.share-vpcs.lit.ts | 8 +- .../aws-ec2/test/integ.vpc-endpoint.lit.ts | 2 +- packages/@aws-cdk/aws-ec2/test/integ.vpc.ts | 2 +- packages/@aws-cdk/aws-ec2/test/integ.vpn.ts | 2 +- .../@aws-cdk/aws-ec2/test/test.connections.ts | 24 +- .../aws-ec2/test/test.security-group.ts | 52 ++- .../aws-ec2/test/test.vpc-endpoint.ts | 42 +-- packages/@aws-cdk/aws-ec2/test/test.vpc.ts | 85 ++--- packages/@aws-cdk/aws-ec2/test/test.vpn.ts | 24 +- .../@aws-cdk/aws-ecs/lib/base/base-service.ts | 2 +- packages/@aws-cdk/aws-ecs/lib/cluster.ts | 47 +-- .../load-balanced-fargate-service-applet.ts | 4 +- .../aws-ecs/lib/load-balanced-service-base.ts | 2 +- .../aws-ecs/test/ec2/integ.event-task.lit.ts | 2 +- .../aws-ecs/test/ec2/integ.lb-awsvpc-nw.ts | 4 +- .../aws-ecs/test/ec2/integ.lb-bridge-nw.ts | 4 +- .../aws-ecs/test/ec2/integ.sd-awsvpc-nw.ts | 2 +- .../aws-ecs/test/ec2/integ.sd-bridge-nw.ts | 2 +- .../test/ec2/test.ec2-event-rule-target.ts | 2 +- .../aws-ecs/test/ec2/test.ec2-service.ts | 52 +-- .../aws-ecs/test/fargate/integ.asset-image.ts | 4 +- .../@aws-cdk/aws-ecs/test/fargate/integ.l3.ts | 2 +- .../test/fargate/integ.lb-awsvpc-nw.ts | 4 +- .../test/fargate/test.fargate-service.ts | 20 +- .../@aws-cdk/aws-ecs/test/test.ecs-cluster.ts | 31 +- packages/@aws-cdk/aws-ecs/test/test.l3s.ts | 12 +- .../test.load-balanced-fargate-service.ts | 4 +- packages/@aws-cdk/aws-eks/lib/cluster.ts | 57 +-- .../test/example.ssh-into-nodes.lit.ts | 2 +- .../aws-eks/test/integ.eks-cluster.lit.ts | 2 +- .../@aws-cdk/aws-eks/test/test.cluster.ts | 30 +- .../lib/load-balancer.ts | 6 +- .../test/integ.elb.ts | 2 +- .../test/test.loadbalancer.ts | 8 +- .../lib/alb/application-listener.ts | 51 +-- .../lib/alb/application-load-balancer.ts | 47 +-- .../lib/alb/application-target-group.ts | 20 +- .../lib/nlb/network-listener.ts | 61 +-- .../lib/nlb/network-load-balancer.ts | 94 ++--- .../lib/shared/base-listener.ts | 12 +- .../lib/shared/base-load-balancer.ts | 41 +- .../lib/shared/base-target-group.ts | 24 +- .../lib/shared/imported.ts | 6 +- .../test/alb/test.listener.ts | 51 ++- .../test/alb/test.load-balancer.ts | 16 +- .../test/alb/test.security-groups.ts | 35 +- .../test/helpers.ts | 2 +- .../test/integ.alb-alias-target.ts | 2 +- .../test/integ.alb.ts | 2 +- .../test/integ.nlb.ts | 2 +- .../test/nlb/test.listener.ts | 18 +- .../test/nlb/test.load-balancer.ts | 8 +- packages/@aws-cdk/aws-events/lib/rule-ref.ts | 13 - packages/@aws-cdk/aws-events/lib/rule.ts | 16 +- .../@aws-cdk/aws-events/test/test.rule.ts | 6 +- packages/@aws-cdk/aws-glue/lib/database.ts | 67 +--- packages/@aws-cdk/aws-glue/lib/table.ts | 24 +- .../@aws-cdk/aws-glue/test/integ.table.ts | 2 +- .../@aws-cdk/aws-glue/test/test.database.ts | 145 +------ packages/@aws-cdk/aws-glue/test/test.table.ts | 6 +- packages/@aws-cdk/aws-iam/lib/lazy-role.ts | 6 +- packages/@aws-cdk/aws-iam/lib/role.ts | 75 +--- packages/@aws-cdk/aws-iam/test/test.role.ts | 28 +- packages/@aws-cdk/aws-kinesis/lib/stream.ts | 42 +-- .../@aws-cdk/aws-kinesis/test/test.stream.ts | 354 +++++------------- packages/@aws-cdk/aws-kms/lib/alias.ts | 4 +- packages/@aws-cdk/aws-kms/lib/key.ts | 82 +--- .../aws-kms/test/integ.key-sharing.lit.ts | 6 +- packages/@aws-cdk/aws-kms/test/integ.key.ts | 4 +- packages/@aws-cdk/aws-kms/test/test.alias.ts | 10 +- packages/@aws-cdk/aws-kms/test/test.key.ts | 65 +--- packages/@aws-cdk/aws-lambda/lib/alias.ts | 10 +- .../@aws-cdk/aws-lambda/lib/function-base.ts | 10 - packages/@aws-cdk/aws-lambda/lib/function.ts | 23 +- packages/@aws-cdk/aws-lambda/lib/layers.ts | 22 +- .../aws-lambda/lib/singleton-lambda.ts | 6 +- .../aws-lambda/test/integ.vpc-lambda.ts | 2 +- .../@aws-cdk/aws-lambda/test/test.lambda.ts | 28 +- .../aws-lambda/test/test.vpc-lambda.ts | 35 +- .../@aws-cdk/aws-quickstarts/lib/database.ts | 2 +- packages/@aws-cdk/aws-quickstarts/lib/rdgw.ts | 2 +- .../lib/cluster-parameter-group-ref.ts | 46 --- .../aws-rds/lib/cluster-parameter-group.ts | 49 +-- packages/@aws-cdk/aws-rds/lib/cluster-ref.ts | 24 +- packages/@aws-cdk/aws-rds/lib/cluster.ts | 144 ++----- .../@aws-cdk/aws-rds/lib/database-secret.ts | 2 +- packages/@aws-cdk/aws-rds/lib/props.ts | 4 +- .../aws-rds/lib/rotation-single-user.ts | 2 +- .../test/integ.cluster-rotation.lit.ts | 2 +- .../@aws-cdk/aws-rds/test/integ.cluster.ts | 4 +- .../@aws-cdk/aws-rds/test/test.cluster.ts | 48 +-- .../aws-rds/test/test.rotation-single-user.ts | 8 +- .../aws-route53/lib/hosted-zone-ref.ts | 5 - .../@aws-cdk/aws-route53/lib/hosted-zone.ts | 40 +- .../aws-route53/test/integ.route53.ts | 2 +- .../@aws-cdk/aws-route53/test/test.route53.ts | 41 +- packages/@aws-cdk/aws-s3/README.md | 2 +- packages/@aws-cdk/aws-s3/lib/bucket.ts | 38 +- .../aws-s3/test/demo.import-export.ts | 68 ---- packages/@aws-cdk/aws-s3/test/test.bucket.ts | 191 +--------- .../@aws-cdk/aws-secretsmanager/lib/secret.ts | 65 +--- .../aws-secretsmanager/test/test.secret.ts | 8 +- .../lib/alias-target-instance.ts | 4 +- .../lib/cname-instance.ts | 6 +- .../lib/http-namespace.ts | 41 +- .../aws-servicediscovery/lib/instance.ts | 7 +- .../aws-servicediscovery/lib/ip-instance.ts | 2 +- .../aws-servicediscovery/lib/namespace.ts | 63 +--- .../lib/non-ip-instance.ts | 2 +- .../lib/private-dns-namespace.ts | 44 ++- .../lib/public-dns-namespace.ts | 44 ++- .../aws-servicediscovery/package.json | 18 - ....service-with-private-dns-namespace.lit.ts | 2 +- .../test/test.instance.ts | 8 +- .../test/test.namespace.ts | 2 +- .../aws-servicediscovery/test/test.service.ts | 4 +- packages/@aws-cdk/aws-ses/README.md | 32 -- .../aws-ses/lib/receipt-rule-action.ts | 2 +- .../@aws-cdk/aws-ses/lib/receipt-rule-set.ts | 31 +- packages/@aws-cdk/aws-ses/lib/receipt-rule.ts | 26 +- .../@aws-cdk/aws-ses/test/integ.receipt.ts | 2 +- .../aws-ses/test/test.receipt-rule-action.ts | 2 +- .../aws-ses/test/test.receipt-rule-set.ts | 30 -- .../aws-ses/test/test.receipt-rule.ts | 42 --- packages/@aws-cdk/aws-sns/lib/topic-base.ts | 18 - packages/@aws-cdk/aws-sns/lib/topic.ts | 51 +-- packages/@aws-cdk/aws-sns/test/test.sns.ts | 32 +- packages/@aws-cdk/aws-sqs/lib/queue-base.ts | 14 +- packages/@aws-cdk/aws-sqs/lib/queue.ts | 36 +- packages/@aws-cdk/aws-sqs/test/test.sqs.ts | 116 +----- .../lib/run-ecs-task-base.ts | 2 +- .../test/ecs-tasks.test.ts | 4 +- .../test/integ.ec2-task.ts | 2 +- .../test/integ.fargate-task.ts | 2 +- packages/decdk/examples/ecs.json | 2 +- packages/decdk/examples/pipeline.json | 2 +- packages/decdk/examples/vpc.json | 2 +- packages/decdk/lib/jsii2schema.ts | 10 +- packages/decdk/package.json | 2 +- tools/awslint/bin/awslint.ts | 5 +- tools/awslint/lib/rules/attributes.ts | 4 +- tools/awslint/lib/rules/cfn-resource.ts | 8 +- tools/awslint/lib/rules/exports.ts | 13 + tools/awslint/lib/rules/index.ts | 3 +- tools/awslint/lib/rules/resource.ts | 9 +- 192 files changed, 1451 insertions(+), 3509 deletions(-) create mode 100644 packages/@aws-cdk/aws-ec2/test/export-helper.ts delete mode 100644 packages/@aws-cdk/aws-rds/lib/cluster-parameter-group-ref.ts delete mode 100644 packages/@aws-cdk/aws-s3/test/demo.import-export.ts create mode 100644 tools/awslint/lib/rules/exports.ts diff --git a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts index 7c4afb3c96999..47e869e66dcd3 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts @@ -7,30 +7,12 @@ import { Method, MethodOptions } from './method'; import { IResource, ResourceBase, ResourceOptions } from './resource'; import { Stage, StageOptions } from './stage'; -export interface RestApiAttributes { - /** - * The REST API ID of an existing REST API resource. - */ - readonly restApiId: string; - - /** - * The resource ID of the root resource. - */ - readonly restApiRootResourceId?: string; -} - export interface IRestApi extends IResourceBase { /** * The ID of this API Gateway RestApi. * @attribute */ readonly restApiId: string; - - /** - * Exports a REST API resource from this stack. - * @returns REST API props that can be imported to another stack. - */ - export(): RestApiAttributes; } export interface RestApiProps extends ResourceOptions { @@ -165,7 +147,6 @@ export class RestApi extends Resource implements IRestApi { public static fromRestApiId(scope: Construct, id: string, restApiId: string): IRestApi { class Import extends Resource implements IRestApi { public readonly restApiId = restApiId; - public export(): RestApiAttributes { return { restApiId }; } } return new Import(scope, id); @@ -237,16 +218,6 @@ export class RestApi extends Resource implements IRestApi { this.root = new RootResource(this, props, resource.restApiRootResourceId); } - /** - * Exports a REST API resource from this stack. - * @returns REST API props that can be imported to another stack. - */ - public export(): RestApiAttributes { - return { - restApiId: new CfnOutput(this, 'RestApiId', { value: this.restApiId }).makeImportValue().toString() - }; - } - /** * The deployed root URL of this REST API. */ diff --git a/packages/@aws-cdk/aws-apigateway/test/test.method.ts b/packages/@aws-cdk/aws-apigateway/test/test.method.ts index d1d2919ee28f0..70b1125b02bd4 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.method.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.method.ts @@ -303,7 +303,7 @@ export = { // GIVEN const stack = new cdk.Stack(); const api = new apigateway.RestApi(stack, 'test-api', { deploy: false }); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const nlb = new elbv2.NetworkLoadBalancer(stack, 'NLB', { vpc }); diff --git a/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts b/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts index 858d7e31816ac..2b8fbe011f7d6 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts @@ -1,4 +1,4 @@ -import { expect, haveResource, haveResourceLike, ResourcePart, SynthUtils } from '@aws-cdk/assert'; +import { expect, haveResource, haveResourceLike, ResourcePart } from '@aws-cdk/assert'; import cdk = require('@aws-cdk/cdk'); import { App, Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; @@ -328,25 +328,15 @@ export = { test.done(); }, - 'import/export'(test: Test) { + 'fromRestApiId'(test: Test) { // GIVEN const stack = new cdk.Stack(); // WHEN const imported = apigateway.RestApi.fromRestApiId(stack, 'imported-api', 'api-rxt4498f'); - const api = new apigateway.RestApi(stack, 'MyRestApi'); - api.root.addMethod('GET'); - - const exported = api.export(); // THEN - stack.node.prepareTree(); - test.deepEqual(SynthUtils.toCloudFormation(stack).Outputs.MyRestApiRestApiIdB93C5C2D, { - Value: { Ref: 'MyRestApi2D1F47A9' }, - Export: { Name: 'Stack:MyRestApiRestApiIdB93C5C2D' } - }); test.deepEqual(imported.node.resolve(imported.restApiId), 'api-rxt4498f'); - test.deepEqual(imported.node.resolve(exported), { restApiId: { 'Fn::ImportValue': 'Stack:MyRestApiRestApiIdB93C5C2D' } }); test.done(); }, diff --git a/packages/@aws-cdk/aws-apigateway/test/test.vpc-link.ts b/packages/@aws-cdk/aws-apigateway/test/test.vpc-link.ts index fb72e0909a315..585dff09030c2 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.vpc-link.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.vpc-link.ts @@ -9,7 +9,7 @@ export = { 'default setup'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const nlb = new elbv2.NetworkLoadBalancer(stack, 'NLB', { vpc }); 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 8e88c3626c5ac..ee85d2bfc4732 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -148,7 +148,7 @@ export interface AutoScalingGroupProps extends CommonAutoScalingGroupProps { /** * VPC to launch these instances in. */ - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; /** * Type of instance to launch diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts index 059995a4177d0..2b392e6972482 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts @@ -6,7 +6,7 @@ import autoscaling = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-autoscaling-integ'); -const vpc = new ec2.VpcNetwork(stack, 'VPC', { +const vpc = new ec2.Vpc(stack, 'VPC', { maxAZs: 2 }); diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.ts index df56de023672f..85d5210e197dd 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.ts @@ -7,7 +7,7 @@ import autoscaling = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-asg-integ'); -const vpc = new ec2.VpcNetwork(stack, 'VPC', { +const vpc = new ec2.Vpc(stack, 'VPC', { maxAZs: 3 }); diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts index 7aa6b0a326d82..b5baca4dfa4b0 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts @@ -7,7 +7,7 @@ import autoscaling = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-asg-integ'); -const vpc = new ec2.VpcNetwork(stack, 'VPC', { +const vpc = new ec2.Vpc(stack, 'VPC', { maxAZs: 2 }); diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.ts index 0bc10c37910f9..aaa40c64d2c3c 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.ts @@ -6,7 +6,7 @@ import autoscaling = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-autoscaling-integ'); -const vpc = new ec2.VpcNetwork(stack, 'VPC', { +const vpc = new ec2.Vpc(stack, 'VPC', { maxAZs: 2 }); diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.ts index dca53af02b900..30a695e896203 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.ts @@ -7,7 +7,7 @@ class TestStack extends cdk.Stack { constructor(scope: cdk.App, id: string) { super(scope, id); - const vpc = new ec2.VpcNetwork(this, 'VPC'); + const vpc = new ec2.Vpc(this, 'VPC'); const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com') }); 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 86885a37f1f60..81bd54cd78137 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 @@ -524,7 +524,7 @@ export = { }; function mockVpc(stack: cdk.Stack) { - return ec2.VpcNetwork.import(stack, 'MyVpc', { + return ec2.Vpc.fromVpcAttributes(stack, 'MyVpc', { vpcId: 'my-vpc', availabilityZones: [ 'az1' ], publicSubnetIds: [ 'pub1' ], diff --git a/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts b/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts index c53b8d73b819e..e680224545f96 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts @@ -10,7 +10,7 @@ export = { 'we can add a lifecycle hook to an ASG'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const asg = new autoscaling.AutoScalingGroup(stack, 'ASG', { vpc, instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.Micro), diff --git a/packages/@aws-cdk/aws-autoscaling/test/test.scaling.ts b/packages/@aws-cdk/aws-autoscaling/test/test.scaling.ts index 3128ca3966a13..d24151415fd9e 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/test.scaling.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/test.scaling.ts @@ -224,13 +224,13 @@ export = { }; class ASGFixture extends cdk.Construct { - public readonly vpc: ec2.VpcNetwork; + public readonly vpc: ec2.Vpc; public readonly asg: autoscaling.AutoScalingGroup; constructor(scope: cdk.Construct, id: string) { super(scope, id); - this.vpc = new ec2.VpcNetwork(this, 'VPC'); + this.vpc = new ec2.Vpc(this, 'VPC'); this.asg = new autoscaling.AutoScalingGroup(this, 'ASG', { vpc: this.vpc, instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.Micro), diff --git a/packages/@aws-cdk/aws-autoscaling/test/test.scheduled-action.ts b/packages/@aws-cdk/aws-autoscaling/test/test.scheduled-action.ts index 48615e9e84068..79677691e55c4 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/test.scheduled-action.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/test.scheduled-action.ts @@ -104,7 +104,7 @@ export = { }; function makeAutoScalingGroup(scope: cdk.Construct) { - const vpc = new ec2.VpcNetwork(scope, 'VPC'); + const vpc = new ec2.Vpc(scope, 'VPC'); return new autoscaling.AutoScalingGroup(scope, 'ASG', { vpc, instanceType: new ec2.InstanceType('t2.micro'), diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts b/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts index 9ca8aa1f301f4..b96de44a7474e 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts +++ b/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts @@ -1,4 +1,4 @@ -import { CfnOutput, Construct, IResource, Resource } from '@aws-cdk/cdk'; +import { Construct, IResource, Resource } from '@aws-cdk/cdk'; import { CfnCertificate } from './certificatemanager.generated'; import { apexDomain } from './util'; @@ -9,21 +9,6 @@ export interface ICertificate extends IResource { * @attribute */ readonly certificateArn: string; - - /** - * Export this certificate from the stack - */ - export(): CertificateAttributes; -} - -/** - * Reference to an existing Certificate - */ -export interface CertificateAttributes { - /** - * The certificate's ARN - */ - readonly certificateArn: string; } /** @@ -79,9 +64,6 @@ export class Certificate extends Resource implements ICertificate { public static fromCertificateArn(scope: Construct, id: string, certificateArn: string): ICertificate { class Import extends Resource implements ICertificate { public certificateArn = certificateArn; - public export(): CertificateAttributes { - return { certificateArn }; - } } return new Import(scope, id); @@ -118,13 +100,4 @@ export class Certificate extends Resource implements ICertificate { }; } } - - /** - * Export this certificate from the stack - */ - public export(): CertificateAttributes { - return { - certificateArn: new CfnOutput(this, 'Arn', { value: this.certificateArn }).makeImportValue().toString() - }; - } } diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/dns-validated-certificate.ts b/packages/@aws-cdk/aws-certificatemanager/lib/dns-validated-certificate.ts index d4548ca669606..d8fc6b9468469 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lib/dns-validated-certificate.ts +++ b/packages/@aws-cdk/aws-certificatemanager/lib/dns-validated-certificate.ts @@ -4,7 +4,7 @@ import lambda = require('@aws-cdk/aws-lambda'); import route53 = require('@aws-cdk/aws-route53'); import cdk = require('@aws-cdk/cdk'); import path = require('path'); -import { CertificateAttributes, CertificateProps, ICertificate } from './certificate'; +import { CertificateProps, ICertificate } from './certificate'; export interface DnsValidatedCertificateProps extends CertificateProps { /** @@ -71,15 +71,6 @@ export class DnsValidatedCertificate extends cdk.Construct implements ICertifica this.certificateArn = certificate.getAtt('Arn').toString(); } - /** - * Export this certificate from the stack - */ - public export(): CertificateAttributes { - return { - certificateArn: new cdk.CfnOutput(this, 'Arn', { value: this.certificateArn }).makeImportValue().toString() - }; - } - protected validate(): string[] { const errors: string[] = []; // Ensure the zone name is a parent zone of the certificate domain name diff --git a/packages/@aws-cdk/aws-certificatemanager/test/test.certificate.ts b/packages/@aws-cdk/aws-certificatemanager/test/test.certificate.ts index 153778195a6e6..eda2e92a825ba 100644 --- a/packages/@aws-cdk/aws-certificatemanager/test/test.certificate.ts +++ b/packages/@aws-cdk/aws-certificatemanager/test/test.certificate.ts @@ -43,14 +43,14 @@ export = { }, 'export and import'(test: Test) { + // GIVEN const stack = new Stack(); - const refProps = new Certificate(stack, 'Cert', { - domainName: 'hello.com', - }).export(); - - Certificate.fromCertificateArn(stack, 'Imported', refProps.certificateArn); + // WHEN + const c = Certificate.fromCertificateArn(stack, 'Imported', 'cert-arn'); + // THEN + test.deepEqual(c.certificateArn, 'cert-arn'); test.done(); } }; diff --git a/packages/@aws-cdk/aws-certificatemanager/test/test.dns-validated-certificate.ts b/packages/@aws-cdk/aws-certificatemanager/test/test.dns-validated-certificate.ts index 8d5bbb720f6d4..e6c39428962b6 100644 --- a/packages/@aws-cdk/aws-certificatemanager/test/test.dns-validated-certificate.ts +++ b/packages/@aws-cdk/aws-certificatemanager/test/test.dns-validated-certificate.ts @@ -80,22 +80,6 @@ export = { test.done(); }, - 'export and import'(test: Test) { - const stack = new Stack(); - - const helloDotComZone = new PublicHostedZone(stack, 'HelloDotCom', { - zoneName: 'hello.com' - }); - - const refProps = new DnsValidatedCertificate(stack, 'Cert', { - domainName: 'hello.com', - hostedZone: helloDotComZone, - }).export(); - - test.ok('certificateArn' in refProps); - test.done(); - }, - 'adds validation error on domain mismatch'(test: Test) { const stack = new Stack(); diff --git a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts index 398be10eb39be..d4815860a38af 100644 --- a/packages/@aws-cdk/aws-cloudtrail/lib/index.ts +++ b/packages/@aws-cdk/aws-cloudtrail/lib/index.ts @@ -2,13 +2,13 @@ import iam = require('@aws-cdk/aws-iam'); import kms = require('@aws-cdk/aws-kms'); import logs = require('@aws-cdk/aws-logs'); import s3 = require('@aws-cdk/aws-s3'); -import cdk = require('@aws-cdk/cdk'); +import { Construct, Resource } from '@aws-cdk/cdk'; import { CfnTrail } from './cloudtrail.generated'; // AWS::CloudTrail CloudFormation Resources: export * from './cloudtrail.generated'; -export interface CloudTrailProps { +export interface TrailProps { /** * For most services, events are recorded in the region where the action occurred. * For global services such as AWS Identity and Access Management (IAM), AWS STS, Amazon CloudFront, and Route 53, @@ -65,7 +65,7 @@ export interface CloudTrailProps { /** The AWS Key Management Service (AWS KMS) key ID that you want to use to encrypt CloudTrail logs. * @default none */ - readonly kmsKey?: kms.IEncryptionKey; + readonly kmsKey?: kms.IKey; /** The name of an Amazon SNS topic that is notified when new log files are published. * @default none @@ -99,12 +99,21 @@ export enum ReadWriteType { * const cloudTrail = new CloudTrail(this, 'MyTrail'); * */ -export class CloudTrail extends cdk.Construct { +export class Trail extends Resource { + + /** + * @attribute + */ + public readonly trailArn: string; + + /** + * @attribute + */ + public readonly trailSnsTopicArn: string; - public readonly cloudTrailArn: string; private eventSelectors: EventSelector[] = []; - constructor(scope: cdk.Construct, id: string, props: CloudTrailProps = {}) { + constructor(scope: Construct, id: string, props: TrailProps = {}) { super(scope, id); const s3bucket = new s3.Bucket(this, 'S3', {encryption: s3.BucketEncryption.Unencrypted}); @@ -157,7 +166,10 @@ export class CloudTrail extends cdk.Construct { snsTopicName: props.snsTopic, eventSelectors: this.eventSelectors }); - this.cloudTrailArn = trail.trailArn; + + this.trailArn = trail.trailArn; + this.trailSnsTopicArn = trail.trailSnsTopicArn; + const s3BucketPolicy = s3bucket.node.findChild("Policy").node.findChild("Resource") as s3.CfnBucketPolicy; trail.node.addDependency(s3BucketPolicy); diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts index f7a59a62bfe5d..ebc80d0fa5b71 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts @@ -7,7 +7,7 @@ const stack = new cdk.Stack(app, 'integ-cloudtrail'); const bucket = new s3.Bucket(stack, 'Bucket', { removalPolicy: cdk.RemovalPolicy.Destroy }); -const trail = new cloudtrail.CloudTrail(stack, 'Trail'); +const trail = new cloudtrail.Trail(stack, 'Trail'); trail.addS3EventSelector([bucket.arnForObjects('')]); app.run(); diff --git a/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts b/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts index b9a25981ccc88..9442c96925cda 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts @@ -2,7 +2,7 @@ import { expect, haveResource, not, SynthUtils } from '@aws-cdk/assert'; import { RetentionDays } from '@aws-cdk/aws-logs'; import { Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { CloudTrail, ReadWriteType } from '../lib'; +import { ReadWriteType, Trail } from '../lib'; const ExpectedBucketPolicyProperties = { PolicyDocument: { @@ -62,7 +62,7 @@ export = { 'constructs the expected resources': { 'with no properties'(test: Test) { const stack = getTestStack(); - new CloudTrail(stack, 'MyAmazingCloudTrail'); + new Trail(stack, 'MyAmazingCloudTrail'); expect(stack).to(haveResource("AWS::CloudTrail::Trail")); expect(stack).to(haveResource("AWS::S3::Bucket")); expect(stack).to(haveResource("AWS::S3::BucketPolicy", ExpectedBucketPolicyProperties)); @@ -74,7 +74,7 @@ export = { 'with cloud watch logs': { 'enabled'(test: Test) { const stack = getTestStack(); - new CloudTrail(stack, 'MyAmazingCloudTrail', { + new Trail(stack, 'MyAmazingCloudTrail', { sendToCloudWatchLogs: true }); @@ -104,7 +104,7 @@ export = { }, 'enabled and custom retention'(test: Test) { const stack = getTestStack(); - new CloudTrail(stack, 'MyAmazingCloudTrail', { + new Trail(stack, 'MyAmazingCloudTrail', { sendToCloudWatchLogs: true, cloudWatchLogsRetentionTimeDays: RetentionDays.OneWeek }); @@ -126,7 +126,7 @@ export = { 'with default props'(test: Test) { const stack = getTestStack(); - const cloudTrail = new CloudTrail(stack, 'MyAmazingCloudTrail'); + const cloudTrail = new Trail(stack, 'MyAmazingCloudTrail'); cloudTrail.addS3EventSelector(["arn:aws:s3:::"]); expect(stack).to(haveResource("AWS::CloudTrail::Trail")); @@ -152,7 +152,7 @@ export = { 'with hand-specified props'(test: Test) { const stack = getTestStack(); - const cloudTrail = new CloudTrail(stack, 'MyAmazingCloudTrail'); + const cloudTrail = new Trail(stack, 'MyAmazingCloudTrail'); cloudTrail.addS3EventSelector(["arn:aws:s3:::"], { includeManagementEvents: false, readWriteType: ReadWriteType.ReadOnly }); expect(stack).to(haveResource("AWS::CloudTrail::Trail")); @@ -178,7 +178,7 @@ export = { 'with management event'(test: Test) { const stack = getTestStack(); - new CloudTrail(stack, 'MyAmazingCloudTrail', { managementEvents: ReadWriteType.WriteOnly }); + new Trail(stack, 'MyAmazingCloudTrail', { managementEvents: ReadWriteType.WriteOnly }); const trail: any = SynthUtils.toCloudFormation(stack).Resources.MyAmazingCloudTrail54516E8D; test.equals(trail.Properties.EventSelectors.length, 1); diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index 54e967296d2dd..b75582ec38708 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -6,7 +6,7 @@ import ecr = require('@aws-cdk/aws-ecr'); import events = require('@aws-cdk/aws-events'); import iam = require('@aws-cdk/aws-iam'); import kms = require('@aws-cdk/aws-kms'); -import { Aws, CfnOutput, Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; +import { Aws, Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; import { BuildArtifacts, CodePipelineBuildArtifacts, NoBuildArtifacts } from './artifacts'; import { Cache } from './cache'; import { CfnProject } from './codebuild.generated'; @@ -130,25 +130,6 @@ export interface IProject extends IResource, iam.IGrantable { * @default sum over 5 minutes */ metricFailedBuilds(props?: cloudwatch.MetricOptions): cloudwatch.Metric; - - /** - * Export this Project. Allows referencing this Project in a different CDK Stack. - */ - export(): ProjectAttributes; -} - -/** - * Properties of a reference to a CodeBuild Project. - * - * @see Project.import - * @see Project.export - */ -export interface ProjectAttributes { - /** - * The human-readable name of the CodeBuild Project we're referencing. - * The Project must be in the same account and region as the root Stack. - */ - readonly projectName: string; } /** @@ -173,8 +154,6 @@ abstract class ProjectBase extends Resource implements IProject { /** The IAM service Role of this Project. */ public abstract readonly role?: iam.IRole; - public abstract export(): ProjectAttributes; - /** * Defines a CloudWatch event rule triggered when the build project state * changes. You can filter specific build status events using an event @@ -395,7 +374,7 @@ export interface CommonProjectProps { * Encryption key to use to read and write artifacts. * If not specified, a role will be created. */ - readonly encryptionKey?: kms.IEncryptionKey; + readonly encryptionKey?: kms.IKey; /** * Caching strategy to use. @@ -437,7 +416,7 @@ export interface CommonProjectProps { * * Specify this if the codebuild project needs to access resources in a VPC. */ - readonly vpc?: ec2.IVpcNetwork; + readonly vpc?: ec2.IVpc; /** * Where to place the network interfaces within the VPC. @@ -522,12 +501,6 @@ export class Project extends ProjectBase { super(s, i); this.grantPrincipal = new iam.ImportedResourcePrincipal({ resource: this }); } - - public export(): ProjectAttributes { - return { - projectName: this.projectName - }; - } } return new Import(scope, id); @@ -567,12 +540,6 @@ export class Project extends ProjectBase { this.grantPrincipal = new iam.ImportedResourcePrincipal({ resource: this }); this.projectName = projectName; } - - public export(): ProjectAttributes { - return { - projectName - }; - } } return new Import(scope, id); @@ -704,15 +671,6 @@ export class Project extends ProjectBase { return this._securityGroups.slice(); } - /** - * Export this Project. Allows referencing this Project in a different CDK Stack. - */ - public export(): ProjectAttributes { - return { - projectName: new CfnOutput(this, 'ProjectName', { value: this.projectName }).makeImportValue().toString(), - }; - } - /** * Add a permission only if there's a policy attached. * @param statement The permissions statement to add diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.project-vpc.ts b/packages/@aws-cdk/aws-codebuild/test/integ.project-vpc.ts index 35534b5992c33..d941f885aee82 100644 --- a/packages/@aws-cdk/aws-codebuild/test/integ.project-vpc.ts +++ b/packages/@aws-cdk/aws-codebuild/test/integ.project-vpc.ts @@ -7,7 +7,7 @@ import { Project } from '../lib'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-codebuild-project-vpc'); -const vpc = new ec2.VpcNetwork(stack, 'MyVPC', { +const vpc = new ec2.Vpc(stack, 'MyVPC', { maxAZs: 1, natGateways: 1, }); diff --git a/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts b/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts index 030bd009fbc1b..7893113869115 100644 --- a/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts +++ b/packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts @@ -626,7 +626,7 @@ export = { const stack = new cdk.Stack(); const bucket = new s3.Bucket(stack, 'MyBucket'); - const vpc = new ec2.VpcNetwork(stack, 'MyVPC'); + const vpc = new ec2.Vpc(stack, 'MyVPC'); const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup1', { groupName: 'Bob', vpc, @@ -673,7 +673,7 @@ export = { const stack = new cdk.Stack(); const bucket = new s3.Bucket(stack, 'MyBucket'); - const vpc = new ec2.VpcNetwork(stack, 'MyVPC'); + const vpc = new ec2.Vpc(stack, 'MyVPC'); const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup1', { groupName: 'Bob', vpc, @@ -695,7 +695,7 @@ export = { 'with VPC configuration but allowAllOutbound identified'(test: Test) { const stack = new cdk.Stack(); const bucket = new s3.Bucket(stack, 'MyBucket'); - const vpc = new ec2.VpcNetwork(stack, 'MyVPC'); + const vpc = new ec2.Vpc(stack, 'MyVPC'); const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup1', { groupName: 'Bob', vpc, diff --git a/packages/@aws-cdk/aws-codecommit/lib/repository.ts b/packages/@aws-cdk/aws-codecommit/lib/repository.ts index 804b2a6a4eae5..3578293c72b20 100644 --- a/packages/@aws-cdk/aws-codecommit/lib/repository.ts +++ b/packages/@aws-cdk/aws-codecommit/lib/repository.ts @@ -1,5 +1,5 @@ import events = require('@aws-cdk/aws-events'); -import { CfnOutput, Construct, IConstruct, IResource, Resource, Stack } from '@aws-cdk/cdk'; +import { Construct, IConstruct, IResource, Resource, Stack } from '@aws-cdk/cdk'; import { CfnRepository } from './codecommit.generated'; export interface IRepository extends IResource { @@ -78,24 +78,6 @@ export interface IRepository extends IResource { * @param branch The branch to monitor. Defaults to all branches. */ onCommit(name: string, target?: events.IEventRuleTarget, branch?: string): events.EventRule; - - /** - * Exports this Repository. Allows the same Repository to be used in 2 different Stacks. - * - * @see import - */ - export(): RepositoryAttributes; -} - -/** - * Properties for the {@link Repository.import} method. - */ -export interface RepositoryAttributes { - /** - * The name of an existing CodeCommit Repository that we are referencing. - * Must be in the same account and region as the root Stack. - */ - readonly repositoryName: string; } /** @@ -120,8 +102,6 @@ abstract class RepositoryBase extends Resource implements IRepository { /** The SSH clone URL */ public abstract readonly repositoryCloneUrlSsh: string; - public abstract export(): RepositoryAttributes; - /** * Defines a CloudWatch event rule which triggers for repository events. Use * `rule.addEventPattern(pattern)` to specify a filter. @@ -250,12 +230,6 @@ export class Repository extends RepositoryBase { public readonly repositoryName = repositoryName; public readonly repositoryCloneUrlHttp = Repository.makeCloneUrl(stack, repositoryName, 'https'); public readonly repositoryCloneUrlSsh = Repository.makeCloneUrl(stack, repositoryName, 'ssh'); - public export() { - return { - repositoryArn: this.repositoryArn, - repositoryName: this.repositoryName - }; - } } return new Import(scope, id); @@ -269,13 +243,6 @@ export class Repository extends RepositoryBase { public repositoryArn = Repository.arnForLocalRepository(repositoryName, scope); public readonly repositoryCloneUrlHttp = Repository.makeCloneUrl(stack, repositoryName, 'https'); public readonly repositoryCloneUrlSsh = Repository.makeCloneUrl(stack, repositoryName, 'ssh'); - - public export() { - return { - repositoryArn: this.repositoryArn, - repositoryName: this.repositoryName, - }; - } } return new Import(scope, id); @@ -321,17 +288,6 @@ export class Repository extends RepositoryBase { return this.repository.repositoryName; } - /** - * Exports this Repository. Allows the same Repository to be used in 2 different Stacks. - * - * @see import - */ - public export(): RepositoryAttributes { - return { - repositoryName: new CfnOutput(this, 'RepositoryName', { value: this.repositoryName }).makeImportValue().toString() - }; - } - /** * Create a trigger to notify another service to run actions on repository events. * @param arn Arn of the resource that repository events will notify diff --git a/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts b/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts index e998a7f20ec0c..515c7fbaf7a4f 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts @@ -1,4 +1,4 @@ -import cdk = require("@aws-cdk/cdk"); +import { Construct, IResource, Resource } from '@aws-cdk/cdk'; import { CfnApplication } from "../codedeploy.generated"; import { arnForApplication } from "../utils"; @@ -12,11 +12,12 @@ import { arnForApplication } from "../utils"; * or one defined in a different CDK Stack, * use the {@link LambdaApplication#import} method. */ -export interface ILambdaApplication extends cdk.IConstruct { +export interface ILambdaApplication extends IResource { + /** @attribute */ readonly applicationArn: string; - readonly applicationName: string; - export(): LambdaApplicationImportProps; + /** @attribute */ + readonly applicationName: string; } /** @@ -33,25 +34,32 @@ export interface LambdaApplicationProps { /** * A CodeDeploy Application that deploys to an AWS Lambda function. + * + * @resource AWS::CodeDeploy::Application */ -export class LambdaApplication extends cdk.Construct implements ILambdaApplication { +export class LambdaApplication extends Resource implements ILambdaApplication { /** * Import an Application defined either outside the CDK, * or in a different CDK Stack and exported using the {@link ILambdaApplication#export} method. * * @param scope the parent Construct for this new Construct * @param id the logical ID of this new Construct - * @param props the properties of the referenced Application + * @param lambdaApplicationName the name of the application to import * @returns a Construct representing a reference to an existing Application */ - public static import(scope: cdk.Construct, id: string, props: LambdaApplicationImportProps): ILambdaApplication { - return new ImportedLambdaApplication(scope, id, props); + public static fromLambdaApplicationName(scope: Construct, id: string, lambdaApplicationName: string): ILambdaApplication { + class Import extends Resource implements ILambdaApplication { + public applicationArn = arnForApplication(lambdaApplicationName); + public applicationName = lambdaApplicationName; + } + + return new Import(scope, id); } public readonly applicationArn: string; public readonly applicationName: string; - constructor(scope: cdk.Construct, id: string, props: LambdaApplicationProps = {}) { + constructor(scope: Construct, id: string, props: LambdaApplicationProps = {}) { super(scope, id); const resource = new CfnApplication(this, 'Resource', { @@ -62,40 +70,4 @@ export class LambdaApplication extends cdk.Construct implements ILambdaApplicati this.applicationName = resource.ref; this.applicationArn = arnForApplication(this.applicationName); } - - public export(): LambdaApplicationImportProps { - return { - applicationName: new cdk.CfnOutput(this, 'ApplicationName', { value: this.applicationName }).makeImportValue().toString() - }; - } -} - -/** - * Properties of a reference to a CodeDeploy Application. - * - * @see LambdaApplication#import - * @see ILambdaApplication#export - */ -export interface LambdaApplicationImportProps { - /** - * The physical, human-readable name of the Lambda Application we're referencing. - * The Application must be in the same account and region as the root Stack. - */ - readonly applicationName: string; -} - -class ImportedLambdaApplication extends cdk.Construct implements ILambdaApplication { - public readonly applicationArn: string; - public readonly applicationName: string; - - constructor(scope: cdk.Construct, id: string, private readonly props: LambdaApplicationImportProps) { - super(scope, id); - - this.applicationName = props.applicationName; - this.applicationArn = arnForApplication(props.applicationName); - } - - public export(): LambdaApplicationImportProps { - return this.props; - } } diff --git a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts index df869a854abcb..7deae49743923 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts @@ -29,11 +29,6 @@ export interface ILambdaDeploymentGroup extends cdk.IResource { * @attribute */ readonly deploymentGroupArn: string; - - /** - * Export this Deployment Group for use in another stack or application. - */ - export(): LambdaDeploymentGroupAttributes; } /** @@ -234,15 +229,6 @@ export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploy actions: ['codedeploy:PutLifecycleEventHookExecutionStatus'], }); } - - public export(): LambdaDeploymentGroupAttributes { - return { - application: this.application, - deploymentGroupName: new cdk.CfnOutput(this, 'DeploymentGroupName', { - value: this.deploymentGroupName - }).makeImportValue().toString() - }; - } } /** @@ -270,14 +256,10 @@ class ImportedLambdaDeploymentGroup extends cdk.Construct implements ILambdaDepl public readonly deploymentGroupName: string; public readonly deploymentGroupArn: string; - constructor(scope: cdk.Construct, id: string, private readonly props: LambdaDeploymentGroupAttributes) { + constructor(scope: cdk.Construct, id: string, props: LambdaDeploymentGroupAttributes) { super(scope, id); this.application = props.application; this.deploymentGroupName = props.deploymentGroupName; this.deploymentGroupArn = arnForDeploymentGroup(props.application.applicationName, props.deploymentGroupName); } - - public export() { - return this.props; - } } diff --git a/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts b/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts index 08a0a9bae23ae..2231c4049a970 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts @@ -1,4 +1,4 @@ -import cdk = require('@aws-cdk/cdk'); +import { Construct, IResource, Resource } from '@aws-cdk/cdk'; import { CfnApplication } from '../codedeploy.generated'; import { arnForApplication } from '../utils'; @@ -12,43 +12,14 @@ import { arnForApplication } from '../utils'; * or one defined in a different CDK Stack, * use the {@link #import} method. */ -export interface IServerApplication extends cdk.IConstruct { +export interface IServerApplication extends IResource { + /** @attribute */ readonly applicationArn: string; - readonly applicationName: string; - - export(): ServerApplicationImportProps; -} -/** - * Properties of a reference to a CodeDeploy EC2/on-premise Application. - * - * @see ServerApplication#import - * @see ServerApplication#export - */ -export interface ServerApplicationImportProps { - /** - * The physical, human-readable name of the CodeDeploy EC2/on-premise Application we're referencing. - * The Application must be in the same account and region as the root Stack. - */ + /** @attribute */ readonly applicationName: string; } -class ImportedServerApplication extends cdk.Construct implements IServerApplication { - public readonly applicationArn: string; - public readonly applicationName: string; - - constructor(scope: cdk.Construct, id: string, private readonly props: ServerApplicationImportProps) { - super(scope, id); - - this.applicationName = props.applicationName; - this.applicationArn = arnForApplication(this.applicationName); - } - - public export(): ServerApplicationImportProps { - return this.props; - } -} - /** * Construction properties for {@link ServerApplication}. */ @@ -63,25 +34,33 @@ export interface ServerApplicationProps { /** * A CodeDeploy Application that deploys to EC2/on-premise instances. + * + * @resource AWS::CodeDeploy::Application */ -export class ServerApplication extends cdk.Construct implements IServerApplication { +export class ServerApplication extends Resource implements IServerApplication { /** * Import an Application defined either outside the CDK, * or in a different CDK Stack and exported using the {@link #export} method. * * @param scope the parent Construct for this new Construct * @param id the logical ID of this new Construct - * @param props the properties of the referenced Application + * @param serverApplicationName the name of the application to import * @returns a Construct representing a reference to an existing Application */ - public static import(scope: cdk.Construct, id: string, props: ServerApplicationImportProps): IServerApplication { - return new ImportedServerApplication(scope, id, props); + public static fromServerApplicationName(scope: Construct, id: string, serverApplicationName: string): IServerApplication { + class Import extends Resource implements IServerApplication { + public readonly applicationArn = arnForApplication(serverApplicationName); + public readonly applicationName = serverApplicationName; + } + + return new Import(scope, id); + } public readonly applicationArn: string; public readonly applicationName: string; - constructor(scope: cdk.Construct, id: string, props: ServerApplicationProps = {}) { + constructor(scope: Construct, id: string, props: ServerApplicationProps = {}) { super(scope, id); const resource = new CfnApplication(this, 'Resource', { @@ -92,10 +71,4 @@ export class ServerApplication extends cdk.Construct implements IServerApplicati this.applicationName = resource.ref; this.applicationArn = arnForApplication(this.applicationName); } - - public export(): ServerApplicationImportProps { - return { - applicationName: new cdk.CfnOutput(this, 'ApplicationName', { value: this.applicationName }).makeImportValue().toString() - }; - } } diff --git a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts index f9e490f4fde5d..3c67e65114e84 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts @@ -19,22 +19,6 @@ export interface IServerDeploymentConfig { * @attribute */ readonly deploymentConfigArn: string; - - export(): ServerDeploymentConfigAttributes; -} - -/** - * Properties of a reference to a CodeDeploy EC2/on-premise Deployment Configuration. - * - * @see ServerDeploymentConfig#import - * @see ServerDeploymentConfig#export - */ -export interface ServerDeploymentConfigAttributes { - /** - * The physical, human-readable name of the custom CodeDeploy EC2/on-premise Deployment Configuration - * that we are referencing. - */ - readonly deploymentConfigName: string; } /** @@ -132,21 +116,12 @@ export class ServerDeploymentConfig extends cdk.Resource implements IServerDeplo this.deploymentConfigName = resource.ref.toString(); this.deploymentConfigArn = arnForDeploymentConfig(this.deploymentConfigName); } - - public export(): ServerDeploymentConfigAttributes { - return { - deploymentConfigName: new cdk.CfnOutput(this, 'DeploymentConfigName', { - value: this.deploymentConfigName, - }).makeImportValue().toString(), - }; - } } function deploymentConfig(name: string): IServerDeploymentConfig { return { deploymentConfigName: name, deploymentConfigArn: arnForDeploymentConfig(name), - export() { return { deploymentConfigName: name }; } }; } diff --git a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts index 643b45b6c5983..2dd9e12c587fd 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts @@ -25,7 +25,6 @@ export interface IServerDeploymentGroup extends cdk.IResource { readonly deploymentGroupArn: string; readonly deploymentConfig: IServerDeploymentConfig; readonly autoScalingGroups?: autoscaling.AutoScalingGroup[]; - export(): ServerDeploymentGroupAttributes; } /** @@ -77,8 +76,6 @@ abstract class ServerDeploymentGroupBase extends cdk.Resource implements IServer super(scope, id); this.deploymentConfig = deploymentConfig || ServerDeploymentConfig.OneAtATime; } - - public abstract export(): ServerDeploymentGroupAttributes; } class ImportedServerDeploymentGroup extends ServerDeploymentGroupBase { @@ -88,17 +85,13 @@ class ImportedServerDeploymentGroup extends ServerDeploymentGroupBase { public readonly deploymentGroupArn: string; public readonly autoScalingGroups?: autoscaling.AutoScalingGroup[] = undefined; - constructor(scope: cdk.Construct, id: string, private readonly props: ServerDeploymentGroupAttributes) { + constructor(scope: cdk.Construct, id: string, props: ServerDeploymentGroupAttributes) { super(scope, id, props.deploymentConfig); this.application = props.application; this.deploymentGroupName = props.deploymentGroupName; this.deploymentGroupArn = arnForDeploymentGroup(props.application.applicationName, props.deploymentGroupName); } - - public export() { - return this.props; - } } /** @@ -312,16 +305,6 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase { this.deploymentGroupArn = arnForDeploymentGroup(this.application.applicationName, this.deploymentGroupName); } - public export(): ServerDeploymentGroupAttributes { - return { - application: this.application, - deploymentGroupName: new cdk.CfnOutput(this, 'DeploymentGroupName', { - value: this.deploymentGroupName - }).makeImportValue().toString(), - deploymentConfig: this.deploymentConfig, - }; - } - /** * Adds an additional auto-scaling group to this Deployment Group. * diff --git a/packages/@aws-cdk/aws-codedeploy/test/server/integ.deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/test/server/integ.deployment-group.ts index b6ea00d31df5b..449057cba245f 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/server/integ.deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/server/integ.deployment-group.ts @@ -9,7 +9,7 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-codedeploy-server-dg'); -const vpc = new ec2.VpcNetwork(stack, 'VPC'); +const vpc = new ec2.Vpc(stack, 'VPC'); const asg = new autoscaling.AutoScalingGroup(stack, 'ASG', { instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M5, ec2.InstanceSize.Large), diff --git a/packages/@aws-cdk/aws-codedeploy/test/server/test.deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/test/server/test.deployment-group.ts index 82957b3302cc2..8267d104c16fb 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/server/test.deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/server/test.deployment-group.ts @@ -31,9 +31,7 @@ export = { 'can be imported'(test: Test) { const stack = new cdk.Stack(); - const application = codedeploy.ServerApplication.import(stack, 'MyApp', { - applicationName: 'MyApp', - }); + const application = codedeploy.ServerApplication.fromServerApplicationName(stack, 'MyApp', 'MyApp'); const deploymentGroup = codedeploy.ServerDeploymentGroup.fromServerDeploymentGroupAttributes(stack, 'MyDG', { application, deploymentGroupName: 'MyDG', @@ -50,7 +48,7 @@ export = { const asg = new autoscaling.AutoScalingGroup(stack, 'ASG', { instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.Standard3, ec2.InstanceSize.Small), machineImage: new ec2.AmazonLinuxImage(), - vpc: new ec2.VpcNetwork(stack, 'VPC'), + vpc: new ec2.Vpc(stack, 'VPC'), }); new codedeploy.ServerDeploymentGroup(stack, 'DeploymentGroup', { @@ -74,7 +72,7 @@ export = { const asg = new autoscaling.AutoScalingGroup(stack, 'ASG', { instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.Standard3, ec2.InstanceSize.Small), machineImage: new ec2.AmazonLinuxImage(), - vpc: new ec2.VpcNetwork(stack, 'VPC'), + vpc: new ec2.Vpc(stack, 'VPC'), }); const deploymentGroup = new codedeploy.ServerDeploymentGroup(stack, 'DeploymentGroup'); @@ -95,7 +93,7 @@ export = { const stack = new cdk.Stack(); const alb = new lbv2.ApplicationLoadBalancer(stack, 'ALB', { - vpc: new ec2.VpcNetwork(stack, 'VPC'), + vpc: new ec2.Vpc(stack, 'VPC'), }); const listener = alb.addListener('Listener', { protocol: lbv2.ApplicationProtocol.Http }); const targetGroup = listener.addTargets('Fleet', { protocol: lbv2.ApplicationProtocol.Http }); @@ -129,7 +127,7 @@ export = { const stack = new cdk.Stack(); const nlb = new lbv2.NetworkLoadBalancer(stack, 'NLB', { - vpc: new ec2.VpcNetwork(stack, 'VPC'), + vpc: new ec2.Vpc(stack, 'VPC'), }); const listener = nlb.addListener('Listener', { port: 80 }); const targetGroup = listener.addTargets('Fleet', { port: 80 }); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts index cf4b0611d2917..84c868595fb47 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts @@ -9,7 +9,7 @@ import { CustomActionRegistration } from "../custom-action-registration"; * instantiate the {@link JenkinsProvider} class directly. * * If you want to reference an already registered provider, - * use the {@link JenkinsProvider#import} method. + * use the {@link JenkinsProvider#fromJenkinsProviderAttributes} method. */ export interface IJenkinsProvider extends cdk.IConstruct { readonly providerName: string; @@ -40,7 +40,7 @@ export interface IJenkinsProvider extends cdk.IConstruct { /** * Properties for importing an existing Jenkins provider. */ -export interface JenkinsProviderImportProps { +export interface JenkinsProviderAttributes { /** * The name of the Jenkins provider that you set in the AWS CodePipeline plugin configuration of your Jenkins project. * @@ -109,20 +109,6 @@ export abstract class BaseJenkinsProvider extends cdk.Construct implements IJenk this.version = version || '1'; } - public export(): JenkinsProviderImportProps { - return { - providerName: new cdk.CfnOutput(this, 'JenkinsProviderName', { - value: this.providerName, - }).makeImportValue().toString(), - serverUrl: new cdk.CfnOutput(this, 'JenkinsServerUrl', { - value: this.serverUrl, - }).makeImportValue().toString(), - version: new cdk.CfnOutput(this, 'JenkinsProviderVersion', { - value: this.version, - }).makeImportValue().toString(), - }; - } - /** * @internal */ @@ -146,11 +132,11 @@ export class JenkinsProvider extends BaseJenkinsProvider { * * @param scope the parent Construct for the new provider * @param id the identifier of the new provider Construct - * @param props the properties used to identify the existing provider + * @param attrs the properties used to identify the existing provider * @returns a new Construct representing a reference to an existing Jenkins provider */ - public static import(scope: cdk.Construct, id: string, props: JenkinsProviderImportProps): IJenkinsProvider { - return new ImportedJenkinsProvider(scope, id, props); + public static fromJenkinsProviderAttributes(scope: cdk.Construct, id: string, attrs: JenkinsProviderAttributes): IJenkinsProvider { + return new ImportedJenkinsProvider(scope, id, attrs); } public readonly providerName: string; @@ -218,7 +204,7 @@ class ImportedJenkinsProvider extends BaseJenkinsProvider { public readonly providerName: string; public readonly serverUrl: string; - constructor(scope: cdk.Construct, id: string, props: JenkinsProviderImportProps) { + constructor(scope: cdk.Construct, id: string, props: JenkinsProviderAttributes) { super(scope, id, props.version); this.providerName = props.providerName; diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/ecs/test.ecs-deploy-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/ecs/test.ecs-deploy-action.ts index d3b063b1b6a0e..11da9af0ca943 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/ecs/test.ecs-deploy-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/ecs/test.ecs-deploy-action.ts @@ -74,7 +74,7 @@ function anyEcsService(): ecs.FargateService { taskDefinition.addContainer('MainContainer', { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), }); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const cluster = new ecs.Cluster(stack, 'Cluster', { vpc, }); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.ts index c98510d3c392f..81ebb797ce552 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.ts @@ -17,7 +17,7 @@ const bucket = new s3.Bucket(stack, 'PipelineBucket', { removalPolicy: cdk.RemovalPolicy.Destroy, }); const key = 'key'; -const trail = new cloudtrail.CloudTrail(stack, 'CloudTrail'); +const trail = new cloudtrail.Trail(stack, 'CloudTrail'); trail.addS3EventSelector([bucket.arnForObjects(key)], { readWriteType: cloudtrail.ReadWriteType.WriteOnly, includeManagementEvents: false }); sourceStage.addAction(new cpactions.S3SourceAction({ actionName: 'Source', diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.ts index 2d1057df99ea4..a33ee05eaee79 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.ts @@ -13,7 +13,7 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-codepipeline-ecs-deploy'); -const vpc = new ec2.VpcNetwork(stack, 'VPC', { +const vpc = new ec2.Vpc(stack, 'VPC', { maxAZs: 1, }); const cluster = new ecs.Cluster(stack, "EcsCluster", { diff --git a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts index b608020f8590a..151088aa2c747 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts @@ -224,7 +224,7 @@ export class Pipeline extends PipelineBase { // If a bucket has been provided, use it - otherwise, create a bucket. let propsBucket = props.artifactBucket; if (!propsBucket) { - const encryptionKey = new kms.EncryptionKey(this, 'ArtifactsBucketEncryptionKey'); + const encryptionKey = new kms.Key(this, 'ArtifactsBucketEncryptionKey'); propsBucket = new s3.Bucket(this, 'ArtifactsBucket', { encryptionKey, encryption: s3.BucketEncryption.Kms, diff --git a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts index b1c039be4d4e9..0256fb2ff6fe6 100644 --- a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts +++ b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts @@ -1,6 +1,6 @@ import iam = require('@aws-cdk/aws-iam'); import lambda = require('@aws-cdk/aws-lambda'); -import { CfnOutput, Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; +import { Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; import { CfnUserPool } from './cognito.generated'; /** @@ -280,12 +280,6 @@ export interface IUserPool extends IResource { * @attribute */ readonly userPoolProviderUrl: string; - - /** - * Exports a User Pool from this stack - * @returns user pool props that can be imported into another stack - */ - export(): UserPoolAttributes; } /** @@ -307,10 +301,6 @@ export class UserPool extends Resource implements IUserPool { public readonly userPoolArn = attrs.userPoolArn; public readonly userPoolProviderName = attrs.userPoolProviderName; public readonly userPoolProviderUrl = attrs.userPoolProviderUrl; - - public export(): UserPoolAttributes { - return attrs; - } } return new Import(scope, id); @@ -493,15 +483,6 @@ export class UserPool extends Resource implements IUserPool { this.triggers = { ...this.triggers, verifyAuthChallengeResponse: fn.functionArn }; } - public export(): UserPoolAttributes { - return { - userPoolId: new CfnOutput(this, 'UserPoolId', { value: this.userPoolId }).makeImportValue().toString(), - userPoolArn: new CfnOutput(this, 'UserPoolArn', { value: this.userPoolArn }).makeImportValue().toString(), - userPoolProviderName: new CfnOutput(this, 'UserPoolProviderName', { value: this.userPoolProviderName }).makeImportValue().toString(), - userPoolProviderUrl: new CfnOutput(this, 'UserPoolProviderUrl', { value: this.userPoolProviderUrl }).makeImportValue().toString() - }; - } - private addLambdaPermission(fn: lambda.IFunction, name: string): void { const normalize = name.charAt(0).toUpperCase() + name.slice(1); fn.addPermission(`${normalize}Cognito`, { diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group-rule.ts b/packages/@aws-cdk/aws-ec2/lib/security-group-rule.ts index 71033b4d25955..4b5d0379b9066 100644 --- a/packages/@aws-cdk/aws-ec2/lib/security-group-rule.ts +++ b/packages/@aws-cdk/aws-ec2/lib/security-group-rule.ts @@ -1,3 +1,4 @@ +import { Token } from '@aws-cdk/cdk'; import { Connections, IConnectable } from "./connections"; /** @@ -152,7 +153,7 @@ export enum Protocol { * A single TCP port */ export class TcpPort implements IPortRange { - public readonly canInlineRule = true; + public readonly canInlineRule = !Token.isToken(this.port); constructor(private readonly port: number) { } @@ -166,29 +167,7 @@ export class TcpPort implements IPortRange { } public toString() { - return `${this.port}`; - } -} - -/** - * A single TCP port that is provided by a resource attribute - */ -export class TcpPortFromAttribute implements IPortRange { - public readonly canInlineRule = false; - - constructor(private readonly port: string) { - } - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.Tcp, - fromPort: this.port, - toPort: this.port - }; - } - - public toString() { - return '{IndirectPort}'; + return Token.isToken(this.port) ? `{IndirectPort}` : this.port.toString(); } } @@ -196,7 +175,7 @@ export class TcpPortFromAttribute implements IPortRange { * A TCP port range */ export class TcpPortRange implements IPortRange { - public readonly canInlineRule = true; + public readonly canInlineRule = !Token.isToken(this.startPort) && !Token.isToken(this.endPort); constructor(private readonly startPort: number, private readonly endPort: number) { } @@ -237,7 +216,7 @@ export class TcpAllPorts implements IPortRange { * A single UDP port */ export class UdpPort implements IPortRange { - public readonly canInlineRule = true; + public readonly canInlineRule = !Token.isToken(this.port); constructor(private readonly port: number) { } @@ -251,29 +230,8 @@ export class UdpPort implements IPortRange { } public toString() { - return `UDP ${this.port}`; - } -} - -/** - * A single UDP port that is provided by a resource attribute - */ -export class UdpPortFromAttribute implements IPortRange { - public readonly canInlineRule = false; - - constructor(private readonly port: string) { - } - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.Udp, - fromPort: this.port, - toPort: this.port - }; - } - - public toString() { - return 'UDP {IndirectPort}'; + const port = Token.isToken(this.port) ? '{IndirectPort}' : this.port; + return `UDP ${port}`; } } @@ -281,7 +239,7 @@ export class UdpPortFromAttribute implements IPortRange { * A UDP port range */ export class UdpPortRange implements IPortRange { - public readonly canInlineRule = true; + public readonly canInlineRule = !Token.isToken(this.startPort) && !Token.isToken(this.endPort); constructor(private readonly startPort: number, private readonly endPort: number) { } @@ -322,7 +280,7 @@ export class UdpAllPorts implements IPortRange { * A set of matching ICMP Type & Code */ export class IcmpTypeAndCode implements IPortRange { - public readonly canInlineRule = true; + public readonly canInlineRule = !Token.isToken(this.type) && !Token.isToken(this.code); constructor(private readonly type: number, private readonly code: number) { } @@ -363,7 +321,7 @@ export class IcmpPing implements IPortRange { * All ICMP Codes for a given ICMP Type */ export class IcmpAllTypeCodes implements IPortRange { - public readonly canInlineRule = true; + public readonly canInlineRule = !Token.isToken(this.type); constructor(private readonly type: number) { } diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group.ts b/packages/@aws-cdk/aws-ec2/lib/security-group.ts index 15245f5af3a05..0a5ea2ce16fd5 100644 --- a/packages/@aws-cdk/aws-ec2/lib/security-group.ts +++ b/packages/@aws-cdk/aws-ec2/lib/security-group.ts @@ -1,8 +1,8 @@ -import { CfnOutput, Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; +import { Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; import { Connections, IConnectable } from './connections'; import { CfnSecurityGroup, CfnSecurityGroupEgress, CfnSecurityGroupIngress } from './ec2.generated'; import { IPortRange, ISecurityGroupRule } from './security-group-rule'; -import { IVpcNetwork } from './vpc'; +import { IVpc } from './vpc'; const isSecurityGroupSymbol = Symbol.for('aws-cdk:isSecurityGroup'); @@ -34,18 +34,6 @@ export interface ISecurityGroup extends IResource, ISecurityGroupRule, IConnecta * SecurityGroup object. */ addEgressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string, remoteRule?: boolean): void; - - /** - * Export the security group - */ - export(): SecurityGroupAttributes; -} - -export interface SecurityGroupAttributes { - /** - * ID of security group - */ - readonly securityGroupId: string; } /** @@ -122,11 +110,6 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { public toEgressRuleJSON(): any { return { destinationSecurityGroupId: this.securityGroupId }; } - - /** - * Export this SecurityGroup for use in a different Stack - */ - public abstract export(): SecurityGroupAttributes; } /** @@ -221,7 +204,7 @@ export interface SecurityGroupProps { /** * The VPC in which to create the security group. */ - readonly vpc: IVpcNetwork; + readonly vpc: IVpc; /** * Whether to allow all outbound traffic by default. @@ -250,9 +233,6 @@ export class SecurityGroup extends SecurityGroupBase { public static fromSecurityGroupId(scope: Construct, id: string, securityGroupId: string): ISecurityGroup { class Import extends SecurityGroupBase { public securityGroupId = securityGroupId; - public export(): SecurityGroupAttributes { - return { securityGroupId }; - } } return new Import(scope, id); @@ -307,15 +287,6 @@ export class SecurityGroup extends SecurityGroupBase { this.addDefaultEgressRule(); } - /** - * Export this SecurityGroup for use in a different Stack - */ - public export(): SecurityGroupAttributes { - return { - securityGroupId: new CfnOutput(this, 'SecurityGroupId', { value: this.securityGroupId }).makeImportValue().toString() - }; - } - public addIngressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string, remoteRule?: boolean) { if (!peer.canInlineRule || !connection.canInlineRule) { super.addIngressRule(peer, connection, description, remoteRule); diff --git a/packages/@aws-cdk/aws-ec2/lib/util.ts b/packages/@aws-cdk/aws-ec2/lib/util.ts index b52c460aba921..ee28b8646f90e 100644 --- a/packages/@aws-cdk/aws-ec2/lib/util.ts +++ b/packages/@aws-cdk/aws-ec2/lib/util.ts @@ -1,5 +1,5 @@ import cdk = require('@aws-cdk/cdk'); -import { IVpcSubnet, SubnetType, VpcSubnet } from './vpc'; +import { ISubnet, Subnet, SubnetType } from './vpc'; /** * Turn an arbitrary string into one that can be used as a CloudFormation identifier by stripping special characters @@ -26,7 +26,7 @@ export function defaultSubnetName(type: SubnetType) { * * All subnet names look like NAME <> "Subnet" <> INDEX */ -export function subnetName(subnet: IVpcSubnet) { +export function subnetName(subnet: ISubnet) { return subnet.node.id.replace(/Subnet\d+$/, ''); } @@ -37,63 +37,6 @@ export function subnetId(name: string, i: number) { return `${name}Subnet${i + 1}`; } -/** - * Helper class to export/import groups of subnets - */ -export class ExportSubnetGroup { - public readonly ids?: string[]; - public readonly names?: string[]; - - private readonly groups: number; - - constructor( - scope: cdk.Construct, - exportName: string, - private readonly subnets: IVpcSubnet[], - private readonly type: SubnetType, - private readonly azs: number) { - - this.groups = subnets.length / azs; - - // ASSERTION - if (Math.floor(this.groups) !== this.groups) { - throw new Error(`Number of subnets (${subnets.length}) must be a multiple of number of availability zones (${azs})`); - } - - this.ids = this.exportIds(scope, exportName); - this.names = this.exportNames(); - } - - private exportIds(scope: cdk.Construct, name: string): string[] | undefined { - if (this.subnets.length === 0) { return undefined; } - return new cdk.StringListCfnOutput(scope, name, { values: this.subnets.map(s => s.subnetId) }).makeImportValues().map(x => x.toString()); - } - - /** - * Return the list of subnet names if they're not equal to the default - */ - private exportNames(): string[] | undefined { - if (this.subnets.length === 0) { return undefined; } - const netNames = this.subnets.map(subnetName); - - // Do some assertion that the 'netNames' array is laid out like this: - // - // [ INGRESS, INGRESS, INGRESS, EGRESS, EGRESS, EGRESS, ... ] - for (let i = 0; i < netNames.length; i++) { - const k = Math.floor(i / this.azs); - if (netNames[i] !== netNames[k * this.azs]) { - throw new Error(`Subnets must be grouped by name, got: ${JSON.stringify(netNames)}`); - } - } - - // Splat down to [ INGRESS, EGRESS, ... ] - const groupNames = range(this.groups).map(i => netNames[i * this.azs]); - if (groupNames.length === 1 && groupNames[0] === defaultSubnetName(this.type)) { return undefined; } - - return groupNames; - } -} - export class ImportSubnetGroup { private readonly subnetIds: string[]; private readonly names: string[]; @@ -118,10 +61,10 @@ export class ImportSubnetGroup { this.names = this.normalizeNames(names, defaultSubnetName(type), nameField); } - public import(scope: cdk.Construct): IVpcSubnet[] { + public import(scope: cdk.Construct): ISubnet[] { return range(this.subnetIds.length).map(i => { const k = Math.floor(i / this.availabilityZones.length); - return VpcSubnet.import(scope, subnetId(this.names[k], i), { + return Subnet.fromSubnetAttributes(scope, subnetId(this.names[k], i), { availabilityZone: this.pickAZ(i), subnetId: this.subnetIds[i] }); diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts index e07837225a4b7..440687e06c2d4 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts @@ -1,22 +1,23 @@ import iam = require('@aws-cdk/aws-iam'); -import cdk = require('@aws-cdk/cdk'); +import { Aws, Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; import { Connections, IConnectable } from './connections'; import { CfnVPCEndpoint } from './ec2.generated'; import { SecurityGroup } from './security-group'; -import { TcpPort, TcpPortFromAttribute } from './security-group-rule'; -import { IVpcNetwork, SubnetSelection, SubnetType } from './vpc'; +import { TcpPort } from './security-group-rule'; +import { IVpc, SubnetSelection, SubnetType } from './vpc'; /** * A VPC endpoint. */ -export interface IVpcEndpoint extends cdk.IConstruct { +export interface IVpcEndpoint extends IResource { /** * The VPC endpoint identifier. + * @attribute */ readonly vpcEndpointId: string; } -export abstract class VpcEndpoint extends cdk.Construct implements IVpcEndpoint { +export abstract class VpcEndpoint extends Resource implements IVpcEndpoint { public abstract readonly vpcEndpointId: string; protected policyDocument?: iam.PolicyDocument; @@ -47,10 +48,6 @@ export abstract class VpcEndpoint extends cdk.Construct implements IVpcEndpoint * A gateway VPC endpoint. */ export interface IGatewayVpcEndpoint extends IVpcEndpoint { - /** - * Exports this VPC endpoint from the stack. - */ - export(): GatewayVpcEndpointImportProps; } /** @@ -98,7 +95,7 @@ export class GatewayVpcEndpointAwsService implements IGatewayVpcEndpointService public readonly name: string; constructor(name: string, prefix?: string) { - this.name = `${prefix || 'com.amazonaws'}.${cdk.Aws.region}.${name}`; + this.name = `${prefix || 'com.amazonaws'}.${Aws.region}.${name}`; } } @@ -126,18 +123,21 @@ export interface GatewayVpcEndpointProps extends GatewayVpcEndpointOptions { /** * The VPC network in which the gateway endpoint will be used. */ - readonly vpc: IVpcNetwork + readonly vpc: IVpc } /** * A gateway VPC endpoint. + * @resource AWS::EC2::VPCEndpoint */ export class GatewayVpcEndpoint extends VpcEndpoint implements IGatewayVpcEndpoint { - /** - * Imports an existing gateway VPC endpoint. - */ - public static import(scope: cdk.Construct, id: string, props: GatewayVpcEndpointImportProps): IGatewayVpcEndpoint { - return new ImportedGatewayVpcEndpoint(scope, id, props); + + public static fromGatewayVpcEndpointId(scope: Construct, id: string, gatewayVpcEndpointId: string): IGatewayVpcEndpoint { + class Import extends VpcEndpoint { + public vpcEndpointId = gatewayVpcEndpointId; + } + + return new Import(scope, id); } /** @@ -147,10 +147,21 @@ export class GatewayVpcEndpoint extends VpcEndpoint implements IGatewayVpcEndpoi /** * The date and time the gateway VPC endpoint was created. + * @attribute */ public readonly vpcEndpointCreationTimestamp: string; - constructor(scope: cdk.Construct, id: string, props: GatewayVpcEndpointProps) { + /** + * @attribute + */ + public readonly vpcEndpointNetworkInterfaceIds: string[]; + + /** + * @attribute + */ + public readonly vpcEndpointDnsEntries: string[]; + + constructor(scope: Construct, id: string, props: GatewayVpcEndpointProps) { super(scope, id); const subnets = props.subnets || [{ subnetType: SubnetType.Private }]; @@ -161,7 +172,7 @@ export class GatewayVpcEndpoint extends VpcEndpoint implements IGatewayVpcEndpoi } const endpoint = new CfnVPCEndpoint(this, 'Resource', { - policyDocument: new cdk.Token(() => this.policyDocument), + policyDocument: new Token(() => this.policyDocument), routeTableIds, serviceName: props.service.name, vpcEndpointType: VpcEndpointType.Gateway, @@ -170,48 +181,8 @@ export class GatewayVpcEndpoint extends VpcEndpoint implements IGatewayVpcEndpoi this.vpcEndpointId = endpoint.vpcEndpointId; this.vpcEndpointCreationTimestamp = endpoint.vpcEndpointCreationTimestamp; - } - - /** - * Exports this gateway VPC endpoint from the stack. - */ - public export(): GatewayVpcEndpointImportProps { - return { - vpcEndpointId: new cdk.CfnOutput(this, 'VpcEndpointId', { value: this.vpcEndpointId }).makeImportValue().toString() - }; - } -} - -/** - * Construction properties for an ImportedGatewayVpcEndpoint. - */ -export interface GatewayVpcEndpointImportProps { - /** - * The gateway VPC endpoint identifier. - */ - readonly vpcEndpointId: string; -} - -/** - * An imported gateway VPC endpoint. - */ -class ImportedGatewayVpcEndpoint extends cdk.Construct implements IGatewayVpcEndpoint { - /** - * The gateway VPC endpoint identifier. - */ - public readonly vpcEndpointId: string; - - constructor(scope: cdk.Construct, id: string, private readonly props: GatewayVpcEndpointImportProps) { - super(scope, id); - - this.vpcEndpointId = props.vpcEndpointId; - } - - /** - * Exports this gateway VPC endpoint from the stack. - */ - public export(): GatewayVpcEndpointImportProps { - return this.props; + this.vpcEndpointDnsEntries = endpoint.vpcEndpointDnsEntries; + this.vpcEndpointNetworkInterfaceIds = endpoint.vpcEndpointNetworkInterfaceIds; } } @@ -283,7 +254,7 @@ export class InterfaceVpcEndpointAwsService implements IInterfaceVpcEndpointServ public readonly port: number; constructor(name: string, prefix?: string, port?: number) { - this.name = `${prefix || 'com.amazonaws'}.${cdk.Aws.region}.${name}`; + this.name = `${prefix || 'com.amazonaws'}.${Aws.region}.${name}`; this.port = port || 443; } } @@ -321,28 +292,34 @@ export interface InterfaceVpcEndpointProps extends InterfaceVpcEndpointOptions { /** * The VPC network in which the interface endpoint will be used. */ - readonly vpc: IVpcNetwork + readonly vpc: IVpc } /** * An interface VPC endpoint. */ export interface IInterfaceVpcEndpoint extends IVpcEndpoint, IConnectable { - /** - * Exports this interface VPC endpoint from the stack. - */ - export(): InterfaceVpcEndpointImportProps; } /** * A interface VPC endpoint. + * @resource AWS::EC2::VPCEndpoint */ export class InterfaceVpcEndpoint extends VpcEndpoint implements IInterfaceVpcEndpoint { /** * Imports an existing interface VPC endpoint. */ - public static import(scope: cdk.Construct, id: string, props: InterfaceVpcEndpointImportProps): IInterfaceVpcEndpoint { - return new ImportedInterfaceVpcEndpoint(scope, id, props); + public static fromInterfaceVpcEndpointAttributes(scope: Construct, id: string, attrs: InterfaceVpcEndpointAttributes): IInterfaceVpcEndpoint { + class Import extends Resource implements IInterfaceVpcEndpoint { + public readonly vpcEndpointId = attrs.vpcEndpointId; + public readonly securityGroupId = attrs.securityGroupId; + public readonly connections = new Connections({ + defaultPortRange: new TcpPort(attrs.port), + securityGroups: [SecurityGroup.fromSecurityGroupId(this, 'SecurityGroup', attrs.securityGroupId)], + }); + } + + return new Import(scope, id); } /** @@ -352,18 +329,21 @@ export class InterfaceVpcEndpoint extends VpcEndpoint implements IInterfaceVpcEn /** * The date and time the interface VPC endpoint was created. + * @attribute */ public readonly vpcEndpointCreationTimestamp: string; /** * The DNS entries for the interface VPC endpoint. + * @attribute */ - public readonly dnsEntries: string[]; + public readonly vpcEndpointDnsEntries: string[]; /** * One or more network interfaces for the interface VPC endpoint. + * @attribute */ - public readonly networkInterfaceIds: string[]; + public readonly vpcEndpointNetworkInterfaceIds: string[]; /** * The identifier of the security group associated with this interface VPC @@ -376,12 +356,9 @@ export class InterfaceVpcEndpoint extends VpcEndpoint implements IInterfaceVpcEn */ public readonly connections: Connections; - private readonly port: number; - - constructor(scope: cdk.Construct, id: string, props: InterfaceVpcEndpointProps) { + constructor(scope: Construct, id: string, props: InterfaceVpcEndpointProps) { super(scope, id); - this.port = props.service.port; const securityGroup = new SecurityGroup(this, 'SecurityGroup', { vpc: props.vpc }); @@ -396,7 +373,7 @@ export class InterfaceVpcEndpoint extends VpcEndpoint implements IInterfaceVpcEn const endpoint = new CfnVPCEndpoint(this, 'Resource', { privateDnsEnabled: props.privateDnsEnabled || true, - policyDocument: new cdk.Token(() => this.policyDocument), + policyDocument: new Token(() => this.policyDocument), securityGroupIds: [this.securityGroupId], serviceName: props.service.name, vpcEndpointType: VpcEndpointType.Interface, @@ -406,26 +383,15 @@ export class InterfaceVpcEndpoint extends VpcEndpoint implements IInterfaceVpcEn this.vpcEndpointId = endpoint.vpcEndpointId; this.vpcEndpointCreationTimestamp = endpoint.vpcEndpointCreationTimestamp; - this.dnsEntries = endpoint.vpcEndpointDnsEntries; - this.networkInterfaceIds = endpoint.vpcEndpointNetworkInterfaceIds; - } - - /** - * Exports this interface VPC endpoint from the stack. - */ - public export(): InterfaceVpcEndpointImportProps { - return { - vpcEndpointId: new cdk.CfnOutput(this, 'VpcEndpointId', { value: this.vpcEndpointId }).makeImportValue().toString(), - securityGroupId: new cdk.CfnOutput(this, 'SecurityGroupId', { value: this.securityGroupId }).makeImportValue().toString(), - port: new cdk.CfnOutput(this, 'port', { value: this.port }).makeImportValue().toString() - }; + this.vpcEndpointDnsEntries = endpoint.vpcEndpointDnsEntries; + this.vpcEndpointNetworkInterfaceIds = endpoint.vpcEndpointNetworkInterfaceIds; } } /** * Construction properties for an ImportedInterfaceVpcEndpoint. */ -export interface InterfaceVpcEndpointImportProps { +export interface InterfaceVpcEndpointAttributes { /** * The interface VPC endpoint identifier. */ @@ -439,45 +405,5 @@ export interface InterfaceVpcEndpointImportProps { /** * The port of the service of the interface VPC endpoint. */ - readonly port: string; -} - -/** - * An imported VPC interface endpoint. - */ -class ImportedInterfaceVpcEndpoint extends cdk.Construct implements IInterfaceVpcEndpoint { - /** - * The interface VPC endpoint identifier. - */ - public readonly vpcEndpointId: string; - - /** - * The identifier of the security group associated with the interface VPC endpoint. - */ - public readonly securityGroupId: string; - - /** - * Access to network connections. - */ - public readonly connections: Connections; - - constructor(scope: cdk.Construct, id: string, private readonly props: InterfaceVpcEndpointImportProps) { - super(scope, id); - - this.vpcEndpointId = props.vpcEndpointId; - - this.securityGroupId = props.securityGroupId; - - this.connections = new Connections({ - defaultPortRange: new TcpPortFromAttribute(props.port), - securityGroups: [SecurityGroup.fromSecurityGroupId(this, 'SecurityGroup', props.securityGroupId)], - }); - } - - /** - * Exports this interface VPC endpoint from the stack. - */ - public export(): InterfaceVpcEndpointImportProps { - return this.props; - } + readonly port: number; } diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts index f8d65f185eec7..574059f78887f 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-network-provider.ts @@ -1,6 +1,6 @@ import cdk = require('@aws-cdk/cdk'); import cxapi = require('@aws-cdk/cx-api'); -import { VpcNetworkImportProps } from './vpc'; +import { VpcAttributes } from './vpc'; /** * Properties for looking up an existing VPC. @@ -8,7 +8,7 @@ import { VpcNetworkImportProps } from './vpc'; * The combination of properties must specify filter down to exactly one * non-default VPC, otherwise an error is raised. */ -export interface VpcNetworkProviderProps { +export interface VpcLookupOptions { /** * The ID of the VPC * @@ -50,14 +50,14 @@ export interface VpcNetworkProviderProps { export class VpcNetworkProvider { private provider: cdk.ContextProvider; - constructor(context: cdk.Construct, props: VpcNetworkProviderProps) { - const filter: {[key: string]: string} = props.tags || {}; + constructor(context: cdk.Construct, options: VpcLookupOptions) { + const filter: {[key: string]: string} = options.tags || {}; // We give special treatment to some tags - if (props.vpcId) { filter['vpc-id'] = props.vpcId; } - if (props.vpcName) { filter['tag:Name'] = props.vpcName; } - if (props.isDefault !== undefined) { - filter.isDefault = props.isDefault ? 'true' : 'false'; + if (options.vpcId) { filter['vpc-id'] = options.vpcId; } + if (options.vpcName) { filter['tag:Name'] = options.vpcName; } + if (options.isDefault !== undefined) { + filter.isDefault = options.isDefault ? 'true' : 'false'; } this.provider = new cdk.ContextProvider(context, cxapi.VPC_PROVIDER, { filter } as cxapi.VpcContextQuery); @@ -66,7 +66,7 @@ export class VpcNetworkProvider { /** * Return the VPC import props matching the filter */ - public get vpcProps(): VpcNetworkImportProps { + public get vpcProps(): VpcAttributes { const ret: cxapi.VpcContextResponse = this.provider.getValue(DUMMY_VPC_PROPS); return ret; } diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index 0d88c5ba6161d..2853c6fa21631 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -1,15 +1,15 @@ import cdk = require('@aws-cdk/cdk'); -import { ConcreteDependable, Construct, IConstruct, IDependable } from '@aws-cdk/cdk'; +import { ConcreteDependable, Construct, IConstruct, IDependable, IResource, Resource } from '@aws-cdk/cdk'; import { CfnEIP, CfnInternetGateway, CfnNatGateway, CfnRoute, CfnVPNGateway, CfnVPNGatewayRoutePropagation } from './ec2.generated'; import { CfnRouteTable, CfnSubnet, CfnSubnetRouteTableAssociation, CfnVPC, CfnVPCGatewayAttachment } from './ec2.generated'; import { NetworkBuilder } from './network-util'; -import { defaultSubnetName, ExportSubnetGroup, ImportSubnetGroup, subnetId, subnetName } from './util'; +import { defaultSubnetName, ImportSubnetGroup, subnetId, subnetName } from './util'; import { GatewayVpcEndpoint, GatewayVpcEndpointAwsService, GatewayVpcEndpointOptions } from './vpc-endpoint'; import { InterfaceVpcEndpoint, InterfaceVpcEndpointOptions } from './vpc-endpoint'; -import { VpcNetworkProvider, VpcNetworkProviderProps } from './vpc-network-provider'; +import { VpcLookupOptions, VpcNetworkProvider } from './vpc-network-provider'; import { VpnConnection, VpnConnectionOptions, VpnConnectionType } from './vpn'; -export interface IVpcSubnet extends IConstruct { +export interface ISubnet extends IResource { /** * The Availability Zone the subnet is located in */ @@ -17,6 +17,7 @@ export interface IVpcSubnet extends IConstruct { /** * The subnetId for this particular subnet + * @attribute */ readonly subnetId: string; @@ -29,33 +30,29 @@ export interface IVpcSubnet extends IConstruct { * Route table ID */ readonly routeTableId?: string; - - /** - * Exports this subnet to another stack. - */ - export(): VpcSubnetImportProps; } -export interface IVpcNetwork extends IConstruct { +export interface IVpc extends IResource { /** * Identifier for this VPC + * @attribute */ readonly vpcId: string; /** * List of public subnets in this VPC */ - readonly publicSubnets: IVpcSubnet[]; + readonly publicSubnets: ISubnet[]; /** * List of private subnets in this VPC */ - readonly privateSubnets: IVpcSubnet[]; + readonly privateSubnets: ISubnet[]; /** * List of isolated subnets in this VPC */ - readonly isolatedSubnets: IVpcSubnet[]; + readonly isolatedSubnets: ISubnet[]; /** * AZs for this VPC @@ -65,7 +62,7 @@ export interface IVpcNetwork extends IConstruct { /** * Region where this VPC is located */ - readonly vpcRegion: string; + readonly region: string; /** * Identifier for the VPN gateway @@ -104,11 +101,6 @@ export interface IVpcNetwork extends IConstruct { * Adds a new interface endpoint to this VPC */ addInterfaceEndpoint(id: string, options: InterfaceVpcEndpointOptions): InterfaceVpcEndpoint - - /** - * Exports this VPC so it can be consumed by another stack. - */ - export(): VpcNetworkImportProps; } /** @@ -215,7 +207,7 @@ export interface SelectedSubnets { /** * A new or imported VPC */ -abstract class VpcNetworkBase extends Construct implements IVpcNetwork { +abstract class VpcBase extends Resource implements IVpc { /** * Identifier for this VPC @@ -225,17 +217,17 @@ abstract class VpcNetworkBase extends Construct implements IVpcNetwork { /** * List of public subnets in this VPC */ - public abstract readonly publicSubnets: IVpcSubnet[]; + public abstract readonly publicSubnets: ISubnet[]; /** * List of private subnets in this VPC */ - public abstract readonly privateSubnets: IVpcSubnet[]; + public abstract readonly privateSubnets: ISubnet[]; /** * List of isolated subnets in this VPC */ - public abstract readonly isolatedSubnets: IVpcSubnet[]; + public abstract readonly isolatedSubnets: ISubnet[]; /** * AZs for this VPC @@ -295,11 +287,6 @@ abstract class VpcNetworkBase extends Construct implements IVpcNetwork { }); } - /** - * Export this VPC from the stack - */ - public abstract export(): VpcNetworkImportProps; - /** * Return whether all of the given subnets are from the VPC's public subnets. */ @@ -311,16 +298,16 @@ abstract class VpcNetworkBase extends Construct implements IVpcNetwork { /** * The region where this VPC is defined */ - public get vpcRegion(): string { + public get region(): string { return this.node.stack.region; } /** * Return the subnets appropriate for the placement strategy */ - protected selectSubnetObjects(selection: SubnetSelection = {}): IVpcSubnet[] { + protected selectSubnetObjects(selection: SubnetSelection = {}): ISubnet[] { selection = reifySelectionDefaults(selection); - let subnets: IVpcSubnet[] = []; + let subnets: ISubnet[] = []; if (selection.subnetName !== undefined) { // Select by name const allSubnets = [...this.publicSubnets, ...this.privateSubnets, ...this.isolatedSubnets]; @@ -349,7 +336,7 @@ abstract class VpcNetworkBase extends Construct implements IVpcNetwork { /** * Properties that reference an external VpcNetwork */ -export interface VpcNetworkImportProps { +export interface VpcAttributes { /** * VPC's identifier */ @@ -408,7 +395,7 @@ export interface VpcNetworkImportProps { readonly vpnGatewayId?: string; } -export interface VpcSubnetImportProps { +export interface SubnetAttributes { /** * The Availability Zone the subnet is located in */ @@ -426,9 +413,9 @@ export interface VpcSubnetImportProps { const NAME_TAG: string = 'Name'; /** - * VpcNetworkProps allows you to specify configuration options for a VPC + * Configuration for Vpc */ -export interface VpcNetworkProps { +export interface VpcProps { /** * The CIDR range to use for the VPC (e.g. '10.0.0.0/16'). Should be a minimum of /28 and maximum size of /16. @@ -622,9 +609,9 @@ export interface SubnetConfiguration { * VpcNetwork deploys an AWS VPC, with public and private subnets per Availability Zone. * For example: * - * import { VpcNetwork } from '@aws-cdk/aws-ec2' + * import { Vpc } from '@aws-cdk/aws-ec2' * - * const vpc = new VpcNetwork(this, { + * const vpc = new Vpc(this, { * cidr: "10.0.0.0/16" * }) * @@ -637,15 +624,10 @@ export interface SubnetConfiguration { * for (let subnet of vpc.privateSubnets) { * * } + * + * @resource AWS::EC2::VPC */ -export class VpcNetwork extends VpcNetworkBase { - /** - * @returns The IPv4 CidrBlock as returned by the VPC - */ - public get cidr(): string { - return this.resource.getAtt("CidrBlock").toString(); - } - +export class Vpc extends VpcBase { /** * The default CIDR range used when creating VPCs. * This can be overridden using VpcNetworkProps when creating a VPCNetwork resource. @@ -672,15 +654,15 @@ export class VpcNetwork extends VpcNetworkBase { /** * Import an exported VPC */ - public static import(scope: cdk.Construct, id: string, props: VpcNetworkImportProps): IVpcNetwork { - return new ImportedVpcNetwork(scope, id, props); + public static fromVpcAttributes(scope: cdk.Construct, id: string, attrs: VpcAttributes): IVpc { + return new ImportedVpc(scope, id, attrs); } /** - * Import an existing VPC from context + * Import an existing VPC from by querying the AWS environment this stack is deployed to. */ - public static importFromContext(scope: cdk.Construct, id: string, props: VpcNetworkProviderProps): IVpcNetwork { - return VpcNetwork.import(scope, id, new VpcNetworkProvider(scope, props).vpcProps); + public static fromLookup(scope: cdk.Construct, id: string, options: VpcLookupOptions): IVpc { + return Vpc.fromVpcAttributes(scope, id, new VpcNetworkProvider(scope, options).vpcProps); } /** @@ -688,20 +670,45 @@ export class VpcNetwork extends VpcNetworkBase { */ public readonly vpcId: string; + /** + * @attribute + */ + public readonly vpcCidrBlock: string; + + /** + * @attribute + */ + public readonly vpcDefaultNetworkAcl: string; + + /** + * @attribute + */ + public readonly vpcCidrBlockAssociations: string[]; + + /** + * @attribute + */ + public readonly vpcDefaultSecurityGroup: string; + + /** + * @attribute + */ + public readonly vpcIpv6CidrBlocks: string[]; + /** * List of public subnets in this VPC */ - public readonly publicSubnets: IVpcSubnet[] = []; + public readonly publicSubnets: ISubnet[] = []; /** * List of private subnets in this VPC */ - public readonly privateSubnets: IVpcSubnet[] = []; + public readonly privateSubnets: ISubnet[] = []; /** * List of isolated subnets in this VPC */ - public readonly isolatedSubnets: IVpcSubnet[] = []; + public readonly isolatedSubnets: ISubnet[] = []; /** * AZs for this VPC @@ -716,7 +723,7 @@ export class VpcNetwork extends VpcNetworkBase { /** * The VPC resource */ - private resource: CfnVPC; + private readonly resource: CfnVPC; /** * The NetworkBuilder @@ -739,7 +746,7 @@ export class VpcNetwork extends VpcNetworkBase { * Network routing for the public subnets will be configured to allow outbound access directly via an Internet Gateway. * Network routing for the private subnets will be configured to allow outbound access via a set of resilient NAT Gateways (one per AZ). */ - constructor(scope: cdk.Construct, id: string, props: VpcNetworkProps = {}) { + constructor(scope: cdk.Construct, id: string, props: VpcProps = {}) { super(scope, id); // Can't have enabledDnsHostnames without enableDnsSupport @@ -747,7 +754,7 @@ export class VpcNetwork extends VpcNetworkBase { throw new Error('To use DNS Hostnames, DNS Support must be enabled, however, it was explicitly disabled.'); } - const cidrBlock = ifUndefined(props.cidr, VpcNetwork.DEFAULT_CIDR_RANGE); + const cidrBlock = ifUndefined(props.cidr, Vpc.DEFAULT_CIDR_RANGE); this.networkBuilder = new NetworkBuilder(cidrBlock); const enableDnsHostnames = props.enableDnsHostnames == null ? true : props.enableDnsHostnames; @@ -762,6 +769,12 @@ export class VpcNetwork extends VpcNetworkBase { instanceTenancy, }); + this.vpcDefaultNetworkAcl = this.resource.vpcDefaultNetworkAcl; + this.vpcCidrBlockAssociations = this.resource.vpcCidrBlockAssociations; + this.vpcCidrBlock = this.resource.vpcCidrBlock; + this.vpcDefaultSecurityGroup = this.resource.vpcDefaultSecurityGroup; + this.vpcIpv6CidrBlocks = this.resource.vpcIpv6CidrBlocks; + this.node.apply(new cdk.Tag(NAME_TAG, this.node.path)); this.availabilityZones = new cdk.AvailabilityZoneProvider(this).availabilityZones; @@ -772,7 +785,7 @@ export class VpcNetwork extends VpcNetworkBase { this.vpcId = this.resource.vpcId; - this.subnetConfiguration = ifUndefined(props.subnetConfiguration, VpcNetwork.DEFAULT_SUBNETS); + this.subnetConfiguration = ifUndefined(props.subnetConfiguration, Vpc.DEFAULT_SUBNETS); // subnetConfiguration and natGateways must be set before calling createSubnets this.createSubnets(); @@ -789,14 +802,14 @@ export class VpcNetwork extends VpcNetworkBase { vpcId: this.resource.ref }); - (this.publicSubnets as VpcPublicSubnet[]).forEach(publicSubnet => { + (this.publicSubnets as PublicSubnet[]).forEach(publicSubnet => { publicSubnet.addDefaultInternetRoute(igw.ref, att); }); // if gateways are needed create them this.createNatGateways(props.natGateways, props.natGatewaySubnets); - (this.privateSubnets as VpcPrivateSubnet[]).forEach((privateSubnet, i) => { + (this.privateSubnets as PrivateSubnet[]).forEach((privateSubnet, i) => { let ngwId = this.natGatewayByAZ[privateSubnet.availabilityZone]; if (ngwId === undefined) { const ngwArray = Array.from(Object.values(this.natGatewayByAZ)); @@ -886,31 +899,6 @@ export class VpcNetwork extends VpcNetworkBase { }); } - /** - * Export this VPC from the stack - */ - public export(): VpcNetworkImportProps { - const pub = new ExportSubnetGroup(this, 'PublicSubnetIDs', this.publicSubnets, SubnetType.Public, this.availabilityZones.length); - const priv = new ExportSubnetGroup(this, 'PrivateSubnetIDs', this.privateSubnets, SubnetType.Private, this.availabilityZones.length); - const iso = new ExportSubnetGroup(this, 'IsolatedSubnetIDs', this.isolatedSubnets, SubnetType.Isolated, this.availabilityZones.length); - - const vpnGatewayId = this.vpnGatewayId - ? new cdk.CfnOutput(this, 'VpnGatewayId', { value: this.vpnGatewayId }).makeImportValue().toString() - : undefined; - - return { - vpcId: new cdk.CfnOutput(this, 'VpcId', { value: this.vpcId }).makeImportValue().toString(), - vpnGatewayId, - availabilityZones: this.availabilityZones, - publicSubnetIds: pub.ids, - publicSubnetNames: pub.names, - privateSubnetIds: priv.ids, - privateSubnetNames: priv.names, - isolatedSubnetIds: iso.ids, - isolatedSubnetNames: iso.names, - }; - } - private createNatGateways(gateways?: number, placement?: SubnetSelection): void { const useNatGateway = this.subnetConfiguration.filter( subnet => (subnet.subnetType === SubnetType.Private)).length > 0; @@ -918,7 +906,7 @@ export class VpcNetwork extends VpcNetworkBase { const natCount = ifUndefined(gateways, useNatGateway ? this.availabilityZones.length : 0); - let natSubnets: VpcPublicSubnet[]; + let natSubnets: PublicSubnet[]; if (placement) { const subnets = this.selectSubnetObjects(placement); for (const sub of subnets) { @@ -926,9 +914,9 @@ export class VpcNetwork extends VpcNetworkBase { throw new Error(`natGatewayPlacement ${placement} contains non public subnet ${sub}`); } } - natSubnets = subnets as VpcPublicSubnet[]; + natSubnets = subnets as PublicSubnet[]; } else { - natSubnets = this.publicSubnets as VpcPublicSubnet[]; + natSubnets = this.publicSubnets as PublicSubnet[]; } natSubnets = natSubnets.slice(0, natCount); @@ -974,27 +962,27 @@ export class VpcNetwork extends VpcNetworkBase { } const name = subnetId(subnetConfig.name, index); - const subnetProps: VpcSubnetProps = { + const subnetProps: SubnetProps = { availabilityZone: zone, vpcId: this.vpcId, cidrBlock: this.networkBuilder.addSubnet(cidrMask), mapPublicIpOnLaunch: (subnetConfig.subnetType === SubnetType.Public), }; - let subnet: VpcSubnet; + let subnet: Subnet; switch (subnetConfig.subnetType) { case SubnetType.Public: - const publicSubnet = new VpcPublicSubnet(this, name, subnetProps); + const publicSubnet = new PublicSubnet(this, name, subnetProps); this.publicSubnets.push(publicSubnet); subnet = publicSubnet; break; case SubnetType.Private: - const privateSubnet = new VpcPrivateSubnet(this, name, subnetProps); + const privateSubnet = new PrivateSubnet(this, name, subnetProps); this.privateSubnets.push(privateSubnet); subnet = privateSubnet; break; case SubnetType.Isolated: - const isolatedSubnet = new VpcPrivateSubnet(this, name, subnetProps); + const isolatedSubnet = new PrivateSubnet(this, name, subnetProps); this.isolatedSubnets.push(isolatedSubnet); subnet = isolatedSubnet; break; @@ -1024,7 +1012,7 @@ function subnetTypeTagValue(type: SubnetType) { /** * Specify configuration parameters for a VPC subnet */ -export interface VpcSubnetProps { +export interface SubnetProps { /** * The availability zone for the subnet @@ -1053,15 +1041,17 @@ const IS_VPC_SUBNET = Symbol.for('@aws-cdk/aws-ec2.VpcSubnet'); /** * Represents a new VPC subnet resource + * + * @resource AWS::EC2::Subnet */ -export class VpcSubnet extends cdk.Construct implements IVpcSubnet { +export class Subnet extends cdk.Resource implements ISubnet { - public static isVpcSubnet(o: any): o is VpcSubnet { + public static isVpcSubnet(o: any): o is Subnet { return IS_VPC_SUBNET in o; } - public static import(scope: cdk.Construct, id: string, props: VpcSubnetImportProps): IVpcSubnet { - return new ImportedVpcSubnet(scope, id, props); + public static fromSubnetAttributes(scope: cdk.Construct, id: string, attrs: SubnetAttributes): ISubnet { + return new ImportedSubnet(scope, id, attrs); } /** @@ -1074,6 +1064,26 @@ export class VpcSubnet extends cdk.Construct implements IVpcSubnet { */ public readonly subnetId: string; + /** + * @attribute + */ + public readonly subnetVpcId: string; + + /** + * @attribute + */ + public readonly subnetAvailabilityZone: string; + + /** + * @attribute + */ + public readonly subnetIpv6CidrBlocks: string[]; + + /** + * @attribute + */ + public readonly subnetNetworkAclAssociationId: string; + /** * Parts of this VPC subnet */ @@ -1086,7 +1096,7 @@ export class VpcSubnet extends cdk.Construct implements IVpcSubnet { private readonly internetDependencies = new ConcreteDependable(); - constructor(scope: cdk.Construct, id: string, props: VpcSubnetProps) { + constructor(scope: cdk.Construct, id: string, props: SubnetProps) { super(scope, id); Object.defineProperty(this, IS_VPC_SUBNET, { value: true }); @@ -1101,6 +1111,11 @@ export class VpcSubnet extends cdk.Construct implements IVpcSubnet { mapPublicIpOnLaunch: props.mapPublicIpOnLaunch, }); this.subnetId = subnet.subnetId; + this.subnetVpcId = subnet.subnetVpcId; + this.subnetAvailabilityZone = subnet.subnetAvailabilityZone; + this.subnetIpv6CidrBlocks = subnet.subnetIpv6CidrBlocks; + this.subnetNetworkAclAssociationId = subnet.subnetNetworkAclAssociationId; + const table = new CfnRouteTable(this, 'RouteTable', { vpcId: props.vpcId, }); @@ -1113,13 +1128,6 @@ export class VpcSubnet extends cdk.Construct implements IVpcSubnet { }); } - public export(): VpcSubnetImportProps { - return { - availabilityZone: new cdk.CfnOutput(this, 'AvailabilityZone', { value: this.availabilityZone }).makeImportValue().toString(), - subnetId: new cdk.CfnOutput(this, 'VpcSubnetId', { value: this.subnetId }).makeImportValue().toString(), - }; - } - public get internetConnectivityEstablished(): IDependable { return this.internetDependencies; } @@ -1159,16 +1167,23 @@ export class VpcSubnet extends cdk.Construct implements IVpcSubnet { } // tslint:disable-next-line:no-empty-interface -export interface VpcPublicSubnetProps extends VpcSubnetProps { +export interface PublicSubnetProps extends SubnetProps { } +export interface IPublicSubnet extends ISubnet { } +export interface PublicSubnetAttributes extends SubnetAttributes { } + /** * Represents a public VPC subnet resource */ -export class VpcPublicSubnet extends VpcSubnet { +export class PublicSubnet extends Subnet implements IPublicSubnet { + + public static fromPublicSubnetAttributes(scope: Construct, id: string, attrs: PublicSubnetAttributes): IPublicSubnet { + return new ImportedSubnet(scope, id, attrs); + } - constructor(scope: cdk.Construct, id: string, props: VpcPublicSubnetProps) { + constructor(scope: cdk.Construct, id: string, props: PublicSubnetProps) { super(scope, id, props); } @@ -1190,15 +1205,24 @@ export class VpcPublicSubnet extends VpcSubnet { } // tslint:disable-next-line:no-empty-interface -export interface VpcPrivateSubnetProps extends VpcSubnetProps { +export interface PrivateSubnetProps extends SubnetProps { } +export interface IPrivateSubnet extends ISubnet { } + +export interface PrivateSubnetAttributes extends SubnetAttributes { } + /** * Represents a private VPC subnet resource */ -export class VpcPrivateSubnet extends VpcSubnet { - constructor(scope: cdk.Construct, id: string, props: VpcPrivateSubnetProps) { +export class PrivateSubnet extends Subnet implements IPrivateSubnet { + + public static fromPrivateSubnetAttributes(scope: Construct, id: string, attrs: PrivateSubnetAttributes): IPrivateSubnet { + return new ImportedSubnet(scope, id, attrs); + } + + constructor(scope: cdk.Construct, id: string, props: PrivateSubnetProps) { super(scope, id, props); } } @@ -1207,15 +1231,15 @@ function ifUndefined(value: T | undefined, defaultValue: T): T { return value !== undefined ? value : defaultValue; } -class ImportedVpcNetwork extends VpcNetworkBase { +class ImportedVpc extends VpcBase { public readonly vpcId: string; - public readonly publicSubnets: IVpcSubnet[]; - public readonly privateSubnets: IVpcSubnet[]; - public readonly isolatedSubnets: IVpcSubnet[]; + public readonly publicSubnets: ISubnet[]; + public readonly privateSubnets: ISubnet[]; + public readonly isolatedSubnets: ISubnet[]; public readonly availabilityZones: string[]; public readonly vpnGatewayId?: string; - constructor(scope: cdk.Construct, id: string, private readonly props: VpcNetworkImportProps) { + constructor(scope: cdk.Construct, id: string, props: VpcAttributes) { super(scope, id); this.vpcId = props.vpcId; @@ -1232,28 +1256,6 @@ class ImportedVpcNetwork extends VpcNetworkBase { this.privateSubnets = priv.import(this); this.isolatedSubnets = iso.import(this); } - - public export() { - return this.props; - } -} - -class ImportedVpcSubnet extends cdk.Construct implements IVpcSubnet { - public readonly internetConnectivityEstablished: cdk.IDependable = new cdk.ConcreteDependable(); - public readonly availabilityZone: string; - public readonly subnetId: string; - public readonly routeTableId?: string = undefined; - - constructor(scope: cdk.Construct, id: string, private readonly props: VpcSubnetImportProps) { - super(scope, id); - - this.subnetId = props.subnetId; - this.availabilityZone = props.availabilityZone; - } - - public export() { - return this.props; - } } /** @@ -1320,3 +1322,17 @@ function tap(x: T, fn: (x: T) => void): T { function notUndefined(x: T | undefined): x is T { return x !== undefined; } + +class ImportedSubnet extends cdk.Resource implements ISubnet, IPublicSubnet, IPrivateSubnet { + public readonly internetConnectivityEstablished: cdk.IDependable = new cdk.ConcreteDependable(); + public readonly availabilityZone: string; + public readonly subnetId: string; + public readonly routeTableId?: string = undefined; + + constructor(scope: Construct, id: string, attrs: SubnetAttributes) { + super(scope, id); + + this.availabilityZone = attrs.availabilityZone; + this.subnetId = attrs.subnetId; + } +} diff --git a/packages/@aws-cdk/aws-ec2/lib/vpn.ts b/packages/@aws-cdk/aws-ec2/lib/vpn.ts index ace419446ba45..b607dddc22a93 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpn.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpn.ts @@ -2,7 +2,7 @@ import cloudwatch = require('@aws-cdk/aws-cloudwatch'); import cdk = require('@aws-cdk/cdk'); import net = require('net'); import { CfnCustomerGateway, CfnVPNConnection, CfnVPNConnectionRoute } from './ec2.generated'; -import { IVpcNetwork } from './vpc'; +import { IVpc } from './vpc'; export interface IVpnConnection extends cdk.IConstruct { /** @@ -79,7 +79,7 @@ export interface VpnConnectionProps extends VpnConnectionOptions { /** * The VPC to connect to. */ - readonly vpc: IVpcNetwork; + readonly vpc: IVpc; } /** diff --git a/packages/@aws-cdk/aws-ec2/test/export-helper.ts b/packages/@aws-cdk/aws-ec2/test/export-helper.ts new file mode 100644 index 0000000000000..978c77d52ee18 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/export-helper.ts @@ -0,0 +1,82 @@ +import { CfnOutput, Construct, StringListCfnOutput } from '@aws-cdk/cdk'; +import { ISubnet, SubnetType, Vpc } from '../lib'; +import { defaultSubnetName, range, subnetName } from '../lib/util'; + +export function exportVpc(vpc: Vpc) { + const pub = new ExportSubnetGroup(vpc, 'PublicSubnetIDs', vpc.publicSubnets, SubnetType.Public, vpc.availabilityZones.length); + const priv = new ExportSubnetGroup(vpc, 'PrivateSubnetIDs', vpc.privateSubnets, SubnetType.Private, vpc.availabilityZones.length); + const iso = new ExportSubnetGroup(vpc, 'IsolatedSubnetIDs', vpc.isolatedSubnets, SubnetType.Isolated, vpc.availabilityZones.length); + + const vpnGatewayId = vpc.vpnGatewayId + ? new CfnOutput(vpc, 'VpnGatewayId', { value: vpc.vpnGatewayId }).makeImportValue().toString() + : undefined; + + return { + vpcId: new CfnOutput(vpc, 'VpcId', { value: vpc.vpcId }).makeImportValue().toString(), + vpnGatewayId, + availabilityZones: vpc.availabilityZones, + publicSubnetIds: pub.ids, + publicSubnetNames: pub.names, + privateSubnetIds: priv.ids, + privateSubnetNames: priv.names, + isolatedSubnetIds: iso.ids, + isolatedSubnetNames: iso.names, + }; +} + +/** + * Helper class to export/import groups of subnets + */ +export class ExportSubnetGroup { + public readonly ids?: string[]; + public readonly names?: string[]; + + private readonly groups: number; + + constructor( + scope: Construct, + exportName: string, + private readonly subnets: ISubnet[], + private readonly type: SubnetType, + private readonly azs: number) { + + this.groups = subnets.length / azs; + + // ASSERTION + if (Math.floor(this.groups) !== this.groups) { + throw new Error(`Number of subnets (${subnets.length}) must be a multiple of number of availability zones (${azs})`); + } + + this.ids = this.exportIds(scope, exportName); + this.names = this.exportNames(); + } + + private exportIds(scope: Construct, name: string): string[] | undefined { + if (this.subnets.length === 0) { return undefined; } + return new StringListCfnOutput(scope, name, { values: this.subnets.map(s => s.subnetId) }).makeImportValues().map(x => x.toString()); + } + + /** + * Return the list of subnet names if they're not equal to the default + */ + private exportNames(): string[] | undefined { + if (this.subnets.length === 0) { return undefined; } + const netNames = this.subnets.map(subnetName); + + // Do some assertion that the 'netNames' array is laid out like this: + // + // [ INGRESS, INGRESS, INGRESS, EGRESS, EGRESS, EGRESS, ... ] + for (let i = 0; i < netNames.length; i++) { + const k = Math.floor(i / this.azs); + if (netNames[i] !== netNames[k * this.azs]) { + throw new Error(`Subnets must be grouped by name, got: ${JSON.stringify(netNames)}`); + } + } + + // Splat down to [ INGRESS, EGRESS, ... ] + const groupNames = range(this.groups).map(i => netNames[i * this.azs]); + if (groupNames.length === 1 && groupNames[0] === defaultSubnetName(this.type)) { return undefined; } + + return groupNames; + } +} diff --git a/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts b/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts index 9208c3eaf09bd..4448cabe06e63 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts @@ -5,7 +5,7 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-ec2-import'); /// !show -const vpc = ec2.VpcNetwork.importFromContext(stack, 'VPC', { +const vpc = ec2.Vpc.fromLookup(stack, 'VPC', { // This imports the default VPC but you can also // specify a 'vpcName' or 'tags'. isDefault: true diff --git a/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts b/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts index b64036ce05013..c41c7c576493c 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts @@ -4,7 +4,7 @@ import ec2 = require("../lib"); const app = new cdk.App(); interface ConstructThatTakesAVpcProps { - vpc: ec2.IVpcNetwork; + vpc: ec2.IVpc; } class ConstructThatTakesAVpc extends cdk.Construct { @@ -18,17 +18,17 @@ class ConstructThatTakesAVpc extends cdk.Construct { * Stack1 creates the VPC */ class Stack1 extends cdk.Stack { - public readonly vpc: ec2.VpcNetwork; + public readonly vpc: ec2.Vpc; constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); - this.vpc = new ec2.VpcNetwork(this, 'VPC'); + this.vpc = new ec2.Vpc(this, 'VPC'); } } interface Stack2Props extends cdk.StackProps { - vpc: ec2.IVpcNetwork; + vpc: ec2.IVpc; } /** diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint.lit.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint.lit.ts index 4e9dca508c896..0de5e4720fe57 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint.lit.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint.lit.ts @@ -10,7 +10,7 @@ class VpcEndpointStack extends cdk.Stack { /// !show // Add gateway endpoints when creating the VPC - const vpc = new ec2.VpcNetwork(this, 'MyVpc', { + const vpc = new ec2.Vpc(this, 'MyVpc', { gatewayEndpoints: { S3: { service: ec2.GatewayVpcEndpointAwsService.S3 diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts index fe66412cd50de..103fadda5ae64 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts @@ -4,7 +4,7 @@ import ec2 = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-ec2-vpc'); -const vpc = new ec2.VpcNetwork(stack, 'MyVpc'); +const vpc = new ec2.Vpc(stack, 'MyVpc'); // Test Security Group Rules const sg = new ec2.SecurityGroup(stack, 'SG', { vpc }); diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpn.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpn.ts index 7d1db5544e51d..dd1bd34526fc0 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpn.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpn.ts @@ -4,7 +4,7 @@ import ec2 = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-ec2-vpn'); -const vpc = new ec2.VpcNetwork(stack, 'MyVpc', { +const vpc = new ec2.Vpc(stack, 'MyVpc', { cidr: '10.10.0.0/16', vpnConnections: { Dynamic: { // Dynamic routing diff --git a/packages/@aws-cdk/aws-ec2/test/test.connections.ts b/packages/@aws-cdk/aws-ec2/test/test.connections.ts index dca715d87ff44..f93ac6dea6eb6 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.connections.ts +++ b/packages/@aws-cdk/aws-ec2/test/test.connections.ts @@ -8,7 +8,7 @@ import { SecurityGroup, TcpAllPorts, TcpPort, - VpcNetwork, + Vpc, } from "../lib"; export = { @@ -16,7 +16,7 @@ export = { // GIVEN const stack = new Stack(undefined, 'TestStack', { env: { account: '12345678', region: 'dummy' }}); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); const sg1 = new SecurityGroup(stack, 'SG1', { vpc }); const sg2 = new SecurityGroup(stack, 'SG2', { vpc }); @@ -33,7 +33,7 @@ export = { '(imported) SecurityGroup can be used as target of .allowTo()'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); const sg1 = new SecurityGroup(stack, 'SomeSecurityGroup', { vpc, allowAllOutbound: false }); const somethingConnectable = new SomethingConnectable(new Connections({ securityGroups: [sg1] })); @@ -68,7 +68,7 @@ export = { 'security groups added to connections after rule still gets rule'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); const sg1 = new SecurityGroup(stack, 'SecurityGroup1', { vpc, allowAllOutbound: false }); const sg2 = new SecurityGroup(stack, 'SecurityGroup2', { vpc, allowAllOutbound: false }); const connections = new Connections({ securityGroups: [sg1] }); @@ -110,7 +110,7 @@ export = { 'when security groups are added to target they also get the rule'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); const sg1 = new SecurityGroup(stack, 'SecurityGroup1', { vpc, allowAllOutbound: false }); const sg2 = new SecurityGroup(stack, 'SecurityGroup2', { vpc, allowAllOutbound: false }); const sg3 = new SecurityGroup(stack, 'SecurityGroup3', { vpc, allowAllOutbound: false }); @@ -143,7 +143,7 @@ export = { 'multiple security groups allows internally between them'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); const sg1 = new SecurityGroup(stack, 'SecurityGroup1', { vpc, allowAllOutbound: false }); const sg2 = new SecurityGroup(stack, 'SecurityGroup2', { vpc, allowAllOutbound: false }); const connections = new Connections({ securityGroups: [sg1] }); @@ -168,11 +168,11 @@ export = { const app = new App(); const stack1 = new Stack(app, 'Stack1'); - const vpc1 = new VpcNetwork(stack1, 'VPC'); + const vpc1 = new Vpc(stack1, 'VPC'); const sg1 = new SecurityGroup(stack1, 'SecurityGroup', { vpc: vpc1, allowAllOutbound: false }); const stack2 = new Stack(app, 'Stack2'); - const vpc2 = new VpcNetwork(stack2, 'VPC'); + const vpc2 = new Vpc(stack2, 'VPC'); const sg2 = new SecurityGroup(stack2, 'SecurityGroup', { vpc: vpc2, allowAllOutbound: false }); // WHEN @@ -199,11 +199,11 @@ export = { const app = new App(); const stack1 = new Stack(app, 'Stack1'); - const vpc1 = new VpcNetwork(stack1, 'VPC'); + const vpc1 = new Vpc(stack1, 'VPC'); const sg1 = new SecurityGroup(stack1, 'SecurityGroup', { vpc: vpc1, allowAllOutbound: false }); const stack2 = new Stack(app, 'Stack2'); - const vpc2 = new VpcNetwork(stack2, 'VPC'); + const vpc2 = new Vpc(stack2, 'VPC'); const sg2 = new SecurityGroup(stack2, 'SecurityGroup', { vpc: vpc2, allowAllOutbound: false }); // WHEN @@ -230,12 +230,12 @@ export = { const app = new App(); const stack1 = new Stack(app, 'Stack1'); - const vpc1 = new VpcNetwork(stack1, 'VPC'); + const vpc1 = new Vpc(stack1, 'VPC'); const sg1a = new SecurityGroup(stack1, 'SecurityGroupA', { vpc: vpc1, allowAllOutbound: false }); const sg1b = new SecurityGroup(stack1, 'SecurityGroupB', { vpc: vpc1, allowAllOutbound: false }); const stack2 = new Stack(app, 'Stack2'); - const vpc2 = new VpcNetwork(stack2, 'VPC'); + const vpc2 = new Vpc(stack2, 'VPC'); const sg2 = new SecurityGroup(stack2, 'SecurityGroup', { vpc: vpc2, allowAllOutbound: false }); // WHEN diff --git a/packages/@aws-cdk/aws-ec2/test/test.security-group.ts b/packages/@aws-cdk/aws-ec2/test/test.security-group.ts index 2f4dd54eef80c..f54af3a228ce2 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.security-group.ts +++ b/packages/@aws-cdk/aws-ec2/test/test.security-group.ts @@ -1,5 +1,5 @@ import { expect, haveResource } from '@aws-cdk/assert'; -import { Stack } from '@aws-cdk/cdk'; +import { Stack, Token } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; import { @@ -14,20 +14,18 @@ import { SecurityGroup, TcpAllPorts, TcpPort, - TcpPortFromAttribute, TcpPortRange, UdpAllPorts, UdpPort, - UdpPortFromAttribute, UdpPortRange, - VpcNetwork + Vpc } from "../lib"; export = { 'security group can allows all outbound traffic by default'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); // WHEN new SecurityGroup(stack, 'SG1', { vpc, allowAllOutbound: true }); @@ -49,7 +47,7 @@ export = { 'no new outbound rule is added if we are allowing all traffic anyway'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); // WHEN const sg = new SecurityGroup(stack, 'SG1', { vpc, allowAllOutbound: true }); @@ -72,7 +70,7 @@ export = { 'security group disallow outbound traffic by default'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); // WHEN new SecurityGroup(stack, 'SG1', { vpc, allowAllOutbound: false }); @@ -96,7 +94,7 @@ export = { 'bogus outbound rule disappears if another rule is added'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); // WHEN const sg = new SecurityGroup(stack, 'SG1', { vpc, allowAllOutbound: false }); @@ -121,7 +119,7 @@ export = { 'all outbound rule cannot be added after creation'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); // WHEN const sg = new SecurityGroup(stack, 'SG1', { vpc, allowAllOutbound: false }); @@ -135,7 +133,7 @@ export = { 'peer between all types of peers and port range types'(test: Test) { // GIVEN const stack = new Stack(undefined, 'TestStack', { env: { account: '12345678', region: 'dummy' }}); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); const sg = new SecurityGroup(stack, 'SG', { vpc }); const peers = [ @@ -147,11 +145,11 @@ export = { const ports = [ new TcpPort(1234), - new TcpPortFromAttribute("tcp-test-port!"), + new TcpPort(new Token(5000).toNumber()), new TcpAllPorts(), new TcpPortRange(80, 90), new UdpPort(2345), - new UdpPortFromAttribute("udp-test-port!"), + new UdpPort(new Token(777).toNumber()), new UdpAllPorts(), new UdpPortRange(85, 95), new IcmpTypeAndCode(5, 1), @@ -171,6 +169,36 @@ export = { // THEN -- no crash + test.done(); + }, + + 'if tokens are used in ports, `canInlineRule` should be false to avoid cycles'(test: Test) { + // GIVEN + const p1 = new Token(() => 80).toNumber(); + const p2 = new Token(() => 5000).toNumber(); + + // WHEN + const ports = [ + new TcpPort(p1), + new TcpPort(p2), + new TcpPortRange(p1, 90), + new TcpPortRange(80, p2), + new TcpPortRange(p1, p2), + new UdpPort(p1), + new UdpPortRange(p1, 95), + new UdpPortRange(85, p2), + new UdpPortRange(p1, p2), + new IcmpTypeAndCode(p1, 1), + new IcmpTypeAndCode(5, p1), + new IcmpTypeAndCode(p1, p2), + new IcmpAllTypeCodes(p1), + ]; + + // THEN + for (const range of ports) { + test.equal(range.canInlineRule, false, range.toString()); + } + 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/test.vpc-endpoint.ts index 6de8f2f83f38f..6eb97b3f3653b 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.vpc-endpoint.ts +++ b/packages/@aws-cdk/aws-ec2/test/test.vpc-endpoint.ts @@ -3,7 +3,7 @@ import { PolicyStatement } from '@aws-cdk/aws-iam'; import { Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; // tslint:disable-next-line:max-line-length -import { GatewayVpcEndpoint, GatewayVpcEndpointAwsService, InterfaceVpcEndpoint, InterfaceVpcEndpointAwsService, SubnetType, VpcNetwork } from '../lib'; +import { GatewayVpcEndpoint, GatewayVpcEndpointAwsService, InterfaceVpcEndpoint, InterfaceVpcEndpointAwsService, SubnetType, Vpc } from '../lib'; export = { 'gateway endpoint': { @@ -12,7 +12,7 @@ export = { const stack = new Stack(); // WHEN - new VpcNetwork(stack, 'VpcNetwork', { + new Vpc(stack, 'VpcNetwork', { gatewayEndpoints: { S3: { service: GatewayVpcEndpointAwsService.S3 @@ -59,7 +59,7 @@ export = { const stack = new Stack(); // WHEN - new VpcNetwork(stack, 'VpcNetwork', { + new Vpc(stack, 'VpcNetwork', { gatewayEndpoints: { S3: { service: GatewayVpcEndpointAwsService.S3, @@ -121,7 +121,7 @@ export = { 'add statements to policy'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VpcNetwork'); + const vpc = new Vpc(stack, 'VpcNetwork'); const endpoint = vpc.addGatewayEndpoint('S3', { service: GatewayVpcEndpointAwsService.S3 }); @@ -158,7 +158,7 @@ export = { 'throws when adding a statement without a principal'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VpcNetwork'); + const vpc = new Vpc(stack, 'VpcNetwork'); const endpoint = vpc.addGatewayEndpoint('S3', { service: GatewayVpcEndpointAwsService.S3 }); @@ -175,24 +175,20 @@ export = { 'import/export'(test: Test) { // GIVEN - const stack1 = new Stack(); const stack2 = new Stack(); - const vpc = new VpcNetwork(stack1, 'Vpc1'); - const endpoint = vpc.addGatewayEndpoint('DynamoDB', { - service: GatewayVpcEndpointAwsService.DynamoDb - }); // WHEN - GatewayVpcEndpoint.import(stack2, 'ImportedEndpoint', endpoint.export()); + const ep = GatewayVpcEndpoint.fromGatewayVpcEndpointId(stack2, 'ImportedEndpoint', 'endpoint-id'); - // THEN: No error + // THEN + test.deepEqual(ep.vpcEndpointId, 'endpoint-id'); test.done(); }, 'conveniance methods for S3 and DynamoDB'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VpcNetwork'); + const vpc = new Vpc(stack, 'VpcNetwork'); // WHEN vpc.addS3Endpoint('S3'); @@ -235,7 +231,7 @@ export = { 'throws with an imported vpc'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = VpcNetwork.import(stack, 'VPC', { + const vpc = Vpc.fromVpcAttributes(stack, 'VPC', { vpcId: 'id', privateSubnetIds: ['1', '2', '3'], availabilityZones: ['a', 'b', 'c'] @@ -255,7 +251,7 @@ export = { 'add an endpoint to a vpc'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VpcNetwork'); + const vpc = new Vpc(stack, 'VpcNetwork'); // WHEN vpc.addInterfaceEndpoint('EcrDocker', { @@ -314,23 +310,21 @@ export = { 'import/export'(test: Test) { // GIVEN - const stack1 = new Stack(); const stack2 = new Stack(); - const vpc = new VpcNetwork(stack1, 'Vpc1'); - const endpoint = vpc.addInterfaceEndpoint('EC2', { - service: InterfaceVpcEndpointAwsService.Ec2 - }); // WHEN - const importedEndpoint = InterfaceVpcEndpoint.import(stack2, 'ImportedEndpoint', endpoint.export()); + const importedEndpoint = InterfaceVpcEndpoint.fromInterfaceVpcEndpointAttributes(stack2, 'ImportedEndpoint', { + securityGroupId: 'security-group-id', + vpcEndpointId: 'vpc-endpoint-id', + port: 80 + }); importedEndpoint.connections.allowDefaultPortFromAnyIpv4(); // THEN expect(stack2).to(haveResource('AWS::EC2::SecurityGroupIngress', { - GroupId: { - 'Fn::ImportValue': 'Stack:Vpc1EC2SecurityGroupId3B169C3F' - } + GroupId: 'security-group-id' })); + test.deepEqual(importedEndpoint.vpcEndpointId, 'vpc-endpoint-id'); test.done(); } diff --git a/packages/@aws-cdk/aws-ec2/test/test.vpc.ts b/packages/@aws-cdk/aws-ec2/test/test.vpc.ts index 4b384638a46f9..40532e0167ada 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.vpc.ts +++ b/packages/@aws-cdk/aws-ec2/test/test.vpc.ts @@ -1,7 +1,8 @@ import { countResources, expect, haveResource, haveResourceLike, isSuperObject } from '@aws-cdk/assert'; import { AvailabilityZoneProvider, Construct, Stack, Tag } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { CfnVPC, DefaultInstanceTenancy, IVpcNetwork, SubnetType, VpcNetwork } from '../lib'; +import { CfnVPC, DefaultInstanceTenancy, IVpc, SubnetType, Vpc } from '../lib'; +import { exportVpc } from './export-helper'; export = { "When creating a VPC": { @@ -9,16 +10,16 @@ export = { "vpc.vpcId returns a token to the VPC ID"(test: Test) { const stack = getTestStack(); - const vpc = new VpcNetwork(stack, 'TheVPC'); + const vpc = new Vpc(stack, 'TheVPC'); test.deepEqual(stack.node.resolve(vpc.vpcId), {Ref: 'TheVPC92636AB0' } ); test.done(); }, "it uses the correct network range"(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'TheVPC'); + new Vpc(stack, 'TheVPC'); expect(stack).to(haveResource('AWS::EC2::VPC', { - CidrBlock: VpcNetwork.DEFAULT_CIDR_RANGE, + CidrBlock: Vpc.DEFAULT_CIDR_RANGE, EnableDnsHostnames: true, EnableDnsSupport: true, InstanceTenancy: DefaultInstanceTenancy.Default, @@ -27,7 +28,7 @@ export = { }, 'the Name tag is defaulted to path'(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'TheVPC'); + new Vpc(stack, 'TheVPC'); expect(stack).to( haveResource('AWS::EC2::VPC', hasTags( [ {Key: 'Name', Value: 'TheVPC'} ])) @@ -43,7 +44,7 @@ export = { "with all of the properties set, it successfully sets the correct VPC properties"(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'TheVPC', { + new Vpc(stack, 'TheVPC', { cidr: "192.168.0.0/16", enableDnsHostnames: false, enableDnsSupport: false, @@ -61,7 +62,7 @@ export = { "contains the correct number of subnets"(test: Test) { const stack = getTestStack(); - const vpc = new VpcNetwork(stack, 'TheVPC'); + const vpc = new Vpc(stack, 'TheVPC'); const zones = new AvailabilityZoneProvider(stack).availabilityZones.length; test.equal(vpc.publicSubnets.length, zones); test.equal(vpc.privateSubnets.length, zones); @@ -71,7 +72,7 @@ export = { "with only isolated subnets, the VPC should not contain an IGW or NAT Gateways"(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'TheVPC', { + new Vpc(stack, 'TheVPC', { subnetConfiguration: [ { subnetType: SubnetType.Isolated, @@ -89,7 +90,7 @@ export = { "with no private subnets, the VPC should have an IGW but no NAT Gateways"(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'TheVPC', { + new Vpc(stack, 'TheVPC', { subnetConfiguration: [ { subnetType: SubnetType.Public, @@ -109,7 +110,7 @@ export = { "with no subnets defined, the VPC should have an IGW, and a NAT Gateway per AZ"(test: Test) { const stack = getTestStack(); const zones = new AvailabilityZoneProvider(stack).availabilityZones.length; - new VpcNetwork(stack, 'TheVPC', { }); + new Vpc(stack, 'TheVPC', { }); expect(stack).to(countResources("AWS::EC2::InternetGateway", 1)); expect(stack).to(countResources("AWS::EC2::NatGateway", zones)); test.done(); @@ -117,7 +118,7 @@ export = { "with subnets and reserved subnets defined, VPC subnet count should not contain reserved subnets "(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'TheVPC', { + new Vpc(stack, 'TheVPC', { cidr: '10.0.0.0/16', subnetConfiguration: [ { @@ -144,7 +145,7 @@ export = { }, "with reserved subnets, any other subnets should not have cidrBlock from within reserved space"(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'TheVPC', { + new Vpc(stack, 'TheVPC', { cidr: '10.0.0.0/16', subnetConfiguration: [ { @@ -186,7 +187,7 @@ export = { "with custom subnets, the VPC should have the right number of subnets, an IGW, and a NAT Gateway per AZ"(test: Test) { const stack = getTestStack(); const zones = new AvailabilityZoneProvider(stack).availabilityZones.length; - new VpcNetwork(stack, 'TheVPC', { + new Vpc(stack, 'TheVPC', { cidr: '10.0.0.0/21', subnetConfiguration: [ { @@ -224,7 +225,7 @@ export = { }, "with custom subents and natGateways = 2 there should be only two NATGW"(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'TheVPC', { + new Vpc(stack, 'TheVPC', { cidr: '10.0.0.0/21', natGateways: 2, subnetConfiguration: [ @@ -263,7 +264,7 @@ export = { }, "with enableDnsHostnames enabled but enableDnsSupport disabled, should throw an Error"(test: Test) { const stack = getTestStack(); - test.throws(() => new VpcNetwork(stack, 'TheVPC', { + test.throws(() => new Vpc(stack, 'TheVPC', { enableDnsHostnames: true, enableDnsSupport: false })); @@ -271,7 +272,7 @@ export = { }, "with public subnets MapPublicIpOnLaunch is true"(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'VPC', { + new Vpc(stack, 'VPC', { maxAZs: 1, subnetConfiguration: [ { @@ -291,7 +292,7 @@ export = { "maxAZs defaults to 3 if unset"(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'VPC'); + new Vpc(stack, 'VPC'); expect(stack).to(countResources("AWS::EC2::Subnet", 6)); expect(stack).to(countResources("AWS::EC2::Route", 6)); for (let i = 0; i < 6; i++) { @@ -309,7 +310,7 @@ export = { "with maxAZs set to 2"(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'VPC', { maxAZs: 2 }); + new Vpc(stack, 'VPC', { maxAZs: 2 }); expect(stack).to(countResources("AWS::EC2::Subnet", 4)); expect(stack).to(countResources("AWS::EC2::Route", 4)); for (let i = 0; i < 4; i++) { @@ -325,7 +326,7 @@ export = { }, "with natGateway set to 1"(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'VPC', { + new Vpc(stack, 'VPC', { natGateways: 1, }); expect(stack).to(countResources("AWS::EC2::Subnet", 6)); @@ -339,7 +340,7 @@ export = { }, 'with natGateway subnets defined'(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'VPC', { + new Vpc(stack, 'VPC', { subnetConfiguration: [ { cidrMask: 24, @@ -372,7 +373,7 @@ export = { }, 'with mis-matched nat and subnet configs it throws'(test: Test) { const stack = getTestStack(); - test.throws(() => new VpcNetwork(stack, 'VPC', { + test.throws(() => new Vpc(stack, 'VPC', { subnetConfiguration: [ { cidrMask: 24, @@ -393,7 +394,7 @@ export = { }, 'with a vpn gateway'(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'VPC', { + new Vpc(stack, 'VPC', { vpnGateway: true, vpnGatewayAsn: 65000 }); @@ -433,7 +434,7 @@ export = { }, 'with a vpn gateway and route propagation on isolated subnets'(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'VPC', { + new Vpc(stack, 'VPC', { subnetConfiguration: [ { subnetType: SubnetType.Private, name: 'Private' }, { subnetType: SubnetType.Isolated, name: 'Isolated' }, @@ -467,7 +468,7 @@ export = { }, 'with a vpn gateway and route propagation on private and isolated subnets'(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'VPC', { + new Vpc(stack, 'VPC', { subnetConfiguration: [ { subnetType: SubnetType.Private, name: 'Private' }, { subnetType: SubnetType.Isolated, name: 'Isolated' }, @@ -515,7 +516,7 @@ export = { // GIVEN const stack = new Stack(); - test.throws(() => new VpcNetwork(stack, 'VpcNetwork', { + test.throws(() => new Vpc(stack, 'VpcNetwork', { vpnGateway: false, vpnConnections: { VpnConnection: { @@ -531,7 +532,7 @@ export = { // GIVEN const stack = new Stack(); - test.throws(() => new VpcNetwork(stack, 'VpcNetwork', { + test.throws(() => new Vpc(stack, 'VpcNetwork', { vpnGateway: false, vpnGatewayAsn: 65000, }), /`vpnGatewayAsn`.+`vpnGateway`.+false/); @@ -544,7 +545,7 @@ export = { "When creating a VPC with a custom CIDR range": { "vpc.vpcCidrBlock is the correct network range"(test: Test) { const stack = getTestStack(); - new VpcNetwork(stack, 'TheVPC', { cidr: '192.168.0.0/16' }); + new Vpc(stack, 'TheVPC', { cidr: '192.168.0.0/16' }); expect(stack).to(haveResource("AWS::EC2::VPC", { CidrBlock: '192.168.0.0/16' })); @@ -562,7 +563,7 @@ export = { }; const allTags = {...tags, ...noPropTags}; - const vpc = new VpcNetwork(stack, 'TheVPC'); + const vpc = new Vpc(stack, 'TheVPC'); // overwrite to set propagate vpc.node.apply(new Tag('BusinessUnit', 'Marketing', {includeResourceTypes: [CfnVPC.resourceTypeName]})); vpc.node.apply(new Tag('VpcType', 'Good')); @@ -578,7 +579,7 @@ export = { }, 'Subnet Name will propagate to route tables and NATGW'(test: Test) { const stack = getTestStack(); - const vpc = new VpcNetwork(stack, 'TheVPC'); + const vpc = new Vpc(stack, 'TheVPC'); for (const subnet of vpc.publicSubnets) { const tag = {Key: 'Name', Value: subnet.node.path}; expect(stack).to(haveResource('AWS::EC2::NatGateway', hasTags([tag]))); @@ -593,7 +594,7 @@ export = { 'Tags can be added after the Vpc is created with `vpc.tags.setTag(...)`'(test: Test) { const stack = getTestStack(); - const vpc = new VpcNetwork(stack, 'TheVPC'); + const vpc = new Vpc(stack, 'TheVPC'); const tag = {Key: 'Late', Value: 'Adder'}; expect(stack).notTo(haveResource('AWS::EC2::VPC', hasTags([tag]))); vpc.node.apply(new Tag(tag.Key, tag.Value)); @@ -606,7 +607,7 @@ export = { 'selecting default subnets returns the private ones'(test: Test) { // GIVEN const stack = getTestStack(); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); // WHEN const { subnetIds } = vpc.selectSubnets(); @@ -619,7 +620,7 @@ export = { 'can select public subnets'(test: Test) { // GIVEN const stack = getTestStack(); - const vpc = new VpcNetwork(stack, 'VPC'); + const vpc = new Vpc(stack, 'VPC'); // WHEN const { subnetIds } = vpc.selectSubnets({ subnetType: SubnetType.Public }); @@ -633,7 +634,7 @@ export = { 'can select isolated subnets'(test: Test) { // GIVEN const stack = getTestStack(); - const vpc = new VpcNetwork(stack, 'VPC', { + const vpc = new Vpc(stack, 'VPC', { subnetConfiguration: [ { subnetType: SubnetType.Private, name: 'Private' }, { subnetType: SubnetType.Isolated, name: 'Isolated' }, @@ -652,7 +653,7 @@ export = { 'can select subnets by name'(test: Test) { // GIVEN const stack = getTestStack(); - const vpc = new VpcNetwork(stack, 'VPC', { + const vpc = new Vpc(stack, 'VPC', { subnetConfiguration: [ { subnetType: SubnetType.Private, name: 'DontTalkToMe' }, { subnetType: SubnetType.Isolated, name: 'DontTalkAtAll' }, @@ -670,7 +671,7 @@ export = { 'selecting default subnets in a VPC with only public subnets throws an error'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = VpcNetwork.import(stack, 'VPC', { + const vpc = Vpc.fromVpcAttributes(stack, 'VPC', { vpcId: 'vpc-1234', availabilityZones: ['dummy1a', 'dummy1b', 'dummy1c'], publicSubnetIds: ['pub-1', 'pub-2', 'pub-3'], @@ -686,7 +687,7 @@ export = { 'select subnets with az restriction'(test: Test) { // GIVEN const stack = getTestStack(); - const vpc = new VpcNetwork(stack, 'VpcNetwork', { + const vpc = new Vpc(stack, 'VpcNetwork', { maxAZs: 1, subnetConfiguration: [ {name: 'app', subnetType: SubnetType.Private }, @@ -708,7 +709,7 @@ export = { 'simple VPC'(test: Test) { // WHEN const vpc2 = doImportExportTest(stack => { - return new VpcNetwork(stack, 'TheVPC'); + return new Vpc(stack, 'TheVPC'); }); // THEN @@ -722,7 +723,7 @@ export = { 'multiple subnets of the same type'(test: Test) { // WHEN const imported = doImportExportTest(stack => { - return new VpcNetwork(stack, 'TheVPC', { + return new Vpc(stack, 'TheVPC', { subnetConfiguration: [ { name: 'Ingress', subnetType: SubnetType.Public }, { name: 'Egress', subnetType: SubnetType.Public }, @@ -752,7 +753,7 @@ export = { 'can select isolated subnets by type'(test: Test) { // GIVEN const importedVpc = doImportExportTest(stack => { - return new VpcNetwork(stack, 'TheVPC', { + return new Vpc(stack, 'TheVPC', { subnetConfiguration: [ { subnetType: SubnetType.Private, name: 'Private' }, { subnetType: SubnetType.Isolated, name: 'Isolated' }, @@ -775,7 +776,7 @@ export = { for (const isolatedName of ['Isolated', 'LeaveMeAlone']) { // GIVEN const importedVpc = doImportExportTest(stack => { - return new VpcNetwork(stack, 'TheVPC', { + return new Vpc(stack, 'TheVPC', { subnetConfiguration: [ { subnetType: SubnetType.Private, name: 'Private' }, { subnetType: SubnetType.Isolated, name: isolatedName }, @@ -804,7 +805,7 @@ function getTestStack(): Stack { /** * Do a complete import/export test, return the imported VPC */ -function doImportExportTest(constructFn: (scope: Construct) => VpcNetwork): IVpcNetwork { +function doImportExportTest(constructFn: (scope: Construct) => Vpc): IVpc { // GIVEN const stack1 = getTestStack(); const stack2 = getTestStack(); @@ -812,7 +813,7 @@ function doImportExportTest(constructFn: (scope: Construct) => VpcNetwork): IVpc const vpc1 = constructFn(stack1); // WHEN - return VpcNetwork.import(stack2, 'VPC2', vpc1.export()); + return Vpc.fromVpcAttributes(stack2, 'VPC2', exportVpc(vpc1)); } function toCfnTags(tags: any): Array<{Key: string, Value: string}> { diff --git a/packages/@aws-cdk/aws-ec2/test/test.vpn.ts b/packages/@aws-cdk/aws-ec2/test/test.vpn.ts index 3d88da1409339..3f2ba05a24ee9 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.vpn.ts +++ b/packages/@aws-cdk/aws-ec2/test/test.vpn.ts @@ -1,7 +1,7 @@ import { expect, haveResource, } from '@aws-cdk/assert'; import { Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { VpcNetwork, VpnConnection } from '../lib'; +import { Vpc, VpnConnection } from '../lib'; export = { 'can add a vpn connection to a vpc with a vpn gateway'(test: Test) { @@ -9,7 +9,7 @@ export = { const stack = new Stack(); // WHEN - new VpcNetwork(stack, 'VpcNetwork', { + new Vpc(stack, 'VpcNetwork', { vpnConnections: { VpnConnection: { asn: 65001, @@ -44,7 +44,7 @@ export = { const stack = new Stack(); // WHEN - new VpcNetwork(stack, 'VpcNetwork', { + new Vpc(stack, 'VpcNetwork', { vpnConnections: { static: { ip: '192.0.2.1', @@ -89,7 +89,7 @@ export = { // GIVEN const stack = new Stack(); - new VpcNetwork(stack, 'VpcNetwork', { + new Vpc(stack, 'VpcNetwork', { vpnConnections: { VpnConnection: { ip: '192.0.2.1', @@ -127,7 +127,7 @@ export = { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VpcNetwork'); + const vpc = new Vpc(stack, 'VpcNetwork'); test.throws(() => vpc.addVpnConnection('VpnConnection', { asn: 65000, @@ -141,7 +141,7 @@ export = { // GIVEN const stack = new Stack(); - test.throws(() => new VpcNetwork(stack, 'VpcNetwork', { + test.throws(() => new Vpc(stack, 'VpcNetwork', { vpnConnections: { VpnConnection: { ip: '192.0.2.256' @@ -156,7 +156,7 @@ export = { // GIVEN const stack = new Stack(); - test.throws(() => new VpcNetwork(stack, 'VpcNetwork', { + test.throws(() => new Vpc(stack, 'VpcNetwork', { vpnConnections: { VpnConnection: { ip: '192.0.2.1', @@ -182,7 +182,7 @@ export = { // GIVEN const stack = new Stack(); - test.throws(() => new VpcNetwork(stack, 'VpcNetwork', { + test.throws(() => new Vpc(stack, 'VpcNetwork', { vpnConnections: { VpnConnection: { ip: '192.0.2.1', @@ -205,7 +205,7 @@ export = { // GIVEN const stack = new Stack(); - test.throws(() => new VpcNetwork(stack, 'VpcNetwork', { + test.throws(() => new Vpc(stack, 'VpcNetwork', { vpnConnections: { VpnConnection: { ip: '192.0.2.1', @@ -225,7 +225,7 @@ export = { // GIVEN const stack = new Stack(); - test.throws(() => new VpcNetwork(stack, 'VpcNetwork', { + test.throws(() => new Vpc(stack, 'VpcNetwork', { vpnConnections: { VpnConnection: { ip: '192.0.2.1', @@ -245,7 +245,7 @@ export = { // GIVEN const stack = new Stack(); - test.throws(() => new VpcNetwork(stack, 'VpcNetwork', { + test.throws(() => new Vpc(stack, 'VpcNetwork', { vpnConnections: { VpnConnection: { ip: '192.0.2.1', @@ -265,7 +265,7 @@ export = { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VpcNetwork', { + const vpc = new Vpc(stack, 'VpcNetwork', { vpnGateway: true }); diff --git a/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts b/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts index 1c0f652e9b630..6b80ba9625dd0 100644 --- a/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts @@ -234,7 +234,7 @@ export abstract class BaseService extends Resource * Set up AWSVPC networking for this construct */ // tslint:disable-next-line:max-line-length - protected configureAwsVpcNetworking(vpc: ec2.IVpcNetwork, assignPublicIp?: boolean, vpcSubnets?: ec2.SubnetSelection, securityGroup?: ec2.ISecurityGroup) { + protected configureAwsVpcNetworking(vpc: ec2.IVpc, assignPublicIp?: boolean, vpcSubnets?: ec2.SubnetSelection, securityGroup?: ec2.ISecurityGroup) { if (vpcSubnets === undefined) { vpcSubnets = { subnetType: assignPublicIp ? ec2.SubnetType.Public : ec2.SubnetType.Private }; } diff --git a/packages/@aws-cdk/aws-ecs/lib/cluster.ts b/packages/@aws-cdk/aws-ecs/lib/cluster.ts index 7e37bb6a3b699..0ff11bf584cec 100644 --- a/packages/@aws-cdk/aws-ecs/lib/cluster.ts +++ b/packages/@aws-cdk/aws-ecs/lib/cluster.ts @@ -3,7 +3,7 @@ import cloudwatch = require ('@aws-cdk/aws-cloudwatch'); import ec2 = require('@aws-cdk/aws-ec2'); import iam = require('@aws-cdk/aws-iam'); import cloudmap = require('@aws-cdk/aws-servicediscovery'); -import { CfnOutput, Construct, IResource, Resource, SSMParameterProvider } from '@aws-cdk/cdk'; +import { Construct, IResource, Resource, SSMParameterProvider } from '@aws-cdk/cdk'; import { InstanceDrainHook } from './drain-hook/instance-drain-hook'; import { CfnCluster } from './ecs.generated'; @@ -21,7 +21,7 @@ export interface ClusterProps { /** * The VPC where your ECS instances will be running or your ENIs will be deployed */ - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; } /** @@ -43,7 +43,7 @@ export class Cluster extends Resource implements ICluster { /** * The VPC this cluster was created in. */ - public readonly vpc: ec2.IVpcNetwork; + public readonly vpc: ec2.IVpc; /** * The ARN of this cluster @@ -183,20 +183,6 @@ export class Cluster extends Resource implements ICluster { return this._hasEc2Capacity; } - /** - * Export the Cluster - */ - public export(): ClusterAttributes { - return { - clusterName: new CfnOutput(this, 'ClusterName', { value: this.clusterName }).makeImportValue().toString(), - clusterArn: this.clusterArn, - vpc: this.vpc.export(), - securityGroups: this.connections.securityGroups.map(sg => sg.export()), - hasEc2Capacity: this.hasEc2Capacity, - defaultNamespace: this._defaultNamespace && this._defaultNamespace.export(), - }; - } - /** * Metric for cluster CPU reservation * @@ -287,7 +273,7 @@ export interface ICluster extends IResource { /** * VPC that the cluster instances are running in */ - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; /** * Connections manager of the cluster instances @@ -303,11 +289,6 @@ export interface ICluster extends IResource { * Getter for Cloudmap namespace created in the cluster */ readonly defaultNamespace?: cloudmap.INamespace; - - /** - * Export the Cluster - */ - export(): ClusterAttributes; } /** @@ -329,12 +310,12 @@ export interface ClusterAttributes { /** * VPC that the cluster instances are running in */ - readonly vpc: ec2.VpcNetworkImportProps; + readonly vpc: ec2.IVpc; /** * Security group of the cluster instances */ - readonly securityGroups: ec2.SecurityGroupAttributes[]; + readonly securityGroups: ec2.ISecurityGroup[]; /** * Whether the given cluster has EC2 capacity @@ -348,7 +329,7 @@ export interface ClusterAttributes { * * @default - No default namespace */ - readonly defaultNamespace?: cloudmap.NamespaceImportProps; + readonly defaultNamespace?: cloudmap.INamespace; } /** @@ -368,7 +349,7 @@ class ImportedCluster extends Construct implements ICluster { /** * VPC that the cluster instances are running in */ - public readonly vpc: ec2.IVpcNetwork; + public readonly vpc: ec2.IVpc; /** * Security group of the cluster instances @@ -385,12 +366,12 @@ class ImportedCluster extends Construct implements ICluster { */ private _defaultNamespace?: cloudmap.INamespace; - constructor(scope: Construct, id: string, private readonly props: ClusterAttributes) { + constructor(scope: Construct, id: string, props: ClusterAttributes) { super(scope, id); this.clusterName = props.clusterName; - this.vpc = ec2.VpcNetwork.import(this, "vpc", props.vpc); + this.vpc = ec2.Vpc.fromVpcAttributes(this, "vpc", props.vpc); this.hasEc2Capacity = props.hasEc2Capacity !== false; - this._defaultNamespace = props.defaultNamespace && cloudmap.Namespace.import(this, 'Namespace', props.defaultNamespace); + this._defaultNamespace = props.defaultNamespace; this.clusterArn = props.clusterArn !== undefined ? props.clusterArn : this.node.stack.formatArn({ service: 'ecs', @@ -414,10 +395,6 @@ class ImportedCluster extends Construct implements ICluster { public get defaultNamespace(): cloudmap.INamespace | undefined { return this._defaultNamespace; } - - public export() { - return this.props; - } } /** @@ -473,7 +450,7 @@ export interface NamespaceOptions { * * @default VPC of the cluster for Private DNS Namespace, otherwise none */ - readonly vpc?: ec2.IVpcNetwork; + readonly vpc?: ec2.IVpc; } /** diff --git a/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service-applet.ts b/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service-applet.ts index 4a20c1287ebbe..4225dc27daa2c 100644 --- a/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service-applet.ts +++ b/packages/@aws-cdk/aws-ecs/lib/load-balanced-fargate-service-applet.ts @@ -1,5 +1,5 @@ import { Certificate } from '@aws-cdk/aws-certificatemanager'; -import { VpcNetwork } from '@aws-cdk/aws-ec2'; +import { Vpc } from '@aws-cdk/aws-ec2'; import { HostedZoneProvider } from '@aws-cdk/aws-route53'; import cdk = require('@aws-cdk/cdk'); import { Cluster } from './cluster'; @@ -112,7 +112,7 @@ export class LoadBalancedFargateServiceApplet extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props: LoadBalancedFargateServiceAppletProps) { super(scope, id, props); - const vpc = new VpcNetwork(this, 'MyVpc', { maxAZs: 2 }); + const vpc = new Vpc(this, 'MyVpc', { maxAZs: 2 }); const cluster = new Cluster(this, 'Cluster', { vpc }); let domainZone; diff --git a/packages/@aws-cdk/aws-ecs/lib/load-balanced-service-base.ts b/packages/@aws-cdk/aws-ecs/lib/load-balanced-service-base.ts index 110f44bf1ab5b..5d6429ad6ee2d 100644 --- a/packages/@aws-cdk/aws-ecs/lib/load-balanced-service-base.ts +++ b/packages/@aws-cdk/aws-ecs/lib/load-balanced-service-base.ts @@ -121,7 +121,7 @@ export abstract class LoadBalancedServiceBase extends cdk.Construct { this.targetGroup = this.listener.addTargets('ECS', targetProps); } - new cdk.CfnOutput(this, 'LoadBalancerDNS', { value: this.loadBalancer.dnsName }); + new cdk.CfnOutput(this, 'LoadBalancerDNS', { value: this.loadBalancer.loadBalancerDnsName }); } protected addServiceAsTarget(service: BaseService) { diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.event-task.lit.ts b/packages/@aws-cdk/aws-ecs/test/ec2/integ.event-task.lit.ts index 3b6844b81c1fb..b59f6953932a0 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.event-task.lit.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.event-task.lit.ts @@ -11,7 +11,7 @@ class EventStack extends cdk.Stack { constructor(scope: cdk.App, id: string) { super(scope, id); - const vpc = new ec2.VpcNetwork(this, 'Vpc', { maxAZs: 1 }); + const vpc = new ec2.Vpc(this, 'Vpc', { maxAZs: 1 }); const cluster = new ecs.Cluster(this, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.ts b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.ts index 3bae4398bcf2d..7b6508d8a3eae 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.ts @@ -7,7 +7,7 @@ import { NetworkMode } from '../../lib'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-ecs-integ'); -const vpc = new ec2.VpcNetwork(stack, 'Vpc', { maxAZs: 2 }); +const vpc = new ec2.Vpc(stack, 'Vpc', { maxAZs: 2 }); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { @@ -40,6 +40,6 @@ listener.addTargets('ECS', { targets: [service] }); -new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: lb.dnsName, }); +new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: lb.loadBalancerDnsName, }); app.run(); diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.ts b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.ts index b8bfe2bfcc0e9..edc41d6893259 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.ts @@ -7,7 +7,7 @@ import ecs = require('../../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-ecs-integ-ecs'); -const vpc = new ec2.VpcNetwork(stack, 'Vpc', { maxAZs: 2 }); +const vpc = new ec2.Vpc(stack, 'Vpc', { maxAZs: 2 }); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { @@ -42,6 +42,6 @@ listener.addTargets('ECS', { targets: [service] }); -new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: lb.dnsName, }); +new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: lb.loadBalancerDnsName, }); app.run(); diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.ts b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.ts index 31a4f592d3c97..33248c93ef306 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.ts @@ -6,7 +6,7 @@ import { NetworkMode } from '../../lib'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-ecs-integ-ecs'); -const vpc = new ec2.VpcNetwork(stack, 'Vpc', { maxAZs: 2 }); +const vpc = new ec2.Vpc(stack, 'Vpc', { maxAZs: 2 }); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.ts b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.ts index bb26b16da810d..3845637bbdca3 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.ts @@ -5,7 +5,7 @@ import ecs = require('../../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-ecs-integ-ecs'); -const vpc = new ec2.VpcNetwork(stack, 'Vpc', { maxAZs: 2 }); +const vpc = new ec2.Vpc(stack, 'Vpc', { maxAZs: 2 }); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/test.ec2-event-rule-target.ts b/packages/@aws-cdk/aws-ecs/test/ec2/test.ec2-event-rule-target.ts index 055d1b80fc890..d7f8e5c7ba915 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/test.ec2-event-rule-target.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/test.ec2-event-rule-target.ts @@ -9,7 +9,7 @@ export = { "Can use EC2 taskdef as EventRule target"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Vpc', { maxAZs: 1 }); + const vpc = new ec2.Vpc(stack, 'Vpc', { maxAZs: 1 }); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/test.ec2-service.ts b/packages/@aws-cdk/aws-ecs/test/ec2/test.ec2-service.ts index 179f22c7341ee..df0d7ed05a21f 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/test.ec2-service.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/test.ec2-service.ts @@ -12,7 +12,7 @@ export = { "with only required properties set, it correctly sets default properties"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -51,7 +51,7 @@ export = { "errors if daemon and desiredCount both specified"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -76,7 +76,7 @@ export = { "errors if daemon and maximumPercent not 100"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -101,7 +101,7 @@ export = { "errors if daemon and minimum not 0"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -126,7 +126,7 @@ export = { 'Output does not contain DesiredCount if daemon mode is set'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -153,7 +153,7 @@ export = { "errors if no container definitions"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -171,7 +171,7 @@ export = { "sets daemon scheduling strategy"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -203,7 +203,7 @@ export = { "it errors if vpcSubnets is specified"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef', { @@ -235,7 +235,7 @@ export = { "it creates a security group for the service"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef', { @@ -286,7 +286,7 @@ export = { "it allows vpcSubnets"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef', { @@ -314,7 +314,7 @@ export = { "with distinctInstance placement constraint"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -343,7 +343,7 @@ export = { "with memberOf placement constraints"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -374,7 +374,7 @@ export = { "with placeSpreadAcross placement strategy"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -405,7 +405,7 @@ export = { "errors with placeSpreadAcross placement strategy if daemon specified"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -432,7 +432,7 @@ export = { "with placeRandomly placement strategy"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc'); + const vpc = new ec2.Vpc(stack, 'MyVpc'); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -462,7 +462,7 @@ export = { "errors with placeRandomly placement strategy if daemon specified"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc'); + const vpc = new ec2.Vpc(stack, 'MyVpc'); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -489,7 +489,7 @@ export = { "with placePackedBy placement strategy"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -520,7 +520,7 @@ export = { "errors with placePackedBy placement strategy if daemon specified"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef'); @@ -549,7 +549,7 @@ export = { 'can attach to classic ELB'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TD', { networkMode: ecs.NetworkMode.Host }); @@ -583,7 +583,7 @@ export = { 'throws if namespace has not been added to cluster'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); @@ -612,7 +612,7 @@ export = { 'throws if network mode is none'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef', { @@ -643,7 +643,7 @@ export = { 'creates AWS Cloud Map service for Private DNS namespace with bridge network mode'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); @@ -719,7 +719,7 @@ export = { 'creates AWS Cloud Map service for Private DNS namespace with host network mode'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); @@ -796,7 +796,7 @@ export = { 'throws if wrong DNS record type specified with bridge network mode'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); @@ -830,7 +830,7 @@ export = { 'creates AWS Cloud Map service for Private DNS namespace with AwsVpc network mode'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); @@ -905,7 +905,7 @@ export = { 'creates AWS Cloud Map service for Private DNS namespace with AwsVpc network mode with SRV records'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); diff --git a/packages/@aws-cdk/aws-ecs/test/fargate/integ.asset-image.ts b/packages/@aws-cdk/aws-ecs/test/fargate/integ.asset-image.ts index eb4eef79aaf7b..e01601395cc6a 100644 --- a/packages/@aws-cdk/aws-ecs/test/fargate/integ.asset-image.ts +++ b/packages/@aws-cdk/aws-ecs/test/fargate/integ.asset-image.ts @@ -5,7 +5,7 @@ import ecs = require('../../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-ecs-integ'); -const vpc = new ec2.VpcNetwork(stack, 'Vpc', { maxAZs: 2 }); +const vpc = new ec2.Vpc(stack, 'Vpc', { maxAZs: 2 }); const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); @@ -22,6 +22,6 @@ const fargateService = new ecs.LoadBalancedFargateService(stack, "FargateService }); // CfnOutput the DNS where you can access your service -new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: fargateService.loadBalancer.dnsName }); +new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: fargateService.loadBalancer.loadBalancerDnsName }); app.run(); diff --git a/packages/@aws-cdk/aws-ecs/test/fargate/integ.l3.ts b/packages/@aws-cdk/aws-ecs/test/fargate/integ.l3.ts index c39e53cb8fe4e..a9faa6e434284 100644 --- a/packages/@aws-cdk/aws-ecs/test/fargate/integ.l3.ts +++ b/packages/@aws-cdk/aws-ecs/test/fargate/integ.l3.ts @@ -5,7 +5,7 @@ import ecs = require('../../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-ecs-integ'); -const vpc = new ec2.VpcNetwork(stack, 'Vpc', { maxAZs: 2 }); +const vpc = new ec2.Vpc(stack, 'Vpc', { maxAZs: 2 }); const cluster = new ecs.Cluster(stack, 'FargateCluster', { vpc }); diff --git a/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.ts b/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.ts index 769caf9e97f78..cbdd41cd40a04 100644 --- a/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.ts +++ b/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.ts @@ -6,7 +6,7 @@ import ecs = require('../../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-ecs-integ'); -const vpc = new ec2.VpcNetwork(stack, 'Vpc', { maxAZs: 2 }); +const vpc = new ec2.Vpc(stack, 'Vpc', { maxAZs: 2 }); const cluster = new ecs.Cluster(stack, 'FargateCluster', { vpc }); @@ -40,6 +40,6 @@ listener.addTargets('Fargate', { targets: [service] }); -new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: lb.dnsName, }); +new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: lb.loadBalancerDnsName, }); app.run(); diff --git a/packages/@aws-cdk/aws-ecs/test/fargate/test.fargate-service.ts b/packages/@aws-cdk/aws-ecs/test/fargate/test.fargate-service.ts index 483d403bf625c..0345d199ab196 100644 --- a/packages/@aws-cdk/aws-ecs/test/fargate/test.fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs/test/fargate/test.fargate-service.ts @@ -12,7 +12,7 @@ export = { "with only required properties set, it correctly sets default properties"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef'); @@ -87,7 +87,7 @@ export = { "errors when no container specified on task definition"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef'); @@ -105,7 +105,7 @@ export = { "allows specifying assignPublicIP as enabled"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef'); @@ -134,7 +134,7 @@ export = { "allows specifying 0 for minimumHealthyPercent"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef'); @@ -163,7 +163,7 @@ export = { 'grace period is respected'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef'); taskDefinition.addContainer('MainContainer', { @@ -190,7 +190,7 @@ export = { 'allows auto scaling by ALB request per target'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef'); const container = taskDefinition.addContainer('MainContainer', { @@ -260,7 +260,7 @@ export = { 'allows auto scaling by ALB with new service arn format'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef'); const container = taskDefinition.addContainer('MainContainer', { @@ -327,7 +327,7 @@ export = { 'throws if namespace has not been added to cluster'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef'); const container = taskDefinition.addContainer('MainContainer', { @@ -353,7 +353,7 @@ export = { 'creates cloud map service for Private DNS namespace'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef'); const container = taskDefinition.addContainer('MainContainer', { @@ -410,7 +410,7 @@ export = { 'creates AWS Cloud Map service for Private DNS namespace with SRV records'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); diff --git a/packages/@aws-cdk/aws-ecs/test/test.ecs-cluster.ts b/packages/@aws-cdk/aws-ecs/test/test.ecs-cluster.ts index 9cdec4cfa9dba..4feddac48b2f2 100644 --- a/packages/@aws-cdk/aws-ecs/test/test.ecs-cluster.ts +++ b/packages/@aws-cdk/aws-ecs/test/test.ecs-cluster.ts @@ -11,7 +11,7 @@ export = { "with only required properties set, it correctly sets default properties"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc, }); @@ -159,7 +159,7 @@ export = { 'lifecycle hook is automatically added'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc, }); @@ -186,7 +186,7 @@ export = { "allows specifying instance type"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { @@ -204,7 +204,7 @@ export = { "allows specifying cluster size"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { @@ -223,7 +223,7 @@ export = { "allows adding default service discovery namespace"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { @@ -249,7 +249,7 @@ export = { "allows adding public service discovery namespace"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { @@ -273,7 +273,7 @@ export = { "throws if default service discovery namespace added more than once"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {}); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { @@ -298,7 +298,7 @@ export = { 'export/import of a cluster with a namespace'(test: Test) { // GIVEN const stack1 = new cdk.Stack(); - const vpc1 = new ec2.VpcNetwork(stack1, 'Vpc'); + const vpc1 = new ec2.Vpc(stack1, 'Vpc'); const cluster1 = new ecs.Cluster(stack1, 'Cluster', { vpc: vpc1 }); cluster1.addDefaultCloudMapNamespace({ name: 'hello.com', @@ -307,13 +307,20 @@ export = { const stack2 = new cdk.Stack(); // WHEN - const cluster2 = ecs.Cluster.fromClusterAttributes(stack2, 'Cluster', cluster1.export()); + const cluster2 = ecs.Cluster.fromClusterAttributes(stack2, 'Cluster', { + vpc: vpc1, + securityGroups: cluster1.connections.securityGroups, + defaultNamespace: cloudmap.PrivateDnsNamespace.fromPrivateDnsNamespaceAttributes(stack2, 'ns', { + namespaceId: 'import-namespace-id', + namespaceArn: 'import-namespace-arn', + namespaceName: 'import-namespace-name', + }), + clusterName: 'cluster-name', + }); // THEN test.equal(cluster2.defaultNamespace!.type, cloudmap.NamespaceType.DnsPrivate); - test.deepEqual(stack2.node.resolve(cluster2.defaultNamespace!.namespaceId), { - 'Fn::ImportValue': 'Stack:ClusterDefaultServiceDiscoveryNamespaceNamespaceId516C01B9', - }); + test.deepEqual(stack2.node.resolve(cluster2.defaultNamespace!.namespaceId), 'import-namespace-id'); test.done(); } diff --git a/packages/@aws-cdk/aws-ecs/test/test.l3s.ts b/packages/@aws-cdk/aws-ecs/test/test.l3s.ts index bdea16f2e191b..28e0dc9702fc0 100644 --- a/packages/@aws-cdk/aws-ecs/test/test.l3s.ts +++ b/packages/@aws-cdk/aws-ecs/test/test.l3s.ts @@ -10,7 +10,7 @@ export = { 'test ECS loadbalanced construct'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); @@ -58,7 +58,7 @@ export = { 'test ECS loadbalanced construct with memoryReservationMiB'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') }); @@ -86,7 +86,7 @@ export = { 'test Fargate loadbalanced construct'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); // WHEN @@ -142,7 +142,7 @@ export = { 'test Fargate loadbalanced construct opting out of log driver creation'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); // WHEN @@ -188,7 +188,7 @@ export = { 'test Fargateloadbalanced construct with TLS'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); const zone = new PublicHostedZone(stack, 'HostedZone', { zoneName: 'example.com' }); @@ -234,7 +234,7 @@ export = { "errors when setting domainName but not domainZone"(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); // THEN diff --git a/packages/@aws-cdk/aws-ecs/test/test.load-balanced-fargate-service.ts b/packages/@aws-cdk/aws-ecs/test/test.load-balanced-fargate-service.ts index 8bd6678387dbb..6d52b4fb612de 100644 --- a/packages/@aws-cdk/aws-ecs/test/test.load-balanced-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs/test/test.load-balanced-fargate-service.ts @@ -9,7 +9,7 @@ export = { 'certificate requires an application load balancer'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); // WHEN @@ -31,7 +31,7 @@ export = { 'setting loadBalancerType to Network creates an NLB'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); // WHEN diff --git a/packages/@aws-cdk/aws-eks/lib/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster.ts index eee8de971dacc..e751732070855 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster.ts @@ -1,6 +1,6 @@ import autoscaling = require('@aws-cdk/aws-autoscaling'); import ec2 = require('@aws-cdk/aws-ec2'); -import { VpcSubnet } from '@aws-cdk/aws-ec2'; +import { Subnet } from '@aws-cdk/aws-ec2'; import iam = require('@aws-cdk/aws-iam'); import { CfnOutput, Construct, IResource, Resource, Tag } from '@aws-cdk/cdk'; import { EksOptimizedAmi, nodeTypeForInstanceType } from './ami'; @@ -14,7 +14,7 @@ export interface ICluster extends IResource, ec2.IConnectable { /** * The VPC in which this Cluster was created */ - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; /** * The physical name of the Cluster @@ -40,48 +40,13 @@ export interface ICluster extends IResource, ec2.IConnectable { * @attribute */ readonly clusterCertificateAuthorityData: string; - - /** - * Export cluster references to use in other stacks - */ - export(): ClusterAttributes; -} - -/** - * A SecurityGroup Reference, object not created with this template. - */ -abstract class ClusterBase extends Resource implements ICluster { - public abstract readonly connections: ec2.Connections; - public abstract readonly vpc: ec2.IVpcNetwork; - public abstract readonly clusterName: string; - public abstract readonly clusterArn: string; - public abstract readonly clusterEndpoint: string; - public abstract readonly clusterCertificateAuthorityData: string; - - /** - * Export cluster references to use in other stacks - */ - public export(): ClusterAttributes { - return { - vpc: this.vpc.export(), - clusterName: this.makeOutput('ClusterNameExport', this.clusterName), - clusterArn: this.makeOutput('ClusterArn', this.clusterArn), - clusterEndpoint: this.makeOutput('ClusterEndpoint', this.clusterEndpoint), - clusterCertificateAuthorityData: this.makeOutput('ClusterCAData', this.clusterCertificateAuthorityData), - securityGroups: this.connections.securityGroups.map(sg => sg.export()), - }; - } - - private makeOutput(name: string, value: any): string { - return new CfnOutput(this, name, { value }).makeImportValue().toString(); - } } export interface ClusterAttributes { /** * The VPC in which this Cluster was created */ - readonly vpc: ec2.VpcNetworkImportProps; + readonly vpc: ec2.IVpc; /** * The physical name of the Cluster @@ -104,7 +69,7 @@ export interface ClusterAttributes { */ readonly clusterCertificateAuthorityData: string; - readonly securityGroups: ec2.SecurityGroupAttributes[]; + readonly securityGroups: ec2.ISecurityGroup[]; } /** @@ -114,7 +79,7 @@ export interface ClusterProps { /** * The VPC in which to create the Cluster */ - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; /** * Where to place EKS Control Plane ENIs @@ -168,7 +133,7 @@ export interface ClusterProps { * This is a fully managed cluster of API Servers (control-plane) * The user is still required to create the worker nodes. */ -export class Cluster extends ClusterBase { +export class Cluster extends Resource implements ICluster { /** * Import an existing cluster * @@ -183,7 +148,7 @@ export class Cluster extends ClusterBase { /** * The VPC in which this Cluster was created */ - public readonly vpc: ec2.IVpcNetwork; + public readonly vpc: ec2.IVpc; /** * The Name of the created EKS Cluster @@ -366,7 +331,7 @@ export class Cluster extends ClusterBase { */ private tagSubnets() { for (const subnet of this.vpc.privateSubnets) { - if (!VpcSubnet.isVpcSubnet(subnet)) { + if (!Subnet.isVpcSubnet(subnet)) { // Just give up, all of them will be the same. this.node.addWarning('Could not auto-tag private subnets with "kubernetes.io/role/internal-elb=1", please remember to do this manually'); return; @@ -403,8 +368,8 @@ export interface AddAutoScalingGroupOptions { /** * Import a cluster to use in another stack */ -class ImportedCluster extends ClusterBase { - public readonly vpc: ec2.IVpcNetwork; +class ImportedCluster extends Resource implements ICluster { + public readonly vpc: ec2.IVpc; public readonly clusterCertificateAuthorityData: string; public readonly clusterName: string; public readonly clusterArn: string; @@ -414,7 +379,7 @@ class ImportedCluster extends ClusterBase { constructor(scope: Construct, id: string, props: ClusterAttributes) { super(scope, id); - this.vpc = ec2.VpcNetwork.import(this, "VPC", props.vpc); + this.vpc = ec2.Vpc.fromVpcAttributes(this, "VPC", props.vpc); this.clusterName = props.clusterName; this.clusterEndpoint = props.clusterEndpoint; this.clusterArn = props.clusterArn; diff --git a/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts b/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts index 5d188d352cadf..d0ff91ed29e01 100644 --- a/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts +++ b/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts @@ -6,7 +6,7 @@ class EksClusterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); - const vpc = new ec2.VpcNetwork(this, 'VPC'); + const vpc = new ec2.Vpc(this, 'VPC'); const cluster = new eks.Cluster(this, 'EKSCluster', { vpc diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.lit.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.lit.ts index 611bab4f7cce3..0c33f9e28544b 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.lit.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.lit.ts @@ -7,7 +7,7 @@ class EksClusterStack extends cdk.Stack { super(scope, id, props); /// !show - const vpc = new ec2.VpcNetwork(this, 'VPC'); + const vpc = new ec2.Vpc(this, 'VPC'); const cluster = new eks.Cluster(this, 'EKSCluster', { vpc diff --git a/packages/@aws-cdk/aws-eks/test/test.cluster.ts b/packages/@aws-cdk/aws-eks/test/test.cluster.ts index 79421b32b5d0b..59ada983faa02 100644 --- a/packages/@aws-cdk/aws-eks/test/test.cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/test.cluster.ts @@ -1,6 +1,7 @@ import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert'; import ec2 = require('@aws-cdk/aws-ec2'); import cdk = require('@aws-cdk/cdk'); +import { CfnOutput } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; import eks = require('../lib'); @@ -110,24 +111,39 @@ export = { 'exercise export/import'(test: Test) { // GIVEN const [stack1, vpc] = testFixture(); - const stack2 = new cdk.Stack(); + const stack2 = new cdk.Stack(undefined, 'stack2', { env: { region: 'us-east-1' } }); const cluster = new eks.Cluster(stack1, 'Cluster', { vpc }); // WHEN - const imported = eks.Cluster.fromClusterAttributes(stack2, 'Imported', cluster.export()); + const imported = eks.Cluster.fromClusterAttributes(stack2, 'Imported', { + clusterArn: cluster.clusterArn, + vpc: cluster.vpc, + clusterEndpoint: cluster.clusterEndpoint, + clusterName: cluster.clusterName, + securityGroups: cluster.connections.securityGroups, + clusterCertificateAuthorityData: cluster.clusterCertificateAuthorityData + }); + + // this should cause an export/import + new CfnOutput(stack2, 'ClusterARN', { value: imported.clusterArn }); // THEN - test.deepEqual(stack2.node.resolve(imported.clusterArn), { - 'Fn::ImportValue': 'Stack:ClusterClusterArn00DCA0E0' + expect(stack2).toMatch({ + Outputs: { + ClusterARN: { + Value: { + "Fn::ImportValue": "Stack:ExportsOutputFnGetAttClusterEB0386A7Arn2F2E3C3F" + } + } + } }); - test.done(); }, }; -function testFixture(): [cdk.Stack, ec2.VpcNetwork] { +function testFixture(): [cdk.Stack, ec2.Vpc] { const stack = new cdk.Stack(undefined, 'Stack', { env: { region: 'us-east-1' }}); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); return [stack, vpc]; } diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts index 76e164f4862a3..47c04e61ed6b9 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts @@ -1,6 +1,6 @@ import { AnyIPv4, Connections, IConnectable, IPortRange, ISecurityGroup, - IVpcNetwork, IVpcSubnet, SecurityGroup, TcpPort } from '@aws-cdk/aws-ec2'; + ISubnet, IVpc, SecurityGroup, TcpPort } from '@aws-cdk/aws-ec2'; import { Construct, Resource, Token } from '@aws-cdk/cdk'; import { CfnLoadBalancer } from './elasticloadbalancing.generated'; @@ -11,7 +11,7 @@ export interface LoadBalancerProps { /** * VPC network of the fleet instances */ - readonly vpc: IVpcNetwork; + readonly vpc: IVpc; /** * Whether this is an internet-facing Load Balancer @@ -212,7 +212,7 @@ export class LoadBalancer extends Resource implements IConnectable { this.connections = new Connections({ securityGroups: [this.securityGroup] }); // Depending on whether the ELB has public or internal IPs, pick the right backend subnets - const subnets: IVpcSubnet[] = props.internetFacing ? props.vpc.publicSubnets : props.vpc.privateSubnets; + const subnets: ISubnet[] = props.internetFacing ? props.vpc.publicSubnets : props.vpc.privateSubnets; this.elb = new CfnLoadBalancer(this, 'Resource', { securityGroups: [ this.securityGroup.securityGroupId ], diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts index f7cccc03f82e4..04496c4f351e5 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts @@ -6,7 +6,7 @@ import elb = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-elb-integ'); -const vpc = new ec2.VpcNetwork(stack, 'VPC', { +const vpc = new ec2.Vpc(stack, 'VPC', { maxAZs: 1 }); diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts b/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts index 0ffe5a7b7a279..96c94a973def7 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts @@ -1,5 +1,5 @@ import { expect, haveResource } from '@aws-cdk/assert'; -import { CidrIPv4, Connections, VpcNetwork } from '@aws-cdk/aws-ec2'; +import { CidrIPv4, Connections, Vpc } from '@aws-cdk/aws-ec2'; import { Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; import { ILoadBalancerTarget, LoadBalancer, LoadBalancingProtocol } from '../lib'; @@ -8,7 +8,7 @@ export = { 'test specifying nonstandard port works'(test: Test) { const stack = new Stack(undefined, undefined, { env: { account: '1234', region: 'test' }}); stack.node.setContext('availability-zones:1234:test', ['test-1a', 'test-1b']); - const vpc = new VpcNetwork(stack, 'VCP'); + const vpc = new Vpc(stack, 'VCP'); const lb = new LoadBalancer(stack, 'LB', { vpc }); @@ -34,7 +34,7 @@ export = { 'add a health check'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VCP'); + const vpc = new Vpc(stack, 'VCP'); // WHEN new LoadBalancer(stack, 'LB', { @@ -64,7 +64,7 @@ export = { 'add a listener and load balancing target'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new VpcNetwork(stack, 'VCP'); + const vpc = new Vpc(stack, 'VCP'); const elb = new LoadBalancer(stack, 'LB', { vpc, healthCheck: { diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts index 799908d4b4906..1b11c5bb3ce46 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts @@ -1,5 +1,5 @@ import ec2 = require('@aws-cdk/aws-ec2'); -import cdk = require('@aws-cdk/cdk'); +import { Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; import { BaseListener } from '../shared/base-listener'; import { HealthCheck } from '../shared/base-target-group'; import { ApplicationProtocol, SslPolicy } from '../shared/enums'; @@ -74,13 +74,15 @@ export interface ApplicationListenerProps extends BaseApplicationListenerProps { /** * Define an ApplicationListener + * + * @resource AWS::ElasticLoadBalancingV2::Listener */ export class ApplicationListener extends BaseListener implements IApplicationListener { /** * Import an existing listener */ - public static import(scope: cdk.Construct, id: string, props: ApplicationListenerImportProps): IApplicationListener { - return new ImportedApplicationListener(scope, id, props); + public static fromApplicationListenerAttributes(scope: Construct, id: string, attrs: ApplicationListenerAttributes): IApplicationListener { + return new ImportedApplicationListener(scope, id, attrs); } /** @@ -103,17 +105,12 @@ export class ApplicationListener extends BaseListener implements IApplicationLis */ private readonly protocol: ApplicationProtocol; - /** - * The default port on which this listener is listening - */ - private readonly defaultPort: number; - - constructor(scope: cdk.Construct, id: string, props: ApplicationListenerProps) { + constructor(scope: Construct, id: string, props: ApplicationListenerProps) { const [protocol, port] = determineProtocolAndPort(props.protocol, props.port); super(scope, id, { loadBalancerArn: props.loadBalancer.loadBalancerArn, - certificates: new cdk.Token(() => this.certificateArns.map(certificateArn => ({ certificateArn }))), + certificates: new Token(() => this.certificateArns.map(certificateArn => ({ certificateArn }))), protocol, port, sslPolicy: props.sslPolicy, @@ -123,7 +120,6 @@ export class ApplicationListener extends BaseListener implements IApplicationLis this.protocol = protocol; this.certificateArns = []; this.certificateArns.push(...(props.certificateArns || [])); - this.defaultPort = port; // This listener edits the securitygroup of the load balancer, // but adds its own default port. @@ -251,17 +247,6 @@ export class ApplicationListener extends BaseListener implements IApplicationLis this.connections.allowTo(connectable, portRange, 'Load balancer to target'); } - /** - * Export this listener - */ - public export(): ApplicationListenerImportProps { - return { - listenerArn: new cdk.CfnOutput(this, 'ListenerArn', { value: this.listenerArn }).makeImportValue().toString(), - securityGroupId: this.connections.securityGroups[0]!.export().securityGroupId, - defaultPort: new cdk.CfnOutput(this, 'Port', { value: this.defaultPort }).makeImportValue().toString(), - }; - } - /** * Validate this listener. */ @@ -285,9 +270,10 @@ export class ApplicationListener extends BaseListener implements IApplicationLis /** * Properties to reference an existing listener */ -export interface IApplicationListener extends cdk.IConstruct, ec2.IConnectable { +export interface IApplicationListener extends IResource, ec2.IConnectable { /** * ARN of the listener + * @attribute */ readonly listenerArn: string; @@ -323,17 +309,12 @@ export interface IApplicationListener extends cdk.IConstruct, ec2.IConnectable { * Don't call this directly. It is called by ApplicationTargetGroup. */ registerConnectable(connectable: ec2.IConnectable, portRange: ec2.IPortRange): void; - - /** - * Export this listener - */ - export(): ApplicationListenerImportProps; } /** * Properties to reference an existing listener */ -export interface ApplicationListenerImportProps { +export interface ApplicationListenerAttributes { /** * ARN of the listener */ @@ -347,10 +328,10 @@ export interface ApplicationListenerImportProps { /** * The default port on which this listener is listening */ - readonly defaultPort?: string; + readonly defaultPort?: number; } -class ImportedApplicationListener extends cdk.Construct implements IApplicationListener { +class ImportedApplicationListener extends Resource implements IApplicationListener { public readonly connections: ec2.Connections; /** @@ -358,12 +339,12 @@ class ImportedApplicationListener extends cdk.Construct implements IApplicationL */ public readonly listenerArn: string; - constructor(scope: cdk.Construct, id: string, private readonly props: ApplicationListenerImportProps) { + constructor(scope: Construct, id: string, props: ApplicationListenerAttributes) { super(scope, id); this.listenerArn = props.listenerArn; - const defaultPortRange = props.defaultPort !== undefined ? new ec2.TcpPortFromAttribute(props.defaultPort) : undefined; + const defaultPortRange = props.defaultPort !== undefined ? new ec2.TcpPort(props.defaultPort) : undefined; this.connections = new ec2.Connections({ securityGroups: [ec2.SecurityGroup.fromSecurityGroupId(this, 'SecurityGroup', props.securityGroupId)], @@ -371,10 +352,6 @@ class ImportedApplicationListener extends cdk.Construct implements IApplicationL }); } - public export() { - return this.props; - } - /** * Add one or more certificates to this listener. */ diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts index 1c1d5b6b2755d..742f073c37574 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts @@ -2,7 +2,7 @@ import cloudwatch = require('@aws-cdk/aws-cloudwatch'); import ec2 = require('@aws-cdk/aws-ec2'); import iam = require('@aws-cdk/aws-iam'); import s3 = require('@aws-cdk/aws-s3'); -import cdk = require('@aws-cdk/cdk'); +import { Construct, IResource, Token } from '@aws-cdk/cdk'; import { BaseLoadBalancer, BaseLoadBalancerProps } from '../shared/base-load-balancer'; import { IpAddressType } from '../shared/enums'; import { ApplicationListener, BaseApplicationListenerProps } from './application-listener'; @@ -44,22 +44,26 @@ export interface ApplicationLoadBalancerProps extends BaseLoadBalancerProps { /** * Define an Application Load Balancer + * + * @resource AWS::ElasticLoadBalancingV2::LoadBalancer */ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplicationLoadBalancer { /** * Import an existing Application Load Balancer */ - public static import(scope: cdk.Construct, id: string, props: ApplicationLoadBalancerImportProps): IApplicationLoadBalancer { - return new ImportedApplicationLoadBalancer(scope, id, props); + public static fromApplicationLoadBalancerAttributes( + scope: Construct, id: string, attrs: ApplicationLoadBalancerAttributes): IApplicationLoadBalancer { + + return new ImportedApplicationLoadBalancer(scope, id, attrs); } public readonly connections: ec2.Connections; private readonly securityGroup: ec2.ISecurityGroup; - constructor(scope: cdk.Construct, id: string, props: ApplicationLoadBalancerProps) { + constructor(scope: Construct, id: string, props: ApplicationLoadBalancerProps) { super(scope, id, props, { type: "application", - securityGroups: new cdk.Token(() => [this.securityGroup.securityGroupId]), + securityGroups: new Token(() => [this.securityGroup.securityGroupId]), ipAddressType: props.ipAddressType, }); @@ -105,16 +109,6 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic }); } - /** - * Export this load balancer - */ - public export(): ApplicationLoadBalancerImportProps { - return { - loadBalancerArn: new cdk.CfnOutput(this, 'LoadBalancerArn', { value: this.loadBalancerArn }).makeImportValue().toString(), - securityGroupId: this.securityGroup.export().securityGroupId, - }; - } - /** * Return the given named metric for this Application Load Balancer * @@ -124,7 +118,7 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic return new cloudwatch.Metric({ namespace: 'AWS/ApplicationELB', metricName, - dimensions: { LoadBalancer: this.fullName }, + dimensions: { LoadBalancer: this.loadBalancerFullName }, ...props }); } @@ -474,7 +468,7 @@ export enum HttpCodeTarget { /** * An application load balancer */ -export interface IApplicationLoadBalancer extends cdk.IConstruct, ec2.IConnectable { +export interface IApplicationLoadBalancer extends IResource, ec2.IConnectable { /** * The ARN of this load balancer */ @@ -483,23 +477,18 @@ export interface IApplicationLoadBalancer extends cdk.IConstruct, ec2.IConnectab /** * The VPC this load balancer has been created in (if available) */ - readonly vpc?: ec2.IVpcNetwork; + readonly vpc?: ec2.IVpc; /** * Add a new listener to this load balancer */ addListener(id: string, props: BaseApplicationListenerProps): ApplicationListener; - - /** - * Export this load balancer - */ - export(): ApplicationLoadBalancerImportProps; } /** * Properties to reference an existing load balancer */ -export interface ApplicationLoadBalancerImportProps { +export interface ApplicationLoadBalancerAttributes { /** * ARN of the load balancer */ @@ -537,7 +526,7 @@ const ELBV2_ACCOUNTS: {[region: string]: string } = { /** * An ApplicationLoadBalancer that has been defined elsewhere */ -class ImportedApplicationLoadBalancer extends cdk.Construct implements IApplicationLoadBalancer { +class ImportedApplicationLoadBalancer extends Construct implements IApplicationLoadBalancer { /** * Manage connections for this load balancer */ @@ -553,9 +542,9 @@ class ImportedApplicationLoadBalancer extends cdk.Construct implements IApplicat * * Always undefined. */ - public readonly vpc?: ec2.IVpcNetwork; + public readonly vpc?: ec2.IVpc; - constructor(scope: cdk.Construct, id: string, private readonly props: ApplicationLoadBalancerImportProps) { + constructor(scope: Construct, id: string, props: ApplicationLoadBalancerAttributes) { super(scope, id); this.loadBalancerArn = props.loadBalancerArn; @@ -564,10 +553,6 @@ class ImportedApplicationLoadBalancer extends cdk.Construct implements IApplicat }); } - public export() { - return this.props; - } - public addListener(id: string, props: BaseApplicationListenerProps): ApplicationListener { return new ApplicationListener(this, id, { loadBalancer: this, diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts index d580a1cf8c709..1b416498c6de9 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts @@ -1,6 +1,6 @@ import cloudwatch = require('@aws-cdk/aws-cloudwatch'); import ec2 = require('@aws-cdk/aws-ec2'); -import cdk = require('@aws-cdk/cdk'); +import { Construct, IConstruct } from '@aws-cdk/cdk'; import { BaseTargetGroupProps, ITargetGroup, loadBalancerNameFromListenerArn, LoadBalancerTargetProps, TargetGroupBase, TargetGroupImportProps } from '../shared/base-target-group'; import { ApplicationProtocol } from '../shared/enums'; @@ -66,14 +66,14 @@ export class ApplicationTargetGroup extends TargetGroupBase implements IApplicat /** * Import an existing target group */ - public static import(scope: cdk.Construct, id: string, props: TargetGroupImportProps): IApplicationTargetGroup { + public static import(scope: Construct, id: string, props: TargetGroupImportProps): IApplicationTargetGroup { return new ImportedApplicationTargetGroup(scope, id, props); } private readonly connectableMembers: ConnectableMember[]; private readonly listeners: IApplicationListener[]; - constructor(scope: cdk.Construct, id: string, props: ApplicationTargetGroupProps) { + constructor(scope: Construct, id: string, props: ApplicationTargetGroupProps) { const [protocol, port] = determineProtocolAndPort(props.protocol, props.port); super(scope, id, props, { @@ -119,13 +119,7 @@ export class ApplicationTargetGroup extends TargetGroupBase implements IApplicat * Don't call this directly. It will be called by load balancing targets. */ public registerConnectable(connectable: ec2.IConnectable, portRange?: ec2.IPortRange) { - if (portRange === undefined) { - if (cdk.Token.isToken(this.defaultPort)) { - portRange = new ec2.TcpPortFromAttribute(this.defaultPort); - } else { - portRange = new ec2.TcpPort(parseInt(this.defaultPort, 10)); - } - } + portRange = portRange || new ec2.TcpPort(this.defaultPort); // Notify all listeners that we already know about of this new connectable. // Then remember for new listeners that might get added later. @@ -140,7 +134,7 @@ export class ApplicationTargetGroup extends TargetGroupBase implements IApplicat * * Don't call this directly. It will be called by listeners. */ - public registerListener(listener: IApplicationListener, associatingConstruct?: cdk.IConstruct) { + public registerListener(listener: IApplicationListener, associatingConstruct?: IConstruct) { // Notify this listener of all connectables that we know about. // Then remember for new connectables that might get added later. for (const member of this.connectableMembers) { @@ -324,14 +318,14 @@ export interface IApplicationTargetGroup extends ITargetGroup { * * Don't call this directly. It will be called by listeners. */ - registerListener(listener: IApplicationListener, associatingConstruct?: cdk.IConstruct): void; + registerListener(listener: IApplicationListener, associatingConstruct?: IConstruct): void; } /** * An imported application target group */ class ImportedApplicationTargetGroup extends ImportedTargetGroupBase implements IApplicationTargetGroup { - public registerListener(_listener: IApplicationListener, _associatingConstruct?: cdk.IConstruct) { + public registerListener(_listener: IApplicationListener, _associatingConstruct?: IConstruct) { // Nothing to do, we know nothing of our members } } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts index b26555fb260a7..6ae87fdf346c9 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts @@ -1,4 +1,4 @@ -import cdk = require('@aws-cdk/cdk'); +import { Construct, IResource, Resource } from '@aws-cdk/cdk'; import { BaseListener } from '../shared/base-listener'; import { HealthCheck } from '../shared/base-target-group'; import { Protocol, SslPolicy } from '../shared/enums'; @@ -59,13 +59,19 @@ export interface NetworkListenerProps extends BaseNetworkListenerProps { /** * Define a Network Listener + * + * @resource AWS::ElasticLoadBalancingV2::Listener */ export class NetworkListener extends BaseListener implements INetworkListener { /** * Import an existing listener */ - public static import(scope: cdk.Construct, id: string, props: NetworkListenerImportProps): INetworkListener { - return new ImportedNetworkListener(scope, id, props); + public static fromNetworkListenerArn(scope: Construct, id: string, networkListenerArn: string): INetworkListener { + class Import extends Resource implements INetworkListener { + public listenerArn = networkListenerArn; + } + + return new Import(scope, id); } /** @@ -73,7 +79,7 @@ export class NetworkListener extends BaseListener implements INetworkListener { */ private readonly loadBalancer: INetworkLoadBalancer; - constructor(scope: cdk.Construct, id: string, props: NetworkListenerProps) { + constructor(scope: Construct, id: string, props: NetworkListenerProps) { const certs = props.certificates || []; const proto = props.protocol || (certs.length > 0 ? Protocol.Tls : Protocol.Tcp); @@ -141,62 +147,19 @@ export class NetworkListener extends BaseListener implements INetworkListener { return group; } - - /** - * Export this listener - */ - public export(): NetworkListenerImportProps { - return { - listenerArn: new cdk.CfnOutput(this, 'ListenerArn', { value: this.listenerArn }).makeImportValue().toString() - }; - } -} - -/** - * Properties to reference an existing listener - */ -export interface INetworkListener extends cdk.IConstruct { - /** - * ARN of the listener - */ - readonly listenerArn: string; - - /** - * Export this listener - */ - export(): NetworkListenerImportProps; } /** * Properties to reference an existing listener */ -export interface NetworkListenerImportProps { +export interface INetworkListener extends IResource { /** * ARN of the listener + * @attribute */ readonly listenerArn: string; } -/** - * An imported Network Listener - */ -class ImportedNetworkListener extends cdk.Construct implements INetworkListener { - /** - * ARN of the listener - */ - public readonly listenerArn: string; - - constructor(scope: cdk.Construct, id: string, private readonly props: NetworkListenerImportProps) { - super(scope, id); - - this.listenerArn = props.listenerArn; - } - - public export() { - return this.props; - } -} - /** * Properties for adding new network targets to a listener */ diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts index ba906d8de2f67..5565a35ce9169 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts @@ -1,6 +1,6 @@ import cloudwatch = require('@aws-cdk/aws-cloudwatch'); import ec2 = require('@aws-cdk/aws-ec2'); -import cdk = require('@aws-cdk/cdk'); +import { Construct, IResource, Resource } from '@aws-cdk/cdk'; import { BaseLoadBalancer, BaseLoadBalancerProps } from '../shared/base-load-balancer'; import { BaseNetworkListenerProps, NetworkListener } from './network-listener'; @@ -18,13 +18,26 @@ export interface NetworkLoadBalancerProps extends BaseLoadBalancerProps { /** * Define a new network load balancer + * + * @resource AWS::ElasticLoadBalancingV2::LoadBalancer */ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoadBalancer { - public static import(scope: cdk.Construct, id: string, props: NetworkLoadBalancerImportProps): INetworkLoadBalancer { - return new ImportedNetworkLoadBalancer(scope, id, props); - } - - constructor(scope: cdk.Construct, id: string, props: NetworkLoadBalancerProps) { + public static fromNetworkLoadBalancerArn(scope: Construct, id: string, networkLoadBalancerArn: string): INetworkLoadBalancer { + class Import extends Resource implements INetworkLoadBalancer { + public readonly loadBalancerArn = networkLoadBalancerArn; + public readonly vpc?: ec2.IVpc = undefined; + public addListener(lid: string, props: BaseNetworkListenerProps): NetworkListener { + return new NetworkListener(this, lid, { + loadBalancer: this, + ...props + }); + } + } + + return new Import(scope, id); + } + + constructor(scope: Construct, id: string, props: NetworkLoadBalancerProps) { super(scope, id, props, { type: "network", }); @@ -44,15 +57,6 @@ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoa }); } - /** - * Export this load balancer - */ - public export(): NetworkLoadBalancerImportProps { - return { - loadBalancerArn: new cdk.CfnOutput(this, 'LoadBalancerArn', { value: this.loadBalancerArn }).makeImportValue().toString() - }; - } - /** * Return the given named metric for this Network Load Balancer * @@ -62,7 +66,7 @@ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoa return new cloudwatch.Metric({ namespace: 'AWS/NetworkELB', metricName, - dimensions: { LoadBalancer: this.fullName }, + dimensions: { LoadBalancer: this.loadBalancerFullName }, ...props }); } @@ -187,7 +191,7 @@ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoa /** * A network load balancer */ -export interface INetworkLoadBalancer extends cdk.IConstruct { +export interface INetworkLoadBalancer extends IResource { /** * The ARN of this load balancer */ @@ -196,7 +200,7 @@ export interface INetworkLoadBalancer extends cdk.IConstruct { /** * The VPC this load balancer has been created in (if available) */ - readonly vpc?: ec2.IVpcNetwork; + readonly vpc?: ec2.IVpc; /** * Add a listener to this load balancer @@ -204,58 +208,4 @@ export interface INetworkLoadBalancer extends cdk.IConstruct { * @returns The newly created listener */ addListener(id: string, props: BaseNetworkListenerProps): NetworkListener; - - /** - * Export this load balancer - */ - export(): NetworkLoadBalancerImportProps; -} - -/** - * Properties to reference an existing load balancer - */ -export interface NetworkLoadBalancerImportProps { - /** - * ARN of the load balancer - */ - readonly loadBalancerArn: string; -} - -/** - * An imported network load balancer - */ -class ImportedNetworkLoadBalancer extends cdk.Construct implements INetworkLoadBalancer { - /** - * ARN of the load balancer - */ - public readonly loadBalancerArn: string; - - /** - * VPC of the load balancer - * - * Always undefined. - */ - public readonly vpc?: ec2.IVpcNetwork; - - constructor(scope: cdk.Construct, id: string, private readonly props: NetworkLoadBalancerImportProps) { - super(scope, id); - - this.loadBalancerArn = props.loadBalancerArn; - } - - public export() { - return this.props; - } - - /** - * Add a listener to this load balancer - * - * @returns The newly created listener - */ - public addListener(id: string, props: BaseNetworkListenerProps): NetworkListener { - return new NetworkListener(this, id, { - loadBalancer: this, - ...props - }); - } } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-listener.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-listener.ts index 0d20e2dd60967..9b233274671cc 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-listener.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-listener.ts @@ -1,20 +1,24 @@ -import cdk = require('@aws-cdk/cdk'); +import { Construct, Resource, Token } from '@aws-cdk/cdk'; import { CfnListener } from '../elasticloadbalancingv2.generated'; import { ITargetGroup } from './base-target-group'; /** * Base class for listeners */ -export abstract class BaseListener extends cdk.Construct { +export abstract class BaseListener extends Resource { + /** + * @attribute + */ public readonly listenerArn: string; + private readonly defaultActions: CfnListener.ActionProperty[] = []; - constructor(scope: cdk.Construct, id: string, additionalProps: any) { + constructor(scope: Construct, id: string, additionalProps: any) { super(scope, id); const resource = new CfnListener(this, 'Resource', { ...additionalProps, - defaultActions: new cdk.Token(() => this.defaultActions), + defaultActions: new Token(() => this.defaultActions), }); this.listenerArn = resource.ref; 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 5d3e73bb723ee..ff1f813273967 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 @@ -1,6 +1,6 @@ import ec2 = require('@aws-cdk/aws-ec2'); import route53 = require('@aws-cdk/aws-route53'); -import cdk = require('@aws-cdk/cdk'); +import { Construct, Resource, Token } from '@aws-cdk/cdk'; import { CfnLoadBalancer } from '../elasticloadbalancingv2.generated'; import { Attributes, ifUndefined, renderAttributes } from './util'; @@ -18,7 +18,7 @@ export interface BaseLoadBalancerProps { /** * The VPC network to place the load balancer in */ - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; /** * Whether the load balancer has an internet-routable address @@ -45,32 +45,36 @@ export interface BaseLoadBalancerProps { /** * Base class for both Application and Network Load Balancers */ -export abstract class BaseLoadBalancer extends cdk.Construct implements route53.IAliasRecordTarget { +export abstract class BaseLoadBalancer extends Resource implements route53.IAliasRecordTarget { /** * The canonical hosted zone ID of this load balancer * - * @example Z2P70J7EXAMPLE + * @example Z2P70J7EXAMPLE + * @attribute */ - public readonly canonicalHostedZoneId: string; + public readonly loadBalancerCanonicalHostedZoneId: string; /** * The DNS name of this load balancer * * @example my-load-balancer-424835706.us-west-2.elb.amazonaws.com + * @attribute */ - public readonly dnsName: string; + public readonly loadBalancerDnsName: string; /** * The full name of this load balancer * * @example app/my-load-balancer/50dc6c495c0c9188 + * @attribute */ - public readonly fullName: string; + public readonly loadBalancerFullName: string; /** * The name of this load balancer * * @example my-load-balancer + * @attribute */ public readonly loadBalancerName: string; @@ -78,22 +82,28 @@ export abstract class BaseLoadBalancer extends cdk.Construct implements route53. * The ARN of this load balancer * * @example arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-internal-load-balancer/50dc6c495c0c9188 + * @attribute */ public readonly loadBalancerArn: string; + /** + * @attribute + */ + public readonly loadBalancerSecurityGroups: string[]; + /** * The VPC this load balancer has been created in, if available * * If the Load Balancer was imported, the VPC is not available. */ - public readonly vpc?: ec2.IVpcNetwork; + public readonly vpc?: ec2.IVpc; /** * Attributes set on this load balancer */ private readonly attributes: Attributes = {}; - constructor(scope: cdk.Construct, id: string, baseProps: BaseLoadBalancerProps, additionalProps: any) { + constructor(scope: Construct, id: string, baseProps: BaseLoadBalancerProps, additionalProps: any) { super(scope, id); const internetFacing = ifUndefined(baseProps.internetFacing, false); @@ -109,7 +119,7 @@ export abstract class BaseLoadBalancer extends cdk.Construct implements route53. name: baseProps.loadBalancerName, subnets: subnetIds, scheme: internetFacing ? 'internet-facing' : 'internal', - loadBalancerAttributes: new cdk.Token(() => renderAttributes(this.attributes)), + loadBalancerAttributes: new Token(() => renderAttributes(this.attributes)), ...additionalProps }); if (internetFacing) { @@ -118,11 +128,12 @@ export abstract class BaseLoadBalancer extends cdk.Construct implements route53. if (baseProps.deletionProtection) { this.setAttribute('deletion_protection.enabled', 'true'); } - this.canonicalHostedZoneId = resource.loadBalancerCanonicalHostedZoneId; - this.dnsName = resource.loadBalancerDnsName; - this.fullName = resource.loadBalancerFullName; + this.loadBalancerCanonicalHostedZoneId = resource.loadBalancerCanonicalHostedZoneId; + this.loadBalancerDnsName = resource.loadBalancerDnsName; + this.loadBalancerFullName = resource.loadBalancerFullName; this.loadBalancerName = resource.loadBalancerName; this.loadBalancerArn = resource.ref; + this.loadBalancerSecurityGroups = resource.loadBalancerSecurityGroups; } /** @@ -143,8 +154,8 @@ export abstract class BaseLoadBalancer extends cdk.Construct implements route53. public asAliasRecordTarget(): route53.AliasRecordTargetProps { return { - hostedZoneId: this.canonicalHostedZoneId, - dnsName: this.dnsName + hostedZoneId: this.loadBalancerCanonicalHostedZoneId, + dnsName: this.loadBalancerDnsName }; } } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts index 5ab5bfe336231..821d65ecc3a2d 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-target-group.ts @@ -22,12 +22,12 @@ export interface BaseTargetGroupProps { /** * The virtual private cloud (VPC). */ - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; /** * The amount of time for Elastic Load Balancing to wait before deregistering a target. * - * The range is 0–3600 seconds. + * The range is 0-3600 seconds. * * @default 300 */ @@ -174,7 +174,7 @@ export abstract class TargetGroupBase extends cdk.Construct implements ITargetGr /** * Default port configured for members of this target group */ - protected readonly defaultPort: string; + protected readonly defaultPort: number; /** * Configurable dependable with all resources that lead to load balancer attachment @@ -238,7 +238,7 @@ export abstract class TargetGroupBase extends cdk.Construct implements ITargetGr this.targetGroupFullName = this.resource.targetGroupFullName; this.loadBalancerArns = this.resource.targetGroupLoadBalancerArns.toString(); this.targetGroupName = this.resource.targetGroupName; - this.defaultPort = `${additionalProps.port}`; + this.defaultPort = additionalProps.port; } /** @@ -264,16 +264,6 @@ export abstract class TargetGroupBase extends cdk.Construct implements ITargetGr this.attributes[key] = value; } - /** - * Export this target group - */ - public export(): TargetGroupImportProps { - return { - targetGroupArn: new cdk.CfnOutput(this, 'TargetGroupArn', { value: this.targetGroupArn }).makeImportValue().toString(), - defaultPort: new cdk.CfnOutput(this, 'Port', { value: this.defaultPort }).makeImportValue().toString(), - }; - } - /** * Register the given load balancing target as part of this group */ @@ -327,12 +317,6 @@ export interface ITargetGroup extends cdk.IConstruct { * Return an object to depend on the listeners added to this target group */ readonly loadBalancerAttached: cdk.IDependable; - - /** - * Export this target group - */ - export(): TargetGroupImportProps; - } /** diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts index e2dc46523121b..6def9ea86ff42 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/imported.ts @@ -20,14 +20,10 @@ export abstract class ImportedTargetGroupBase extends cdk.Construct implements I */ public readonly loadBalancerAttached: cdk.IDependable = new cdk.ConcreteDependable(); - constructor(scope: cdk.Construct, id: string, private readonly props: TargetGroupImportProps) { + constructor(scope: cdk.Construct, id: string, props: TargetGroupImportProps) { super(scope, id); this.targetGroupArn = props.targetGroupArn; this.loadBalancerArns = props.loadBalancerArns || cdk.Aws.noValue; } - - public export() { - return this.props; - } } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.listener.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.listener.ts index acdad7562e2c7..2aa275e993bed 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.listener.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.listener.ts @@ -9,7 +9,7 @@ export = { 'Listener guesses protocol from port'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); // WHEN @@ -30,7 +30,7 @@ export = { 'Listener guesses port from protocol'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); // WHEN @@ -50,7 +50,7 @@ export = { 'Listener default to open'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const loadBalancer = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); // WHEN @@ -78,7 +78,7 @@ export = { 'HTTPS listener requires certificate'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); // WHEN @@ -97,7 +97,7 @@ export = { 'Can configure targetType on TargetGroups'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN new elbv2.ApplicationTargetGroup(stack, 'TargetGroup', { @@ -117,7 +117,7 @@ export = { 'Can configure name on TargetGroups'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN new elbv2.ApplicationTargetGroup(stack, 'TargetGroup', { @@ -137,7 +137,7 @@ export = { 'Can add target groups with and without conditions'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); const listener = lb.addListener('Listener', { port: 80 }); const group = new elbv2.ApplicationTargetGroup(stack, 'TargetGroup', { vpc, port: 80 }); @@ -183,7 +183,7 @@ export = { 'Can implicitly create target groups with and without conditions'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); const listener = lb.addListener('Listener', { port: 80 }); @@ -239,7 +239,7 @@ export = { 'Add certificate to constructed listener'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); const listener = lb.addListener('Listener', { port: 443 }); @@ -259,13 +259,12 @@ export = { 'Add certificate to imported listener'(test: Test) { // GIVEN - const stack1 = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack1, 'Stack'); - const lb = new elbv2.ApplicationLoadBalancer(stack1, 'LB', { vpc }); - const listener1 = lb.addListener('Listener', { port: 443 }); - const stack2 = new cdk.Stack(); - const listener2 = elbv2.ApplicationListener.import(stack2, 'Listener', listener1.export()); + const listener2 = elbv2.ApplicationListener.fromApplicationListenerAttributes(stack2, 'Listener', { + listenerArn: 'listener-arn', + defaultPort: 443, + securityGroupId: 'security-group-id' + }); // WHEN listener2.addCertificateArns('Arns', ['cert']); @@ -283,7 +282,7 @@ export = { 'Enable stickiness for targets'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); const listener = lb.addListener('Listener', { port: 80 }); @@ -318,7 +317,7 @@ export = { 'Enable health check for targets'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); const listener = lb.addListener('Listener', { port: 80 }); @@ -348,8 +347,8 @@ export = { 'Can call addTargetGroups on imported listener'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); - const listener = elbv2.ApplicationListener.import(stack, 'Listener', { + const vpc = new ec2.Vpc(stack, 'VPC'); + const listener = elbv2.ApplicationListener.fromApplicationListenerAttributes(stack, 'Listener', { listenerArn: 'ieks', securityGroupId: 'sg-12345' }); @@ -380,7 +379,7 @@ export = { 'Can depend on eventual listener via TargetGroup'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const loadBalancer = new elbv2.ApplicationLoadBalancer(stack, 'LoadBalancer', { vpc }); const group = new elbv2.ApplicationTargetGroup(stack, 'TargetGroup', { vpc, port: 80 }); @@ -408,7 +407,7 @@ export = { 'Exercise metrics'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); const group = new elbv2.ApplicationTargetGroup(stack, 'TargetGroup', { vpc, port: 80 }); lb.addListener('SomeListener', { @@ -452,7 +451,7 @@ export = { 'Can add dependency on ListenerRule via TargetGroup'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const loadBalancer = new elbv2.ApplicationLoadBalancer(stack, 'LoadBalancer', { vpc }); const group1 = new elbv2.ApplicationTargetGroup(stack, 'TargetGroup1', { vpc, port: 80 }); const group2 = new elbv2.ApplicationTargetGroup(stack, 'TargetGroup2', { vpc, port: 80 }); @@ -486,7 +485,7 @@ export = { 'Can add fixed responses'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LoadBalancer', { vpc }); @@ -539,7 +538,7 @@ export = { 'status code'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LoadBalancer', { vpc }); @@ -558,7 +557,7 @@ export = { 'message body'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LoadBalancer', { vpc }); @@ -579,7 +578,7 @@ export = { 'Throws when specifying both target groups and fixed reponse'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LoadBalancer', { vpc }); diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.load-balancer.ts index af42eff905686..7a372c2fdc806 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.load-balancer.ts @@ -10,7 +10,7 @@ export = { 'Trivial construction: internet facing'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN new elbv2.ApplicationLoadBalancer(stack, 'LB', { @@ -35,7 +35,7 @@ export = { 'internet facing load balancer has dependency on IGW'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN new elbv2.ApplicationLoadBalancer(stack, 'LB', { @@ -58,7 +58,7 @@ export = { 'Trivial construction: internal'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); @@ -80,7 +80,7 @@ export = { 'Attributes'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN new elbv2.ApplicationLoadBalancer(stack, 'LB', { @@ -114,7 +114,7 @@ export = { 'Access logging'(test: Test) { // GIVEN const stack = new cdk.Stack(undefined, undefined, { env: { region: 'us-east-1' }}); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const bucket = new s3.Bucket(stack, 'AccessLoggingBucket'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); @@ -163,7 +163,7 @@ export = { 'access logging with prefix'(test: Test) { // GIVEN const stack = new cdk.Stack(undefined, undefined, { env: { region: 'us-east-1' }}); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const bucket = new s3.Bucket(stack, 'AccessLoggingBucket'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); @@ -210,7 +210,7 @@ export = { 'Exercise metrics'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc }); // WHEN @@ -251,7 +251,7 @@ export = { 'loadBalancerName'(test: Test) { // GIVEN const stack = new Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN new elbv2.ApplicationLoadBalancer(stack, 'ALB', { diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.security-groups.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.security-groups.ts index 6b418f832d43b..20ddb56cff47d 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.security-groups.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/test.security-groups.ts @@ -103,7 +103,7 @@ export = { // GIVEN const fixture = new TestFixture(); const stack2 = new cdk.Stack(); - const vpc2 = new ec2.VpcNetwork(stack2, 'VPC'); + const vpc2 = new ec2.Vpc(stack2, 'VPC'); const group = new elbv2.ApplicationTargetGroup(stack2, 'TargetGroup', { // We're assuming the 2nd VPC is peered to the 1st, or something. vpc: vpc2, @@ -112,7 +112,10 @@ export = { }); // WHEN - const lb2 = elbv2.ApplicationLoadBalancer.import(stack2, 'LB', fixture.lb.export()); + const lb2 = elbv2.ApplicationLoadBalancer.fromApplicationLoadBalancerAttributes(stack2, 'LB', { + loadBalancerArn: fixture.lb.loadBalancerArn, + securityGroupId: fixture.lb.connections.securityGroups[0].securityGroupId + }); const listener2 = lb2.addListener('YetAnotherListener', { port: 80 }); listener2.addTargetGroups('Default', { targetGroups: [group] }); @@ -126,7 +129,7 @@ export = { // GIVEN const fixture = new TestFixture(); const stack2 = new cdk.Stack(); - const vpc2 = new ec2.VpcNetwork(stack2, 'VPC'); + const vpc2 = new ec2.Vpc(stack2, 'VPC'); const group = new elbv2.ApplicationTargetGroup(stack2, 'TargetGroup', { // We're assuming the 2nd VPC is peered to the 1st, or something. vpc: vpc2, @@ -135,7 +138,11 @@ export = { }); // WHEN - const listener2 = elbv2.ApplicationListener.import(stack2, 'YetAnotherListener', fixture.listener.export()); + const listener2 = elbv2.ApplicationListener.fromApplicationListenerAttributes(stack2, 'YetAnotherListener', { + defaultPort: 8008, + securityGroupId: fixture.listener.connections.securityGroups[0].securityGroupId, + listenerArn: fixture.listener.listenerArn + }); listener2.addTargetGroups('Default', { // Must be a non-default target priority: 10, @@ -175,12 +182,14 @@ export = { 'default port peering works on imported listener'(test: Test) { // GIVEN - const fixture = new TestFixture(); - fixture.listener.addTargets('Default', { port: 8080, targets: [new elbv2.InstanceTarget('i-12345')] }); const stack2 = new cdk.Stack(); // WHEN - const listener2 = elbv2.ApplicationListener.import(stack2, 'YetAnotherListener', fixture.listener.export()); + const listener2 = elbv2.ApplicationListener.fromApplicationListenerAttributes(stack2, 'YetAnotherListener', { + listenerArn: 'listener-arn', + securityGroupId: 'imported-security-group-id', + defaultPort: 8080 + }); listener2.connections.allowDefaultPortFromAnyIpv4('Open to the world'); // THEN @@ -188,9 +197,9 @@ export = { CidrIp: "0.0.0.0/0", Description: "Open to the world", IpProtocol: "tcp", - FromPort: { "Fn::ImportValue": "Stack:LBListenerPort7A9266A6" }, - ToPort: { "Fn::ImportValue": "Stack:LBListenerPort7A9266A6" }, - GroupId: IMPORTED_LB_SECURITY_GROUP + FromPort: 8080, + ToPort: 8080, + GroupId: 'imported-security-group-id' })); test.done(); @@ -198,7 +207,7 @@ export = { }; const LB_SECURITY_GROUP = { "Fn::GetAtt": [ "LBSecurityGroup8A41EA2B", "GroupId" ] }; -const IMPORTED_LB_SECURITY_GROUP = { "Fn::ImportValue": "Stack:LBSecurityGroupSecurityGroupId0270B565" }; +const IMPORTED_LB_SECURITY_GROUP = { "Fn::ImportValue": "Stack:ExportsOutputFnGetAttLBSecurityGroup8A41EA2BGroupId851EE1F6" }; function expectSameStackSGRules(stack: cdk.Stack) { expectSGRules(stack, LB_SECURITY_GROUP); @@ -229,13 +238,13 @@ function expectSGRules(stack: cdk.Stack, lbGroup: any) { class TestFixture { public readonly stack: cdk.Stack; - public readonly vpc: ec2.VpcNetwork; + public readonly vpc: ec2.Vpc; public readonly lb: elbv2.ApplicationLoadBalancer; public readonly listener: elbv2.ApplicationListener; constructor() { this.stack = new cdk.Stack(); - this.vpc = new ec2.VpcNetwork(this.stack, 'VPC', { + this.vpc = new ec2.Vpc(this.stack, 'VPC', { maxAZs: 2 }); this.lb = new elbv2.ApplicationLoadBalancer(this.stack, 'LB', { vpc: this.vpc }); diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/helpers.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/helpers.ts index 7f747e4893890..6e1d2a56d6f8a 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/helpers.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/helpers.ts @@ -7,7 +7,7 @@ export class FakeSelfRegisteringTarget extends cdk.Construct implements elbv2.IA public readonly securityGroup: ec2.SecurityGroup; public readonly connections: ec2.Connections; - constructor(scope: cdk.Construct, id: string, vpc: ec2.VpcNetwork) { + constructor(scope: cdk.Construct, id: string, vpc: ec2.Vpc) { super(scope, id); this.securityGroup = new ec2.SecurityGroup(this, 'SG', { vpc }); this.connections = new ec2.Connections({ diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts index abde2b0edd6a4..3ef471bf210e8 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.ts @@ -7,7 +7,7 @@ import elbv2 = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-elbv2-integ'); -const vpc = new ec2.VpcNetwork(stack, 'VPC', { +const vpc = new ec2.Vpc(stack, 'VPC', { maxAZs: 2 }); diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.ts index 604ea4f8522c6..e02fa524a5bdc 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.ts @@ -6,7 +6,7 @@ import elbv2 = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-elbv2-integ'); -const vpc = new ec2.VpcNetwork(stack, 'VPC', { +const vpc = new ec2.Vpc(stack, 'VPC', { maxAZs: 2 }); diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts index 2dd2ee2c30948..d55917a2275a4 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts @@ -6,7 +6,7 @@ import elbv2 = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-elbv2-integ'); -const vpc = new ec2.VpcNetwork(stack, 'VPC', { +const vpc = new ec2.Vpc(stack, 'VPC', { maxAZs: 2 }); diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.listener.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.listener.ts index 40ee69ff2f1a8..854b06801f6dc 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.listener.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.listener.ts @@ -10,7 +10,7 @@ export = { 'Trivial add listener'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc }); // WHEN @@ -31,7 +31,7 @@ export = { 'Can add target groups'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc }); const listener = lb.addListener('Listener', { port: 443 }); const group = new elbv2.NetworkTargetGroup(stack, 'TargetGroup', { vpc, port: 80 }); @@ -55,7 +55,7 @@ export = { 'Can implicitly create target groups'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc }); const listener = lb.addListener('Listener', { port: 443 }); @@ -89,7 +89,7 @@ export = { 'Enable health check for targets'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc }); const listener = lb.addListener('Listener', { port: 443 }); @@ -117,7 +117,7 @@ export = { 'Enable taking a dependency on an NLB target group\'s load balancer'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc }); const listener = lb.addListener('Listener', { port: 443 }); const group = listener.addTargets('Group', { @@ -149,7 +149,7 @@ export = { 'Trivial add TLS listener'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc }); const cert = new acm.Certificate(stack, 'Certificate', { domainName: 'example.com' @@ -179,7 +179,7 @@ export = { 'Invalid Protocol listener'(test: Test) { const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc }); test.throws(() => lb.addListener('Listener', { @@ -193,7 +193,7 @@ export = { 'Protocol & certs TLS listener'(test: Test) { const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc }); test.throws(() => lb.addListener('Listener', { @@ -207,7 +207,7 @@ export = { 'TLS and certs specified listener'(test: Test) { const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc }); const cert = new acm.Certificate(stack, 'Certificate', { domainName: 'example.com' diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts index 5cfa73c785550..96da83363c6e9 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/nlb/test.load-balancer.ts @@ -8,7 +8,7 @@ export = { 'Trivial construction: internet facing'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN new elbv2.NetworkLoadBalancer(stack, 'LB', { @@ -33,7 +33,7 @@ export = { 'Trivial construction: internal'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc }); @@ -55,7 +55,7 @@ export = { 'Attributes'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN new elbv2.NetworkLoadBalancer(stack, 'LB', { @@ -79,7 +79,7 @@ export = { 'loadBalancerName'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'Stack'); + const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN new elbv2.NetworkLoadBalancer(stack, 'ALB', { diff --git a/packages/@aws-cdk/aws-events/lib/rule-ref.ts b/packages/@aws-cdk/aws-events/lib/rule-ref.ts index 7e9019f55dcbd..8a262b8c6ecaa 100644 --- a/packages/@aws-cdk/aws-events/lib/rule-ref.ts +++ b/packages/@aws-cdk/aws-events/lib/rule-ref.ts @@ -1,13 +1,5 @@ import { IResource } from '@aws-cdk/cdk'; -export interface EventRuleAttributes { - /** - * The value of the event rule Amazon Resource Name (ARN), such as - * arn:aws:events:us-east-2:123456789012:rule/example. - */ - readonly eventRuleArn: string; -} - export interface IEventRule extends IResource { /** * The value of the event rule Amazon Resource Name (ARN), such as @@ -16,9 +8,4 @@ export interface IEventRule extends IResource { * @attribute */ readonly ruleArn: string; - - /** - * Exports this rule resource from this stack and returns an import token. - */ - export(): EventRuleAttributes; } diff --git a/packages/@aws-cdk/aws-events/lib/rule.ts b/packages/@aws-cdk/aws-events/lib/rule.ts index 5bd65aaac7203..ba51df14a2d48 100644 --- a/packages/@aws-cdk/aws-events/lib/rule.ts +++ b/packages/@aws-cdk/aws-events/lib/rule.ts @@ -1,8 +1,8 @@ -import { CfnOutput, Construct, Resource, Token } from '@aws-cdk/cdk'; +import { Construct, Resource, Token } from '@aws-cdk/cdk'; import { EventPattern } from './event-pattern'; import { CfnRule } from './events.generated'; import { TargetInputTemplate } from './input-options'; -import { EventRuleAttributes, IEventRule } from './rule-ref'; +import { IEventRule } from './rule-ref'; import { IEventRuleTarget } from './target'; import { mergeEventPattern } from './util'; @@ -70,9 +70,6 @@ export class EventRule extends Resource implements IEventRule { public static fromEventRuleArn(scope: Construct, id: string, eventRuleArn: string): IEventRule { class Import extends Resource implements IEventRule { public ruleArn = eventRuleArn; - public export(): EventRuleAttributes { - return { eventRuleArn }; - } } return new Import(scope, id); } @@ -105,15 +102,6 @@ export class EventRule extends Resource implements IEventRule { } } - /** - * Exports this rule resource from this stack and returns an import token. - */ - public export(): EventRuleAttributes { - return { - eventRuleArn: new CfnOutput(this, 'RuleArn', { value: this.ruleArn }).makeImportValue().toString() - }; - } - /** * Adds a target to the rule. The abstract class RuleTarget can be extended to define new * targets. diff --git a/packages/@aws-cdk/aws-events/test/test.rule.ts b/packages/@aws-cdk/aws-events/test/test.rule.ts index b15c1187d5ef1..185c29b4763b3 100644 --- a/packages/@aws-cdk/aws-events/test/test.rule.ts +++ b/packages/@aws-cdk/aws-events/test/test.rule.ts @@ -334,19 +334,15 @@ export = { test.done(); }, - 'import/export rule'(test: Test) { + 'fromEventRuleArn'(test: Test) { // GIVEN const stack = new Stack(); - const myRule = new EventRule(stack, 'MyRule'); // WHEN - const exportedRule = myRule.export(); const importedRule = EventRule.fromEventRuleArn(stack, 'ImportedRule', 'arn:of:rule'); // THEN - test.deepEqual(stack.node.resolve(exportedRule), { eventRuleArn: { 'Fn::ImportValue': 'Stack:MyRuleRuleArnDB13ADB1' } }); test.deepEqual(importedRule.ruleArn, 'arn:of:rule'); - test.done(); }, diff --git a/packages/@aws-cdk/aws-glue/lib/database.ts b/packages/@aws-cdk/aws-glue/lib/database.ts index 8e1fb872128e0..aec37901ec5f0 100644 --- a/packages/@aws-cdk/aws-glue/lib/database.ts +++ b/packages/@aws-cdk/aws-glue/lib/database.ts @@ -1,5 +1,5 @@ import s3 = require('@aws-cdk/aws-s3'); -import { CfnOutput, Construct, IResource, Resource } from '@aws-cdk/cdk'; +import { Construct, IResource, Resource } from '@aws-cdk/cdk'; import { CfnDatabase } from './glue.generated'; export interface IDatabase extends IResource { @@ -26,21 +26,6 @@ export interface IDatabase extends IResource { * @attribute */ readonly databaseName: string; - - /** - * The location of the database (for example, an HDFS path). - */ - readonly locationUri: string; - - export(): DatabaseAttributes; -} - -export interface DatabaseAttributes { - readonly catalogArn: string; - readonly catalogId: string; - readonly databaseArn: string; - readonly databaseName: string; - readonly locationUri: string; } export interface DatabaseProps { @@ -68,43 +53,6 @@ export class Database extends Resource implements IDatabase { public databaseName = scope.node.stack.parseArn(databaseArn).resourceName!; public catalogArn = scope.node.stack.formatArn({ service: 'glue', resource: 'catalog' }); public catalogId = scope.node.stack.accountId; - - public get locationUri(): string { - throw new Error(`glue.Database.fromDatabaseArn: no "locationUri"`); - } - - public export(): DatabaseAttributes { - return { - catalogArn: this.catalogArn, - catalogId: this.catalogId, - databaseName: this.databaseName, - databaseArn: this.databaseArn, - locationUri: this.locationUri, - }; - } - } - - return new Import(scope, id); - } - - /** - * Creates a Database construct that represents an external database. - * - * @param scope The scope creating construct (usually `this`). - * @param id The construct's id. - * @param attrs A `DatabaseAttributes` object. Can be obtained from a call to `database.export()` or manually created. - */ - public static fromDatabaseAttributes(scope: Construct, id: string, attrs: DatabaseAttributes): IDatabase { - - class Import extends Construct implements IDatabase { - public readonly catalogArn = attrs.catalogArn; - public readonly catalogId = attrs.catalogId; - public readonly databaseArn = attrs.databaseArn; - public readonly databaseName = attrs.databaseName; - public readonly locationUri = attrs.locationUri; - public export() { - return attrs; - } } return new Import(scope, id); @@ -167,17 +115,4 @@ export class Database extends Resource implements IDatabase { resource: 'catalog' }); } - - /** - * Exports this database from the stack. - */ - public export(): DatabaseAttributes { - return { - catalogArn: new CfnOutput(this, 'CatalogArn', { value: this.catalogArn }).makeImportValue().toString(), - catalogId: new CfnOutput(this, 'CatalogId', { value: this.catalogId }).makeImportValue().toString(), - databaseArn: new CfnOutput(this, 'DatabaseArn', { value: this.databaseArn }).makeImportValue().toString(), - databaseName: new CfnOutput(this, 'DatabaseName', { value: this.databaseName }).makeImportValue().toString(), - locationUri: new CfnOutput(this, 'LocationURI', { value: this.locationUri }).makeImportValue().toString() - }; - } } diff --git a/packages/@aws-cdk/aws-glue/lib/table.ts b/packages/@aws-cdk/aws-glue/lib/table.ts index 07428424b06ed..7546c289c51f1 100644 --- a/packages/@aws-cdk/aws-glue/lib/table.ts +++ b/packages/@aws-cdk/aws-glue/lib/table.ts @@ -1,7 +1,7 @@ import iam = require('@aws-cdk/aws-iam'); import kms = require('@aws-cdk/aws-kms'); import s3 = require('@aws-cdk/aws-s3'); -import { CfnOutput, Construct, Fn, IResource, Resource } from '@aws-cdk/cdk'; +import { Construct, Fn, IResource, Resource } from '@aws-cdk/cdk'; import { DataFormat } from './data-format'; import { IDatabase } from './database'; import { CfnTable } from './glue.generated'; @@ -17,8 +17,6 @@ export interface ITable extends IResource { * @attribute */ readonly tableName: string; - - export(): TableAttributes; } /** @@ -136,7 +134,7 @@ export interface TableProps { * * @default key is managed by KMS. */ - readonly encryptionKey?: kms.IEncryptionKey; + readonly encryptionKey?: kms.IKey; /** * Indicates whether the table data is stored in subdirectories. @@ -165,15 +163,12 @@ export class Table extends Resource implements ITable { * * @param scope The scope creating construct (usually `this`). * @param id The construct's id. - * @param attrs A `TableImportProps` object. Can be obtained from a call to `table.export()` or manually created. + * @param attrs Import attributes */ public static fromTableAttributes(scope: Construct, id: string, attrs: TableAttributes): ITable { class Import extends Construct implements ITable { public readonly tableArn = attrs.tableArn; public readonly tableName = attrs.tableName; - public export(): TableAttributes { - return attrs; - } } return new Import(scope, id); @@ -192,7 +187,7 @@ export class Table extends Resource implements ITable { /** * The KMS key used to secure the data if `encryption` is set to `CSE-KMS` or `SSE-KMS`. Otherwise, `undefined`. */ - public readonly encryptionKey?: kms.IEncryptionKey; + public readonly encryptionKey?: kms.IKey; /** * S3 bucket in which the table's data resides. @@ -279,13 +274,6 @@ export class Table extends Resource implements ITable { this.tableArn = `${this.database.databaseArn}/${this.tableName}`; } - public export(): TableAttributes { - return { - tableName: new CfnOutput(this, 'TableName', { value: this.tableName }).makeImportValue().toString(), - tableArn: new CfnOutput(this, 'TableArn', { value: this.tableArn }).makeImportValue().toString(), - }; - } - /** * Grant read permissions to the table and the underlying data stored in S3 to an IAM principal. * @@ -363,11 +351,11 @@ function createBucket(table: Table, props: TableProps) { throw new Error('you can not specify encryption settings if you also provide a bucket'); } - let encryptionKey: kms.IEncryptionKey | undefined; + let encryptionKey: kms.IKey | undefined; if (encryption === TableEncryption.ClientSideKms && props.encryptionKey === undefined) { // CSE-KMS should behave the same as SSE-KMS - use the provided key or create one automatically // Since Bucket only knows about SSE, we repeat the logic for CSE-KMS at the Table level. - encryptionKey = new kms.EncryptionKey(table, 'Key'); + encryptionKey = new kms.Key(table, 'Key'); } else { encryptionKey = props.encryptionKey; } diff --git a/packages/@aws-cdk/aws-glue/test/integ.table.ts b/packages/@aws-cdk/aws-glue/test/integ.table.ts index 329716d2017f4..055eda3fad323 100644 --- a/packages/@aws-cdk/aws-glue/test/integ.table.ts +++ b/packages/@aws-cdk/aws-glue/test/integ.table.ts @@ -71,7 +71,7 @@ const encryptedTable = new glue.Table(stack, 'MyEncryptedTable', { }], dataFormat: glue.DataFormat.Json, encryption: glue.TableEncryption.Kms, - encryptionKey: new kms.EncryptionKey(stack, 'MyKey') + encryptionKey: new kms.Key(stack, 'MyKey') }); const user = new iam.User(stack, 'MyUser'); diff --git a/packages/@aws-cdk/aws-glue/test/test.database.ts b/packages/@aws-cdk/aws-glue/test/test.database.ts index 29dd8ab4faf7d..47df25856ce67 100644 --- a/packages/@aws-cdk/aws-glue/test/test.database.ts +++ b/packages/@aws-cdk/aws-glue/test/test.database.ts @@ -1,12 +1,11 @@ import { expect } from '@aws-cdk/assert'; -import cdk = require('@aws-cdk/cdk'); +import { Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; - import glue = require('../lib'); export = { 'default database creates a bucket to store the datbase'(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); new glue.Database(stack, 'Database', { databaseName: 'test_database' @@ -48,7 +47,7 @@ export = { }, 'explicit locationURI'(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); new glue.Database(stack, 'Database', { databaseName: 'test_database', @@ -75,135 +74,19 @@ export = { test.done(); }, - 'export creates Outputs for catalog ARN/Id, database ARN/Name/LocationURI'(test: Test) { - const stack = new cdk.Stack(); - - const db = new glue.Database(stack, 'Database', { - databaseName: 'test_database' - }); - - glue.Database.fromDatabaseAttributes(new cdk.Stack(), 'Database', db.export()); + 'fromDatabase'(test: Test) { + // GIVEN + const stack = new Stack(); - expect(stack).toMatch({ - Resources: { - DatabaseBucket318AF64F: { - Type: 'AWS::S3::Bucket', - DeletionPolicy: "Retain" - }, - DatabaseB269D8BB: { - Type: 'AWS::Glue::Database', - Properties: { - CatalogId: { - Ref: "AWS::AccountId" - }, - DatabaseInput: { - LocationUri: { - "Fn::Join": [ - "", - [ - "s3://", - { - Ref: "DatabaseBucket318AF64F" - }, - "/test_database" - ] - ] - }, - Name: "test_database" - } - } - } - }, - Outputs: { - DatabaseCatalogArnE5C8063F: { - Value: { - "Fn::Join": [ - "", - [ - "arn:", - { - Ref: "AWS::Partition" - }, - ":glue:", - { - Ref: "AWS::Region" - }, - ":", - { - Ref: "AWS::AccountId" - }, - ":catalog" - ] - ] - }, - Export: { - Name: "Stack:DatabaseCatalogArnE5C8063F" - } - }, - DatabaseCatalogId509C6547: { - Value: { - Ref: "AWS::AccountId" - }, - Export: { - Name: "Stack:DatabaseCatalogId509C6547" - } - }, - DatabaseDatabaseArn157B38E0: { - Value: { - "Fn::Join": [ - "", - [ - "arn:", - { - Ref: "AWS::Partition" - }, - ":glue:", - { - Ref: "AWS::Region" - }, - ":", - { - Ref: "AWS::AccountId" - }, - ":database/", - { - Ref: "DatabaseB269D8BB" - } - ] - ] - }, - Export: { - Name: "Stack:DatabaseDatabaseArn157B38E0" - } - }, - DatabaseDatabaseName925B74A8: { - Value: { - Ref: "DatabaseB269D8BB" - }, - Export: { - Name: "Stack:DatabaseDatabaseName925B74A8" - } - }, - DatabaseLocationURIF74653AF: { - Value: { - "Fn::Join": [ - "", - [ - "s3://", - { - Ref: "DatabaseBucket318AF64F" - }, - "/test_database" - ] - ] - }, - Export: { - Name: "Stack:DatabaseLocationURIF74653AF" - } - } - } - }); + // WHEN + const database = glue.Database.fromDatabaseArn(stack, 'import', 'arn:aws:glue:us-east-1:123456789012:database/db1'); + // THEN + test.deepEqual(database.databaseArn, 'arn:aws:glue:us-east-1:123456789012:database/db1'); + test.deepEqual(database.databaseName, 'db1'); + test.deepEqual(stack.node.resolve(database.catalogArn), { 'Fn::Join': [ '', + [ 'arn:', { Ref: 'AWS::Partition' }, ':glue:', { Ref: 'AWS::Region' }, ':', { Ref: 'AWS::AccountId' }, ':catalog' ] ] }); + test.deepEqual(stack.node.resolve(database.catalogId), { Ref: 'AWS::AccountId' }); test.done(); } }; diff --git a/packages/@aws-cdk/aws-glue/test/test.table.ts b/packages/@aws-cdk/aws-glue/test/test.table.ts index 4d62c517c71e0..bb5914013f759 100644 --- a/packages/@aws-cdk/aws-glue/test/test.table.ts +++ b/packages/@aws-cdk/aws-glue/test/test.table.ts @@ -434,7 +434,7 @@ export = { const database = new glue.Database(stack, 'Database', { databaseName: 'database' }); - const encryptionKey = new kms.EncryptionKey(stack, 'MyKey'); + const encryptionKey = new kms.Key(stack, 'MyKey'); const table = new glue.Table(stack, 'Table', { database, @@ -755,7 +755,7 @@ export = { const database = new glue.Database(stack, 'Database', { databaseName: 'database' }); - const encryptionKey = new kms.EncryptionKey(stack, 'MyKey'); + const encryptionKey = new kms.Key(stack, 'MyKey'); const table = new glue.Table(stack, 'Table', { database, @@ -869,7 +869,7 @@ export = { databaseName: 'database' }); const bucket = new s3.Bucket(stack, 'Bucket'); - const encryptionKey = new kms.EncryptionKey(stack, 'MyKey'); + const encryptionKey = new kms.Key(stack, 'MyKey'); const table = new glue.Table(stack, 'Table', { database, diff --git a/packages/@aws-cdk/aws-iam/lib/lazy-role.ts b/packages/@aws-cdk/aws-iam/lib/lazy-role.ts index a759385c43396..195da9c1d1e8c 100644 --- a/packages/@aws-cdk/aws-iam/lib/lazy-role.ts +++ b/packages/@aws-cdk/aws-iam/lib/lazy-role.ts @@ -3,7 +3,7 @@ import { Grant } from './grant'; import { Policy } from './policy'; import { PolicyStatement, PrincipalPolicyFragment } from './policy-document'; import { IPrincipal } from './principals'; -import { IRole, Role, RoleAttributes, RoleProps } from './role'; +import { IRole, Role, RoleProps } from './role'; // tslint:disable-next-line:no-empty-interface export interface LazyRoleProps extends RoleProps { @@ -31,10 +31,6 @@ export class LazyRole extends cdk.Construct implements IRole { super(scope, id); } - public export(): RoleAttributes { - return this.instantiate().export(); - } - /** * Adds a permission to the role's default policy document. * If there is no default policy attached to this role, it will be created. diff --git a/packages/@aws-cdk/aws-iam/lib/role.ts b/packages/@aws-cdk/aws-iam/lib/role.ts index f1a0ed7644858..272be08adfb95 100644 --- a/packages/@aws-cdk/aws-iam/lib/role.ts +++ b/packages/@aws-cdk/aws-iam/lib/role.ts @@ -1,4 +1,4 @@ -import { CfnOutput, Construct, Resource } from '@aws-cdk/cdk'; +import { Construct, Resource } from '@aws-cdk/cdk'; import { Grant } from './grant'; import { CfnRole } from './iam.generated'; import { IIdentity } from './identity-base'; @@ -102,38 +102,13 @@ export class Role extends Resource implements IRole { * @param roleArn the ARN of the role to import */ public static fromRoleArn(scope: Construct, id: string, roleArn: string): IRole { - return Role.fromRoleAttributes(scope, id, { roleArn }); - } - /** - * Import a role that already exists - */ - public static fromRoleAttributes(scope: Construct, id: string, attrs: RoleAttributes): IRole { - - /** - * A role that already exists - */ class Import extends Construct implements IRole { public readonly grantPrincipal: IPrincipal = this; public readonly assumeRoleAction: string = 'sts:AssumeRole'; - public readonly policyFragment = new ArnPrincipal(attrs.roleArn).policyFragment; - public readonly roleArn = attrs.roleArn; - public readonly roleName = scope.node.stack.parseArn(attrs.roleArn).resourceName!; - private readonly _roleId = attrs.roleId; - - public get roleId() { - if (!this._roleId) { - throw new Error(`No roleId specified for imported role`); - } - return this._roleId; - } - - public export(): RoleAttributes { - return { - roleArn: this.roleArn, - roleId: this._roleId - }; - } + public readonly policyFragment = new ArnPrincipal(roleArn).policyFragment; + public readonly roleArn = roleArn; + public readonly roleName = scope.node.stack.parseArn(roleArn).resourceName!; public addToPolicy(_statement: PolicyStatement): boolean { // Statement will be added to resource instead @@ -169,6 +144,7 @@ export class Role extends Resource implements IRole { } return new Import(scope, id); + } public readonly grantPrincipal: IPrincipal = this; @@ -188,6 +164,8 @@ export class Role extends Resource implements IRole { /** * Returns the stable and unique string identifying the role. For example, * AIDAJQABLZS4A3QDU576Q. + * + * @attribute */ public readonly roleId: string; @@ -240,13 +218,6 @@ export class Role extends Resource implements IRole { } } - public export(): RoleAttributes { - return { - roleArn: new CfnOutput(this, 'RoleArn', { value: this.roleArn }).makeImportValue(), - roleId: new CfnOutput(this, 'RoleId', { value: this.roleId }).makeImportValue() - }; - } - /** * Adds a permission to the role's default policy document. * If there is no default policy attached to this role, it will be created. @@ -309,14 +280,6 @@ export interface IRole extends IIdentity { */ readonly roleArn: string; - /** - * Returns the stable and unique string identifying the role. For example, - * AIDAJQABLZS4A3QDU576Q. - * - * @attribute - */ - readonly roleId: string; - /** * Returns the name of this role. * @@ -324,11 +287,6 @@ export interface IRole extends IIdentity { */ readonly roleName: string; - /** - * Export this role to another stack. - */ - export(): RoleAttributes; - /** * Grant the actions defined in actions to the identity Principal on this resource. */ @@ -362,22 +320,3 @@ function validateMaxSessionDuration(duration?: number) { throw new Error(`maxSessionDuration is set to ${duration}, but must be >= 3600sec (1hr) and <= 43200sec (12hrs)`); } } - -/** - * Properties to import a Role - */ -export interface RoleAttributes { - /** - * The role's ARN - */ - readonly roleArn: string; - - /** - * The stable and unique string identifying the role. For example, - * AIDAJQABLZS4A3QDU576Q. - * - * @default If "roleId" is not specified for an imported role, then - * `role.roleId` will throw an exception. In most cases, role ID is not really needed. - */ - readonly roleId?: string; -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iam/test/test.role.ts b/packages/@aws-cdk/aws-iam/test/test.role.ts index 2e243a8a9b298..755a192dea6c1 100644 --- a/packages/@aws-cdk/aws-iam/test/test.role.ts +++ b/packages/@aws-cdk/aws-iam/test/test.role.ts @@ -252,36 +252,16 @@ export = { test.done(); }, - 'import/export'(test: Test) { + 'fromRoleArn'(test: Test) { // GIVEN const stack = new Stack(); - const myRole = new Role(stack, 'MyRole', { - assumedBy: new ServicePrincipal('boom.boom.boom') - }); // WHEN - const exportedRole = myRole.export(); - const importedRole = Role.fromRoleAttributes(stack, 'ImportedRole', exportedRole); + const importedRole = Role.fromRoleArn(stack, 'ImportedRole', 'arn:aws:iam::123456789012:role/S3Access'); // THEN - test.deepEqual(stack.node.resolve(exportedRole), { - roleArn: { 'Fn::ImportValue': 'Stack:MyRoleRoleArn3388B7E2' }, - roleId: { 'Fn::ImportValue': 'Stack:MyRoleRoleIdF7B258D8' } - }); - - test.deepEqual(stack.node.resolve(importedRole.roleArn), { 'Fn::ImportValue': 'Stack:MyRoleRoleArn3388B7E2' }); - test.deepEqual(stack.node.resolve(importedRole.roleId), { 'Fn::ImportValue': 'Stack:MyRoleRoleIdF7B258D8' }); - test.deepEqual(stack.node.resolve(importedRole.roleName), { - 'Fn::Select': [ 1, { - 'Fn::Split': [ '/', { - 'Fn::Select': [ 5, { - 'Fn::Split': [ ':', { - 'Fn::ImportValue': 'Stack:MyRoleRoleArn3388B7E2' - } ] - } ] - } ] - } ] - }); + test.deepEqual(importedRole.roleArn, 'arn:aws:iam::123456789012:role/S3Access'); + test.deepEqual(importedRole.roleName, 'S3Access'); test.done(); } }; diff --git a/packages/@aws-cdk/aws-kinesis/lib/stream.ts b/packages/@aws-cdk/aws-kinesis/lib/stream.ts index d7155f5f49f29..4a9d1963fdd92 100644 --- a/packages/@aws-cdk/aws-kinesis/lib/stream.ts +++ b/packages/@aws-cdk/aws-kinesis/lib/stream.ts @@ -1,7 +1,7 @@ import iam = require('@aws-cdk/aws-iam'); import kms = require('@aws-cdk/aws-kms'); import logs = require('@aws-cdk/aws-logs'); -import { CfnOutput, Construct, HashedAddressingScheme, IResource, Resource } from '@aws-cdk/cdk'; +import { Construct, HashedAddressingScheme, IResource, Resource } from '@aws-cdk/cdk'; import { CfnStream } from './kinesis.generated'; export interface IStream extends IResource, logs.ILogSubscriptionDestination { @@ -22,12 +22,7 @@ export interface IStream extends IResource, logs.ILogSubscriptionDestination { /** * Optional KMS encryption key associated with this stream. */ - readonly encryptionKey?: kms.IEncryptionKey; - - /** - * Exports this stream from the stack. - */ - export(): StreamAttributes; + readonly encryptionKey?: kms.IKey; /** * Grant read permissions for this stream and its contents to an IAM @@ -71,7 +66,7 @@ export interface StreamAttributes { /** * The KMS key securing the contents of the stream if encryption is enabled. */ - readonly encryptionKey?: kms.EncryptionKeyImportProps; + readonly encryptionKey?: kms.IKey; } /** @@ -105,15 +100,13 @@ abstract class StreamBase extends Resource implements IStream { /** * Optional KMS encryption key associated with this stream. */ - public abstract readonly encryptionKey?: kms.IEncryptionKey; + public abstract readonly encryptionKey?: kms.IKey; /** * The role that can be used by CloudWatch logs to write to this stream */ private cloudWatchLogsRole?: iam.Role; - public abstract export(): StreamAttributes; - /** * Grant write permissions for this stream and its contents to an IAM * principal (Role/Group/User). @@ -278,7 +271,7 @@ export interface StreamProps { * @default If encryption is set to "Kms" and this property is undefined, a * new KMS key will be created and associated with this stream. */ - readonly encryptionKey?: kms.IEncryptionKey; + readonly encryptionKey?: kms.IKey; } /** @@ -298,17 +291,10 @@ export class Stream extends StreamBase { * @param attrs Stream import properties */ public static fromStreamAttributes(scope: Construct, id: string, attrs: StreamAttributes): IStream { - const encryptionKey = attrs.encryptionKey - ? kms.EncryptionKey.import(scope, 'Key', attrs.encryptionKey) - : undefined; - class Import extends StreamBase { public readonly streamArn = attrs.streamArn; public readonly streamName = scope.node.stack.parseArn(attrs.streamArn).resourceName!; - public readonly encryptionKey = encryptionKey; - public export() { - return attrs; - } + public readonly encryptionKey = attrs.encryptionKey; } return new Import(scope, id); @@ -316,7 +302,7 @@ export class Stream extends StreamBase { public readonly streamArn: string; public readonly streamName: string; - public readonly encryptionKey?: kms.IEncryptionKey; + public readonly encryptionKey?: kms.IKey; private readonly stream: CfnStream; @@ -344,23 +330,13 @@ export class Stream extends StreamBase { if (props.streamName) { this.node.addMetadata('aws:cdk:hasPhysicalName', props.streamName); } } - /** - * Exports this stream from the stack. - */ - public export(): StreamAttributes { - return { - streamArn: new CfnOutput(this, 'StreamArn', { value: this.streamArn }).makeImportValue().toString(), - encryptionKey: this.encryptionKey ? this.encryptionKey.export() : undefined, - }; - } - /** * Set up key properties and return the Stream encryption property from the * user's configuration. */ private parseEncryption(props: StreamProps): { streamEncryption?: CfnStream.StreamEncryptionProperty, - encryptionKey?: kms.IEncryptionKey + encryptionKey?: kms.IKey } { // default to unencrypted. @@ -376,7 +352,7 @@ export class Stream extends StreamBase { } if (encryptionType === StreamEncryption.Kms) { - const encryptionKey = props.encryptionKey || new kms.EncryptionKey(this, 'Key', { + const encryptionKey = props.encryptionKey || new kms.Key(this, 'Key', { description: `Created by ${this.node.path}` }); diff --git a/packages/@aws-cdk/aws-kinesis/test/test.stream.ts b/packages/@aws-cdk/aws-kinesis/test/test.stream.ts index eb0de8d1dc7f4..a8f857ef5f5d6 100644 --- a/packages/@aws-cdk/aws-kinesis/test/test.stream.ts +++ b/packages/@aws-cdk/aws-kinesis/test/test.stream.ts @@ -1,7 +1,7 @@ import { expect } from '@aws-cdk/assert'; import iam = require('@aws-cdk/aws-iam'); import kms = require('@aws-cdk/aws-kms'); -import cdk = require('@aws-cdk/cdk'); +import { App, Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; import { Stream, StreamEncryption } from '../lib'; @@ -9,7 +9,7 @@ import { Stream, StreamEncryption } from '../lib'; export = { 'default stream'(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); new Stream(stack, 'MyStream'); @@ -28,7 +28,7 @@ export = { test.done(); }, "uses explicit shard count"(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); new Stream(stack, 'MyStream', { shardCount: 2 @@ -44,12 +44,12 @@ export = { } } } - }); + }); test.done(); }, "uses explicit retention period"(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); new Stream(stack, 'MyStream', { retentionPeriodHours: 168 @@ -72,7 +72,7 @@ export = { "retention period must be between 24 and 168 hours"(test: Test) { test.throws({ block: () => { - new Stream(new cdk.Stack(), 'MyStream', { + new Stream(new Stack(), 'MyStream', { retentionPeriodHours: 169 }); }, @@ -81,7 +81,7 @@ export = { test.throws({ block: () => { - new Stream(new cdk.Stack(), 'MyStream', { + new Stream(new Stack(), 'MyStream', { retentionPeriodHours: 23 }); }, @@ -91,7 +91,7 @@ export = { test.done(); }, "auto-creates KMS key if encryption type is KMS but no key is provided"(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); new Stream(stack, 'MyStream', { encryption: StreamEncryption.Kms @@ -106,40 +106,40 @@ export = { "KeyPolicy": { "Statement": [ { - "Action": [ - "kms:Create*", - "kms:Describe*", - "kms:Enable*", - "kms:List*", - "kms:Put*", - "kms:Update*", - "kms:Revoke*", - "kms:Disable*", - "kms:Get*", - "kms:Delete*", - "kms:ScheduleKeyDeletion", - "kms:CancelKeyDeletion" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" + "Action": [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] ] - ] - } - }, - "Resource": "*" + } + }, + "Resource": "*" } ], "Version": "2012-10-17" @@ -169,9 +169,9 @@ export = { test.done(); }, "uses explicit KMS key if encryption type is KMS and a key is provided"(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); - const explicitKey = new kms.EncryptionKey(stack, 'ExplicitKey', { + const explicitKey = new kms.Key(stack, 'ExplicitKey', { description: `Explicit Key` }); @@ -189,40 +189,40 @@ export = { "KeyPolicy": { "Statement": [ { - "Action": [ - "kms:Create*", - "kms:Describe*", - "kms:Enable*", - "kms:List*", - "kms:Put*", - "kms:Update*", - "kms:Revoke*", - "kms:Disable*", - "kms:Get*", - "kms:Delete*", - "kms:ScheduleKeyDeletion", - "kms:CancelKeyDeletion" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" + "Action": [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] ] - ] - } - }, - "Resource": "*" + } + }, + "Resource": "*" } ], "Version": "2012-10-17" @@ -254,7 +254,7 @@ export = { "permissions": { "with encryption": { "grantRead creates and attaches a policy with read only access to Stream and EncryptionKey"(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); const stream = new Stream(stack, 'MyStream', { encryption: StreamEncryption.Kms }); @@ -358,8 +358,8 @@ export = { "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "MyStream5C050E93", - "Arn" + "MyStream5C050E93", + "Arn" ] } }, @@ -390,7 +390,7 @@ export = { test.done(); }, "grantWrite creates and attaches a policy with write only access to Stream and EncryptionKey"(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); const stream = new Stream(stack, 'MyStream', { encryption: StreamEncryption.Kms }); @@ -534,7 +534,7 @@ export = { test.done(); }, "grantReadWrite creates and attaches a policy with access to Stream and EncryptionKey"(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); const stream = new Stream(stack, 'MyStream', { encryption: StreamEncryption.Kms }); @@ -684,7 +684,7 @@ export = { }, "with no encryption": { "grantRead creates and associates a policy with read only access to Stream"(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); const stream = new Stream(stack, 'MyStream'); const user = new iam.User(stack, "MyUser"); @@ -738,7 +738,7 @@ export = { test.done(); }, "grantWrite creates and attaches a policy with write only access to Stream"(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); const stream = new Stream(stack, 'MyStream'); const user = new iam.User(stack, "MyUser"); @@ -792,7 +792,7 @@ export = { test.done(); }, "greatReadWrite creates and attaches a policy with write only access to Stream"(test: Test) { - const stack = new cdk.Stack(); + const stack = new Stack(); const stream = new Stream(stack, 'MyStream'); const user = new iam.User(stack, "MyUser"); @@ -851,14 +851,12 @@ export = { }, "cross-stack permissions": { "no encryption"(test: Test) { - const stackA = new cdk.Stack(); + const stackA = new Stack(); const streamFromStackA = new Stream(stackA, 'MyStream'); - const refToStreamFromStackA = streamFromStackA.export(); - const stackB = new cdk.Stack(); + const stackB = new Stack(); const user = new iam.User(stackB, 'UserWhoNeedsAccess'); - const theStreamFromStackAAsARefInStackB = Stream.fromStreamAttributes(stackB, 'RefToStreamFromStackA', refToStreamFromStackA); - theStreamFromStackAAsARefInStackB.grantRead(user); + streamFromStackA.grantRead(user); expect(stackA).toMatch({ "Resources": { @@ -869,161 +867,6 @@ export = { "ShardCount": 1 } } - }, - "Outputs": { - "MyStreamStreamArn495BAFC1": { - "Value": { - "Fn::GetAtt": [ - "MyStream5C050E93", - "Arn" - ] - }, - "Export": { - "Name": "Stack:MyStreamStreamArn495BAFC1" - } - } - } - }); - - expect(stackB).toMatch({ - "Resources": { - "UserWhoNeedsAccessF8959C3D": { - "Type": "AWS::IAM::User" - }, - "UserWhoNeedsAccessDefaultPolicy6A9EB530": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "kinesis:DescribeStream", - "kinesis:GetRecords", - "kinesis:GetShardIterator" - ], - "Effect": "Allow", - "Resource": { - "Fn::ImportValue": "Stack:MyStreamStreamArn495BAFC1" - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "UserWhoNeedsAccessDefaultPolicy6A9EB530", - "Users": [ - { - "Ref": "UserWhoNeedsAccessF8959C3D" - } - ] - } - } - } - }); - - test.done(); - }, - "with encryption"(test: Test) { - const stackA = new cdk.Stack(); - const streamFromStackA = new Stream(stackA, 'MyStream', { - encryption: StreamEncryption.Kms - }); - const refToStreamFromStackA = streamFromStackA.export(); - - const stackB = new cdk.Stack(); - const user = new iam.User(stackB, 'UserWhoNeedsAccess'); - const theStreamFromStackAAsARefInStackB = Stream.fromStreamAttributes(stackB, 'RefToStreamFromStackA', refToStreamFromStackA); - theStreamFromStackAAsARefInStackB.grantRead(user); - - expect(stackA).toMatch({ - "Resources": { - "MyStreamKey76F3300E": { - "Type": "AWS::KMS::Key", - "Properties": { - "Description": "Created by MyStream", - "KeyPolicy": { - "Statement": [ - { - "Action": [ - "kms:Create*", - "kms:Describe*", - "kms:Enable*", - "kms:List*", - "kms:Put*", - "kms:Update*", - "kms:Revoke*", - "kms:Disable*", - "kms:Get*", - "kms:Delete*", - "kms:ScheduleKeyDeletion", - "kms:CancelKeyDeletion" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" - ] - ] - } - }, - "Resource": "*" - } - ], - "Version": "2012-10-17" - } - }, - "DeletionPolicy": "Retain" - }, - "MyStream5C050E93": { - "Type": "AWS::Kinesis::Stream", - "Properties": { - "RetentionPeriodHours": 24, - "ShardCount": 1, - "StreamEncryption": { - "EncryptionType": "KMS", - "KeyId": { - "Fn::GetAtt": [ - "MyStreamKey76F3300E", - "Arn" - ] - } - } - } - } - }, - "Outputs": { - "MyStreamKeyKeyArn967BCB03": { - "Value": { - "Fn::GetAtt": [ - "MyStreamKey76F3300E", - "Arn" - ] - }, - "Export": { - "Name": "Stack:MyStreamKeyKeyArn967BCB03" - } - }, - "MyStreamStreamArn495BAFC1": { - "Value": { - "Fn::GetAtt": [ - "MyStream5C050E93", - "Arn" - ] - }, - "Export": { - "Name": "Stack:MyStreamStreamArn495BAFC1" - } - } } }); @@ -1045,14 +888,7 @@ export = { ], "Effect": "Allow", "Resource": { - "Fn::ImportValue": "Stack:MyStreamStreamArn495BAFC1" - } - }, - { - "Action": "kms:Decrypt", - "Effect": "Allow", - "Resource": { - "Fn::ImportValue": "Stack:MyStreamKeyKeyArn967BCB03" + "Fn::ImportValue": "Stack:ExportsOutputFnGetAttMyStream5C050E93Arn4ABF30CD" } } ], @@ -1069,6 +905,20 @@ export = { } }); + test.done(); + }, + "fails with encryption due to cyclic dependency"(test: Test) { + const app = new App(); + const stackA = new Stack(app, 'stackA'); + const streamFromStackA = new Stream(stackA, 'MyStream', { + encryption: StreamEncryption.Kms + }); + + const stackB = new Stack(app, 'stackB'); + const user = new iam.User(stackB, 'UserWhoNeedsAccess'); + streamFromStackA.grantRead(user); + + test.throws(() => app.run(), /'stackB' depends on 'stackA'/); test.done(); } } diff --git a/packages/@aws-cdk/aws-kms/lib/alias.ts b/packages/@aws-cdk/aws-kms/lib/alias.ts index d0a47a5922734..57c21637bdf37 100644 --- a/packages/@aws-cdk/aws-kms/lib/alias.ts +++ b/packages/@aws-cdk/aws-kms/lib/alias.ts @@ -1,5 +1,5 @@ import { Construct } from '@aws-cdk/cdk'; -import { IEncryptionKey } from './key'; +import { IKey } from './key'; import { CfnAlias } from './kms.generated'; const REQUIRED_ALIAS_PREFIX = 'alias/'; @@ -18,7 +18,7 @@ export interface EncryptionKeyAliasProps { * globally unique identifier or Amazon Resource Name (ARN). You can't * specify another alias. */ - readonly key: IEncryptionKey; + readonly key: IKey; } /** diff --git a/packages/@aws-cdk/aws-kms/lib/key.ts b/packages/@aws-cdk/aws-kms/lib/key.ts index 7f7d4c859b620..dda2977bdab18 100644 --- a/packages/@aws-cdk/aws-kms/lib/key.ts +++ b/packages/@aws-cdk/aws-kms/lib/key.ts @@ -1,12 +1,14 @@ import iam = require('@aws-cdk/aws-iam'); import { PolicyDocument, PolicyStatement } from '@aws-cdk/aws-iam'; -import { CfnOutput, Construct, DeletionPolicy, IConstruct } from '@aws-cdk/cdk'; +import { Construct, DeletionPolicy, IResource } from '@aws-cdk/cdk'; import { EncryptionKeyAlias } from './alias'; import { CfnKey } from './kms.generated'; -export interface IEncryptionKey extends IConstruct { +export interface IKey extends IResource { /** * The ARN of the key. + * + * @attribute */ readonly keyArn: string; @@ -24,12 +26,6 @@ export interface IEncryptionKey extends IConstruct { */ addToResourcePolicy(statement: PolicyStatement, allowNoOp?: boolean): void; - /** - * Exports this key from the current stack. - * @returns a key ref which can be used in a call to `EncryptionKey.import(ref)`. - */ - export(): EncryptionKeyImportProps; - /** * Grant the indicated permissions on this key to the given principal */ @@ -51,14 +47,7 @@ export interface IEncryptionKey extends IConstruct { grantEncryptDecrypt(grantee: iam.IGrantable): iam.Grant; } -export interface EncryptionKeyImportProps { - /** - * The ARN of the external KMS key. - */ - readonly keyArn: string; -} - -abstract class EncryptionKeyBase extends Construct implements IEncryptionKey { +abstract class KeyBase extends Construct implements IKey { /** * The ARN of the key. */ @@ -95,8 +84,6 @@ abstract class EncryptionKeyBase extends Construct implements IEncryptionKey { this.policy.addStatement(statement); } - public abstract export(): EncryptionKeyImportProps; - /** * Grant the indicated permissions on this key to the given principal * @@ -150,7 +137,7 @@ abstract class EncryptionKeyBase extends Construct implements IEncryptionKey { /** * Construction properties for a KMS Key object */ -export interface EncryptionKeyProps { +export interface KeyProps { /** * A description of the key. Use a description that helps your users decide * whether the key is appropriate for a particular task. @@ -189,33 +176,21 @@ export interface EncryptionKeyProps { /** * Defines a KMS key. */ -export class EncryptionKey extends EncryptionKeyBase { - /** - * Defines an imported encryption key. - * - * `ref` can be obtained either via a call to `key.export()` or using - * literals. - * - * For example: - * - * const keyAttr = key.export(); - * const keyRef1 = EncryptionKey.import(this, 'MyImportedKey1', keyAttr); - * const keyRef2 = EncryptionKey.import(this, 'MyImportedKey2', { - * keyArn: new KeyArn('arn:aws:kms:...') - * }); - * - * @param scope The parent construct. - * @param id The name of the construct. - * @param props The key reference. - */ - public static import(scope: Construct, id: string, props: EncryptionKeyImportProps): IEncryptionKey { - return new ImportedEncryptionKey(scope, id, props); +export class Key extends KeyBase { + + public static fromKeyArn(scope: Construct, id: string, keyArn: string): IKey { + class Import extends KeyBase { + public keyArn = keyArn; + protected policy?: iam.PolicyDocument | undefined = undefined; + } + + return new Import(scope, id); } public readonly keyArn: string; protected readonly policy?: PolicyDocument; - constructor(scope: Construct, id: string, props: EncryptionKeyProps = {}) { + constructor(scope: Construct, id: string, props: KeyProps = {}) { super(scope, id); if (props.policy) { @@ -238,16 +213,6 @@ export class EncryptionKey extends EncryptionKeyBase { : DeletionPolicy.Retain; } - /** - * Exports this key from the current stack. - * @returns a key ref which can be used in a call to `EncryptionKey.import(ref)`. - */ - public export(): EncryptionKeyImportProps { - return { - keyArn: new CfnOutput(this, 'KeyArn', { value: this.keyArn }).makeImportValue().toString() - }; - } - /** * Let users from this account admin this key. * @link https://aws.amazon.com/premiumsupport/knowledge-center/update-key-policy-future/ @@ -274,18 +239,3 @@ export class EncryptionKey extends EncryptionKeyBase { .addAccountRootPrincipal()); } } - -class ImportedEncryptionKey extends EncryptionKeyBase { - public readonly keyArn: string; - protected readonly policy = undefined; // no policy associated with an imported key - - constructor(scope: Construct, id: string, private readonly props: EncryptionKeyImportProps) { - super(scope, id); - - this.keyArn = props.keyArn; - } - - public export() { - return this.props; - } -} diff --git a/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts b/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts index ce830b9530e33..7f7a9811ac384 100644 --- a/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts +++ b/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts @@ -9,16 +9,16 @@ const app = new cdk.App(); * Stack that defines the key */ class KeyStack extends cdk.Stack { - public readonly key: kms.EncryptionKey; + public readonly key: kms.Key; constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); - this.key = new kms.EncryptionKey(this, 'MyKey', { retain: false }); + this.key = new kms.Key(this, 'MyKey', { retain: false }); } } interface UseStackProps extends cdk.StackProps { - key: kms.IEncryptionKey; // Use IEncryptionKey here + key: kms.IKey; // Use IEncryptionKey here } /** diff --git a/packages/@aws-cdk/aws-kms/test/integ.key.ts b/packages/@aws-cdk/aws-kms/test/integ.key.ts index 47d05f7df73d0..2fae5e51054dc 100644 --- a/packages/@aws-cdk/aws-kms/test/integ.key.ts +++ b/packages/@aws-cdk/aws-kms/test/integ.key.ts @@ -1,12 +1,12 @@ import { PolicyStatement } from '@aws-cdk/aws-iam'; import { App, Stack } from '@aws-cdk/cdk'; -import { EncryptionKey } from '../lib'; +import { Key } from '../lib'; const app = new App(); const stack = new Stack(app, `aws-cdk-kms-1`); -const key = new EncryptionKey(stack, 'MyKey', { retain: false }); +const key = new Key(stack, 'MyKey', { retain: false }); key.addToResourcePolicy(new PolicyStatement() .addAllResources() diff --git a/packages/@aws-cdk/aws-kms/test/test.alias.ts b/packages/@aws-cdk/aws-kms/test/test.alias.ts index 029241c921582..7d52b35a63490 100644 --- a/packages/@aws-cdk/aws-kms/test/test.alias.ts +++ b/packages/@aws-cdk/aws-kms/test/test.alias.ts @@ -1,13 +1,13 @@ import { App, Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { EncryptionKey } from '../lib'; +import { Key } from '../lib'; import { EncryptionKeyAlias } from '../lib/alias'; export = { 'default alias'(test: Test) { const app = new App(); const stack = new Stack(app, 'Test'); - const key = new EncryptionKey(stack, 'Key'); + const key = new Key(stack, 'Key'); new EncryptionKeyAlias(stack, 'Alias', { key, alias: 'alias/foo' }); @@ -26,7 +26,7 @@ export = { const app = new App(); const stack = new Stack(app, 'Test'); - const key = new EncryptionKey(stack, 'MyKey', { + const key = new Key(stack, 'MyKey', { enableKeyRotation: true, enabled: false }); @@ -43,7 +43,7 @@ export = { const app = new App(); const stack = new Stack(app, 'Test'); - const key = new EncryptionKey(stack, 'MyKey', { + const key = new Key(stack, 'MyKey', { enableKeyRotation: true, enabled: false }); @@ -60,7 +60,7 @@ export = { const app = new App(); const stack = new Stack(app, 'Test'); - const key = new EncryptionKey(stack, 'MyKey', { + const key = new Key(stack, 'MyKey', { enableKeyRotation: true, enabled: false }); diff --git a/packages/@aws-cdk/aws-kms/test/test.key.ts b/packages/@aws-cdk/aws-kms/test/test.key.ts index b0afeab8c0978..3d1975b681472 100644 --- a/packages/@aws-cdk/aws-kms/test/test.key.ts +++ b/packages/@aws-cdk/aws-kms/test/test.key.ts @@ -1,14 +1,14 @@ import { exactlyMatchTemplate, expect, haveResource, ResourcePart } from '@aws-cdk/assert'; -import { PolicyDocument, PolicyStatement, User } from '@aws-cdk/aws-iam'; +import { PolicyStatement, User } from '@aws-cdk/aws-iam'; import { App, Stack, Tag } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { EncryptionKey } from '../lib'; +import { Key } from '../lib'; export = { 'default key'(test: Test) { const stack = new Stack(); - new EncryptionKey(stack, 'MyKey'); + new Key(stack, 'MyKey'); expect(stack).to(exactlyMatchTemplate({ Resources: { @@ -68,7 +68,7 @@ export = { const app = new App(); const stack = new Stack(app, 'TestStack'); - new EncryptionKey(stack, 'MyKey', { retain: false }); + new Key(stack, 'MyKey', { retain: false }); expect(app.synthesizeStack(stack.name)).to(haveResource('AWS::KMS::Key', { DeletionPolicy: "Delete" }, ResourcePart.CompleteDefinition)); test.done(); @@ -78,7 +78,7 @@ export = { const app = new App(); const stack = new Stack(app, 'Test'); - const key = new EncryptionKey(stack, 'MyKey'); + const key = new Key(stack, 'MyKey'); const p = new PolicyStatement().addAllResources().addAction('kms:encrypt'); p.addAwsPrincipal('arn'); key.addToResourcePolicy(p); @@ -149,7 +149,7 @@ export = { 'key with some options'(test: Test) { const stack = new Stack(); - const key = new EncryptionKey(stack, 'MyKey', { + const key = new Key(stack, 'MyKey', { enableKeyRotation: true, enabled: false, }); @@ -244,7 +244,7 @@ export = { const app = new App(); const stack = new Stack(app, 'Test'); - const key = new EncryptionKey(stack, 'MyKey', { + const key = new Key(stack, 'MyKey', { enableKeyRotation: true, enabled: false }); @@ -324,7 +324,7 @@ export = { 'grant decrypt on a key'(test: Test) { // GIVEN const stack = new Stack(); - const key = new EncryptionKey(stack, 'Key'); + const key = new Key(stack, 'Key'); const user = new User(stack, 'User'); // WHEN @@ -371,47 +371,8 @@ export = { }, 'import/export can be used to bring in an existing key'(test: Test) { - const stack1 = new Stack(); - const policy = new PolicyDocument(); - policy.addStatement(new PolicyStatement().addAllResources()); - const myKey = new EncryptionKey(stack1, 'MyKey', { policy }); - const exportedKeyRef = myKey.export(); - - expect(stack1).toMatch({ - Resources: { - MyKey6AB29FA6: { - Type: "AWS::KMS::Key", - Properties: { - KeyPolicy: { - Statement: [ - { - Effect: "Allow", - Resource: "*" - } - ], - Version: "2012-10-17" - } - }, - DeletionPolicy: "Retain" - } - }, - Outputs: { - MyKeyKeyArn317F1332: { - Value: { - "Fn::GetAtt": [ - "MyKey6AB29FA6", - "Arn" - ] - }, - Export: { - Name: "Stack:MyKeyKeyArn317F1332" - } - } - } - }); - const stack2 = new Stack(); - const myKeyImported = EncryptionKey.import(stack2, 'MyKeyImported', exportedKeyRef); + const myKeyImported = Key.fromKeyArn(stack2, 'MyKeyImported', 'arn:of:key'); // addAlias can be called on imported keys. myKeyImported.addAlias('alias/hello'); @@ -422,9 +383,7 @@ export = { Type: "AWS::KMS::Alias", Properties: { AliasName: "alias/hello", - TargetKeyId: { - "Fn::ImportValue": "Stack:MyKeyKeyArn317F1332" - } + TargetKeyId: 'arn:of:key' } } } @@ -437,7 +396,7 @@ export = { 'succeed if set to true (default)'(test: Test) { const stack = new Stack(); - const key = EncryptionKey.import(stack, 'Imported', { keyArn: 'foo/bar' }); + const key = Key.fromKeyArn(stack, 'Imported', 'foo/bar'); key.addToResourcePolicy(new PolicyStatement().addAllResources().addAction('*')); @@ -448,7 +407,7 @@ export = { const stack = new Stack(); - const key = EncryptionKey.import(stack, 'Imported', { keyArn: 'foo/bar' }); + const key = Key.fromKeyArn(stack, 'Imported', 'foo/bar'); test.throws(() => key.addToResourcePolicy(new PolicyStatement().addAllResources().addAction('*'), /* allowNoOp */ false), diff --git a/packages/@aws-cdk/aws-lambda/lib/alias.ts b/packages/@aws-cdk/aws-lambda/lib/alias.ts index 4c4512a093ea8..aed8d2c009d7a 100644 --- a/packages/@aws-cdk/aws-lambda/lib/alias.ts +++ b/packages/@aws-cdk/aws-lambda/lib/alias.ts @@ -1,6 +1,6 @@ import cloudwatch = require('@aws-cdk/aws-cloudwatch'); -import { CfnOutput, Construct } from '@aws-cdk/cdk'; -import { FunctionAttributes, FunctionBase, IFunction } from './function-base'; +import { Construct } from '@aws-cdk/cdk'; +import { FunctionBase, IFunction } from './function-base'; import { IVersion } from './lambda-version'; import { CfnAlias } from './lambda.generated'; @@ -126,12 +126,6 @@ export class Alias extends FunctionBase { }); } - public export(): FunctionAttributes { - return { - functionArn: new CfnOutput(this, 'AliasArn', { value: this.functionArn }).makeImportValue().toString() - }; - } - /** * Calculate the routingConfig parameter from the input props */ diff --git a/packages/@aws-cdk/aws-lambda/lib/function-base.ts b/packages/@aws-cdk/aws-lambda/lib/function-base.ts index 0f5c818260697..ef8df5517a763 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function-base.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function-base.ts @@ -90,11 +90,6 @@ export interface IFunction extends IResource, logs.ILogSubscriptionDestination, */ metricThrottles(props?: cloudwatch.MetricOptions): cloudwatch.Metric; - /** - * Export this Function (without the role) - */ - export(): FunctionAttributes; - addEventSource(source: IEventSource): void; } @@ -275,11 +270,6 @@ export abstract class FunctionBase extends Resource implements IFunction { return { arn: this.functionArn }; } - /** - * Export this Function (without the role) - */ - public abstract export(): FunctionAttributes; - /** * Allows this Lambda to be used as a destination for bucket notifications. * Use `bucket.onEvent(lambda)` to subscribe. diff --git a/packages/@aws-cdk/aws-lambda/lib/function.ts b/packages/@aws-cdk/aws-lambda/lib/function.ts index 5f9b69c3938e2..16b0d468e3d06 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function.ts @@ -3,7 +3,7 @@ import ec2 = require('@aws-cdk/aws-ec2'); import iam = require('@aws-cdk/aws-iam'); import logs = require('@aws-cdk/aws-logs'); import sqs = require('@aws-cdk/aws-sqs'); -import { CfnOutput, Construct, Fn, Token } from '@aws-cdk/cdk'; +import { Construct, Fn, Token } from '@aws-cdk/cdk'; import { Code } from './code'; import { IEventSource } from './event-source'; import { FunctionAttributes, FunctionBase, IFunction } from './function-base'; @@ -122,7 +122,7 @@ export interface FunctionProps { * * Specify this if the Lambda function needs to access resources in a VPC. */ - readonly vpc?: ec2.IVpcNetwork; + readonly vpc?: ec2.IVpc; /** * Where to place the network interfaces within the VPC. @@ -236,8 +236,7 @@ export class Function extends FunctionBase { * * @param scope The parent construct * @param id The name of the lambda construct - * @param attrs A reference to a Lambda function. Can be created manually (see - * example above) or obtained through a call to `lambda.export()`. + * @param attrs the attributes of the function to import */ public static fromFunctionAttributes(scope: Construct, id: string, attrs: FunctionAttributes): IFunction { const functionArn = attrs.functionArn; @@ -265,10 +264,6 @@ export class Function extends FunctionBase { }); } } - - public export() { - return attrs; - } } return new Import(scope, id); @@ -458,18 +453,6 @@ export class Function extends FunctionBase { } } - /** - * Export this Function (without the role) - */ - public export(): FunctionAttributes { - return { - functionArn: new CfnOutput(this, 'FunctionArn', { value: this.functionArn }).makeImportValue().toString(), - securityGroupId: this._connections && this._connections.securityGroups[0] - ? new CfnOutput(this, 'SecurityGroupId', { value: this._connections.securityGroups[0].securityGroupId }).makeImportValue().toString() - : undefined - }; - } - /** * Adds an environment variable to this Lambda function. * If this is a ref to a Lambda function, this operation results in a no-op. diff --git a/packages/@aws-cdk/aws-lambda/lib/layers.ts b/packages/@aws-cdk/aws-lambda/lib/layers.ts index 553471d4c6688..6296e28dc2b29 100644 --- a/packages/@aws-cdk/aws-lambda/lib/layers.ts +++ b/packages/@aws-cdk/aws-lambda/lib/layers.ts @@ -1,4 +1,4 @@ -import { CfnOutput, Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; +import { Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; import { Code } from './code'; import { CfnLayerVersion, CfnLayerVersionPermission } from './lambda.generated'; import { Runtime } from './runtime'; @@ -47,12 +47,6 @@ export interface ILayerVersion extends IResource { */ readonly compatibleRuntimes?: Runtime[]; - /** - * Exports this layer for use in another Stack. The resulting object can be passed to the ``LayerVersion.import`` - * function to obtain an ``ILayerVersion`` in the user stack. - */ - export(): LayerVersionAttributes; - /** * Add permission for this layer version to specific entities. Usage within * the same account where the layer is defined is always allowed and does not @@ -86,13 +80,6 @@ abstract class LayerVersionBase extends Resource implements ILayerVersion { organizationId: permission.organizationId, }); } - - public export(): LayerVersionAttributes { - return { - layerVersionArn: new CfnOutput(this, 'LayerVersionArn', { value: this.layerVersionArn }).makeImportValue().toString(), - compatibleRuntimes: this.compatibleRuntimes, - }; - } } /** @@ -225,13 +212,6 @@ export class SingletonLayerVersion extends Construct implements ILayerVersion { return this.layerVersion.compatibleRuntimes; } - public export(): LayerVersionAttributes { - return { - layerVersionArn: this.layerVersionArn, - compatibleRuntimes: this.compatibleRuntimes, - }; - } - public addPermission(id: string, grantee: LayerVersionPermission) { this.layerVersion.addPermission(id, grantee); } diff --git a/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts b/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts index 69929ef56d184..50708d1360867 100644 --- a/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts +++ b/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts @@ -1,7 +1,7 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import { Function as LambdaFunction, FunctionProps } from './function'; -import { FunctionAttributes, FunctionBase, IFunction } from './function-base'; +import { FunctionBase, IFunction } from './function-base'; import { Permission } from './permission'; /** @@ -57,10 +57,6 @@ export class SingletonFunction extends FunctionBase { this.canCreatePermissions = true; // Doesn't matter, addPermission is overriden anyway } - public export(): FunctionAttributes { - return this.lambdaFunction.export(); - } - public addPermission(name: string, permission: Permission) { return this.lambdaFunction.addPermission(name, permission); } diff --git a/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.ts b/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.ts index 8f59243ce5db5..74e4d365922b6 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.ts @@ -5,7 +5,7 @@ import lambda = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-vpc-lambda'); -const vpc = new ec2.VpcNetwork(stack, 'VPC', { maxAZs: 2 }); +const vpc = new ec2.Vpc(stack, 'VPC', { maxAZs: 2 }); new lambda.Function(stack, 'MyLambda', { code: new lambda.InlineCode('def main(event, context): pass'), diff --git a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts index a591078948957..8d9a0046920a0 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts @@ -236,24 +236,22 @@ export = { } }, - 'import/export': { - 'lambda.export() can be used to add Outputs to the stack and returns an IFunction object'(test: Test) { - // GIVEN - const stack1 = new cdk.Stack(); - const stack2 = new cdk.Stack(); - const fn = newTestLambda(stack1); + 'fromFunctionArn'(test: Test) { + // GIVEN + const stack2 = new cdk.Stack(); - // WHEN - const props = fn.export(); - const imported = lambda.Function.fromFunctionAttributes(stack2, 'Imported', props); + // WHEN + const imported = lambda.Function.fromFunctionArn(stack2, 'Imported', 'arn:aws:lambda:us-east-1:123456789012:function:ProcessKinesisRecords'); - // Can call addPermission() but it won't do anything - imported.addPermission('Hello', { - principal: new iam.ServicePrincipal('harry') - }); + // Can call addPermission() but it won't do anything + imported.addPermission('Hello', { + principal: new iam.ServicePrincipal('harry') + }); - test.done(); - }, + // THEN + test.deepEqual(imported.functionArn, 'arn:aws:lambda:us-east-1:123456789012:function:ProcessKinesisRecords'); + test.deepEqual(imported.functionName, 'ProcessKinesisRecords'); + test.done(); }, 'Lambda code can be read from a local directory via an asset'(test: Test) { diff --git a/packages/@aws-cdk/aws-lambda/test/test.vpc-lambda.ts b/packages/@aws-cdk/aws-lambda/test/test.vpc-lambda.ts index fb92bbe244c39..93109237958a4 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.vpc-lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.vpc-lambda.ts @@ -7,13 +7,13 @@ import lambda = require('../lib'); export = { 'lambda in a VPC': classFixture(class Henk { private readonly stack: cdk.Stack; - private readonly vpc: ec2.VpcNetwork; + private readonly vpc: ec2.Vpc; private readonly lambda: lambda.Function; constructor() { // GIVEN this.stack = new cdk.Stack(); - this.vpc = new ec2.VpcNetwork(this.stack, 'VPC'); + this.vpc = new ec2.Vpc(this.stack, 'VPC'); // WHEN this.lambda = new lambda.Function(this.stack, 'Lambda', { @@ -81,26 +81,39 @@ export = { const somethingConnectable = new SomethingConnectable(new ec2.Connections({ securityGroups: [securityGroup] })); // WHEN - const importedLambda = lambda.Function.fromFunctionAttributes(stack2, 'Lambda', this.lambda.export()); - importedLambda.connections.allowTo(somethingConnectable, new ec2.TcpAllPorts(), 'Lambda can call connectable'); + this.lambda.connections.allowTo(somethingConnectable, new ec2.TcpAllPorts(), 'Lambda can call connectable'); // THEN: SomeSecurityGroup accepts connections from Lambda - expect(stack2).to(haveResource("AWS::EC2::SecurityGroupEgress", { - GroupId: { "Fn::ImportValue": "Stack:LambdaSecurityGroupId9A2717B3" }, + expect(this.stack).to(haveResource("AWS::EC2::SecurityGroupEgress", { + GroupId: { + "Fn::GetAtt": [ + "LambdaSecurityGroupE74659A1", + "GroupId" + ] + }, IpProtocol: "tcp", Description: "Lambda can call connectable", - DestinationSecurityGroupId: { "Fn::GetAtt": [ "SomeSecurityGroupEF219AD6", "GroupId" ] }, + DestinationSecurityGroupId: { + "Fn::ImportValue": "Stack:ExportsOutputFnGetAttSomeSecurityGroupEF219AD6GroupId09FCF7BE" + }, FromPort: 0, ToPort: 65535 })); // THEN: Lambda can connect to SomeSecurityGroup - expect(stack2).to(haveResource("AWS::EC2::SecurityGroupIngress", { + expect(this.stack).to(haveResource("AWS::EC2::SecurityGroupIngress", { IpProtocol: "tcp", Description: "Lambda can call connectable", FromPort: 0, - GroupId: { "Fn::GetAtt": [ "SomeSecurityGroupEF219AD6", "GroupId" ] }, - SourceSecurityGroupId: { "Fn::ImportValue": "Stack:LambdaSecurityGroupId9A2717B3" }, + GroupId: { + "Fn::ImportValue": "Stack:ExportsOutputFnGetAttSomeSecurityGroupEF219AD6GroupId09FCF7BE" + }, + SourceSecurityGroupId: { + "Fn::GetAtt": [ + "LambdaSecurityGroupE74659A1", + "GroupId" + ] + }, ToPort: 65535 })); @@ -128,7 +141,7 @@ export = { 'picking public subnets is not allowed'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); // WHEN test.throws(() => { diff --git a/packages/@aws-cdk/aws-quickstarts/lib/database.ts b/packages/@aws-cdk/aws-quickstarts/lib/database.ts index d9fc933f5e1b0..b142f5c81b408 100644 --- a/packages/@aws-cdk/aws-quickstarts/lib/database.ts +++ b/packages/@aws-cdk/aws-quickstarts/lib/database.ts @@ -10,7 +10,7 @@ export interface SqlServerProps { readonly masterUsername: string; readonly masterPassword: string; readonly allocatedStorage?: number; - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; } /** diff --git a/packages/@aws-cdk/aws-quickstarts/lib/rdgw.ts b/packages/@aws-cdk/aws-quickstarts/lib/rdgw.ts index 81ee0f8d36e81..8cab04917e20e 100644 --- a/packages/@aws-cdk/aws-quickstarts/lib/rdgw.ts +++ b/packages/@aws-cdk/aws-quickstarts/lib/rdgw.ts @@ -4,7 +4,7 @@ import cdk = require('@aws-cdk/cdk'); export interface RemoteDesktopGatewayProps { readonly rdgwCIDR: string; - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; readonly keyPairName: string; readonly adminPassword: string; diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group-ref.ts b/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group-ref.ts deleted file mode 100644 index f0b01df78b043..0000000000000 --- a/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group-ref.ts +++ /dev/null @@ -1,46 +0,0 @@ -import cdk = require('@aws-cdk/cdk'); - -/** - * A cluster parameter group - */ -export abstract class ClusterParameterGroupRef extends cdk.Construct { - /** - * Import a parameter group - */ - public static import(scope: cdk.Construct, id: string, props: ClusterParameterGroupRefProps): ClusterParameterGroupRef { - return new ImportedClusterParameterGroup(scope, id, props); - } - - /** - * Name of this parameter group - */ - public abstract readonly parameterGroupName: string; - - /** - * Export this parameter group - */ - public export(): ClusterParameterGroupRefProps { - return { - parameterGroupName: new cdk.CfnOutput(this, 'ParameterGroupName', { value: this.parameterGroupName }).makeImportValue().toString() - }; - } -} - -/** - * Properties to reference a cluster parameter group - */ -export interface ClusterParameterGroupRefProps { - parameterGroupName: string; -} - -/** - * An imported cluster parameter group - */ -class ImportedClusterParameterGroup extends ClusterParameterGroupRef { - public readonly parameterGroupName: string; - - constructor(scope: cdk.Construct, id: string, props: ClusterParameterGroupRefProps) { - super(scope, id); - this.parameterGroupName = props.parameterGroupName; - } -} diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts b/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts index 3f8338a770409..beddc616a74e0 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster-parameter-group.ts @@ -1,20 +1,15 @@ -import cdk = require('@aws-cdk/cdk'); +import { Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; import { Parameters } from './props'; import { CfnDBClusterParameterGroup } from './rds.generated'; /** * A cluster parameter group */ -export interface IClusterParameterGroup extends cdk.IConstruct { +export interface IClusterParameterGroup extends IResource { /** * Name of this parameter group */ readonly parameterGroupName: string; - - /** - * Export this parameter group - */ - export(): ClusterParameterGroupImportProps; } /** @@ -46,25 +41,30 @@ export interface ClusterParameterGroupProps { /** * Defina a cluster parameter group + * + * @resource AWS::RDS::DBClusterParameterGroup */ -export class ClusterParameterGroup extends cdk.Construct implements IClusterParameterGroup { +export class ClusterParameterGroup extends Resource implements IClusterParameterGroup { /** * Import a parameter group */ - public static import(scope: cdk.Construct, id: string, props: ClusterParameterGroupImportProps): IClusterParameterGroup { - return new ImportedClusterParameterGroup(scope, id, props); + public static fromParameterGroupName(scope: Construct, id: string, parameterGroupName: string): IClusterParameterGroup { + class Import extends Resource implements IClusterParameterGroup { + public parameterGroupName = parameterGroupName; + } + return new Import(scope, id); } public readonly parameterGroupName: string; private readonly parameters: Parameters = {}; - constructor(scope: cdk.Construct, id: string, props: ClusterParameterGroupProps) { + constructor(scope: Construct, id: string, props: ClusterParameterGroupProps) { super(scope, id); const resource = new CfnDBClusterParameterGroup(this, 'Resource', { description: props.description, family: props.family, - parameters: new cdk.Token(() => this.parameters), + parameters: new Token(() => this.parameters), }); for (const [key, value] of Object.entries(props.parameters || {})) { @@ -74,15 +74,6 @@ export class ClusterParameterGroup extends cdk.Construct implements IClusterPara this.parameterGroupName = resource.ref; } - /** - * Export this parameter group - */ - public export(): ClusterParameterGroupImportProps { - return { - parameterGroupName: new cdk.CfnOutput(this, 'ParameterGroupName', { value: this.parameterGroupName }).makeImportValue().toString() - }; - } - /** * Set a single parameter in this parameter group */ @@ -112,19 +103,3 @@ export class ClusterParameterGroup extends cdk.Construct implements IClusterPara return []; } } - -/** - * An imported cluster parameter group - */ -class ImportedClusterParameterGroup extends cdk.Construct implements IClusterParameterGroup { - public readonly parameterGroupName: string; - - constructor(scope: cdk.Construct, id: string, private readonly props: ClusterParameterGroupImportProps) { - super(scope, id); - this.parameterGroupName = props.parameterGroupName; - } - - public export() { - return this.props; - } -} diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts index 41b32ff24f5e7..6688e4cf00b7f 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts @@ -1,11 +1,12 @@ import ec2 = require('@aws-cdk/aws-ec2'); import secretsmanager = require('@aws-cdk/aws-secretsmanager'); import cdk = require('@aws-cdk/cdk'); +import { Token } from '@aws-cdk/cdk'; /** * Create a clustered database with a given number of instances. */ -export interface IDatabaseCluster extends cdk.IConstruct, ec2.IConnectable, secretsmanager.ISecretAttachmentTarget { +export interface IDatabaseCluster extends cdk.IResource, ec2.IConnectable, secretsmanager.ISecretAttachmentTarget { /** * Identifier of the cluster */ @@ -18,13 +19,15 @@ export interface IDatabaseCluster extends cdk.IConstruct, ec2.IConnectable, secr /** * The endpoint to use for read/write operations + * @attribute dbClusterEndpointAddress,dbClusterEndpointPort */ readonly clusterEndpoint: Endpoint; /** * Endpoint to use for load-balanced read-only operations. + * @attribute dbClusterReadEndpointAddress */ - readonly readerEndpoint: Endpoint; + readonly clusterReadEndpoint: Endpoint; /** * Endpoints which address each individual replica. @@ -35,21 +38,16 @@ export interface IDatabaseCluster extends cdk.IConstruct, ec2.IConnectable, secr * The security group for this database cluster */ readonly securityGroupId: string; - - /** - * Export a Database Cluster for importing in another stack - */ - export(): DatabaseClusterImportProps; } /** * Properties that describe an existing cluster instance */ -export interface DatabaseClusterImportProps { +export interface DatabaseClusterAttributes { /** * The database port */ - readonly port: string; + readonly port: number; /** * The security group for this database cluster @@ -97,16 +95,18 @@ export class Endpoint { /** * The port of the endpoint */ - public readonly port: string; + public readonly port: number; /** * The combination of "HOSTNAME:PORT" for this endpoint */ public readonly socketAddress: string; - constructor(address: string, port: string) { + constructor(address: string, port: number) { this.hostname = address; this.port = port; - this.socketAddress = `${address}:${port}`; + + const portDesc = Token.isToken(port) ? '{IndirectPort}' : port; + this.socketAddress = `${address}:${portDesc}`; } } diff --git a/packages/@aws-cdk/aws-rds/lib/cluster.ts b/packages/@aws-cdk/aws-rds/lib/cluster.ts index 0b68e29355e8d..1d61342f62273 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster.ts @@ -1,9 +1,9 @@ import ec2 = require('@aws-cdk/aws-ec2'); import kms = require('@aws-cdk/aws-kms'); import secretsmanager = require('@aws-cdk/aws-secretsmanager'); -import cdk = require('@aws-cdk/cdk'); +import { Construct, DeletionPolicy, Resource, Token } from '@aws-cdk/cdk'; import { IClusterParameterGroup } from './cluster-parameter-group'; -import { DatabaseClusterImportProps, Endpoint, IDatabaseCluster } from './cluster-ref'; +import { DatabaseClusterAttributes, Endpoint, IDatabaseCluster } from './cluster-ref'; import { DatabaseSecret } from './database-secret'; import { BackupProps, DatabaseClusterEngine, InstanceProps, Login } from './props'; import { CfnDBCluster, CfnDBInstance, CfnDBSubnetGroup } from './rds.generated'; @@ -85,7 +85,7 @@ export interface DatabaseClusterProps { * * @default default master key */ - readonly kmsKey?: kms.IEncryptionKey; + readonly kmsKey?: kms.IKey; /** * A daily time range in 24-hours UTC format in which backups preferably execute. @@ -109,20 +109,13 @@ export interface DatabaseClusterProps { * * @default Retain */ - readonly deleteReplacePolicy?: cdk.DeletionPolicy + readonly deleteReplacePolicy?: DeletionPolicy } /** * A new or imported clustered database. */ -abstract class DatabaseClusterBase extends cdk.Construct implements IDatabaseCluster { - /** - * Import an existing DatabaseCluster from properties - */ - public static import(scope: cdk.Construct, id: string, props: DatabaseClusterImportProps): IDatabaseCluster { - return new ImportedDatabaseCluster(scope, id, props); - } - +abstract class DatabaseClusterBase extends Resource implements IDatabaseCluster { /** * Identifier of the cluster */ @@ -140,7 +133,7 @@ abstract class DatabaseClusterBase extends cdk.Construct implements IDatabaseClu /** * Endpoint to use for load-balanced read-only operations. */ - public abstract readonly readerEndpoint: Endpoint; + public abstract readonly clusterReadEndpoint: Endpoint; /** * Endpoints which address each individual replica. @@ -157,8 +150,6 @@ abstract class DatabaseClusterBase extends cdk.Construct implements IDatabaseClu */ public abstract readonly securityGroupId: string; - public abstract export(): DatabaseClusterImportProps; - /** * Renders the secret attachment target specifications. */ @@ -172,8 +163,31 @@ abstract class DatabaseClusterBase extends cdk.Construct implements IDatabaseClu /** * Create a clustered database with a given number of instances. + * + * @resource AWS::RDS::DBCluster */ export class DatabaseCluster extends DatabaseClusterBase { + /** + * Import an existing DatabaseCluster from properties + */ + public static fromDatabaseClusterAttributes(scope: Construct, id: string, attrs: DatabaseClusterAttributes): IDatabaseCluster { + class Import extends DatabaseClusterBase implements IDatabaseCluster { + public readonly defaultPortRange = new ec2.TcpPort(attrs.port); + public readonly connections = new ec2.Connections({ + securityGroups: [ec2.SecurityGroup.fromSecurityGroupId(this, 'SecurityGroup', attrs.securityGroupId)], + defaultPortRange: this.defaultPortRange + }); + public readonly clusterIdentifier = attrs.clusterIdentifier; + public readonly instanceIdentifiers: string[] = []; + public readonly clusterEndpoint = new Endpoint(attrs.clusterEndpointAddress, attrs.port); + public readonly clusterReadEndpoint = new Endpoint(attrs.readerEndpointAddress, attrs.port); + public readonly instanceEndpoints = attrs.instanceEndpointAddresses.map(a => new Endpoint(a, attrs.port)); + public readonly securityGroupId = attrs.securityGroupId; + } + + return new Import(scope, id); + } + /** * Identifier of the cluster */ @@ -192,7 +206,7 @@ export class DatabaseCluster extends DatabaseClusterBase { /** * Endpoint to use for load-balanced read-only operations. */ - public readonly readerEndpoint: Endpoint; + public readonly clusterReadEndpoint: Endpoint; /** * Endpoints which address each individual replica. @@ -222,14 +236,14 @@ export class DatabaseCluster extends DatabaseClusterBase { /** * The VPC where the DB subnet group is created. */ - private readonly vpc: ec2.IVpcNetwork; + private readonly vpc: ec2.IVpc; /** * The subnets used by the DB subnet group. */ private readonly vpcSubnets?: ec2.SubnetSelection; - constructor(scope: cdk.Construct, id: string, props: DatabaseClusterProps) { + constructor(scope: Construct, id: string, props: DatabaseClusterProps) { super(scope, id); this.vpc = props.instanceProps.vpc; @@ -288,13 +302,16 @@ export class DatabaseCluster extends DatabaseClusterBase { storageEncrypted: props.kmsKey ? true : props.storageEncrypted }); - const deleteReplacePolicy = props.deleteReplacePolicy || cdk.DeletionPolicy.Retain; + const deleteReplacePolicy = props.deleteReplacePolicy || DeletionPolicy.Retain; cluster.options.deletionPolicy = deleteReplacePolicy; cluster.options.updateReplacePolicy = deleteReplacePolicy; this.clusterIdentifier = cluster.ref; - this.clusterEndpoint = new Endpoint(cluster.dbClusterEndpointAddress, cluster.dbClusterEndpointPort); - this.readerEndpoint = new Endpoint(cluster.dbClusterReadEndpointAddress, cluster.dbClusterEndpointPort); + + // create a number token that represents the port of the cluster + const portAttribute = new Token(() => cluster.dbClusterEndpointPort).toNumber(); + this.clusterEndpoint = new Endpoint(cluster.dbClusterEndpointAddress, portAttribute); + this.clusterReadEndpoint = new Endpoint(cluster.dbClusterReadEndpointAddress, portAttribute); if (secret) { this.secret = secret.addTargetAttachment('AttachedSecret', { @@ -338,10 +355,10 @@ export class DatabaseCluster extends DatabaseClusterBase { instance.node.addDependency(internetConnected); this.instanceIdentifiers.push(instance.ref); - this.instanceEndpoints.push(new Endpoint(instance.dbInstanceEndpointAddress, instance.dbInstanceEndpointPort)); + this.instanceEndpoints.push(new Endpoint(instance.dbInstanceEndpointAddress, portAttribute)); } - const defaultPortRange = new ec2.TcpPortFromAttribute(this.clusterEndpoint.port); + const defaultPortRange = new ec2.TcpPort(this.clusterEndpoint.port); this.connections = new ec2.Connections({ securityGroups: [securityGroup], defaultPortRange }); } @@ -361,23 +378,6 @@ export class DatabaseCluster extends DatabaseClusterBase { ...options }); } - - /** - * Export a Database Cluster for importing in another stack - */ - public export(): DatabaseClusterImportProps { - // tslint:disable:max-line-length - return { - port: new cdk.CfnOutput(this, 'Port', { value: this.clusterEndpoint.port, }).makeImportValue().toString(), - securityGroupId: new cdk.CfnOutput(this, 'SecurityGroupId', { value: this.securityGroupId, }).makeImportValue().toString(), - clusterIdentifier: new cdk.CfnOutput(this, 'ClusterIdentifier', { value: this.clusterIdentifier, }).makeImportValue().toString(), - instanceIdentifiers: new cdk.StringListCfnOutput(this, 'InstanceIdentifiers', { values: this.instanceIdentifiers }).makeImportValues().map(x => x.toString()), - clusterEndpointAddress: new cdk.CfnOutput(this, 'ClusterEndpointAddress', { value: this.clusterEndpoint.hostname, }).makeImportValue().toString(), - readerEndpointAddress: new cdk.CfnOutput(this, 'ReaderEndpointAddress', { value: this.readerEndpoint.hostname, }).makeImportValue().toString(), - instanceEndpointAddresses: new cdk.StringListCfnOutput(this, 'InstanceEndpointAddresses', { values: this.instanceEndpoints.map(e => e.hostname) }).makeImportValues().map(x => x.toString()), - }; - // tslint:enable:max-line-length - } } /** @@ -387,70 +387,6 @@ function databaseInstanceType(instanceType: ec2.InstanceType) { return 'db.' + instanceType.toString(); } -/** - * An imported Database Cluster - */ -class ImportedDatabaseCluster extends DatabaseClusterBase implements IDatabaseCluster { - /** - * Default port to connect to this database - */ - public readonly defaultPortRange: ec2.IPortRange; - - /** - * Access to the network connections - */ - public readonly connections: ec2.Connections; - - /** - * Identifier of the cluster - */ - public readonly clusterIdentifier: string; - - /** - * Identifiers of the replicas - */ - public readonly instanceIdentifiers: string[] = []; - - /** - * The endpoint to use for read/write operations - */ - public readonly clusterEndpoint: Endpoint; - - /** - * Endpoint to use for load-balanced read-only operations. - */ - public readonly readerEndpoint: Endpoint; - - /** - * Endpoints which address each individual replica. - */ - public readonly instanceEndpoints: Endpoint[] = []; - - /** - * Security group identifier of this database - */ - public readonly securityGroupId: string; - - constructor(scope: cdk.Construct, name: string, private readonly props: DatabaseClusterImportProps) { - super(scope, name); - - this.securityGroupId = props.securityGroupId; - this.defaultPortRange = new ec2.TcpPortFromAttribute(props.port); - this.connections = new ec2.Connections({ - securityGroups: [ec2.SecurityGroup.fromSecurityGroupId(this, 'SecurityGroup', props.securityGroupId)], - defaultPortRange: this.defaultPortRange - }); - this.clusterIdentifier = props.clusterIdentifier; - this.clusterEndpoint = new Endpoint(props.clusterEndpointAddress, props.port); - this.readerEndpoint = new Endpoint(props.readerEndpointAddress, props.port); - this.instanceEndpoints = props.instanceEndpointAddresses.map(a => new Endpoint(a, props.port)); - } - - public export() { - return this.props; - } -} - /** * Transforms a DatbaseClusterEngine to a DatabaseEngine. * diff --git a/packages/@aws-cdk/aws-rds/lib/database-secret.ts b/packages/@aws-cdk/aws-rds/lib/database-secret.ts index 23cdef86fd163..46bb307a35978 100644 --- a/packages/@aws-cdk/aws-rds/lib/database-secret.ts +++ b/packages/@aws-cdk/aws-rds/lib/database-secret.ts @@ -16,7 +16,7 @@ export interface DatabaseSecretProps { * * @default default master key */ - readonly encryptionKey?: kms.IEncryptionKey; + readonly encryptionKey?: kms.IKey; } /** diff --git a/packages/@aws-cdk/aws-rds/lib/props.ts b/packages/@aws-cdk/aws-rds/lib/props.ts index 0a414f1e3c834..e25b0d63910c4 100644 --- a/packages/@aws-cdk/aws-rds/lib/props.ts +++ b/packages/@aws-cdk/aws-rds/lib/props.ts @@ -26,7 +26,7 @@ export interface InstanceProps { * * Must be at least 2 subnets in two different AZs. */ - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; /** * Where to place the instances within the VPC @@ -82,7 +82,7 @@ export interface Login { * * @default default master key */ - readonly kmsKey?: kms.IEncryptionKey; + readonly kmsKey?: kms.IKey; } /** diff --git a/packages/@aws-cdk/aws-rds/lib/rotation-single-user.ts b/packages/@aws-cdk/aws-rds/lib/rotation-single-user.ts index 6ff5dd4dd0e93..2340ac049c2d6 100644 --- a/packages/@aws-cdk/aws-rds/lib/rotation-single-user.ts +++ b/packages/@aws-cdk/aws-rds/lib/rotation-single-user.ts @@ -103,7 +103,7 @@ export interface RotationSingleUserProps extends RotationSingleUserOptions { /** * The VPC where the Lambda rotation function will run. */ - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; /** * The type of subnets in the VPC where the Lambda rotation function will run. diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.ts b/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.ts index bcd41ecf298d4..ed1a0772820d2 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.ts +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.ts @@ -5,7 +5,7 @@ import rds = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-rds-cluster-rotation'); -const vpc = new ec2.VpcNetwork(stack, 'VPC'); +const vpc = new ec2.Vpc(stack, 'VPC'); /// !show const cluster = new rds.DatabaseCluster(stack, 'Database', { diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster.ts b/packages/@aws-cdk/aws-rds/test/integ.cluster.ts index a6eea21795b90..84f843221df86 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster.ts +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster.ts @@ -8,7 +8,7 @@ import { ClusterParameterGroup } from '../lib/cluster-parameter-group'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-rds-integ'); -const vpc = new ec2.VpcNetwork(stack, 'VPC', { maxAZs: 2 }); +const vpc = new ec2.Vpc(stack, 'VPC', { maxAZs: 2 }); const params = new ClusterParameterGroup(stack, 'Params', { family: 'aurora5.6', @@ -16,7 +16,7 @@ const params = new ClusterParameterGroup(stack, 'Params', { }); params.setParameter('character_set_database', 'utf8mb4'); -const kmsKey = new kms.EncryptionKey(stack, 'DbSecurity'); +const kmsKey = new kms.Key(stack, 'DbSecurity'); const cluster = new DatabaseCluster(stack, 'Database', { engine: DatabaseClusterEngine.Aurora, masterUser: { diff --git a/packages/@aws-cdk/aws-rds/test/test.cluster.ts b/packages/@aws-cdk/aws-rds/test/test.cluster.ts index de8557f34a865..09d7e6a8615d2 100644 --- a/packages/@aws-cdk/aws-rds/test/test.cluster.ts +++ b/packages/@aws-cdk/aws-rds/test/test.cluster.ts @@ -10,7 +10,7 @@ export = { 'check that instantiation works'(test: Test) { // GIVEN const stack = testStack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); // WHEN new DatabaseCluster(stack, 'Database', { @@ -45,34 +45,10 @@ export = { test.done(); }, - 'check that exporting/importing works'(test: Test) { - // GIVEN - const stack1 = testStack(); - const stack2 = testStack(); - - const cluster = new DatabaseCluster(stack1, 'Database', { - engine: DatabaseClusterEngine.Aurora, - masterUser: { - username: 'admin', - password: SecretValue.plainText('tooshort'), - }, - instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.Burstable2, ec2.InstanceSize.Small), - vpc: new ec2.VpcNetwork(stack1, 'VPC') - } - }); - - // WHEN - DatabaseCluster.import(stack2, 'Database', cluster.export()); - - // THEN: No error - - test.done(); - }, 'can create a cluster with a single instance'(test: Test) { // GIVEN const stack = testStack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); // WHEN new DatabaseCluster(stack, 'Database', { @@ -103,7 +79,7 @@ export = { 'can create a cluster with imported vpc and security group'(test: Test) { // GIVEN const stack = testStack(); - const vpc = ec2.VpcNetwork.importFromContext(stack, 'VPC', { + const vpc = ec2.Vpc.fromLookup(stack, 'VPC', { vpcId: "VPC12345" }); const sg = ec2.SecurityGroup.fromSecurityGroupId(stack, 'SG', "SecurityGroupId12345"); @@ -138,7 +114,7 @@ export = { 'cluster with parameter group'(test: Test) { // GIVEN const stack = testStack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); // WHEN const group = new ClusterParameterGroup(stack, 'Params', { @@ -172,25 +148,19 @@ export = { 'import/export cluster parameter group'(test: Test) { // GIVEN const stack = testStack(); - const group = new ClusterParameterGroup(stack, 'Params', { - family: 'hello', - description: 'desc' - }); // WHEN - const exported = group.export(); - const imported = ClusterParameterGroup.import(stack, 'ImportParams', exported); + const imported = ClusterParameterGroup.fromParameterGroupName(stack, 'ImportParams', 'name-of-param-group'); // THEN - test.deepEqual(stack.node.resolve(exported), { parameterGroupName: { 'Fn::ImportValue': 'Stack:ParamsParameterGroupNameA6B808D7' } }); - test.deepEqual(stack.node.resolve(imported.parameterGroupName), { 'Fn::ImportValue': 'Stack:ParamsParameterGroupNameA6B808D7' }); + test.deepEqual(stack.node.resolve(imported.parameterGroupName), 'name-of-param-group'); test.done(); }, 'creates a secret when master credentials are not specified'(test: Test) { // GIVEN const stack = testStack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); // WHEN new DatabaseCluster(stack, 'Database', { @@ -247,7 +217,7 @@ export = { 'create an encrypted cluster with custom KMS key'(test: Test) { // GIVEN const stack = testStack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); // WHEN new DatabaseCluster(stack, 'Database', { @@ -259,7 +229,7 @@ export = { instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.Burstable2, ec2.InstanceSize.Small), vpc }, - kmsKey: new kms.EncryptionKey(stack, 'Key') + kmsKey: new kms.Key(stack, 'Key') }); // THEN diff --git a/packages/@aws-cdk/aws-rds/test/test.rotation-single-user.ts b/packages/@aws-cdk/aws-rds/test/test.rotation-single-user.ts index 0c64f5759707a..45c95cb7e9e69 100644 --- a/packages/@aws-cdk/aws-rds/test/test.rotation-single-user.ts +++ b/packages/@aws-cdk/aws-rds/test/test.rotation-single-user.ts @@ -12,7 +12,7 @@ export = { 'add a rds rotation single user to a cluster'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const cluster = new rds.DatabaseCluster(stack, 'Database', { engine: rds.DatabaseClusterEngine.AuroraMysql, masterUser: { @@ -161,7 +161,7 @@ export = { 'throws when trying to add rotation to a cluster without secret'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); // WHEN const cluster = new rds.DatabaseCluster(stack, 'Database', { @@ -185,7 +185,7 @@ export = { 'throws when both application location and engine are not specified'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', { vpc, }); @@ -208,7 +208,7 @@ export = { 'throws when connections object has no default port range'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); const secret = new secretsmanager.Secret(stack, 'Secret'); const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', { vpc, diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts index 1b006a7f8e7a5..836e3c2f79bda 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts @@ -25,11 +25,6 @@ export interface IHostedZone extends IResource { * @attribute */ readonly hostedZoneNameServers?: string[]; - - /** - * Export the hosted zone - */ - export(): HostedZoneAttributes; } /** diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts index 921b37a84fdc8..af99ddb1efbb0 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts @@ -1,5 +1,5 @@ import ec2 = require('@aws-cdk/aws-ec2'); -import { CfnOutput, Construct, Resource, Token } from '@aws-cdk/cdk'; +import { Construct, Resource, Token } from '@aws-cdk/cdk'; import { HostedZoneAttributes, IHostedZone } from './hosted-zone-ref'; import { ZoneDelegationRecord } from './records'; import { CfnHostedZone } from './route53.generated'; @@ -39,7 +39,7 @@ export interface HostedZoneProps extends CommonHostedZoneProps { * * @default public (no VPCs associated) */ - readonly vpcs?: ec2.IVpcNetwork[]; + readonly vpcs?: ec2.IVpc[]; } export class HostedZone extends Resource implements IHostedZone { @@ -50,12 +50,6 @@ export class HostedZone extends Resource implements IHostedZone { public get zoneName(): string { throw new Error(`HostedZone.fromHostedZoneId doesn't support "zoneName"`); } - public export(): HostedZoneAttributes { - return { - hostedZoneId: this.hostedZoneId, - zoneName: this.zoneName - }; - } } return new Import(scope, id); @@ -68,9 +62,6 @@ export class HostedZone extends Resource implements IHostedZone { class Import extends Construct implements IHostedZone { public readonly hostedZoneId = attrs.hostedZoneId; public readonly zoneName = attrs.zoneName; - public export() { - return attrs; - } } return new Import(scope, id); @@ -106,20 +97,13 @@ export class HostedZone extends Resource implements IHostedZone { } } - public export(): HostedZoneAttributes { - return { - hostedZoneId: new CfnOutput(this, 'HostedZoneId', { value: this.hostedZoneId }).makeImportValue(), - zoneName: this.zoneName, - }; - } - /** * Add another VPC to this private hosted zone. * * @param vpc the other VPC to add. */ - public addVpc(vpc: ec2.IVpcNetwork) { - this.vpcs.push({ vpcId: vpc.vpcId, vpcRegion: vpc.vpcRegion }); + public addVpc(vpc: ec2.IVpc) { + this.vpcs.push({ vpcId: vpc.vpcId, vpcRegion: vpc.region }); } } @@ -137,12 +121,6 @@ export class PublicHostedZone extends HostedZone implements IPublicHostedZone { class Import extends Resource implements IPublicHostedZone { public readonly hostedZoneId = publicHostedZoneId; public get zoneName(): string { throw new Error(`cannot retrieve "zoneName" from an an imported hosted zone`); } - public export(): HostedZoneAttributes { - return { - hostedZoneId: this.hostedZoneId, - zoneName: this.zoneName - }; - } } return new Import(scope, id); } @@ -151,7 +129,7 @@ export class PublicHostedZone extends HostedZone implements IPublicHostedZone { super(scope, id, props); } - public addVpc(_vpc: ec2.IVpcNetwork) { + public addVpc(_vpc: ec2.IVpc) { throw new Error('Cannot associate public hosted zones with a VPC'); } @@ -198,7 +176,7 @@ export interface PrivateHostedZoneProps extends CommonHostedZoneProps { * Private hosted zones must be associated with at least one VPC. You can * associated additional VPCs using `addVpc(vpc)`. */ - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; } export interface IPrivateHostedZone extends IHostedZone {} @@ -217,12 +195,6 @@ export class PrivateHostedZone extends HostedZone implements IPrivateHostedZone class Import extends Resource implements IPrivateHostedZone { public readonly hostedZoneId = privateHostedZoneId; public get zoneName(): string { throw new Error(`cannot retrieve "zoneName" from an an imported hosted zone`); } - public export(): HostedZoneAttributes { - return { - hostedZoneId: this.hostedZoneId, - zoneName: this.zoneName - }; - } } return new Import(scope, id); } diff --git a/packages/@aws-cdk/aws-route53/test/integ.route53.ts b/packages/@aws-cdk/aws-route53/test/integ.route53.ts index b39e4178e28a7..625357e5717b6 100644 --- a/packages/@aws-cdk/aws-route53/test/integ.route53.ts +++ b/packages/@aws-cdk/aws-route53/test/integ.route53.ts @@ -6,7 +6,7 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-route53-integ'); -const vpc = new ec2.VpcNetwork(stack, 'VPC'); +const vpc = new ec2.Vpc(stack, 'VPC'); const privateZone = new PrivateHostedZone(stack, 'PrivateZone', { zoneName: 'cdk.local', vpc diff --git a/packages/@aws-cdk/aws-route53/test/test.route53.ts b/packages/@aws-cdk/aws-route53/test/test.route53.ts index f79bf07177a04..3a5c456ba3182 100644 --- a/packages/@aws-cdk/aws-route53/test/test.route53.ts +++ b/packages/@aws-cdk/aws-route53/test/test.route53.ts @@ -23,7 +23,7 @@ export = { }, 'private hosted zone'(test: Test) { const app = new TestApp(); - const vpcNetwork = new ec2.VpcNetwork(app.stack, 'VPC'); + const vpcNetwork = new ec2.Vpc(app.stack, 'VPC'); new PrivateHostedZone(app.stack, 'HostedZone', { zoneName: 'test.private', vpc: vpcNetwork }); expect(app.synthesizeTemplate()).to(beASupersetOfTemplate({ Resources: { @@ -43,8 +43,8 @@ export = { }, 'when specifying multiple VPCs'(test: Test) { const app = new TestApp(); - const vpcNetworkA = new ec2.VpcNetwork(app.stack, 'VPC1'); - const vpcNetworkB = new ec2.VpcNetwork(app.stack, 'VPC2'); + const vpcNetworkA = new ec2.Vpc(app.stack, 'VPC1'); + const vpcNetworkB = new ec2.Vpc(app.stack, 'VPC2'); new PrivateHostedZone(app.stack, 'HostedZone', { zoneName: 'test.private', vpc: vpcNetworkA }) .addVpc(vpcNetworkB); expect(app.synthesizeTemplate()).to(beASupersetOfTemplate({ @@ -70,40 +70,21 @@ export = { }, 'exporting and importing works'(test: Test) { - const stack1 = new cdk.Stack(); const stack2 = new cdk.Stack(); - const zone = new PublicHostedZone(stack1, 'Zone', { - zoneName: 'cdk.local', + const importedZone = HostedZone.fromHostedZoneAttributes(stack2, 'Imported', { + hostedZoneId: 'hosted-zone-id', + zoneName: 'cdk.local' }); - const zoneRef = zone.export(); - const importedZone = HostedZone.fromHostedZoneAttributes(stack2, 'Imported', zoneRef); new TxtRecord(importedZone as any, 'Record', { zone: importedZone, recordName: 'lookHere', recordValue: 'SeeThere' }); - expect(stack1).to(exactlyMatchTemplate({ - Resources: { - ZoneA5DE4B68: { - Type: "AWS::Route53::HostedZone", - Properties: { - Name: "cdk.local." - } - } - }, - Outputs: { - ZoneHostedZoneId413B8768: { - Value: { Ref: "ZoneA5DE4B68" }, - Export: { Name: "Stack:ZoneHostedZoneId413B8768" } - } - } - })); - expect(stack2).to(haveResource("AWS::Route53::RecordSet", { - HostedZoneId: { "Fn::ImportValue": "Stack:ZoneHostedZoneId413B8768" }, + HostedZoneId: "hosted-zone-id", Name: "lookHere.cdk.local.", ResourceRecords: [ "\"SeeThere\"" ], Type: "TXT" @@ -140,9 +121,9 @@ export = { 'a hosted zone can be assiciated with a VPC either upon creation or using "addVpc"'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc1 = new ec2.VpcNetwork(stack, 'VPC1'); - const vpc2 = new ec2.VpcNetwork(stack, 'VPC2'); - const vpc3 = new ec2.VpcNetwork(stack, 'VPC3'); + const vpc1 = new ec2.Vpc(stack, 'VPC1'); + const vpc2 = new ec2.Vpc(stack, 'VPC2'); + const vpc3 = new ec2.Vpc(stack, 'VPC3'); // WHEN const zone = new HostedZone(stack, 'MyHostedZone', { @@ -187,7 +168,7 @@ export = { // GIVEN const stack = new cdk.Stack(); const zone = new PublicHostedZone(stack, 'MyHostedZone', { zoneName: 'zonename' }); - const vpc = new ec2.VpcNetwork(stack, 'VPC'); + const vpc = new ec2.Vpc(stack, 'VPC'); // THEN test.throws(() => zone.addVpc(vpc), /Cannot associate public hosted zones with a VPC/); diff --git a/packages/@aws-cdk/aws-s3/README.md b/packages/@aws-cdk/aws-s3/README.md index 06a02424dd7d9..94ee63bca2db4 100644 --- a/packages/@aws-cdk/aws-s3/README.md +++ b/packages/@aws-cdk/aws-s3/README.md @@ -29,7 +29,7 @@ const bucket = new Bucket(this, 'MyUnencryptedBucket', { }); // you can access the encryption key: -assert(bucket.encryptionKey instanceof kms.EncryptionKey); +assert(bucket.encryptionKey instanceof kms.Key); ``` You can also supply your own key: diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index 96b5e2593f6e1..0fca2c2e13a64 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -2,7 +2,7 @@ import events = require('@aws-cdk/aws-events'); import iam = require('@aws-cdk/aws-iam'); import kms = require('@aws-cdk/aws-kms'); import { IBucketNotificationDestination } from '@aws-cdk/aws-s3-notifications'; -import { applyRemovalPolicy, CfnOutput, Construct, IResource, RemovalPolicy, Resource, Token } from '@aws-cdk/cdk'; +import { applyRemovalPolicy, Construct, IResource, RemovalPolicy, Resource, Token } from '@aws-cdk/cdk'; import { EOL } from 'os'; import { BucketPolicy } from './bucket-policy'; import { BucketNotifications } from './notifications-resource'; @@ -51,7 +51,7 @@ export interface IBucket extends IResource { /** * Optional KMS encryption key associated with this bucket. */ - readonly encryptionKey?: kms.IEncryptionKey; + readonly encryptionKey?: kms.IKey; /** * The resource policy assoicated with this bucket. @@ -61,11 +61,6 @@ export interface IBucket extends IResource { */ policy?: BucketPolicy; - /** - * Exports this bucket from the stack. - */ - export(): BucketAttributes; - /** * Adds a statement to the resource policy for a principal (i.e. * account/role/service) to perform actions on this bucket and/or it's @@ -267,7 +262,7 @@ abstract class BucketBase extends Resource implements IBucket { /** * Optional KMS encryption key associated with this bucket. */ - public abstract readonly encryptionKey?: kms.IEncryptionKey; + public abstract readonly encryptionKey?: kms.IKey; /** * The resource policy assoicated with this bucket. @@ -288,11 +283,6 @@ abstract class BucketBase extends Resource implements IBucket { */ protected abstract disallowPublicAccess?: boolean; - /** - * Exports this bucket from the stack. - */ - public abstract export(): BucketAttributes; - public onPutObject(name: string, target?: events.IEventRuleTarget, path?: string): events.EventRule { const eventRule = new events.EventRule(this, name, { eventPattern: { @@ -604,7 +594,7 @@ export interface BucketProps { * @default If encryption is set to "Kms" and this property is undefined, a * new KMS key will be created and associated with this bucket. */ - readonly encryptionKey?: kms.IEncryptionKey; + readonly encryptionKey?: kms.IKey; /** * Physical name of this bucket. @@ -716,7 +706,7 @@ export class Bucket extends BucketBase { public readonly bucketRegionalDomainName = attrs.bucketRegionalDomainName || `${bucketName}.s3.${region}.${urlSuffix}`; public readonly bucketDualStackDomainName = attrs.bucketDualStackDomainName || `${bucketName}.s3.dualstack.${region}.${urlSuffix}`; public readonly bucketWebsiteNewUrlFormat = newUrlFormat; - public readonly encryptionKey?: kms.EncryptionKey; + public readonly encryptionKey?: kms.IKey; public policy?: BucketPolicy = undefined; protected autoCreatePolicy = false; protected disallowPublicAccess = false; @@ -739,7 +729,7 @@ export class Bucket extends BucketBase { public readonly bucketDualStackDomainName: string; public readonly bucketRegionalDomainName: string; - public readonly encryptionKey?: kms.IEncryptionKey; + public readonly encryptionKey?: kms.IKey; public policy?: BucketPolicy; protected autoCreatePolicy = true; protected disallowPublicAccess?: boolean; @@ -795,18 +785,6 @@ export class Bucket extends BucketBase { } } - /** - * Exports this bucket from the stack. - */ - public export(): BucketAttributes { - return { - bucketArn: new CfnOutput(this, 'BucketArn', { value: this.bucketArn }).makeImportValue().toString(), - bucketName: new CfnOutput(this, 'BucketName', { value: this.bucketName }).makeImportValue().toString(), - bucketDomainName: new CfnOutput(this, 'DomainName', { value: this.bucketDomainName }).makeImportValue().toString(), - bucketWebsiteUrl: new CfnOutput(this, 'WebsiteURL', { value: this.bucketWebsiteUrl }).makeImportValue().toString() - }; - } - /** * Add a lifecycle rule to the bucket * @@ -918,7 +896,7 @@ export class Bucket extends BucketBase { */ private parseEncryption(props: BucketProps): { bucketEncryption?: CfnBucket.BucketEncryptionProperty, - encryptionKey?: kms.IEncryptionKey + encryptionKey?: kms.IKey } { // default to unencrypted. @@ -934,7 +912,7 @@ export class Bucket extends BucketBase { } if (encryptionType === BucketEncryption.Kms) { - const encryptionKey = props.encryptionKey || new kms.EncryptionKey(this, 'Key', { + const encryptionKey = props.encryptionKey || new kms.Key(this, 'Key', { description: `Created by ${this.node.path}` }); diff --git a/packages/@aws-cdk/aws-s3/test/demo.import-export.ts b/packages/@aws-cdk/aws-s3/test/demo.import-export.ts deleted file mode 100644 index 4cd40c719266f..0000000000000 --- a/packages/@aws-cdk/aws-s3/test/demo.import-export.ts +++ /dev/null @@ -1,68 +0,0 @@ -import iam = require('@aws-cdk/aws-iam'); -import cdk = require('@aws-cdk/cdk'); -import s3 = require('../lib'); - -// Define a stack with an S3 bucket and export it using `bucket.export()`. -// bucket.export returns an `IBucket` object which can later be used in -// `Bucket.import`. - -class Producer extends cdk.Stack { - public readonly myBucketRef: s3.BucketAttributes; - - constructor(scope: cdk.App, id: string) { - super(scope, id); - - const bucket = new s3.Bucket(this, 'MyBucket'); - this.myBucketRef = bucket.export(); - } -} - -interface ConsumerConstructProps { - bucket: s3.IBucket; -} - -class ConsumerConstruct extends cdk.Construct { - constructor(scope: cdk.Construct, id: string, props: ConsumerConstructProps) { - super(scope, id); - - props.bucket.addToResourcePolicy(new iam.PolicyStatement().addAction('*')); - } -} - -// Define a stack that requires an IBucket as an input and uses `Bucket.import` -// to create a `Bucket` object that represents this external bucket. Grant a -// user principal created within this consuming stack read/write permissions to -// this bucket and contents. - -interface ConsumerProps { - userBucketRef: s3.BucketAttributes; -} - -class Consumer extends cdk.Stack { - constructor(scope: cdk.App, id: string, props: ConsumerProps) { - super(scope, id); - - const user = new iam.User(this, 'MyUser'); - const userBucket = s3.Bucket.fromBucketAttributes(this, 'ImportBucket', props.userBucketRef); - - new ConsumerConstruct(this, 'SomeConstruct', { bucket: userBucket }); - - userBucket.grantReadWrite(user); - } -} - -// ------------------------------------------------------- -// NOTE: To deploy this, just run `cdk -a "node file.js" deploy`. The stacks -// will be deployed IN-ORDER which means that the producer will be deployed -// first. In the future the toolkit will be able to understand the relationships -// between the stacks and will deploy them in order. - -const app = new cdk.App(); - -const producer = new Producer(app, 'produce'); - -new Consumer(app, 'consume', { - userBucketRef: producer.myBucketRef -}); - -app.run(); diff --git a/packages/@aws-cdk/aws-s3/test/test.bucket.ts b/packages/@aws-cdk/aws-s3/test/test.bucket.ts index 20fb0cedd162d..344d1dfc10da9 100644 --- a/packages/@aws-cdk/aws-s3/test/test.bucket.ts +++ b/packages/@aws-cdk/aws-s3/test/test.bucket.ts @@ -213,7 +213,7 @@ export = { 'fails if encryption key is used with managed encryption'(test: Test) { const stack = new cdk.Stack(); - const myKey = new kms.EncryptionKey(stack, 'MyKey'); + const myKey = new kms.Key(stack, 'MyKey'); test.throws(() => new s3.Bucket(stack, 'MyBucket', { encryption: s3.BucketEncryption.KmsManaged, @@ -225,7 +225,7 @@ export = { 'fails if encryption key is used with encryption set to unencrypted'(test: Test) { const stack = new cdk.Stack(); - const myKey = new kms.EncryptionKey(stack, 'MyKey'); + const myKey = new kms.Key(stack, 'MyKey'); test.throws(() => new s3.Bucket(stack, 'MyBucket', { encryption: s3.BucketEncryption.Unencrypted, @@ -238,7 +238,7 @@ export = { 'encryptionKey can specify kms key'(test: Test) { const stack = new cdk.Stack(); - const encryptionKey = new kms.EncryptionKey(stack, 'MyKey', { description: 'hello, world' }); + const encryptionKey = new kms.Key(stack, 'MyKey', { description: 'hello, world' }); new s3.Bucket(stack, 'MyBucket', { encryptionKey, encryption: s3.BucketEncryption.Kms }); @@ -536,31 +536,6 @@ export = { }, 'import/export': { - 'export creates outputs for the bucket attributes and returns a ref object'(test: Test) { - const stack = new cdk.Stack(undefined, 'MyStack'); - const bucket = new s3.Bucket(stack, 'MyBucket'); - const bucketRef = bucket.export(); - test.deepEqual(bucket.node.resolve(bucketRef), { - bucketArn: { 'Fn::ImportValue': 'MyStack:MyBucketBucketArnE260558C' }, - bucketName: { 'Fn::ImportValue': 'MyStack:MyBucketBucketName8A027014' }, - bucketDomainName: { 'Fn::ImportValue': 'MyStack:MyBucketDomainNameF76B9A7A' }, - bucketWebsiteUrl: { 'Fn::ImportValue': 'MyStack:MyBucketWebsiteURL9C222788' } - }); - test.done(); - }, - - 'refs will include the bucket\'s encryption key if defined'(test: Test) { - const stack = new cdk.Stack(undefined, 'MyStack'); - const bucket = new s3.Bucket(stack, 'MyBucket', { encryption: s3.BucketEncryption.Kms }); - const bucketRef = bucket.export(); - test.deepEqual(bucket.node.resolve(bucketRef), { - bucketArn: { 'Fn::ImportValue': 'MyStack:MyBucketBucketArnE260558C' }, - bucketName: { 'Fn::ImportValue': 'MyStack:MyBucketBucketName8A027014' }, - bucketDomainName: { 'Fn::ImportValue': 'MyStack:MyBucketDomainNameF76B9A7A' }, - bucketWebsiteUrl: { 'Fn::ImportValue': 'MyStack:MyBucketWebsiteURL9C222788' } - }); - test.done(); - }, 'static import(ref) allows importing an external/existing bucket'(test: Test) { const stack = new cdk.Stack(); @@ -633,117 +608,6 @@ export = { test.done(); }, - - 'this is how export/import work together'(test: Test) { - const stack1 = new cdk.Stack(undefined, 'S1'); - const bucket = new s3.Bucket(stack1, 'MyBucket'); - const bucketRef = bucket.export(); - - expect(stack1).toMatch({ - "Resources": { - "MyBucketF68F3FF0": { - "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Retain", - } - }, - "Outputs": { - "MyBucketBucketArnE260558C": { - "Value": { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "Arn" - ] - }, - "Export": { - "Name": "S1:MyBucketBucketArnE260558C" - } - }, - "MyBucketBucketName8A027014": { - "Value": { - "Ref": "MyBucketF68F3FF0" - }, - "Export": { - "Name": "S1:MyBucketBucketName8A027014" - } - }, - "MyBucketDomainNameF76B9A7A": { - "Value": { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "DomainName" - ] - }, - "Export": { - "Name": "S1:MyBucketDomainNameF76B9A7A" - } - }, - "MyBucketWebsiteURL9C222788": { - "Value": { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "WebsiteURL" - ] - }, - "Export": { - "Name": "S1:MyBucketWebsiteURL9C222788" - } - } - } - }); - - const stack2 = new cdk.Stack(undefined, 'S2'); - const importedBucket = s3.Bucket.fromBucketAttributes(stack2, 'ImportedBucket', bucketRef); - const user = new iam.User(stack2, 'MyUser'); - importedBucket.grantRead(user); - - expect(stack2).toMatch({ - "Resources": { - "MyUserDC45028B": { - "Type": "AWS::IAM::User" - }, - "MyUserDefaultPolicy7B897426": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::ImportValue": "S1:MyBucketBucketArnE260558C" - }, - { - "Fn::Join": [ - "", - [ - { "Fn::ImportValue": "S1:MyBucketBucketArnE260558C" }, - "/*" - ] - ] - } - ] - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "MyUserDefaultPolicy7B897426", - "Users": [ - { - "Ref": "MyUserDC45028B" - } - ] - } - } - } - }); - - test.done(); - } }, 'grantRead'(test: Test) { @@ -1135,12 +999,10 @@ export = { 'cross-stack permissions'(test: Test) { const stackA = new cdk.Stack(); const bucketFromStackA = new s3.Bucket(stackA, 'MyBucket'); - const refToBucketFromStackA = bucketFromStackA.export(); const stackB = new cdk.Stack(); const user = new iam.User(stackB, 'UserWhoNeedsAccess'); - const theBucketFromStackAAsARefInStackB = s3.Bucket.fromBucketAttributes(stackB, 'RefToBucketFromStackA', refToBucketFromStackA); - theBucketFromStackAAsARefInStackB.grantRead(user); + bucketFromStackA.grantRead(user); expect(stackA).toMatch({ "Resources": { @@ -1148,47 +1010,6 @@ export = { "Type": "AWS::S3::Bucket", "DeletionPolicy": "Retain", } - }, - "Outputs": { - "MyBucketBucketArnE260558C": { - "Value": { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "Arn" - ] - }, - "Export": { - "Name": "Stack:MyBucketBucketArnE260558C" - } - }, - "MyBucketBucketName8A027014": { - "Value": { - "Ref": "MyBucketF68F3FF0" - }, - "Export": { - "Name": "Stack:MyBucketBucketName8A027014" - } - }, - "MyBucketDomainNameF76B9A7A": { - "Value": { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "DomainName" - ] - }, - "Export": { - "Name": "Stack:MyBucketDomainNameF76B9A7A" - } - }, - "MyBucketWebsiteURL9C222788": { - "Value": { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "WebsiteURL" - ] - }, - "Export": { "Name": "Stack:MyBucketWebsiteURL9C222788" } - } } }); @@ -1211,14 +1032,14 @@ export = { "Effect": "Allow", "Resource": [ { - "Fn::ImportValue": "Stack:MyBucketBucketArnE260558C" + "Fn::ImportValue": "Stack:ExportsOutputFnGetAttMyBucketF68F3FF0Arn0F7E8E58" }, { "Fn::Join": [ "", [ { - "Fn::ImportValue": "Stack:MyBucketBucketArnE260558C" + "Fn::ImportValue": "Stack:ExportsOutputFnGetAttMyBucketF68F3FF0Arn0F7E8E58" }, "/*" ] diff --git a/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts b/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts index cfb67cf87411e..a626de80eaf2f 100644 --- a/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts +++ b/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts @@ -12,7 +12,7 @@ export interface ISecret extends IResource { * The customer-managed encryption key that is used to encrypt this secret, if any. When not specified, the default * KMS key for the account and region is being used. */ - readonly encryptionKey?: kms.IEncryptionKey; + readonly encryptionKey?: kms.IKey; /** * The ARN of the secret in AWS Secrets Manager. @@ -31,13 +31,6 @@ export interface ISecret extends IResource { */ secretJsonValue(key: string): SecretValue; - /** - * Exports this secret. - * - * @return import props that can be passed back to ``Secret.import``. - */ - export(): SecretAttributes; - /** * Grants reading the secret value to some role. * @@ -67,7 +60,7 @@ export interface SecretProps { * * @default a default KMS key for the account and region is used. */ - readonly encryptionKey?: kms.IEncryptionKey; + readonly encryptionKey?: kms.IKey; /** * Configuration for how to generate a secret value. @@ -93,7 +86,7 @@ export interface SecretAttributes { /** * The encryption key that is used to encrypt the secret, unless the default SecretsManager key is used. */ - readonly encryptionKey?: kms.IEncryptionKey; + readonly encryptionKey?: kms.IKey; /** * The ARN of the secret in SecretsManager. @@ -105,11 +98,9 @@ export interface SecretAttributes { * The common behavior of Secrets. Users should not use this class directly, and instead use ``Secret``. */ abstract class SecretBase extends Resource implements ISecret { - public abstract readonly encryptionKey?: kms.IEncryptionKey; + public abstract readonly encryptionKey?: kms.IKey; public abstract readonly secretArn: string; - public abstract export(): SecretAttributes; - public grantRead(grantee: iam.IGrantable, versionStages?: string[]): iam.Grant { // @see https://docs.aws.amazon.com/fr_fr/secretsmanager/latest/userguide/auth-and-access_identity-based-policies.html @@ -168,10 +159,15 @@ export class Secret extends SecretBase { * @param attrs the attributes of the imported secret. */ public static fromSecretAttributes(scope: Construct, id: string, attrs: SecretAttributes): ISecret { - return new ImportedSecret(scope, id, attrs); + class Import extends SecretBase { + public readonly encryptionKey = attrs.encryptionKey; + public readonly secretArn = attrs.secretArn; + } + + return new Import(scope, id); } - public readonly encryptionKey?: kms.IEncryptionKey; + public readonly encryptionKey?: kms.IKey; public readonly secretArn: string; constructor(scope: Construct, id: string, props: SecretProps = {}) { @@ -205,13 +201,6 @@ export class Secret extends SecretBase { ...options }); } - - public export(): SecretAttributes { - return { - encryptionKey: this.encryptionKey, - secretArn: this.secretArn, - }; - } } /** @@ -290,20 +279,15 @@ export class SecretTargetAttachment extends SecretBase implements ISecretTargetA public static fromSecretTargetAttachmentSecretArn(scope: Construct, id: string, secretTargetAttachmentSecretArn: string): ISecretTargetAttachment { class Import extends SecretBase implements ISecretTargetAttachment { - public encryptionKey?: kms.IEncryptionKey | undefined; + public encryptionKey?: kms.IKey | undefined; public secretArn = secretTargetAttachmentSecretArn; public secretTargetAttachmentSecretArn = secretTargetAttachmentSecretArn; - public export(): SecretAttributes { - return { - secretArn: this.secretArn - }; - } } return new Import(scope, id); } - public readonly encryptionKey?: kms.IEncryptionKey; + public readonly encryptionKey?: kms.IKey; public readonly secretArn: string; /** @@ -326,13 +310,6 @@ export class SecretTargetAttachment extends SecretBase implements ISecretTargetA this.secretArn = attachment.secretTargetAttachmentSecretArn; this.secretTargetAttachmentSecretArn = attachment.secretTargetAttachmentSecretArn; } - - public export(): SecretAttributes { - return { - encryptionKey: this.encryptionKey, - secretArn: this.secretArn, - }; - } } /** @@ -411,19 +388,3 @@ export interface SecretStringGenerator { */ readonly generateStringKey?: string; } - -class ImportedSecret extends SecretBase { - public readonly encryptionKey?: kms.IEncryptionKey; - public readonly secretArn: string; - - constructor(scope: Construct, id: string, private readonly props: SecretAttributes) { - super(scope, id); - - this.encryptionKey = props.encryptionKey; - this.secretArn = props.secretArn; - } - - public export() { - return this.props; - } -} diff --git a/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts b/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts index f1034c369a7f2..94121ebb2591e 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts +++ b/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts @@ -72,7 +72,7 @@ export = { 'grantRead'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const key = new kms.EncryptionKey(stack, 'KMS'); + const key = new kms.Key(stack, 'KMS'); const secret = new secretsmanager.Secret(stack, 'Secret', { encryptionKey: key }); const role = new iam.Role(stack, 'Role', { assumedBy: new iam.AccountRootPrincipal() }); @@ -166,7 +166,7 @@ export = { 'grantRead with version label constraint'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const key = new kms.EncryptionKey(stack, 'KMS'); + const key = new kms.Key(stack, 'KMS'); const secret = new secretsmanager.Secret(stack, 'Secret', { encryptionKey: key }); const role = new iam.Role(stack, 'Role', { assumedBy: new iam.AccountRootPrincipal() }); @@ -265,7 +265,7 @@ export = { 'secretValue'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const key = new kms.EncryptionKey(stack, 'KMS'); + const key = new kms.Key(stack, 'KMS'); const secret = new secretsmanager.Secret(stack, 'Secret', { encryptionKey: key }); // WHEN @@ -292,7 +292,7 @@ export = { 'import'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const encryptionKey = new kms.EncryptionKey(stack, 'KMS'); + const encryptionKey = new kms.Key(stack, 'KMS'); const secretArn = 'arn::of::a::secret'; // WHEN diff --git a/packages/@aws-cdk/aws-servicediscovery/lib/alias-target-instance.ts b/packages/@aws-cdk/aws-servicediscovery/lib/alias-target-instance.ts index e2eaf06efb0c8..5c9092f09b95b 100644 --- a/packages/@aws-cdk/aws-servicediscovery/lib/alias-target-instance.ts +++ b/packages/@aws-cdk/aws-servicediscovery/lib/alias-target-instance.ts @@ -19,9 +19,11 @@ export interface AliasTargetInstanceProps extends BaseInstanceProps { readonly service: IService; } -/* +/** * Instance that uses Route 53 Alias record type. Currently, the only resource types supported are Elastic Load * Balancers. + * + * @resource AWS::ServiceDiscovery::Instance */ export class AliasTargetInstance extends InstanceBase { /** diff --git a/packages/@aws-cdk/aws-servicediscovery/lib/cname-instance.ts b/packages/@aws-cdk/aws-servicediscovery/lib/cname-instance.ts index feddb68743a3d..abe0b9b428065 100644 --- a/packages/@aws-cdk/aws-servicediscovery/lib/cname-instance.ts +++ b/packages/@aws-cdk/aws-servicediscovery/lib/cname-instance.ts @@ -26,7 +26,7 @@ export interface CnameInstanceProps extends CnameInstanceBaseProps { readonly service: IService; } -/* +/** * Instance that is accessible using a domain name (CNAME). * @resource AWS::ServiceDiscovery::Instance */ @@ -44,7 +44,7 @@ export class CnameInstance extends InstanceBase { /** * The domain name returned by DNS queries for the instance */ - public readonly instanceCname: string; + public readonly cname: string; constructor(scope: cdk.Construct, id: string, props: CnameInstanceProps) { super(scope, id); @@ -68,6 +68,6 @@ export class CnameInstance extends InstanceBase { this.service = props.service; this.instanceId = resource.instanceId; - this.instanceCname = props.instanceCname; + this.cname = props.instanceCname; } } diff --git a/packages/@aws-cdk/aws-servicediscovery/lib/http-namespace.ts b/packages/@aws-cdk/aws-servicediscovery/lib/http-namespace.ts index 4409cd340df90..fb9dbb82a5ddf 100644 --- a/packages/@aws-cdk/aws-servicediscovery/lib/http-namespace.ts +++ b/packages/@aws-cdk/aws-servicediscovery/lib/http-namespace.ts @@ -1,29 +1,42 @@ -import { Construct } from '@aws-cdk/cdk'; -import { BaseNamespaceProps, INamespace, NamespaceBase, NamespaceType } from './namespace'; +import { Construct, Resource } from '@aws-cdk/cdk'; +import { BaseNamespaceProps, INamespace, NamespaceType } from './namespace'; import { BaseServiceProps, Service } from './service'; import { CfnHttpNamespace } from './servicediscovery.generated'; export interface HttpNamespaceProps extends BaseNamespaceProps {} +export interface IHttpNamespace extends INamespace { } +export interface HttpNamespaceAttributes { + /** + * A name for the Namespace. + */ + readonly namespaceName: string; -export interface IHttpNamespace extends INamespace { /** - * The Amazon Resource Name (ARN) of the namespace, such as - * arn:aws:service-discovery:us-east-1:123456789012:http-namespace/http-namespace-a1bzhi. - * @attribute + * Namespace Id for the Namespace. */ - readonly httpNamespaceArn: string; + readonly namespaceId: string; /** - * The ID of the namespace. - * @attribute + * Namespace ARN for the Namespace. */ - readonly httpNamespaceId: string; + readonly namespaceArn: string; } /** * Define an HTTP Namespace */ -export class HttpNamespace extends NamespaceBase implements IHttpNamespace { +export class HttpNamespace extends Resource implements IHttpNamespace { + + public static fromHttpNamespaceAttributes(scope: Construct, id: string, attrs: HttpNamespaceAttributes): IHttpNamespace { + class Import extends Resource implements IHttpNamespace { + public namespaceName = attrs.namespaceName; + public namespaceId = attrs.namespaceId; + public namespaceArn = attrs.namespaceArn; + public type = NamespaceType.Http; + } + return new Import(scope, id); + } + /** * A name for the namespace. */ @@ -58,7 +71,13 @@ export class HttpNamespace extends NamespaceBase implements IHttpNamespace { this.type = NamespaceType.Http; } + /** @attribute */ public get httpNamespaceArn() { return this.namespaceArn; } + + /** @attribute */ + public get httpNamespaceName() { return this.namespaceName; } + + /** @attribute */ public get httpNamespaceId() { return this.namespaceId; } /** diff --git a/packages/@aws-cdk/aws-servicediscovery/lib/instance.ts b/packages/@aws-cdk/aws-servicediscovery/lib/instance.ts index 8e8f7e05ba406..a694121c179f1 100644 --- a/packages/@aws-cdk/aws-servicediscovery/lib/instance.ts +++ b/packages/@aws-cdk/aws-servicediscovery/lib/instance.ts @@ -1,9 +1,10 @@ -import cdk = require('@aws-cdk/cdk'); +import { IResource, Resource } from '@aws-cdk/cdk'; import { IService } from './service'; -export interface IInstance extends cdk.IConstruct { +export interface IInstance extends IResource { /** * The id of the instance resource + * @attribute */ readonly instanceId: string; @@ -33,7 +34,7 @@ export interface BaseInstanceProps { readonly customAttributes?: { [key: string]: string }; } -export abstract class InstanceBase extends cdk.Construct implements IInstance { +export abstract class InstanceBase extends Resource implements IInstance { /** * The Id of the instance */ diff --git a/packages/@aws-cdk/aws-servicediscovery/lib/ip-instance.ts b/packages/@aws-cdk/aws-servicediscovery/lib/ip-instance.ts index de8eb89130783..85bac26a97f14 100644 --- a/packages/@aws-cdk/aws-servicediscovery/lib/ip-instance.ts +++ b/packages/@aws-cdk/aws-servicediscovery/lib/ip-instance.ts @@ -43,7 +43,7 @@ export interface IpInstanceProps extends IpInstanceBaseProps { readonly service: IService; } -/* +/** * Instance that is accessible using an IP address. * * @resource AWS::ServiceDiscovery::Instance diff --git a/packages/@aws-cdk/aws-servicediscovery/lib/namespace.ts b/packages/@aws-cdk/aws-servicediscovery/lib/namespace.ts index 7f707a2b37051..36126d0cadda1 100644 --- a/packages/@aws-cdk/aws-servicediscovery/lib/namespace.ts +++ b/packages/@aws-cdk/aws-servicediscovery/lib/namespace.ts @@ -1,18 +1,21 @@ -import { CfnOutput, Construct, IResource, Resource } from '@aws-cdk/cdk'; +import { IResource } from '@aws-cdk/cdk'; export interface INamespace extends IResource { /** * A name for the Namespace. + * @attribute */ readonly namespaceName: string; /** * Namespace Id for the Namespace. + * @attribute */ readonly namespaceId: string; /** * Namespace ARN for the Namespace. + * @attribute */ readonly namespaceArn: string; @@ -20,11 +23,6 @@ export interface INamespace extends IResource { * Type of Namespace */ readonly type: NamespaceType; - - /** - * Export the namespace properties - */ - export(): NamespaceImportProps; } export interface BaseNamespaceProps { @@ -41,7 +39,7 @@ export interface BaseNamespaceProps { readonly description?: string; } -export interface NamespaceImportProps { +export interface NamespaceAttributes { /** * A name for the Namespace. */ @@ -81,54 +79,3 @@ export enum NamespaceType { */ DnsPublic = "DNS_PUBLIC", } - -export abstract class NamespaceBase extends Resource implements INamespace { - public abstract readonly namespaceId: string; - public abstract readonly namespaceArn: string; - public abstract readonly namespaceName: string; - public abstract readonly type: NamespaceType; - - public export(): NamespaceImportProps { - return { - namespaceName: new CfnOutput(this, 'NamespaceName', { value: this.namespaceArn }).makeImportValue().toString(), - namespaceArn: new CfnOutput(this, 'NamespaceArn', { value: this.namespaceArn }).makeImportValue().toString(), - namespaceId: new CfnOutput(this, 'NamespaceId', { value: this.namespaceId }).makeImportValue().toString(), - type: this.type, - }; - } -} - -// The class below exists purely so that users can still type Namespace.import(). -// It does not make sense to have HttpNamespace.import({ ..., type: NamespaceType.PublicDns }), -// but at the same time ecs.Cluster wants a type-generic export()/import(). Hence, we put -// it in Namespace. - -/** - * Static Namespace class - */ -export class Namespace { - /** - * Import a namespace - */ - public static import(scope: Construct, id: string, props: NamespaceImportProps): INamespace { - return new ImportedNamespace(scope, id, props); - } - - private constructor() { - } -} - -class ImportedNamespace extends NamespaceBase { - public namespaceId: string; - public namespaceArn: string; - public namespaceName: string; - public type: NamespaceType; - - constructor(scope: Construct, id: string, props: NamespaceImportProps) { - super(scope, id); - this.namespaceId = props.namespaceId; - this.namespaceArn = props.namespaceArn; - this.namespaceName = props.namespaceName; - this.type = props.type; - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicediscovery/lib/non-ip-instance.ts b/packages/@aws-cdk/aws-servicediscovery/lib/non-ip-instance.ts index 8e1ad35314e7d..8d35101900139 100644 --- a/packages/@aws-cdk/aws-servicediscovery/lib/non-ip-instance.ts +++ b/packages/@aws-cdk/aws-servicediscovery/lib/non-ip-instance.ts @@ -18,7 +18,7 @@ export interface NonIpInstanceProps extends NonIpInstanceBaseProps { readonly service: IService; } -/* +/** * Instance accessible using values other than an IP address or a domain name (CNAME). * Specify the other values in Custom attributes. * diff --git a/packages/@aws-cdk/aws-servicediscovery/lib/private-dns-namespace.ts b/packages/@aws-cdk/aws-servicediscovery/lib/private-dns-namespace.ts index a75a46629fb1f..180ab2de89784 100644 --- a/packages/@aws-cdk/aws-servicediscovery/lib/private-dns-namespace.ts +++ b/packages/@aws-cdk/aws-servicediscovery/lib/private-dns-namespace.ts @@ -1,6 +1,6 @@ import ec2 = require('@aws-cdk/aws-ec2'); -import { Construct } from '@aws-cdk/cdk'; -import { BaseNamespaceProps, INamespace, NamespaceBase, NamespaceType } from './namespace'; +import { Construct, Resource } from '@aws-cdk/cdk'; +import { BaseNamespaceProps, INamespace, NamespaceType } from './namespace'; import { DnsServiceProps, Service } from './service'; import { CfnPrivateDnsNamespace} from './servicediscovery.generated'; @@ -8,27 +8,43 @@ export interface PrivateDnsNamespaceProps extends BaseNamespaceProps { /** * The Amazon VPC that you want to associate the namespace with. */ - readonly vpc: ec2.IVpcNetwork; + readonly vpc: ec2.IVpc; } -export interface IPrivateDnsNamespace extends INamespace { +export interface IPrivateDnsNamespace extends INamespace { } + +export interface PrivateDnsNamespaceAttributes { /** - * The ID of the private namespace. - * @attribute + * A name for the Namespace. */ - readonly privateDnsNamespaceId: string; + readonly namespaceName: string; /** - * The Amazon Resource Name (ARN) of the private namespace. - * @attribute + * Namespace Id for the Namespace. */ - readonly privateDnsNamespaceArn: string; + readonly namespaceId: string; + + /** + * Namespace ARN for the Namespace. + */ + readonly namespaceArn: string; } /** * Define a Service Discovery HTTP Namespace */ -export class PrivateDnsNamespace extends NamespaceBase implements IPrivateDnsNamespace { +export class PrivateDnsNamespace extends Resource implements IPrivateDnsNamespace { + + public static fromPrivateDnsNamespaceAttributes(scope: Construct, id: string, attrs: PrivateDnsNamespaceAttributes): IPrivateDnsNamespace { + class Import extends Resource implements IPrivateDnsNamespace { + public namespaceName = attrs.namespaceName; + public namespaceId = attrs.namespaceId; + public namespaceArn = attrs.namespaceArn; + public type = NamespaceType.DnsPrivate; + } + return new Import(scope, id); + } + /** * The name of the PrivateDnsNamespace. */ @@ -67,7 +83,13 @@ export class PrivateDnsNamespace extends NamespaceBase implements IPrivateDnsNam this.type = NamespaceType.DnsPrivate; } + /** @attribute */ public get privateDnsNamespaceArn() { return this.namespaceArn; } + + /** @attribute */ + public get privateDnsNamespaceName() { return this.namespaceName; } + + /** @attribute */ public get privateDnsNamespaceId() { return this.namespaceId; } /** diff --git a/packages/@aws-cdk/aws-servicediscovery/lib/public-dns-namespace.ts b/packages/@aws-cdk/aws-servicediscovery/lib/public-dns-namespace.ts index 70e6b86a2a058..04f98a8bc88e8 100644 --- a/packages/@aws-cdk/aws-servicediscovery/lib/public-dns-namespace.ts +++ b/packages/@aws-cdk/aws-servicediscovery/lib/public-dns-namespace.ts @@ -1,28 +1,42 @@ -import { Construct } from '@aws-cdk/cdk'; -import { BaseNamespaceProps, INamespace, NamespaceBase, NamespaceType } from './namespace'; +import { Construct, Resource } from '@aws-cdk/cdk'; +import { BaseNamespaceProps, INamespace, NamespaceType } from './namespace'; import { DnsServiceProps, Service } from './service'; import { CfnPublicDnsNamespace} from './servicediscovery.generated'; -// tslint:disable:no-empty-interface export interface PublicDnsNamespaceProps extends BaseNamespaceProps {} +export interface IPublicDnsNamespace extends INamespace { } +export interface PublicDnsNamespaceAttributes { + /** + * A name for the Namespace. + */ + readonly namespaceName: string; -export interface IPublicDnsNamespace extends INamespace { /** - * The ID of the public namespace. - * @attribute + * Namespace Id for the Namespace. */ - readonly publicDnsNamespaceId: string; + readonly namespaceId: string; /** - * The Amazon Resource Name (ARN) of the public namespace. - * @attribute + * Namespace ARN for the Namespace. */ - readonly publicDnsNamespaceArn: string; -} + readonly namespaceArn: string; + } + /** * Define a Public DNS Namespace */ -export class PublicDnsNamespace extends NamespaceBase implements IPublicDnsNamespace { +export class PublicDnsNamespace extends Resource implements IPublicDnsNamespace { + + public static fromPublicDnsNamespaceAttributes(scope: Construct, id: string, attrs: PublicDnsNamespaceAttributes): IPublicDnsNamespace { + class Import extends Resource implements IPublicDnsNamespace { + public namespaceName = attrs.namespaceName; + public namespaceId = attrs.namespaceId; + public namespaceArn = attrs.namespaceArn; + public type = NamespaceType.DnsPublic; + } + return new Import(scope, id); + } + /** * A name for the namespace. */ @@ -57,7 +71,13 @@ export class PublicDnsNamespace extends NamespaceBase implements IPublicDnsNames this.type = NamespaceType.DnsPublic; } + /** @attribute */ public get publicDnsNamespaceArn() { return this.namespaceArn; } + + /** @attribute */ + public get publicDnsNamespaceName() { return this.namespaceName; } + + /** @attribute */ public get publicDnsNamespaceId() { return this.namespaceId; } /** diff --git a/packages/@aws-cdk/aws-servicediscovery/package.json b/packages/@aws-cdk/aws-servicediscovery/package.json index b556e5d02bc7f..c2fb0139d1792 100644 --- a/packages/@aws-cdk/aws-servicediscovery/package.json +++ b/packages/@aws-cdk/aws-servicediscovery/package.json @@ -79,23 +79,5 @@ }, "engines": { "node": ">= 8.10.0" - }, - "awslint": { - "exclude": [ - "from-attributes:fromPrivateDnsNamespaceAttributes", - "from-arn:Service.fromServiceArn", - "from-arn:HttpNamespace.fromHttpNamespaceArn", - "from-attributes:fromHttpNamespaceAttributes", - "from-method:@aws-cdk/aws-servicediscovery.PrivateDnsNamespace", - "from-arn:PrivateDnsNamespace.fromPrivateDnsNamespaceArn", - "from-method:@aws-cdk/aws-servicediscovery.HttpNamespace", - "from-method:@aws-cdk/aws-servicediscovery.PublicDnsNamespace", - "from-arn:PublicDnsNamespace.fromPublicDnsNamespaceArn", - "from-attributes:fromPublicDnsNamespaceAttributes", - "from-method:@aws-cdk/aws-servicediscovery.Service", - "from-attributes:@aws-cdk/aws-servicediscovery.HttpNamespace.fromHttpNamespaceAttributes", - "from-attributes:@aws-cdk/aws-servicediscovery.PrivateDnsNamespace.fromPrivateDnsNamespaceAttributes", - "from-attributes:@aws-cdk/aws-servicediscovery.PublicDnsNamespace.fromPublicDnsNamespaceAttributes" - ] } } diff --git a/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-private-dns-namespace.lit.ts b/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-private-dns-namespace.lit.ts index 657328517db17..94de74f9e2dec 100644 --- a/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-private-dns-namespace.lit.ts +++ b/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-private-dns-namespace.lit.ts @@ -6,7 +6,7 @@ import servicediscovery = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-servicediscovery-integ'); -const vpc = new ec2.VpcNetwork(stack, 'Vpc', { maxAZs: 2 }); +const vpc = new ec2.Vpc(stack, 'Vpc', { maxAZs: 2 }); const namespace = new servicediscovery.PrivateDnsNamespace(stack, 'Namespace', { name: 'boobar.com', diff --git a/packages/@aws-cdk/aws-servicediscovery/test/test.instance.ts b/packages/@aws-cdk/aws-servicediscovery/test/test.instance.ts index 5f0fa3951eb68..fbaacf41587d4 100644 --- a/packages/@aws-cdk/aws-servicediscovery/test/test.instance.ts +++ b/packages/@aws-cdk/aws-servicediscovery/test/test.instance.ts @@ -84,7 +84,7 @@ export = { 'IpInstance for service in PrivateDnsNamespace'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc'); + const vpc = new ec2.Vpc(stack, 'MyVpc'); const namespace = new servicediscovery.PrivateDnsNamespace(stack, 'MyNamespace', { name: 'public', @@ -240,7 +240,7 @@ export = { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVPC'); + const vpc = new ec2.Vpc(stack, 'MyVPC'); const alb = new elbv2.ApplicationLoadBalancer(stack, 'MyALB', { vpc }); const namespace = new servicediscovery.PrivateDnsNamespace(stack, 'MyNamespace', { @@ -291,7 +291,7 @@ export = { namespace, }); - const vpc = new ec2.VpcNetwork(stack, 'MyVPC'); + const vpc = new ec2.Vpc(stack, 'MyVPC'); const alb = new elbv2.ApplicationLoadBalancer(stack, 'MyALB', { vpc }); // THEN @@ -315,7 +315,7 @@ export = { routingPolicy: servicediscovery.RoutingPolicy.Multivalue }); - const vpc = new ec2.VpcNetwork(stack, 'MyVPC'); + const vpc = new ec2.Vpc(stack, 'MyVPC'); const alb = new elbv2.ApplicationLoadBalancer(stack, 'MyALB', { vpc }); // THEN diff --git a/packages/@aws-cdk/aws-servicediscovery/test/test.namespace.ts b/packages/@aws-cdk/aws-servicediscovery/test/test.namespace.ts index 4807f46a22061..e261c48554087 100644 --- a/packages/@aws-cdk/aws-servicediscovery/test/test.namespace.ts +++ b/packages/@aws-cdk/aws-servicediscovery/test/test.namespace.ts @@ -49,7 +49,7 @@ export = { 'Private DNS namespace'(test: Test) { const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc'); + const vpc = new ec2.Vpc(stack, 'MyVpc'); new servicediscovery.PrivateDnsNamespace(stack, 'MyNamespace', { name: 'foobar.com', diff --git a/packages/@aws-cdk/aws-servicediscovery/test/test.service.ts b/packages/@aws-cdk/aws-servicediscovery/test/test.service.ts index dad41acdabea5..d371d2a3ec47f 100644 --- a/packages/@aws-cdk/aws-servicediscovery/test/test.service.ts +++ b/packages/@aws-cdk/aws-servicediscovery/test/test.service.ts @@ -299,7 +299,7 @@ export = { 'Throws when specifying healthCheckConfig on PrivateDnsNamespace'(test: Test) { const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc'); + const vpc = new ec2.Vpc(stack, 'MyVpc'); const namespace = new servicediscovery.PrivateDnsNamespace(stack, 'MyNamespace', { name: 'name', @@ -405,7 +405,7 @@ export = { 'Service for Private DNS namespace'(test: Test) { // GIVEN const stack = new cdk.Stack(); - const vpc = new ec2.VpcNetwork(stack, 'MyVpc'); + const vpc = new ec2.Vpc(stack, 'MyVpc'); const namespace = new servicediscovery.PrivateDnsNamespace(stack, 'MyNamespace', { name: 'private', diff --git a/packages/@aws-cdk/aws-ses/README.md b/packages/@aws-cdk/aws-ses/README.md index 7dc46f9b29c8c..8dc4845ea2b80 100644 --- a/packages/@aws-cdk/aws-ses/README.md +++ b/packages/@aws-cdk/aws-ses/README.md @@ -37,38 +37,6 @@ new ses.ReceiptRuleSet(this, 'RuleSet', { This will add a rule at the top of the rule set with a Lambda action that stops processing messages that have at least one spam indicator. See [Lambda Function Examples](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-action-lambda-example-functions.html). -### Import and export receipt rule set and receipt rules -Receipt rule sets and receipt rules can be exported: - -```ts -const ruleSet = new ReceiptRuleSet(this, 'RuleSet'); -const rule = ruleSet.addRule(this, 'Rule', { - recipients: ['hello@mydomain.com'] -}); - -const ruleSetRef = ruleSet.export(); -const ruleRef = rule.export(); -``` - -And imported: -```ts -const importedRuleSet = ses.ReceiptRuleSet.import(this, 'ImportedRuleSet', ruleSetRef); - -const importedRule = ses.ReceiptRule.import(this, 'ImportedRule', ruleRef); - -const otherRule = ses.ReceiptRule.import(this, 'OtherRule', { - name: 'other-rule' -}); - -importedRuleSet.addRule('New', { // This rule is added after the imported rule - after: importedRule, - recipients: ['mydomain.com'] -}); - -importedRuleSet.addRule('Extra', { // Added after the 'New' rule - recipients: ['extra.com'] -}); -``` ### Receipt filter Create a receipt filter: diff --git a/packages/@aws-cdk/aws-ses/lib/receipt-rule-action.ts b/packages/@aws-cdk/aws-ses/lib/receipt-rule-action.ts index dc6058262c35c..e84f2eb64216d 100644 --- a/packages/@aws-cdk/aws-ses/lib/receipt-rule-action.ts +++ b/packages/@aws-cdk/aws-ses/lib/receipt-rule-action.ts @@ -309,7 +309,7 @@ export interface ReceiptRuleS3ActionProps { * * @default no encryption */ - readonly kmsKey?: kms.IEncryptionKey; + readonly kmsKey?: kms.IKey; /** * The key prefix of the S3 bucket. diff --git a/packages/@aws-cdk/aws-ses/lib/receipt-rule-set.ts b/packages/@aws-cdk/aws-ses/lib/receipt-rule-set.ts index f928e6bfe98fa..395e37746d8a0 100644 --- a/packages/@aws-cdk/aws-ses/lib/receipt-rule-set.ts +++ b/packages/@aws-cdk/aws-ses/lib/receipt-rule-set.ts @@ -1,4 +1,4 @@ -import { CfnOutput, Construct, IResource, Resource } from '@aws-cdk/cdk'; +import { Construct, IResource, Resource } from '@aws-cdk/cdk'; import { DropSpamReceiptRule, ReceiptRule, ReceiptRuleOptions } from './receipt-rule'; import { CfnReceiptRuleSet } from './ses.generated'; @@ -17,11 +17,6 @@ export interface IReceiptRuleSet extends IResource { * the last added rule unless `after` is specified. */ addRule(id: string, options?: ReceiptRuleOptions): ReceiptRule; - - /** - * Exports this receipt rule set from the stack. - */ - export(): ReceiptRuleSetAttributes; } /** @@ -72,8 +67,6 @@ abstract class ReceiptRuleSetBase extends Resource implements IReceiptRuleSet { return this.lastAddedRule; } - public abstract export(): ReceiptRuleSetAttributes; - /** * Adds a drop spam rule */ @@ -95,9 +88,6 @@ export class ReceiptRuleSet extends ReceiptRuleSetBase { public static fromReceiptRuleSetName(scope: Construct, id: string, receiptRuleSetName: string): IReceiptRuleSet { class Import extends ReceiptRuleSetBase implements IReceiptRuleSet { public readonly receiptRuleSetName = receiptRuleSetName; - public export(): ReceiptRuleSetAttributes { - return { receiptRuleSetName }; - } } return new Import(scope, id); } @@ -122,23 +112,4 @@ export class ReceiptRuleSet extends ReceiptRuleSetBase { } } } - - /** - * Exports this receipt rule set from the stack. - */ - public export(): ReceiptRuleSetAttributes { - return { - receiptRuleSetName: new CfnOutput(this, 'ReceiptRuleSetName', { value: this.receiptRuleSetName }).makeImportValue().toString() - }; - } -} - -/** - * Construction properties for an ImportedReceiptRuleSet. - */ -export interface ReceiptRuleSetAttributes { - /** - * The receipt rule set name. - */ - readonly receiptRuleSetName: string; } diff --git a/packages/@aws-cdk/aws-ses/lib/receipt-rule.ts b/packages/@aws-cdk/aws-ses/lib/receipt-rule.ts index 7f67d844d15cd..06ce393aa93a1 100644 --- a/packages/@aws-cdk/aws-ses/lib/receipt-rule.ts +++ b/packages/@aws-cdk/aws-ses/lib/receipt-rule.ts @@ -1,5 +1,5 @@ import lambda = require('@aws-cdk/aws-lambda'); -import { CfnOutput, Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; +import { Construct, IResource, Resource, Token } from '@aws-cdk/cdk'; import { IReceiptRuleAction, LambdaInvocationType, ReceiptRuleActionProps, ReceiptRuleLambdaAction } from './receipt-rule-action'; import { IReceiptRuleSet } from './receipt-rule-set'; import { CfnReceiptRule } from './ses.generated'; @@ -13,11 +13,6 @@ export interface IReceiptRule extends IResource { * @attribute */ readonly receiptRuleName: string; - - /** - * Exports this receipt rule from the stack. - */ - export(): ReceiptRuleAttributes; } /** @@ -107,9 +102,6 @@ export class ReceiptRule extends Resource implements IReceiptRule { public static fromReceiptRuleName(scope: Construct, id: string, receiptRuleName: string): IReceiptRule { class Import extends Construct implements IReceiptRule { public readonly receiptRuleName = receiptRuleName; - public export(): ReceiptRuleAttributes { - return { receiptRuleName }; - } } return new Import(scope, id); } @@ -149,15 +141,6 @@ export class ReceiptRule extends Resource implements IReceiptRule { this.renderedActions.push(renderedAction); } - /** - * Exports this receipt rule from the stack. - */ - public export(): ReceiptRuleAttributes { - return { - receiptRuleName: new CfnOutput(this, 'ReceiptRuleName', { value: this.receiptRuleName }).makeImportValue().toString() - }; - } - private getRenderedActions() { if (this.renderedActions.length === 0) { return undefined; @@ -167,13 +150,6 @@ export class ReceiptRule extends Resource implements IReceiptRule { } } -export interface ReceiptRuleAttributes { - /** - * The name of the receipt rule. - */ - readonly receiptRuleName: string; -} - // tslint:disable-next-line:no-empty-interface export interface DropSpamReceiptRuleProps extends ReceiptRuleProps { diff --git a/packages/@aws-cdk/aws-ses/test/integ.receipt.ts b/packages/@aws-cdk/aws-ses/test/integ.receipt.ts index 2994acd4e2f60..fab80a2dafed2 100644 --- a/packages/@aws-cdk/aws-ses/test/integ.receipt.ts +++ b/packages/@aws-cdk/aws-ses/test/integ.receipt.ts @@ -19,7 +19,7 @@ const fn = new lambda.Function(stack, 'Function', { const bucket = new s3.Bucket(stack, 'Bucket'); -const kmsKey = new kms.EncryptionKey(stack, 'Key'); +const kmsKey = new kms.Key(stack, 'Key'); const ruleSet = new ses.ReceiptRuleSet(stack, 'RuleSet', { dropSpam: true diff --git a/packages/@aws-cdk/aws-ses/test/test.receipt-rule-action.ts b/packages/@aws-cdk/aws-ses/test/test.receipt-rule-action.ts index 0d92ac3a8420f..fe3591bedc6de 100644 --- a/packages/@aws-cdk/aws-ses/test/test.receipt-rule-action.ts +++ b/packages/@aws-cdk/aws-ses/test/test.receipt-rule-action.ts @@ -201,7 +201,7 @@ export = { const bucket = new s3.Bucket(stack, 'Bucket'); - const kmsKey = new kms.EncryptionKey(stack, 'Key'); + const kmsKey = new kms.Key(stack, 'Key'); // WHEN new ReceiptRuleSet(stack, 'RuleSet', { diff --git a/packages/@aws-cdk/aws-ses/test/test.receipt-rule-set.ts b/packages/@aws-cdk/aws-ses/test/test.receipt-rule-set.ts index 92c91a123b24e..56707a519b810 100644 --- a/packages/@aws-cdk/aws-ses/test/test.receipt-rule-set.ts +++ b/packages/@aws-cdk/aws-ses/test/test.receipt-rule-set.ts @@ -58,36 +58,6 @@ export = { test.done(); }, - 'export receipt rule set'(test: Test) { - // GIVEN - const stack = new Stack(); - const receiptRuleSet = new ReceiptRuleSet(stack, 'RuleSet'); - - // WHEN - receiptRuleSet.export(); - - // THEN - expect(stack).toMatch({ - "Resources": { - "RuleSetE30C6C48": { - "Type": "AWS::SES::ReceiptRuleSet" - } - }, - "Outputs": { - "RuleSetReceiptRuleSetNameBA4266DD": { - "Value": { - "Ref": "RuleSetE30C6C48" - }, - "Export": { - "Name": "Stack:RuleSetReceiptRuleSetNameBA4266DD" - } - } - } - }); - - test.done(); - }, - 'import receipt rule set'(test: Test) { // GIVEN const stack = new Stack(); diff --git a/packages/@aws-cdk/aws-ses/test/test.receipt-rule.ts b/packages/@aws-cdk/aws-ses/test/test.receipt-rule.ts index 9f899df31a311..38854b1a2d725 100644 --- a/packages/@aws-cdk/aws-ses/test/test.receipt-rule.ts +++ b/packages/@aws-cdk/aws-ses/test/test.receipt-rule.ts @@ -70,48 +70,6 @@ export = { test.done(); }, - 'export receipt rule'(test: Test) { - // GIVEN - const stack = new Stack(); - const receiptRuleSet = new ReceiptRuleSet(stack, 'RuleSet'); - const receiptRule = receiptRuleSet.addRule('Rule'); - - // WHEN - receiptRule.export(); - - // THEN - expect(stack).toMatch({ - "Resources": { - "RuleSetE30C6C48": { - "Type": "AWS::SES::ReceiptRuleSet" - }, - "RuleSetRule0B1D6BCA": { - "Type": "AWS::SES::ReceiptRule", - "Properties": { - "Rule": { - "Enabled": true - }, - "RuleSetName": { - "Ref": "RuleSetE30C6C48" - } - } - } - }, - "Outputs": { - "RuleSetRuleReceiptRuleName5620D98F": { - "Value": { - "Ref": "RuleSetRule0B1D6BCA" - }, - "Export": { - "Name": "Stack:RuleSetRuleReceiptRuleName5620D98F" - } - } - } - }); - - test.done(); - }, - 'import receipt rule'(test: Test) { // GIVEN const stack = new Stack(); diff --git a/packages/@aws-cdk/aws-sns/lib/topic-base.ts b/packages/@aws-cdk/aws-sns/lib/topic-base.ts index 45f02f6707c65..8028540237ee0 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic-base.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic-base.ts @@ -25,11 +25,6 @@ export interface ITopic extends */ readonly topicName: string; - /** - * Export this Topic - */ - export(): TopicAttributes; - /** * Subscribe some endpoint to this topic */ @@ -109,11 +104,6 @@ export abstract class TopicBase extends Resource implements ITopic { /** Buckets permitted to send notifications to this topic */ private readonly notifyingBuckets = new Set(); - /** - * Export this Topic - */ - public abstract export(): TopicAttributes; - /** * Subscribe some endpoint to this topic */ @@ -309,14 +299,6 @@ export abstract class TopicBase extends Resource implements ITopic { } } -/** - * Reference to an external topic. - */ -export interface TopicAttributes { - readonly topicArn: string; - readonly topicName: string; -} - /** * Options for email subscriptions. */ diff --git a/packages/@aws-cdk/aws-sns/lib/topic.ts b/packages/@aws-cdk/aws-sns/lib/topic.ts index 88f3f309cda11..6ee2d498daa80 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic.ts @@ -1,6 +1,6 @@ -import { CfnOutput, Construct } from '@aws-cdk/cdk'; +import { Construct } from '@aws-cdk/cdk'; import { CfnTopic } from './sns.generated'; -import { ITopic, TopicAttributes, TopicBase } from './topic-base'; +import { ITopic, TopicBase } from './topic-base'; /** * Properties for a new SNS topic @@ -31,18 +31,13 @@ export interface TopicProps { export class Topic extends TopicBase { public static fromTopicArn(scope: Construct, id: string, topicArn: string): ITopic { - // arn:aws:sns:region:account-id:topicname - return Topic.fromTopicAttributes(scope, id, { - topicArn, - topicName: scope.node.stack.parseArn(topicArn).resource - }); - } + class Import extends TopicBase { + public readonly topicArn = topicArn; + public readonly topicName = scope.node.stack.parseArn(topicArn).resource; + protected autoCreatePolicy: boolean = false; + } - /** - * Import a Topic defined elsewhere - */ - public static fromTopicAttributes(scope: Construct, id: string, attrs: TopicAttributes): ITopic { - return new ImportedTopic(scope, id, attrs); + return new Import(scope, id); } public readonly topicArn: string; @@ -61,34 +56,4 @@ export class Topic extends TopicBase { this.topicArn = resource.ref; this.topicName = resource.topicName; } - - /** - * Export this Topic - */ - public export(): TopicAttributes { - return { - topicArn: new CfnOutput(this, 'TopicArn', { value: this.topicArn }).makeImportValue().toString(), - topicName: new CfnOutput(this, 'TopicName', { value: this.topicName }).makeImportValue().toString(), - }; - } -} - -/** - * An imported topic - */ -class ImportedTopic extends TopicBase { - public readonly topicArn: string; - public readonly topicName: string; - - protected autoCreatePolicy: boolean = false; - - constructor(scope: Construct, id: string, private readonly props: TopicAttributes) { - super(scope, id); - this.topicArn = props.topicArn; - this.topicName = props.topicName; - } - - public export(): TopicAttributes { - return this.props; - } } diff --git a/packages/@aws-cdk/aws-sns/test/test.sns.ts b/packages/@aws-cdk/aws-sns/test/test.sns.ts index 4f8d9c0e829c6..8c330d9f1215c 100644 --- a/packages/@aws-cdk/aws-sns/test/test.sns.ts +++ b/packages/@aws-cdk/aws-sns/test/test.sns.ts @@ -683,42 +683,18 @@ export = { test.done(); }, - 'export/import'(test: Test) { + 'fromTopicArn'(test: Test) { // GIVEN - const stack1 = new cdk.Stack(); - const topic = new sns.Topic(stack1, 'Topic'); - const stack2 = new cdk.Stack(); const queue = new sqs.Queue(stack2, 'Queue'); // WHEN - const ref = topic.export(); - const imported = sns.Topic.fromTopicAttributes(stack2, 'Imported', ref); + const imported = sns.Topic.fromTopicArn(stack2, 'Imported', 'arn:aws:sns:*:123456789012:my_corporate_topic'); imported.subscribeQueue(queue); // THEN - expect(stack2).to(haveResource('AWS::SNS::Subscription', { - "TopicArn": { "Fn::ImportValue": "Stack:TopicTopicArnB66B79C2" }, - })); - expect(stack2).to(haveResource('AWS::SQS::QueuePolicy', { - PolicyDocument: { - Version: '2012-10-17', - Statement: [ - { - "Action": "sqs:SendMessage", - "Condition": { - "ArnEquals": { - "aws:SourceArn": stack2.node.resolve(imported.topicArn) - } - }, - "Principal": { "Service": "sns.amazonaws.com" }, - "Resource": stack2.node.resolve(queue.queueArn), - "Effect": "Allow", - } - ], - }, - })); - + test.deepEqual(imported.topicName, 'my_corporate_topic'); + test.deepEqual(imported.topicArn, 'arn:aws:sns:*:123456789012:my_corporate_topic'); test.done(); }, diff --git a/packages/@aws-cdk/aws-sqs/lib/queue-base.ts b/packages/@aws-cdk/aws-sqs/lib/queue-base.ts index a0da9686916a1..0e1b0f308eada 100644 --- a/packages/@aws-cdk/aws-sqs/lib/queue-base.ts +++ b/packages/@aws-cdk/aws-sqs/lib/queue-base.ts @@ -27,12 +27,7 @@ export interface IQueue extends IResource, s3n.IBucketNotificationDestination, a /** * If this queue is server-side encrypted, this is the KMS encryption key. */ - readonly encryptionMasterKey?: kms.IEncryptionKey; - - /** - * Export a queue - */ - export(): QueueAttributes; + readonly encryptionMasterKey?: kms.IKey; /** * Adds a statement to the IAM resource policy associated with this queue. @@ -120,7 +115,7 @@ export abstract class QueueBase extends Resource implements IQueue { /** * If this queue is server-side encrypted, this is the KMS encryption key. */ - public abstract readonly encryptionMasterKey?: kms.IEncryptionKey; + public abstract readonly encryptionMasterKey?: kms.IKey; /** * Controls automatic creation of policy objects. @@ -136,11 +131,6 @@ export abstract class QueueBase extends Resource implements IQueue { */ private readonly notifyingBuckets = new Set(); - /** - * Export a queue - */ - public abstract export(): QueueAttributes; - /** * Adds a statement to the IAM resource policy associated with this queue. * diff --git a/packages/@aws-cdk/aws-sqs/lib/queue.ts b/packages/@aws-cdk/aws-sqs/lib/queue.ts index caaa2fd101b1f..983cecec85e21 100644 --- a/packages/@aws-cdk/aws-sqs/lib/queue.ts +++ b/packages/@aws-cdk/aws-sqs/lib/queue.ts @@ -1,5 +1,5 @@ import kms = require('@aws-cdk/aws-kms'); -import { CfnOutput, Construct } from '@aws-cdk/cdk'; +import { Construct } from '@aws-cdk/cdk'; import { IQueue, QueueAttributes, QueueBase } from './queue-base'; import { CfnQueue } from './sqs.generated'; import { validateProps } from './validate-props'; @@ -103,7 +103,7 @@ export interface QueueProps { * * @default If encryption is set to KMS and not specified, a key will be created. */ - readonly encryptionMasterKey?: kms.IEncryptionKey; + readonly encryptionMasterKey?: kms.IKey; /** * The length of time that Amazon SQS reuses a data key before calling KMS again. @@ -198,17 +198,10 @@ export class Queue extends QueueBase { public readonly queueUrl = queueUrl; public readonly queueName = queueName; public readonly encryptionMasterKey = attrs.keyArn - ? kms.EncryptionKey.import(this, 'Key', { keyArn: attrs.keyArn }) + ? kms.Key.fromKeyArn(this, 'Key', attrs.keyArn) : undefined; protected readonly autoCreatePolicy = false; - - /** - * Export a queue - */ - public export() { - return attrs; - } } return new Import(scope, id); @@ -232,7 +225,7 @@ export class Queue extends QueueBase { /** * If this queue is encrypted, this is the KMS key. */ - public readonly encryptionMasterKey?: kms.IEncryptionKey; + public readonly encryptionMasterKey?: kms.IKey; protected readonly autoCreatePolicy = true; @@ -266,7 +259,7 @@ export class Queue extends QueueBase { this.queueName = queue.queueName; this.queueUrl = queue.ref; - function _determineEncryptionProps(this: Queue): { encryptionProps: EncryptionProps, encryptionMasterKey?: kms.IEncryptionKey } { + function _determineEncryptionProps(this: Queue): { encryptionProps: EncryptionProps, encryptionMasterKey?: kms.IKey } { let encryption = props.encryption || QueueEncryption.Unencrypted; if (encryption !== QueueEncryption.Kms && props.encryptionMasterKey) { @@ -278,9 +271,7 @@ export class Queue extends QueueBase { } if (encryption === QueueEncryption.KmsManaged) { - const masterKey = kms.EncryptionKey.import(this, 'Key', { - keyArn: 'alias/aws/sqs' - }); + const masterKey = kms.Key.fromKeyArn(this, 'Key', 'alias/aws/sqs'); return { encryptionMasterKey: masterKey, @@ -292,7 +283,7 @@ export class Queue extends QueueBase { } if (encryption === QueueEncryption.Kms) { - const masterKey = props.encryptionMasterKey || new kms.EncryptionKey(this, 'Key', { + const masterKey = props.encryptionMasterKey || new kms.Key(this, 'Key', { description: `Created by ${this.node.path}` }); @@ -309,19 +300,6 @@ export class Queue extends QueueBase { } } - /** - * Export a queue - */ - public export(): QueueAttributes { - return { - queueArn: new CfnOutput(this, 'QueueArn', { value: this.queueArn }).makeImportValue().toString(), - queueUrl: new CfnOutput(this, 'QueueUrl', { value: this.queueUrl }).makeImportValue().toString(), - keyArn: this.encryptionMasterKey - ? new CfnOutput(this, 'KeyArn', { value: this.encryptionMasterKey.keyArn }).makeImportValue().toString() - : undefined - }; - } - /** * Look at the props, see if the FIFO props agree, and return the correct subset of props */ diff --git a/packages/@aws-cdk/aws-sqs/test/test.sqs.ts b/packages/@aws-cdk/aws-sqs/test/test.sqs.ts index ae1c6e35d517b..12b230a283a94 100644 --- a/packages/@aws-cdk/aws-sqs/test/test.sqs.ts +++ b/packages/@aws-cdk/aws-sqs/test/test.sqs.ts @@ -94,24 +94,17 @@ export = { 'exporting and importing works'(test: Test) { // GIVEN const stack = new Stack(); - const queue = new sqs.Queue(stack, 'Queue'); // WHEN - const ref = queue.export(); - const imports = sqs.Queue.fromQueueAttributes(stack, 'Imported', ref); + const imports = sqs.Queue.fromQueueArn(stack, 'Imported', 'arn:aws:sqs:us-east-1:123456789012:queue1'); // THEN // "import" returns an IQueue bound to `Fn::ImportValue`s. - test.deepEqual(stack.node.resolve(imports.queueArn), { 'Fn::ImportValue': 'Stack:QueueQueueArn8CF496D5' }); - test.deepEqual(stack.node.resolve(imports.queueUrl), { 'Fn::ImportValue': 'Stack:QueueQueueUrlC30FF916' }); - - // the exporting stack has Outputs for QueueARN and QueueURL - const outputs = SynthUtils.toCloudFormation(stack).Outputs; - // tslint:disable-next-line:max-line-length - test.deepEqual(outputs.QueueQueueArn8CF496D5, { Value: { 'Fn::GetAtt': [ 'Queue4A7E3555', 'Arn' ] }, Export: { Name: 'Stack:QueueQueueArn8CF496D5' } }); - test.deepEqual(outputs.QueueQueueUrlC30FF916, { Value: { Ref: 'Queue4A7E3555' }, Export: { Name: 'Stack:QueueQueueUrlC30FF916' } }); - + test.deepEqual(stack.node.resolve(imports.queueArn), 'arn:aws:sqs:us-east-1:123456789012:queue1'); + test.deepEqual(stack.node.resolve(imports.queueUrl), { 'Fn::Join': + [ '', [ 'https://sqs.', { Ref: 'AWS::Region' }, '.', { Ref: 'AWS::URLSuffix' }, '/', { Ref: 'AWS::AccountId' }, '/queue1' ] ] }); + test.deepEqual(stack.node.resolve(imports.queueName), 'queue1'); test.done(); }, @@ -192,7 +185,7 @@ export = { 'encryptionMasterKey can be set to a custom KMS key'(test: Test) { const stack = new Stack(); - const key = new kms.EncryptionKey(stack, 'CustomKey'); + const key = new kms.Key(stack, 'CustomKey'); const queue = new sqs.Queue(stack, 'Queue', { encryptionMasterKey: key }); test.same(queue.encryptionMasterKey, key); @@ -237,103 +230,6 @@ export = { }); test.done(); }, - - 'export should produce outputs the key arn and return import-values for these outputs': { - - 'with custom key'(test: Test) { - const stack = new Stack(); - - const customKey = new sqs.Queue(stack, 'QueueWithCustomKey', { encryption: sqs.QueueEncryption.Kms }); - - const exportCustom = customKey.export(); - - test.deepEqual(stack.node.resolve(exportCustom), { - queueArn: { 'Fn::ImportValue': 'Stack:QueueWithCustomKeyQueueArnD326BB9B' }, - queueUrl: { 'Fn::ImportValue': 'Stack:QueueWithCustomKeyQueueUrlF07DDC70' }, - keyArn: { 'Fn::ImportValue': 'Stack:QueueWithCustomKeyKeyArn537F6E42' } - }); - - test.deepEqual(SynthUtils.toCloudFormation(stack).Outputs, { - "QueueWithCustomKeyQueueArnD326BB9B": { - "Value": { - "Fn::GetAtt": [ - "QueueWithCustomKeyB3E22087", - "Arn" - ] - }, - "Export": { - "Name": "Stack:QueueWithCustomKeyQueueArnD326BB9B" - } - }, - "QueueWithCustomKeyQueueUrlF07DDC70": { - "Value": { - "Ref": "QueueWithCustomKeyB3E22087" - }, - "Export": { - "Name": "Stack:QueueWithCustomKeyQueueUrlF07DDC70" - } - }, - "QueueWithCustomKeyKeyArn537F6E42": { - "Value": { - "Fn::GetAtt": [ - "QueueWithCustomKeyD80425F1", - "Arn" - ] - }, - "Export": { - "Name": "Stack:QueueWithCustomKeyKeyArn537F6E42" - } - } - }); - test.done(); - }, - - 'with managed key'(test: Test) { - const stack = new Stack(); - - const managedKey = new sqs.Queue(stack, 'QueueWithManagedKey', { encryption: sqs.QueueEncryption.KmsManaged }); - - const exportManaged = managedKey.export(); - - test.deepEqual(stack.node.resolve(exportManaged), { - queueArn: { 'Fn::ImportValue': 'Stack:QueueWithManagedKeyQueueArn8798A14E' }, - queueUrl: { 'Fn::ImportValue': 'Stack:QueueWithManagedKeyQueueUrlD735C981' }, - keyArn: { 'Fn::ImportValue': 'Stack:QueueWithManagedKeyKeyArn9C42A85D' } - }); - - test.deepEqual(SynthUtils.toCloudFormation(stack).Outputs, { - "QueueWithManagedKeyQueueArn8798A14E": { - "Value": { - "Fn::GetAtt": [ - "QueueWithManagedKeyE1B747A1", - "Arn" - ] - }, - "Export": { - "Name": "Stack:QueueWithManagedKeyQueueArn8798A14E" - } - }, - "QueueWithManagedKeyQueueUrlD735C981": { - "Value": { - "Ref": "QueueWithManagedKeyE1B747A1" - }, - "Export": { - "Name": "Stack:QueueWithManagedKeyQueueUrlD735C981" - } - }, - "QueueWithManagedKeyKeyArn9C42A85D": { - "Value": "alias/aws/sqs", - "Export": { - "Name": "Stack:QueueWithManagedKeyKeyArn9C42A85D" - } - } - }); - - test.done(); - } - - } - }, 'bucket notifications': { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/run-ecs-task-base.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/run-ecs-task-base.ts index 9a5c773f86ce3..6a4544016cd07 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/run-ecs-task-base.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/run-ecs-task-base.ts @@ -96,7 +96,7 @@ export class EcsRunTaskBase implements ec2.IConnectable, sfn.IStepFunctionsTask } protected configureAwsVpcNetworking( - vpc: ec2.IVpcNetwork, + vpc: ec2.IVpc, assignPublicIp?: boolean, subnetSelection?: ec2.SubnetSelection, securityGroup?: ec2.ISecurityGroup) { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs-tasks.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs-tasks.test.ts index 4f02c420913e8..bfeb535a7d138 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs-tasks.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/ecs-tasks.test.ts @@ -7,13 +7,13 @@ import tasks = require('../lib'); import { JsonPath, NumberValue } from '../lib'; let stack: Stack; -let vpc: ec2.VpcNetwork; +let vpc: ec2.Vpc; let cluster: ecs.Cluster; beforeEach(() => { // GIVEN stack = new Stack(); - vpc = new ec2.VpcNetwork(stack, 'Vpc'); + vpc = new ec2.Vpc(stack, 'Vpc'); cluster = new ecs.Cluster(stack, 'Cluster', { vpc }); cluster.addCapacity('Capacity', { instanceType: new ec2.InstanceType('t3.medium') diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.ec2-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.ec2-task.ts index 4b1b07bb65f52..49d1a0d4dee9c 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.ec2-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.ec2-task.ts @@ -8,7 +8,7 @@ import tasks = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-ecs-integ2'); -const vpc = ec2.VpcNetwork.importFromContext(stack, 'Vpc', { +const vpc = ec2.Vpc.fromLookup(stack, 'Vpc', { isDefault: true }); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.fargate-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.fargate-task.ts index aa1f24764f604..320c278437ab6 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.fargate-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.fargate-task.ts @@ -8,7 +8,7 @@ import tasks = require('../lib'); const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-ecs-integ2'); -const vpc = ec2.VpcNetwork.importFromContext(stack, 'Vpc', { +const vpc = ec2.Vpc.fromLookup(stack, 'Vpc', { isDefault: true }); diff --git a/packages/decdk/examples/ecs.json b/packages/decdk/examples/ecs.json index da80045f8b21f..426df7464c7b7 100644 --- a/packages/decdk/examples/ecs.json +++ b/packages/decdk/examples/ecs.json @@ -2,7 +2,7 @@ "$schema": "../cdk.schema.json", "Resources": { "VPC": { - "Type": "@aws-cdk/aws-ec2.VpcNetwork", + "Type": "@aws-cdk/aws-ec2.Vpc", "Properties": { "maxAZs": 1 } diff --git a/packages/decdk/examples/pipeline.json b/packages/decdk/examples/pipeline.json index 3addb8fcf2478..a616e4a11d450 100644 --- a/packages/decdk/examples/pipeline.json +++ b/packages/decdk/examples/pipeline.json @@ -8,7 +8,7 @@ } }, "Key": { - "Type": "@aws-cdk/aws-kms.EncryptionKey" + "Type": "@aws-cdk/aws-kms.Key" }, "BuildProject": { "Type": "@aws-cdk/aws-codebuild.PipelineProject", diff --git a/packages/decdk/examples/vpc.json b/packages/decdk/examples/vpc.json index 6b075a14eeeeb..091920e330a39 100644 --- a/packages/decdk/examples/vpc.json +++ b/packages/decdk/examples/vpc.json @@ -2,7 +2,7 @@ "$schema": "../cdk.schema.json", "Resources": { "VPC": { - "Type": "@aws-cdk/aws-ec2.VpcNetwork" + "Type": "@aws-cdk/aws-ec2.Vpc" } } } \ No newline at end of file diff --git a/packages/decdk/lib/jsii2schema.ts b/packages/decdk/lib/jsii2schema.ts index f6b9b25f48d5e..2477576d8c31f 100644 --- a/packages/decdk/lib/jsii2schema.ts +++ b/packages/decdk/lib/jsii2schema.ts @@ -439,6 +439,7 @@ export function isDataType(t: jsiiReflect.Type | undefined): t is jsiiReflect.In // Must only have properties, all of which are scalars, // lists or isSerializableInterface types. export function isSerializableTypeReference(type: jsiiReflect.TypeReference, errorPrefix?: string): boolean { + if (type.primitive) { return true; } @@ -463,6 +464,10 @@ export function isSerializableTypeReference(type: jsiiReflect.TypeReference, err } function isSerializableType(type: jsiiReflect.Type, errorPrefix?: string): boolean { + // if this is a cosntruct class, we can represent it as a "Ref" + if (isConstruct(type)) { + return true; + } if (isEnum(type)) { return true; @@ -477,11 +482,6 @@ function isSerializableType(type: jsiiReflect.Type, errorPrefix?: string): boole return true; } - // if this is a cosntruct class, we can represent it as a "Ref" - if (isConstruct(type)) { - return true; - } - if (allImplementationsOfType(type).length > 0) { return true; } diff --git a/packages/decdk/package.json b/packages/decdk/package.json index 0ab98a9800e86..c016dbbeb168c 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -148,4 +148,4 @@ "engines": { "node": ">= 8.10.0" } -} +} \ No newline at end of file diff --git a/tools/awslint/bin/awslint.ts b/tools/awslint/bin/awslint.ts index 68dc273e85327..236393580ce33 100644 --- a/tools/awslint/bin/awslint.ts +++ b/tools/awslint/bin/awslint.ts @@ -5,7 +5,7 @@ import fs = require('fs-extra'); import reflect = require('jsii-reflect'); import path = require('path'); import yargs = require('yargs'); -import { AggregateLinter, apiLinter, attributesLinter, cfnResourceLinter, constructLinter, DiagnosticLevel, importsLinter, moduleLinter, resourceLinter } from '../lib'; +import { AggregateLinter, apiLinter, attributesLinter, cfnResourceLinter, constructLinter, DiagnosticLevel, importsLinter, moduleLinter, resourceLinter, exportsLinter } from '../lib'; const linter = new AggregateLinter( moduleLinter, @@ -14,7 +14,8 @@ const linter = new AggregateLinter( resourceLinter, apiLinter, importsLinter, - attributesLinter + attributesLinter, + exportsLinter ); let stackTrace = false; diff --git a/tools/awslint/lib/rules/attributes.ts b/tools/awslint/lib/rules/attributes.ts index 532c1791627be..bd47ded6eb9d8 100644 --- a/tools/awslint/lib/rules/attributes.ts +++ b/tools/awslint/lib/rules/attributes.ts @@ -15,7 +15,7 @@ class AttributeReflection { public readonly fqn: string; constructor(public readonly resource: ResourceReflection, public readonly attr: Attribute) { - this.fqn = resource.fqn + '.' + attr.name; + this.fqn = resource.fqn + '.' + attr.property.name; } } @@ -32,6 +32,6 @@ attributesLinter.add({ message: 'attribute properties must have an "@attribute" doctag on: ', eval: e => { const tag = e.ctx.attr.property.docs.customTag('attribute'); - e.assert(tag, e.ctx.fqn, `${e.ctx.attr.property.parentType.fqn}.${e.ctx.attr.name}`); + e.assert(tag, e.ctx.fqn, `${e.ctx.attr.property.parentType.fqn}.${e.ctx.attr.property.name}`); } }); diff --git a/tools/awslint/lib/rules/cfn-resource.ts b/tools/awslint/lib/rules/cfn-resource.ts index c0270b1e7c94d..ff2b0d6ac96e3 100644 --- a/tools/awslint/lib/rules/cfn-resource.ts +++ b/tools/awslint/lib/rules/cfn-resource.ts @@ -94,7 +94,13 @@ export class CfnResourceReflection { this.fullname = fullname; this.namespace = fullname.split('::').slice(0, 2).join('::'); - this.attributePrefix = this.basename[0].toLowerCase() + this.basename.slice(1); + + // special-case + const basename = this.basename + .replace(/VPC/g, 'Vpc') + .replace(/DB/g, 'Db'); + + this.attributePrefix = basename[0].toLowerCase() + basename.slice(1); this.attributeNames = cls.ownProperties .filter(p => (p.docs.docs.custom || {}).cloudformationAttribute) diff --git a/tools/awslint/lib/rules/exports.ts b/tools/awslint/lib/rules/exports.ts new file mode 100644 index 0000000000000..7d6bd5f350c73 --- /dev/null +++ b/tools/awslint/lib/rules/exports.ts @@ -0,0 +1,13 @@ +import { Linter } from '../linter'; + +export const exportsLinter = new Linter(assembly => assembly.types); + +exportsLinter.add({ + code: 'no-export', + message: 'the "export" methods are deprecated', + eval: e => { + if (e.ctx.isClassType() || e.ctx.isInterfaceType()) { + e.assert(!e.ctx.allMethods.some(m => m.name === 'export'), e.ctx.fqn); + } + } +}); \ No newline at end of file diff --git a/tools/awslint/lib/rules/index.ts b/tools/awslint/lib/rules/index.ts index 5edde09ca4515..2f8db16866e8e 100644 --- a/tools/awslint/lib/rules/index.ts +++ b/tools/awslint/lib/rules/index.ts @@ -4,4 +4,5 @@ export * from './resource'; export * from './imports'; export * from './cfn-resource'; export * from './attributes'; -export * from './api'; \ No newline at end of file +export * from './api'; +export * from './exports'; diff --git a/tools/awslint/lib/rules/resource.ts b/tools/awslint/lib/rules/resource.ts index 3161626e8275a..2257c329a03a6 100644 --- a/tools/awslint/lib/rules/resource.ts +++ b/tools/awslint/lib/rules/resource.ts @@ -14,7 +14,7 @@ export const resourceLinter = new Linter(a => ResourceReflection.findAll(a)); export interface Attribute { site: AttributeSite; property: reflect.Property; - name: string; // bucketArn + names: string[]; // bucketArn } export enum AttributeSite { @@ -91,7 +91,8 @@ export class ResourceReflection { // if there's an `@attribute` doc tag with a value other than "true" // it should be used as the attribute name instead of the property name - const propertyName = (tag && tag !== 'true') ? tag : p.name; + // multiple attribute names can be listed as a comma-delimited list + const propertyNames = (tag && tag !== 'true') ? tag.split(',') : [ p.name ]; // check if this attribute is defined on an interface or on a class const property = findDeclarationSite(p); @@ -99,7 +100,7 @@ export class ResourceReflection { result.push({ site, - name: propertyName, + names: propertyNames, property }); } @@ -158,7 +159,7 @@ resourceLinter.add({ message: 'resources must represent all cloudformation attributes as attribute properties. missing property: ', eval: e => { for (const name of e.ctx.cfn.attributeNames) { - const found = e.ctx.attributes.find(a => a.name === name); + const found = e.ctx.attributes.find(a => a.names.includes(name)); e.assert(found, `${e.ctx.fqn}.${name}`, name); } }