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); } }