From c42523e9c7bd0d45d1cf6185bbaa5daa14f5c44a Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 21 Jun 2019 13:43:28 +0200 Subject: [PATCH] refactor(ec2): API cleanups, more control over UserData (#2954) Clean up EC2 APIs, hide all free-floating subclasses and introduce static factory functions (`Peer` and `Port`). Start extensibility campaign for UserData. There are now classes for Linux and Windows-formatted UserData, and users can supply their own instance and/or subclass when creating an ASG. Simplify the user of `IMachineImage`. Fixes #2674. BREAKING CHANGES: * **ec2**: `TcpPort` etc have moved to factory method on the `Port` class. * **ec2**: `InstanceTypePair` has moved to factory method on `InstanceType`. * **ec2**: `natDependencies` and `internetDependencies` removed, replaced with `internetConnectivityEstablished`. * **ec2**: removed `selectSubnetIds`. * **ec2**: removed `isPublicSubnets`. * **ec2**: `VpnConnection` is now a `Resource`. * **ec2**: `VpcNetworkProvider` is no longer available directly, use `Vpc.fromLookup()` instead. * **ec2**: `routeTableId` is now a `IRouteTable` object. * **ec2**: `AnyIPv4` etc have move as factory functions onto `Peer`. * **ec2**: `IMachineImageSource` => `IMachineImage`. * **ec2** : `MachineImage` => `MachineImageConfig`. --- NOTICE | 1 + packages/@aws-cdk/assert/package-lock.json | 2 +- packages/@aws-cdk/assets/package-lock.json | 2 +- .../aws-autoscaling/lib/auto-scaling-group.ts | 35 +- .../test/integ.amazonlinux2.expected.json | 4 +- .../test/integ.amazonlinux2.ts | 2 +- ...g.asg-w-classic-loadbalancer.expected.json | 4 +- .../test/integ.asg-w-classic-loadbalancer.ts | 2 +- .../test/integ.asg-w-elbv2.expected.json | 4 +- .../aws-autoscaling/test/integ.asg-w-elbv2.ts | 2 +- .../test/integ.custom-scaling.expected.json | 4 +- .../test/integ.custom-scaling.ts | 2 +- .../test/integ.external-role.expected.json | 4 +- .../test/integ.external-role.ts | 2 +- .../test/integ.spot-instances.expected.json | 4 +- .../test/integ.spot-instances.ts | 2 +- .../test/test.auto-scaling-group.ts | 86 +++- .../test/test.lifecyclehooks.ts | 2 +- .../aws-autoscaling/test/test.scaling.ts | 4 +- .../package-lock.json | 2 +- .../aws-cloudformation/package-lock.json | 2 +- .../test/server/integ.deployment-group.ts | 2 +- .../test/server/test.deployment-group.ts | 4 +- .../package-lock.json | 2 +- .../package-lock.json | 2 +- packages/@aws-cdk/aws-ec2/lib/connections.ts | 53 +-- packages/@aws-cdk/aws-ec2/lib/index.ts | 5 +- .../@aws-cdk/aws-ec2/lib/instance-types.ts | 29 +- .../@aws-cdk/aws-ec2/lib/machine-image.ts | 381 ++++-------------- packages/@aws-cdk/aws-ec2/lib/peer.ts | 166 ++++++++ packages/@aws-cdk/aws-ec2/lib/port.ts | 201 +++++++++ .../aws-ec2/lib/security-group-rule.ts | 376 ----------------- .../@aws-cdk/aws-ec2/lib/security-group.ts | 41 +- packages/@aws-cdk/aws-ec2/lib/user-data.ts | 82 ++++ packages/@aws-cdk/aws-ec2/lib/util.ts | 17 +- packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts | 9 +- packages/@aws-cdk/aws-ec2/lib/vpc.ts | 127 +++--- packages/@aws-cdk/aws-ec2/lib/vpn.ts | 11 +- .../@aws-cdk/aws-ec2/lib/windows-versions.ts | 232 +++++++++++ packages/@aws-cdk/aws-ec2/package.json | 2 + .../aws-ec2/test/integ.vpc.expected.json | 4 +- packages/@aws-cdk/aws-ec2/test/integ.vpc.ts | 14 +- .../@aws-cdk/aws-ec2/test/test.connections.ts | 21 +- .../aws-ec2/test/test.security-group.ts | 84 ++-- .../@aws-cdk/aws-ecs/lib/base/base-service.ts | 4 +- packages/@aws-cdk/aws-ecs/lib/cluster.ts | 11 +- packages/@aws-cdk/aws-eks/lib/ami.ts | 2 +- packages/@aws-cdk/aws-eks/lib/cluster.ts | 16 +- .../test/example.ssh-into-nodes.lit.ts | 2 +- .../lib/load-balancer.ts | 14 +- .../test/integ.elb.ts | 2 +- .../test/test.loadbalancer.ts | 4 +- .../lib/alb/application-listener.ts | 14 +- .../lib/alb/application-target-group.ts | 6 +- .../lib/shared/base-load-balancer.ts | 4 +- .../test/integ.nlb.ts | 2 +- .../@aws-cdk/aws-lambda/package-lock.json | 2 +- .../aws-lambda/test/test.vpc-lambda.ts | 6 +- packages/@aws-cdk/aws-rds/lib/cluster.ts | 10 +- packages/@aws-cdk/aws-rds/lib/instance.ts | 10 +- packages/@aws-cdk/aws-rds/lib/option-group.ts | 2 +- .../@aws-cdk/aws-rds/lib/secret-rotation.ts | 2 +- .../test/integ.cluster-rotation.lit.ts | 2 +- .../@aws-cdk/aws-rds/test/integ.cluster.ts | 2 +- .../aws-rds/test/integ.instance.lit.ts | 2 +- .../@aws-cdk/aws-rds/test/test.cluster.ts | 18 +- .../@aws-cdk/aws-rds/test/test.instance.ts | 22 +- .../aws-rds/test/test.secret-rotation.ts | 8 +- .../@aws-cdk/aws-route53/lib/hosted-zone.ts | 4 +- .../lib/sagemaker-train-task.ts | 2 +- .../lib/sagemaker-transform-task.ts | 4 +- .../test/sagemaker-training-job.test.ts | 6 +- .../test/sagemaker-transform-job.test.ts | 6 +- packages/@aws-cdk/cdk/package-lock.json | 2 +- .../cloudformation-diff/package-lock.json | 2 +- packages/@aws-cdk/cx-api/package-lock.json | 2 +- packages/aws-cdk/package-lock.json | 2 +- packages/cdk-dasm/package-lock.json | 2 +- packages/decdk/package-lock.json | 2 +- tools/awslint/package-lock.json | 2 +- tools/cdk-build-tools/package-lock.json | 2 +- tools/cfn2ts/package-lock.json | 2 +- 82 files changed, 1193 insertions(+), 1051 deletions(-) create mode 100644 packages/@aws-cdk/aws-ec2/lib/peer.ts create mode 100644 packages/@aws-cdk/aws-ec2/lib/port.ts delete mode 100644 packages/@aws-cdk/aws-ec2/lib/security-group-rule.ts create mode 100644 packages/@aws-cdk/aws-ec2/lib/user-data.ts create mode 100644 packages/@aws-cdk/aws-ec2/lib/windows-versions.ts diff --git a/NOTICE b/NOTICE index 95fd48569c743..bf61ddbe53e78 100644 --- a/NOTICE +++ b/NOTICE @@ -1,2 +1,3 @@ AWS Cloud Development Kit (AWS CDK) Copyright 2018-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + diff --git a/packages/@aws-cdk/assert/package-lock.json b/packages/@aws-cdk/assert/package-lock.json index 929f7175f543a..473a5d0f04d48 100644 --- a/packages/@aws-cdk/assert/package-lock.json +++ b/packages/@aws-cdk/assert/package-lock.json @@ -1,6 +1,6 @@ { "name": "@aws-cdk/assert", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/@aws-cdk/assets/package-lock.json b/packages/@aws-cdk/assets/package-lock.json index 7ea35fae94b35..d11f3fe1e66c3 100644 --- a/packages/@aws-cdk/assets/package-lock.json +++ b/packages/@aws-cdk/assets/package-lock.json @@ -1,6 +1,6 @@ { "name": "@aws-cdk/assets", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { 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 92136c9774abd..2ae6e6e0c4bb3 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -175,7 +175,17 @@ export interface AutoScalingGroupProps extends CommonAutoScalingGroupProps { /** * AMI to launch */ - readonly machineImage: ec2.IMachineImageSource; + readonly machineImage: ec2.IMachineImage; + + /** + * Specific UserData to use + * + * The UserData may still be mutated after creation. + * + * @default - A UserData object appropriate for the MachineImage's + * Operating System is created. + */ + readonly userData?: ec2.UserData; /** * An IAM role to associate with the instance profile assigned to this Auto Scaling Group. @@ -354,7 +364,11 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements */ public readonly autoScalingGroupArn: string; - private readonly userDataLines = new Array(); + /** + * UserData for the instances + */ + public readonly userData: ec2.UserData; + private readonly autoScalingGroup: CfnAutoScalingGroup; private readonly securityGroup: ec2.ISecurityGroup; private readonly securityGroups: ec2.ISecurityGroup[] = []; @@ -381,12 +395,13 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements }); // use delayed evaluation - const machineImage = props.machineImage.getImage(this); - const userDataToken = Lazy.stringValue({ produce: () => Fn.base64((machineImage.os.createUserData(this.userDataLines))) }); + const imageConfig = props.machineImage.getImage(this); + this.userData = props.userData || imageConfig.userData || ec2.UserData.forOperatingSystem(imageConfig.osType); + const userDataToken = Lazy.stringValue({ produce: () => Fn.base64(this.userData.render()) }); const securityGroupsToken = Lazy.listValue({ produce: () => this.securityGroups.map(sg => sg.securityGroupId) }); const launchConfig = new CfnLaunchConfiguration(this, 'LaunchConfig', { - imageId: machineImage.imageId, + imageId: imageConfig.imageId, keyName: props.keyName, instanceType: props.instanceType.toString(), securityGroups: securityGroupsToken, @@ -409,7 +424,7 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements throw new Error(`Should have minCapacity (${minCapacity}) <= desiredCapacity (${desiredCapacity}) <= maxCapacity (${maxCapacity})`); } - const { subnetIds } = props.vpc.selectSubnets(props.vpcSubnets); + const { subnetIds, hasPublic } = props.vpc.selectSubnets(props.vpcSubnets); const asgProps: CfnAutoScalingGroupProps = { cooldown: props.cooldown !== undefined ? props.cooldown.toSeconds().toString() : undefined, minSize: minCapacity.toString(), @@ -432,12 +447,12 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements vpcZoneIdentifier: subnetIds }; - if (!props.vpc.isPublicSubnets(subnetIds) && props.associatePublicIpAddress) { + if (!hasPublic && props.associatePublicIpAddress) { throw new Error("To set 'associatePublicIpAddress: true' you must select Public subnets (vpcSubnets: { subnetType: SubnetType.Public })"); } this.autoScalingGroup = new CfnAutoScalingGroup(this, 'ASG', asgProps); - this.osType = machineImage.os.type; + this.osType = imageConfig.osType; this.autoScalingGroupName = this.autoScalingGroup.ref; this.autoScalingGroupArn = Stack.of(this).formatArn({ service: 'autoscaling', @@ -487,8 +502,8 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements * Add command to the startup script of fleet instances. * The command must be in the scripting language supported by the fleet's OS (i.e. Linux/Windows). */ - public addUserData(...scriptLines: string[]) { - scriptLines.forEach(scriptLine => this.userDataLines.push(scriptLine)); + public addUserData(...commands: string[]) { + this.userData.addCommands(...commands); } /** diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.expected.json b/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.expected.json index 36919e49f9646..00f727cca526f 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.expected.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.expected.json @@ -428,7 +428,7 @@ } ], "UserData": { - "Fn::Base64": "#!/bin/bash\n" + "Fn::Base64": "#!/bin/bash" } }, "DependsOn": [ @@ -467,4 +467,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts index b85e65649f059..52306e76e53b6 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts @@ -12,7 +12,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', { new autoscaling.AutoScalingGroup(stack, 'Fleet', { vpc, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }), }); diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.expected.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.expected.json index c8f20ad8aa6bd..362581f9be8c0 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.expected.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.expected.json @@ -602,7 +602,7 @@ } ], "UserData": { - "Fn::Base64": "#!/bin/bash\n" + "Fn::Base64": "#!/bin/bash" } }, "DependsOn": [ @@ -735,4 +735,4 @@ ] } } -} \ No newline at end of file +} 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 00f141a7872e0..235eb3b0ceb37 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 @@ -13,7 +13,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', { const asg = new autoscaling.AutoScalingGroup(stack, 'Fleet', { vpc, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), }); diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json index cf18393b3d0cf..fd90ff4aac3a1 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json @@ -449,7 +449,7 @@ } ], "UserData": { - "Fn::Base64": "#!/bin/bash\n" + "Fn::Base64": "#!/bin/bash" } }, "DependsOn": [ @@ -667,4 +667,4 @@ } } } -} \ No newline at end of file +} 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 905468709bf1e..4bb96d7a63dfe 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 @@ -13,7 +13,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', { const asg = new autoscaling.AutoScalingGroup(stack, 'Fleet', { vpc, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), }); diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.expected.json b/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.expected.json index af6f77223f4cb..ad1777577b027 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.expected.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.expected.json @@ -428,7 +428,7 @@ } ], "UserData": { - "Fn::Base64": "#!/bin/bash\n" + "Fn::Base64": "#!/bin/bash" } }, "DependsOn": [ @@ -502,4 +502,4 @@ } } } -} \ No newline at end of file +} 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 9f79543d36767..2bf929d10d267 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.ts @@ -12,7 +12,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', { const asg = new autoscaling.AutoScalingGroup(stack, 'Fleet', { vpc, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }), }); diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.expected.json b/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.expected.json index 44e040031454c..1df2089be9bd2 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.expected.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.expected.json @@ -581,7 +581,7 @@ } ], "UserData": { - "Fn::Base64": "#!/bin/bash\n" + "Fn::Base64": "#!/bin/bash" } }, "DependsOn": [ @@ -623,4 +623,4 @@ } } } -} \ No newline at end of file +} 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 6612ea50bbe8f..b3c192adf81f3 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.ts @@ -13,7 +13,7 @@ class TestStack extends cdk.Stack { }); new asg.AutoScalingGroup(this, 'ASG', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO), vpc, machineImage: new ec2.AmazonLinuxImage(), role diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.expected.json b/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.expected.json index 8dd9fdaf2d9da..9e3f6e786723d 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.expected.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.expected.json @@ -429,7 +429,7 @@ ], "SpotPrice": "0.20", "UserData": { - "Fn::Base64": "#!/bin/bash\n" + "Fn::Base64": "#!/bin/bash" } }, "DependsOn": [ @@ -468,4 +468,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.ts index 114cf2f4c2fb0..7be3961428631 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.ts @@ -12,7 +12,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', { new autoscaling.AutoScalingGroup(stack, 'Fleet', { vpc, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }), spotPrice: '0.20' }); 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 e41d936ea7b76..b1da8df6a1964 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 @@ -13,7 +13,7 @@ export = { const vpc = mockVpc(stack); new autoscaling.AutoScalingGroup(stack, 'MyFleet', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc }); @@ -92,7 +92,7 @@ export = { } ], "UserData": { - "Fn::Base64": "#!/bin/bash\n" + "Fn::Base64": "#!/bin/bash" } }, "DependsOn": [ @@ -137,7 +137,7 @@ export = { const vpc = mockVpc(stack); new autoscaling.AutoScalingGroup(stack, 'MyFleet', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, minCapacity: 0, @@ -155,6 +155,56 @@ export = { test.done(); }, + 'userdata can be overriden by image'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = mockVpc(stack); + + const ud = ec2.UserData.forLinux(); + ud.addCommands('it me!'); + + // WHEN + const asg = new autoscaling.AutoScalingGroup(stack, 'MyFleet', { + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + machineImage: new ec2.AmazonLinuxImage({ + userData: ud + }), + vpc, + }); + + // THEN + test.equals(asg.userData.render(), '#!/bin/bash\nit me!'); + + test.done(); + }, + + 'userdata can be overriden at ASG directly'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = mockVpc(stack); + + const ud1 = ec2.UserData.forLinux(); + ud1.addCommands('it me!'); + + const ud2 = ec2.UserData.forLinux(); + ud2.addCommands('no me!'); + + // WHEN + const asg = new autoscaling.AutoScalingGroup(stack, 'MyFleet', { + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + machineImage: new ec2.AmazonLinuxImage({ + userData: ud1 + }), + vpc, + userData: ud2 + }); + + // THEN + test.equals(asg.userData.render(), '#!/bin/bash\nno me!'); + + test.done(); + }, + 'can specify only min capacity'(test: Test) { // GIVEN const stack = new cdk.Stack(); @@ -162,7 +212,7 @@ export = { // WHEN new autoscaling.AutoScalingGroup(stack, 'MyFleet', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, minCapacity: 10 @@ -186,7 +236,7 @@ export = { // WHEN new autoscaling.AutoScalingGroup(stack, 'MyFleet', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, maxCapacity: 10 @@ -210,7 +260,7 @@ export = { // WHEN new autoscaling.AutoScalingGroup(stack, 'MyFleet', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, desiredCapacity: 10 @@ -232,7 +282,7 @@ export = { const vpc = mockVpc(stack); const fleet = new autoscaling.AutoScalingGroup(stack, 'MyFleet', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc }); @@ -264,7 +314,7 @@ export = { // WHEN new autoscaling.AutoScalingGroup(stack, 'MyFleet', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, updateType: autoscaling.UpdateType.REPLACING_UPDATE, @@ -295,7 +345,7 @@ export = { // WHEN new autoscaling.AutoScalingGroup(stack, 'MyFleet', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, updateType: autoscaling.UpdateType.ROLLING_UPDATE, @@ -327,7 +377,7 @@ export = { // WHEN new autoscaling.AutoScalingGroup(stack, 'MyFleet', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, resourceSignalCount: 5, @@ -354,7 +404,7 @@ export = { // WHEN const asg = new autoscaling.AutoScalingGroup(stack, 'MyFleet', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, }); @@ -380,7 +430,7 @@ export = { // WHEN const asg = new autoscaling.AutoScalingGroup(stack, 'MyFleet', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, updateType: autoscaling.UpdateType.ROLLING_UPDATE, @@ -422,7 +472,7 @@ export = { // WHEN new autoscaling.AutoScalingGroup(stack, 'MyStack', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, @@ -444,7 +494,7 @@ export = { // WHEN new autoscaling.AutoScalingGroup(stack, 'MyStack', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, minCapacity: 0, @@ -471,7 +521,7 @@ export = { // WHEN test.throws(() => { new autoscaling.AutoScalingGroup(stack, 'MyStack', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, minCapacity: 0, @@ -490,7 +540,7 @@ export = { // WHEN new autoscaling.AutoScalingGroup(stack, 'MyStack', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, minCapacity: 0, @@ -514,7 +564,7 @@ export = { // WHEN new autoscaling.AutoScalingGroup(stack, 'MyStack', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), vpc, minCapacity: 0, @@ -544,7 +594,7 @@ export = { // WHEN const asg = new autoscaling.AutoScalingGroup(stack, 'MyASG', { vpc, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), role: importedRole }); diff --git a/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts b/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts index d462ddd42b473..8d1bfedcc4ac2 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts @@ -13,7 +13,7 @@ export = { 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), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), }); diff --git a/packages/@aws-cdk/aws-autoscaling/test/test.scaling.ts b/packages/@aws-cdk/aws-autoscaling/test/test.scaling.ts index 92fa2d1aac61d..c2faf188ea1a3 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/test.scaling.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/test.scaling.ts @@ -233,8 +233,8 @@ class ASGFixture extends cdk.Construct { 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), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), machineImage: new ec2.AmazonLinuxImage(), }); } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package-lock.json b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package-lock.json index 22425269e1277..1c75e7de20f37 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package-lock.json +++ b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package-lock.json @@ -1,6 +1,6 @@ { "name": "dns_validated_certificate_handler", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/@aws-cdk/aws-cloudformation/package-lock.json b/packages/@aws-cdk/aws-cloudformation/package-lock.json index 93056873737f1..cd40533cbfa97 100644 --- a/packages/@aws-cdk/aws-cloudformation/package-lock.json +++ b/packages/@aws-cdk/aws-cloudformation/package-lock.json @@ -1,6 +1,6 @@ { "name": "@aws-cdk/aws-cloudformation", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { 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 8da3a180499ec..4e10fcc064567 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 @@ -12,7 +12,7 @@ const stack = new cdk.Stack(app, 'aws-cdk-codedeploy-server-dg'); const vpc = new ec2.Vpc(stack, 'VPC'); const asg = new autoscaling.AutoScalingGroup(stack, 'ASG', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE), machineImage: new ec2.AmazonLinuxImage(), vpc, }); 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 6ad904aeeafd5..ecfd55aa4a6cc 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 @@ -46,7 +46,7 @@ export = { const stack = new cdk.Stack(); const asg = new autoscaling.AutoScalingGroup(stack, 'ASG', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.STANDARD3, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.STANDARD3, ec2.InstanceSize.SMALL), machineImage: new ec2.AmazonLinuxImage(), vpc: new ec2.Vpc(stack, 'VPC'), }); @@ -70,7 +70,7 @@ export = { const stack = new cdk.Stack(); const asg = new autoscaling.AutoScalingGroup(stack, 'ASG', { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.STANDARD3, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.STANDARD3, ec2.InstanceSize.SMALL), machineImage: new ec2.AmazonLinuxImage(), vpc: new ec2.Vpc(stack, 'VPC'), }); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/package-lock.json b/packages/@aws-cdk/aws-codepipeline-actions/package-lock.json index ddfd1474422df..7269e675e43d8 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/package-lock.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/package-lock.json @@ -1,6 +1,6 @@ { "name": "@aws-cdk/aws-codepipeline-actions", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package-lock.json b/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package-lock.json index 158553f516be0..b5fe6adad9eec 100644 --- a/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package-lock.json +++ b/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package-lock.json @@ -1,6 +1,6 @@ { "name": "aws-global-lambda-coordinator", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/@aws-cdk/aws-ec2/lib/connections.ts b/packages/@aws-cdk/aws-ec2/lib/connections.ts index 72854790af010..dc9013a5f0c40 100644 --- a/packages/@aws-cdk/aws-ec2/lib/connections.ts +++ b/packages/@aws-cdk/aws-ec2/lib/connections.ts @@ -1,5 +1,6 @@ +import { IPeer, Peer } from "./peer"; +import { Port } from './port'; import { ISecurityGroup } from "./security-group"; -import { AnyIPv4, IPortRange, ISecurityGroupRule } from "./security-group-rule"; /** * The goal of this module is to make possible to write statements like this: @@ -33,7 +34,7 @@ export interface ConnectionsProps { * * @default Derived from securityGroup if set. */ - readonly securityGroupRule?: ISecurityGroupRule; + readonly peer?: IPeer; /** * What securityGroup(s) this object is managing connections for @@ -45,9 +46,9 @@ export interface ConnectionsProps { /** * Default port range for initiating connections to and from this object * - * @default No default port range + * @default - No default port */ - readonly defaultPortRange?: IPortRange; + readonly defaultPort?: Port; } /** @@ -67,7 +68,7 @@ export class Connections implements IConnectable { /** * The default port configured for this connection peer, if available */ - public readonly defaultPortRange?: IPortRange; + public readonly defaultPort?: Port; /** * Underlying securityGroup for this Connections object, if present @@ -80,7 +81,7 @@ export class Connections implements IConnectable { /** * The rule that defines how to represent this peer in a security group */ - private readonly _securityGroupRules = new ReactiveList(); + private readonly _securityGroupRules = new ReactiveList(); /** * When doing bidirectional grants between Connections, make sure we don't recursive infinitely @@ -97,11 +98,11 @@ export class Connections implements IConnectable { this._securityGroups.push(...(props.securityGroups || [])); this._securityGroupRules.push(...this._securityGroups.asArray()); - if (props.securityGroupRule) { - this._securityGroupRules.push(props.securityGroupRule); + if (props.peer) { + this._securityGroupRules.push(props.peer); } - this.defaultPortRange = props.defaultPortRange; + this.defaultPort = props.defaultPort; } public get securityGroups(): ISecurityGroup[] { @@ -121,7 +122,7 @@ export class Connections implements IConnectable { /** * Allow connections to the peer on the given port */ - public allowTo(other: IConnectable, portRange: IPortRange, description?: string) { + public allowTo(other: IConnectable, portRange: Port, description?: string) { if (this.skip) { return; } const remoteRule = this.remoteRule; // Capture current value into local for callback to close over @@ -144,7 +145,7 @@ export class Connections implements IConnectable { /** * Allow connections from the peer on the given port */ - public allowFrom(other: IConnectable, portRange: IPortRange, description?: string) { + public allowFrom(other: IConnectable, portRange: Port, description?: string) { if (this.skip) { return; } const remoteRule = this.remoteRule; // Capture current value into local for callback to close over @@ -167,7 +168,7 @@ export class Connections implements IConnectable { /** * Allow hosts inside the security group to connect to each other on the given port */ - public allowInternally(portRange: IPortRange, description?: string) { + public allowInternally(portRange: Port, description?: string) { this._securityGroups.forEachAndForever(securityGroup => { this._securityGroupRules.forEachAndForever(rule => { securityGroup.addIngressRule(rule, portRange, description); @@ -180,15 +181,15 @@ export class Connections implements IConnectable { /** * Allow to all IPv4 ranges */ - public allowToAnyIPv4(portRange: IPortRange, description?: string) { - this.allowTo(new AnyIPv4(), portRange, description); + public allowToAnyIPv4(portRange: Port, description?: string) { + this.allowTo(Peer.anyIpv4(), portRange, description); } /** * Allow from any IPv4 ranges */ - public allowFromAnyIPv4(portRange: IPortRange, description?: string) { - this.allowFrom(new AnyIPv4(), portRange, description); + public allowFromAnyIPv4(portRange: Port, description?: string) { + this.allowFrom(Peer.anyIpv4(), portRange, description); } /** @@ -197,41 +198,41 @@ export class Connections implements IConnectable { * Even if the peer has a default port, we will always use our default port. */ public allowDefaultPortFrom(other: IConnectable, description?: string) { - if (!this.defaultPortRange) { + if (!this.defaultPort) { throw new Error('Cannot call allowDefaultPortFrom(): this resource has no default port'); } - this.allowFrom(other, this.defaultPortRange, description); + this.allowFrom(other, this.defaultPort, description); } /** * Allow hosts inside the security group to connect to each other */ public allowDefaultPortInternally(description?: string) { - if (!this.defaultPortRange) { + if (!this.defaultPort) { throw new Error('Cannot call allowDefaultPortInternally(): this resource has no default port'); } - this.allowInternally(this.defaultPortRange, description); + this.allowInternally(this.defaultPort, description); } /** * Allow default connections from all IPv4 ranges */ public allowDefaultPortFromAnyIpv4(description?: string) { - if (!this.defaultPortRange) { + if (!this.defaultPort) { throw new Error('Cannot call allowDefaultPortFromAnyIpv4(): this resource has no default port'); } - this.allowFromAnyIPv4(this.defaultPortRange, description); + this.allowFromAnyIPv4(this.defaultPort, description); } /** * Allow connections to the security group on their default port */ public allowToDefaultPort(other: IConnectable, description?: string) { - if (other.connections.defaultPortRange === undefined) { + if (other.connections.defaultPort === undefined) { throw new Error('Cannot call alloToDefaultPort(): other resource has no default port'); } - this.allowTo(other, other.connections.defaultPortRange, description); + this.allowTo(other, other.connections.defaultPort, description); } /** @@ -240,10 +241,10 @@ export class Connections implements IConnectable { * Even if the peer has a default port, we will always use our default port. */ public allowDefaultPortTo(other: IConnectable, description?: string) { - if (!this.defaultPortRange) { + if (!this.defaultPort) { throw new Error('Cannot call allowDefaultPortTo(): this resource has no default port'); } - this.allowTo(other, this.defaultPortRange, description); + this.allowTo(other, this.defaultPort, description); } } diff --git a/packages/@aws-cdk/aws-ec2/lib/index.ts b/packages/@aws-cdk/aws-ec2/lib/index.ts index 4bbfedd98c42e..4c9337e333d8f 100644 --- a/packages/@aws-cdk/aws-ec2/lib/index.ts +++ b/packages/@aws-cdk/aws-ec2/lib/index.ts @@ -1,12 +1,15 @@ export * from './connections'; export * from './instance-types'; export * from './machine-image'; +export * from './port'; export * from './security-group'; -export * from './security-group-rule'; +export * from './peer'; export * from './vpc'; export * from './vpc-lookup'; export * from './vpn'; export * from './vpc-endpoint'; +export * from './user-data'; +export * from './windows-versions'; // AWS::EC2 CloudFormation Resources: export * from './ec2.generated'; diff --git a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts index 447f0bde2eb73..77530875d53b9 100644 --- a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts +++ b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts @@ -228,6 +228,18 @@ export enum InstanceSize { * know the identifier of the type you want. */ export class InstanceType { + /** + * Instance type for EC2 instances + * + * This class takes a combination of a class and size. + * + * Be aware that not all combinations of class and size are available, and not all + * classes are available in all regions. + */ + public static of(instanceClass: InstanceClass, instanceSize: InstanceSize) { + return new InstanceType(`${instanceClass}.${instanceSize}`); + } + constructor(private readonly instanceTypeIdentifier: string) { } @@ -237,19 +249,4 @@ export class InstanceType { public toString(): string { return this.instanceTypeIdentifier; } -} - -/** - * Instance type for EC2 instances - * - * This class takes a combination of a class and size. - * - * Be aware that not all combinations of class and size are available, and not all - * classes are available in all regions. - */ -export class InstanceTypePair extends InstanceType { - constructor(public readonly instanceClass: InstanceClass, - public readonly instanceSize: InstanceSize) { - super(instanceClass + '.' + instanceSize); - } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/lib/machine-image.ts b/packages/@aws-cdk/aws-ec2/lib/machine-image.ts index 3b4ec33297089..f74ebbf37091f 100644 --- a/packages/@aws-cdk/aws-ec2/lib/machine-image.ts +++ b/packages/@aws-cdk/aws-ec2/lib/machine-image.ts @@ -1,14 +1,50 @@ import ssm = require('@aws-cdk/aws-ssm'); import { Construct, Stack, Token } from '@aws-cdk/cdk'; +import { UserData } from './user-data'; +import { WindowsVersion } from './windows-versions'; /** * Interface for classes that can select an appropriate machine image to use */ -export interface IMachineImageSource { +export interface IMachineImage { /** * Return the image to use in the given context */ - getImage(scope: Construct): MachineImage; + getImage(scope: Construct): MachineImageConfig; +} + +/** + * Configuration for a machine image + */ +export interface MachineImageConfig { + /** + * The AMI ID of the image to use + */ + readonly imageId: string; + + /** + * Operating system type for this image + */ + readonly osType: OperatingSystemType; + + /** + * Initial UserData for this image + * + * @default - Default UserData appropriate for the osType is created + */ + readonly userData?: UserData; +} + +/** + * Configuration options for WindowsImage + */ +export interface WindowsImageProps { + /** + * Initial user data + * + * @default - Empty UserData for Windows machines + */ + readonly userData?: UserData; } /** @@ -18,24 +54,28 @@ export interface IMachineImageSource { * * https://aws.amazon.com/blogs/mt/query-for-the-latest-windows-ami-using-systems-manager-parameter-store/ */ -export class WindowsImage implements IMachineImageSource { - constructor(private readonly version: WindowsVersion) { +export class WindowsImage implements IMachineImage { + constructor(private readonly version: WindowsVersion, private readonly props: WindowsImageProps = {}) { } /** * Return the image to use in the given context */ - public getImage(scope: Construct): MachineImage { - const parameterName = this.imageParameterName(this.version); + public getImage(scope: Construct): MachineImageConfig { + const parameterName = this.imageParameterName(); const ami = ssm.StringParameter.valueForStringParameter(scope, parameterName); - return new MachineImage(ami, new WindowsOS()); + return { + imageId: ami, + userData: this.props.userData, + osType: OperatingSystemType.WINDOWS, + }; } /** * Construct the SSM parameter name for the given Windows image */ - private imageParameterName(version: WindowsVersion): string { - return '/aws/service/ami-windows-latest/' + version; + private imageParameterName(): string { + return '/aws/service/ami-windows-latest/' + this.version; } } @@ -70,6 +110,13 @@ export interface AmazonLinuxImageProps { * @default GeneralPurpose */ readonly storage?: AmazonLinuxStorage; + + /** + * Initial user data + * + * @default - Empty UserData for Linux machines + */ + readonly userData?: UserData; } /** @@ -77,13 +124,13 @@ export interface AmazonLinuxImageProps { * * The AMI ID is selected using the values published to the SSM parameter store. */ -export class AmazonLinuxImage implements IMachineImageSource { +export class AmazonLinuxImage implements IMachineImage { private readonly generation: AmazonLinuxGeneration; private readonly edition: AmazonLinuxEdition; private readonly virtualization: AmazonLinuxVirt; private readonly storage: AmazonLinuxStorage; - constructor(props?: AmazonLinuxImageProps) { + constructor(private readonly props: AmazonLinuxImageProps = {}) { this.generation = (props && props.generation) || AmazonLinuxGeneration.AMAZON_LINUX; this.edition = (props && props.edition) || AmazonLinuxEdition.STANDARD; this.virtualization = (props && props.virtualization) || AmazonLinuxVirt.HVM; @@ -93,7 +140,7 @@ export class AmazonLinuxImage implements IMachineImageSource { /** * Return the image to use in the given context */ - public getImage(scope: Construct): MachineImage { + public getImage(scope: Construct): MachineImageConfig { const parts: Array = [ this.generation, 'ami', @@ -105,7 +152,12 @@ export class AmazonLinuxImage implements IMachineImageSource { const parameterName = '/aws/service/ami-amazon-linux-latest/' + parts.join('-'); const ami = ssm.StringParameter.valueForStringParameter(scope, parameterName); - return new MachineImage(ami, new LinuxOS()); + + return { + imageId: ami, + userData: this.props.userData, + osType: OperatingSystemType.LINUX, + }; } } @@ -171,17 +223,29 @@ export enum AmazonLinuxStorage { GENERAL_PURPOSE = 'gp2', } +/** + * Configuration options for GenericLinuxImage + */ +export interface GenericLinuxImageProps { + /** + * Initial user data + * + * @default - Empty UserData for Windows machines + */ + readonly userData?: UserData; +} + /** * Construct a Linux machine image from an AMI map * * Linux images IDs are not published to SSM parameter store yet, so you'll have to * manually specify an AMI map. */ -export class GenericLinuxImage implements IMachineImageSource { - constructor(private readonly amiMap: {[region: string]: string}) { +export class GenericLinuxImage implements IMachineImage { + constructor(private readonly amiMap: {[region: string]: string}, private readonly props: GenericLinuxImageProps = {}) { } - public getImage(scope: Construct): MachineImage { + public getImage(scope: Construct): MachineImageConfig { const region = Stack.of(scope).region; if (Token.isUnresolved(region)) { throw new Error(`Unable to determine AMI from AMI map since stack is region-agnostic`); @@ -192,250 +256,11 @@ export class GenericLinuxImage implements IMachineImageSource { throw new Error(`Unable to find AMI in AMI map: no AMI specified for region '${region}'`); } - return new MachineImage(ami, new LinuxOS()); - } -} - -/** - * The Windows version to use for the WindowsImage - */ -export enum WindowsVersion { - WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_SQL_2008_SP4_EXPRESS = 'Windows_Server-2008-SP2-English-64Bit-SQL_2008_SP4_Express', - WINDOWS_SERVER_2012_R2_RTM_CHINESE_SIMPLIFIED_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Chinese_Simplified-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_CHINESE_TRADITIONAL_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Chinese_Traditional-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_DUTCH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Dutch-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_ENTERPRISE = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP2_Enterprise', - WINDOWS_SERVER_2012_R2_RTM_HUNGARIAN_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Hungarian-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-Base', - WINDOWS_SERVER_2016_ENGLISH_CORE_CONTAINERS = 'Windows_Server-2016-English-Core-Containers', - WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_WEB = 'Windows_Server-2016-English-Core-SQL_2016_SP1_Web', - WINDOWS_SERVER_2016_GERMAL_FULL_BASE = 'Windows_Server-2016-German-Full-Base', - WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_32BIT_BASE = 'Windows_Server-2003-R2_SP2-Language_Packs-32Bit-Base', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_WEB = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2008_R2_SP3_Web', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_EXPRESS = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2012_SP4_Express', - WINDOWS_SERVER_2012_R2_SP1_PORTUGESE_BRAZIL_64BIT_CORE = 'Windows_Server-2008-R2_SP1-Portuguese_Brazil-64Bit-Core', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_STANDARD = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP2_Standard', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_EXPRESS = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP2_Express', - WINDOWS_SERVER_2012_RTM_ITALIAN_64BIT_BASE = 'Windows_Server-2012-RTM-Italian-64Bit-Base', - WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_EXPRESS = 'Windows_Server-2016-English-Core-SQL_2016_SP1_Express', - WINDOWS_SERVER_2016_ENGLISH_DEEP_LEARNING = 'Windows_Server-2016-English-Deep-Learning', - WINDOWS_SERVER_2019_ITALIAN_FULL_BASE = 'Windows_Server-2019-Italian-Full-Base', - WINDOWS_SERVER_2008_R2_SP1_KOREAN_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Korean-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_EXPRESS = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP1_Express', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_WEB = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP2_Web', - WINDOWS_SERVER_2016_JAPANESE_FULL_FQL_2016_SP2_WEB = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP2_Web', - WINDOWS_SERVER_2016_KOREAN_FULL_BASE = 'Windows_Server-2016-Korean-Full-Base', - WINDOWS_SERVER_2016_KOREAN_FULL_SQL_2016_SP2_STANDARD = 'Windows_Server-2016-Korean-Full-SQL_2016_SP2_Standard', - WINDOWS_SERVER_2016_PORTUGESE_PORTUGAL_FULL_BASE = 'Windows_Server-2016-Portuguese_Portugal-Full-Base', - WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_WEB = 'Windows_Server-2019-English-Full-SQL_2017_Web', - WINDOWS_SERVER_2019_FRENCH_FULL_BASE = 'Windows_Server-2019-French-Full-Base', - WINDOWS_SERVER_2019_KOREAN_FULL_BASE = 'Windows_Server-2019-Korean-Full-Base', - WINDOWS_SERVER_2008_R2_SP1_CHINESE_HONG_KONG_SAR_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Chinese_Hong_Kong_SAR-64Bit-Base', - WINDOWS_SERVER_2008_R2_SP1_CHINESE_PRC_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Chinese_PRC-64Bit-Base', - WINDOWS_SERVER_2012_RTM_FRENCH_64BIT_BASE = 'Windows_Server-2012-RTM-French-64Bit-Base', - WINDOWS_SERVER_2016_ENGLISH_FULL_CONTAINERS = 'Windows_Server-2016-English-Full-Containers', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_STANDARD = 'Windows_Server-2016-English-Full-SQL_2016_SP1_Standard', - WINDOWS_SERVER_2016_RUSSIAN_FULL_BASE = 'Windows_Server-2016-Russian-Full-Base', - WINDOWS_SERVER_2019_CHINESE_SIMPLIFIED_FULL_BASE = 'Windows_Server-2019-Chinese_Simplified-Full-Base', - WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_STANDARD = 'Windows_Server-2019-English-Full-SQL_2016_SP2_Standard', - WINDOWS_SERVER_2019_HUNGARIAN_FULL_BASE = 'Windows_Server-2019-Hungarian-Full-Base', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_EXPRESS = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2008_R2_SP3_Express', - WINDOWS_SERVER_2007_R2_SP1_LANGUAGE_PACKS_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Language_Packs-64Bit-Base', - WINDOWS_SERVER_2008_SP2_ENGLISH_32BIT_BASE = 'Windows_Server-2008-SP2-English-32Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2012_SP4_Enterprise', - WINDOWS_SERVER_2012_RTM_CHINESE_TRADITIONAL_64BIT_BASE = 'Windows_Server-2012-RTM-Chinese_Traditional-64Bit-Base', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2008_R2_SP3_EXPRESS = 'Windows_Server-2012-RTM-English-64Bit-SQL_2008_R2_SP3_Express', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_STANDARD = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP2_Standard', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_EXPRESS = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP2_Express', - WINDOWS_SERVER_2016_POLISH_FULL_BASE = 'Windows_Server-2016-Polish-Full-Base', - WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_WEB = 'Windows_Server-2019-English-Full-SQL_2016_SP2_Web', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_STANDARD = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP3_Standard', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_EXPRESS = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP2_Express', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_DEEP_LEARNING = 'Windows_Server-2012-R2_RTM-English-Deep-Learning', - WINDOWS_SERVER_2012_R2_RTM_GERMAN_64BIT_BASE = 'Windows_Server-2012-R2_RTM-German-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_EXPRESS = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP1_Express', - WINDOWS_SERVER_2012_R2_RTM_RUSSIAN_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Russian-64Bit-Base', - WINDOWS_SERVER_2012_RTM_CHINESE_TRADITIONAL_HONG_KONG_SAR_64BIT_BASE = 'Windows_Server-2012-RTM-Chinese_Traditional_Hong_Kong_SAR-64Bit-Base', - WINDOWS_SERVER_2012_RTM_HUNGARIAN_64BIT_BASE = 'Windows_Server-2012-RTM-Hungarian-64Bit-Base', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_STANDARD = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP3_Standard', - WINDOWS_SERVER_2019_ENGLISH_FULL_HYPERV = 'Windows_Server-2019-English-Full-HyperV', - WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_SQL_2005_SP4_EXPRESS = 'Windows_Server-2003-R2_SP2-English-64Bit-SQL_2005_SP4_Express', - WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2012_SP4_EXPRESS = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-SQL_2012_SP4_Express', - WINDOWS_SERVER_2012_RTM_GERMAN_64BIT_BASE = 'Windows_Server-2012-RTM-German-64Bit-Base', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2008_R2_SP3_STANDARD = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2008_R2_SP3_Standard', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_STANDARD = 'Windows_Server-2016-English-Full-SQL_2016_SP2_Standard', - WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_EXPRESS = 'Windows_Server-2019-English-Full-SQL_2017_Express', - WINDOWS_SERVER_2019_JAPANESE_FULL_BASE = 'Windows_Server-2019-Japanese-Full-Base', - WINDOWS_SERVER_2019_RUSSIAN_FULL_BASE = 'Windows_Server-2019-Russian-Full-Base', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_STANDARD = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP2_Standard', - WINDOWS_SERVER_2012_R2_RTM_ITALIAN_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Italian-64Bit-Base', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_BASE = 'Windows_Server-2012-RTM-English-64Bit-Base', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2008_R2_SP3_STANDARD = 'Windows_Server-2012-RTM-English-64Bit-SQL_2008_R2_SP3_Standard', - WINDOWS_SERVER_2016_ENGLISH_FULL_HYPERV = 'Windows_Server-2016-English-Full-HyperV', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2016-English-Full-SQL_2016_SP2_Enterprise', - WINDOWS_SERVER_2019_CHINESE_TRADITIONAL_FULL_BASE = 'Windows_Server-2019-Chinese_Traditional-Full-Base', - WINDOWS_SERVER_2019_ENGLISH_CORE_BASE = 'Windows_Server-2019-English-Core-Base', - WINDOWS_SERVER_2019_ENGLISH_CORE_CONTAINERSLATEST = 'Windows_Server-2019-English-Core-ContainersLatest', - WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_BASE = 'Windows_Server-2008-SP2-English-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_FRENCH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-French-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_POLISH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Polish-64Bit-Base', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_EXPRESS = 'Windows_Server-2012-RTM-English-64Bit-SQL_2012_SP4_Express', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP3_STANDARD = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP3_Standard', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_2012_SP4_STANDARD = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2012_SP4_Standard', - WINDOWS_SERVER_2016_ENGLISH_CORE_CONTAINERSLATEST = 'Windows_Server-2016-English-Core-ContainersLatest', - WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_EXPRESS = 'Windows_Server-2019-English-Full-SQL_2016_SP2_Express', - WINDOWS_SERVER_2019_TURKISH_FULL_BASE = 'Windows_Server-2019-Turkish-Full-Base', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_EXPRESS = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP2_Express', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_WEB = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP3_Web', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_WEB = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP1_Web', - WINDOWS_SERVER_2012_R2_RTM_PORTUGESE_BRAZIL_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Portuguese_Brazil-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_PORTUGESE_PORTUGAL_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Portuguese_Portugal-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_SWEDISH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Swedish-64Bit-Base', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_EXPRESS = 'Windows_Server-2016-English-Full-SQL_2016_SP1_Express', - WINDOWS_SERVER_2016_ITALIAN_FULL_BASE = 'Windows_Server-2016-Italian-Full-Base', - WINDOWS_SERVER_2016_SPANISH_FULL_BASE = 'Windows_Server-2016-Spanish-Full-Base', - WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_STANDARD = 'Windows_Server-2019-English-Full-SQL_2017_Standard', - WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_SQL_2005_SP4_STANDARD = 'Windows_Server-2003-R2_SP2-Language_Packs-64Bit-SQL_2005_SP4_Standard', - WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_STANDARD = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-SQL_2008_R2_SP3_Standard', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_STANDARD = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP1_Standard', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2007_R2_SP3_WEB = 'Windows_Server-2012-RTM-English-64Bit-SQL_2008_R2_SP3_Web', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_WEB = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP2_Web', - WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2016-English-Core-SQL_2016_SP2_Enterprise', - WINDOWS_SERVER_2016_PORTUGESE_BRAZIL_FULL_BASE = 'Windows_Server-2016-Portuguese_Brazil-Full-Base', - WINDOWS_SERVER_2019_ENGLISH_FULL_BASE = 'Windows_Server-2019-English-Full-Base', - WINDOWS_SERVER_2003_R2_SP2_ENGLISH_32BIT_BASE = 'Windows_Server-2003-R2_SP2-English-32Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_CZECH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Czech-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_STANDARD = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP1_Standard', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP2_EXPRESS = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2014_SP2_Express', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_STANDARD = 'Windows_Server-2012-RTM-English-64Bit-SQL_2012_SP4_Standard', - WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_ENTERPRISE = 'Windows_Server-2016-English-Core-SQL_2016_SP1_Enterprise', - WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_WEB = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP1_Web', - WINDOWS_SERVER_2016_SWEDISH_FULL_BASE = 'Windows_Server-2016-Swedish-Full-Base', - WINDOWS_SERVER_2016_TURKISH_FULL_BASE = 'Windows_Server-2016-Turkish-Full-Base', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_CORE_SQL_2012_SP4_STANDARD = 'Windows_Server-2008-R2_SP1-English-64Bit-Core_SQL_2012_SP4_Standard', -// tslint:disable-next-line: max-line-length - WINDOWS_SERVER_2008_R2_SP1_LANGUAGE_PACKS_64BIT_SQL_2008_R2_SP3_STANDARD = 'Windows_Server-2008-R2_SP1-Language_Packs-64Bit-SQL_2008_R2_SP3_Standard', - WINDOWS_SERVER_2012_RTM_CZECH_64BIT_BASE = 'Windows_Server-2012-RTM-Czech-64Bit-Base', - WINDOWS_SERVER_2012_RTM_TURKISH_64BIT_BASE = 'Windows_Server-2012-RTM-Turkish-64Bit-Base', - WINDOWS_SERVER_2016_DUTCH_FULL_BASE = 'Windows_Server-2016-Dutch-Full-Base', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_EXPRESS = 'Windows_Server-2016-English-Full-SQL_2016_SP2_Express', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_ENTERPRISE = 'Windows_Server-2016-English-Full-SQL_2017_Enterprise', - WINDOWS_SERVER_2016_HUNGARIAN_FULL_BASE = 'Windows_Server-2016-Hungarian-Full-Base', - WINDOWS_SERVER_2016_KOREAN_FULL_SQL_2016_SP1_STANDARD = 'Windows_Server-2016-Korean-Full-SQL_2016_SP1_Standard', - WINDOWS_SERVER_2019_SPANISH_FULL_BASE = 'Windows_Server-2019-Spanish-Full-Base', - WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_BASE = 'Windows_Server-2003-R2_SP2-English-64Bit-Base', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_BASE = 'Windows_Server-2008-R2_SP1-English-64Bit-Base', - WINDOWS_SERVER_2008_R2_SP1_LANGUAGE_PACKS_64BIT_SQL_2008_R2_SP3_EXPRESS = 'Windows_Server-2008-R2_SP1-Language_Packs-64Bit-SQL_2008_R2_SP3_Express', - WINDOWS_SERVER_2012_SP2_PORTUGESE_BRAZIL_64BIT_BASE = 'Windows_Server-2008-SP2-Portuguese_Brazil-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_WEB = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP1_Web', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP3_EXPRESS = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2014_SP3_Express', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP2_Enterprise', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_BASE = 'Windows_Server-2012-RTM-Japanese-64Bit-Base', - WINDOWS_SERVER_2019_ENGLISH_FULL_CONTAINERSLATEST = 'Windows_Server-2019-English-Full-ContainersLatest', - WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_ENTERPRISE = 'Windows_Server-2019-English-Full-SQL_2017_Enterprise', - WINDOWS_SERVER_1709_ENGLISH_CORE_CONTAINERSLATEST = 'Windows_Server-1709-English-Core-ContainersLatest', - WINDOWS_SERVER_1803_ENGLISH_CORE_BASE = 'Windows_Server-1803-English-Core-Base', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_WEB = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2012_SP4_Web', - WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-Base', - WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_SQL_2008_SP4_STANDARD = 'Windows_Server-2008-SP2-English-64Bit-SQL_2008_SP4_Standard', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-English-64Bit-Base', - WINDOWS_SERVER_2012_RTM_PORTUGESE_BRAZIL_64BIT_BASE = 'Windows_Server-2012-RTM-Portuguese_Brazil-64Bit-Base', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_WEB = 'Windows_Server-2016-English-Full-SQL_2016_SP1_Web', - WINDOWS_SERVER_2016_ENGLISH_P3 = 'Windows_Server-2016-English-P3', - WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_ENTERPRISE = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP1_Enterprise', - WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_BASE = 'Windows_Server-2003-R2_SP2-Language_Packs-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_CHINESE_TRADITIONAL_HONG_KONG_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Chinese_Traditional_Hong_Kong-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_EXPRESS = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP3_Express', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP2_Enterprise', - WINDOWS_SERVER_2012_RTM_CHINESE_SIMPLIFIED_64BIT_BASE = 'Windows_Server-2012-RTM-Chinese_Simplified-64Bit-Base', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_WEB = 'Windows_Server-2012-RTM-English-64Bit-SQL_2012_SP4_Web', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_WEB = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP3_Web', - WINDOWS_SERVER_2016_JAPANESE_FULL_BASE = 'Windows_Server-2016-Japanese-Full-Base', - WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_EXPRESS = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP1_Express', - WINDOWS_SERVER_1803_ENGLISH_CORE_CONTAINERSLATEST = 'Windows_Server-1803-English-Core-ContainersLatest', - WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2012_SP4_STANDARD = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-SQL_2012_SP4_Standard', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_CORE = 'Windows_Server-2012-R2_RTM-English-64Bit-Core', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_WEB = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP2_Web', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_ENTERPRISE = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP3_Enterprise', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_STANDARD = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP2_Standard', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_2014_SP3_WEB = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP3_Web', - WINDOWS_SERVER_2012_RTM_SWEDISH_64BIT_BASE = 'Windows_Server-2012-RTM-Swedish-64Bit-Base', - WINDOWS_SERVER_2016_CHINESE_SIMPLIFIED_FULL_BASE = 'Windows_Server-2016-Chinese_Simplified-Full-Base', - WINDOWS_SERVER_2019_POLISH_FULL_BASE = 'Windows_Server-2019-Polish-Full-Base', - WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_WEB = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-SQL_2008_R2_SP3_Web', - WINDOWS_SERVER_2008_R2_SP1_PORTUGESE_BRAZIL_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Portuguese_Brazil-64Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_ENTERPRISE = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP1_Enterprise', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2016_SP2_EXPRESS = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP2_Express', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP3_EXPRESS = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP3_Express', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_STANDARD = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP2_Standard', - WINDOWS_SERVER_2016_ENGLISH_CORE_BASE = 'Windows_Server-2016-English-Core-Base', - WINDOWS_SERVER_2016_ENGLISH_FULL_BASE = 'Windows_Server-2016-English-Full-Base', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_WEB = 'Windows_Server-2016-English-Full-SQL_2017_Web', - WINDOWS_SERVER_2019_GERMAN_FULL_BASE = 'Windows_Server-2019-German-Full-Base', - WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_SQL_2005_SP4_STANDARD = 'Windows_Server-2003-R2_SP2-English-64Bit-SQL_2005_SP4_Standard', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2012_SP4_Enterprise', - WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_EXPRESS = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-SQL_2008_R2_SP3_Express', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_ENTERPRISE = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP1_Enterprise', - WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_WEB = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP2_Web', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2008_R2_SP3_EXPRESS = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2008_R2_SP3_Express', - WINDOWS_SERVER_2016_FRENCH_FULL_BASE = 'Windows_Server-2016-French-Full-Base', - WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP2_Enterprise', - WINDOWS_SERVER_2019_CZECH_FULL_BASE = 'Windows_Server-2019-Czech-Full-Base', - WINDOWS_SERVER_1809_ENGLISH_CORE_BASE = 'Windows_Server-1809-English-Core-Base', - WINDOWS_SERVER_1809_ENGLISH_CORE_CONTAINERSLATEST = 'Windows_Server-1809-English-Core-ContainersLatest', - WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_SQL_2005_SP4_EXPRESS = 'Windows_Server-2003-R2_SP2-Language_Packs-64Bit-SQL_2005_SP4_Express', - WINDOWS_SERVER_2012_R2_RTM_TURKISH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Turkish-64Bit-Base', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2012_SP4_WEB = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2012_SP4_Web', - WINDOWS_SERVER_2012_RTM_POLISH_64BIT_BASE = 'Windows_Server-2012-RTM-Polish-64Bit-Base', - WINDOWS_SERVER_2012_RTM_SPANISH_64BIT_BASE = 'Windows_Server-2012-RTM-Spanish-64Bit-Base', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_ENTERPRISE = 'Windows_Server-2016-English-Full-SQL_2016_SP1_Enterprise', - WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_EXPRESS = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP2_Express', - WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2019-English-Full-SQL_2016_SP2_Enterprise', - WINDOWS_SERVER_1709_ENGLISH_CORE_BASE = 'Windows_Server-1709-English-Core-Base', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_61BIT_SQL_2012_RTM_SP2_ENTERPRISE = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2012_RTM_SP2_Enterprise', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_STANDARD = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2012_SP4_Standard', - WINDOWS_SERVER_2008_SP2_PORTUGESE_BRAZIL_32BIT_BASE = 'Windows_Server-2008-SP2-Portuguese_Brazil-32Bit-Base', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP2_STANDARD = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2014_SP2_Standard', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2012_SP4_EXPRESS = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2012_SP4_Express', - WINDOWS_SERVER_2012_RTM_PORTUGESE_PORTUGAL_64BIT_BASE = 'Windows_Server-2012-RTM-Portuguese_Portugal-64Bit-Base', - WINDOWS_SERVER_2016_CZECH_FULL_BASE = 'Windows_Server-2016-Czech-Full-Base', - WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_STANDARD = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP1_Standard', - WINDOWS_SERVER_2019_DUTCH_FULL_BASE = 'Windows_Server-2019-Dutch-Full-Base', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_CORE = 'Windows_Server-2008-R2_SP1-English-64Bit-Core', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_WEB = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP2_Web', - WINDOWS_SERVER_2012_R2_RTM_KOREAN_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Korean-64Bit-Base', - WINDOWS_SERVER_2012_RTM_DUTCH_64BIT_BASE = 'Windows_Server-2012-RTM-Dutch-64Bit-Base', - WINDOWS_SERVER_2016_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE = 'Windows_Server-2016-English-64Bit-SQL_2012_SP4_Enterprise', - WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_STANDARD = 'Windows_Server-2016-English-Core-SQL_2016_SP1_Standard', - WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_EXPRESS = 'Windows_Server-2016-English-Core-SQL_2016_SP2_Express', - WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_WEB = 'Windows_Server-2016-English-Core-SQL_2016_SP2_Web', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_STANDARD = 'Windows_Server-2016-English-Full-SQL_2017_Standard', - WINDOWS_SERVER_2019_PORTUGESE_BRAZIL_FULL_BASE = 'Windows_Server-2019-Portuguese_Brazil-Full-Base', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_STANDARD = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2008_R2_SP3_Standard', - WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SHAREPOINT_2010_SP2_FOUNDATION = 'Windows_Server-2008-R2_SP1-English-64Bit-SharePoint_2010_SP2_Foundation', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_P3 = 'Windows_Server-2012-R2_RTM-English-P3', - WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP3_STANDARD = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2014_SP3_Standard', - WINDOWS_SERVER_2012_R2_RTM_SPANISH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Spanish-64Bit-Base', - WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_EXPRESS = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP3_Express', - WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_STANDARD = 'Windows_Server-2016-English-Core-SQL_2016_SP2_Standard', - WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_STANDARD = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP2_Standard', - WINDOWS_SERVER_2019_PORTUGESE_PORTUGAL_FULL_BASE = 'Windows_Server-2019-Portuguese_Portugal-Full-Base', - WINDOWS_SERVER_2019_SWEDISH_FULL_BASE = 'Windows_Server-2019-Swedish-Full-Base', - WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_HYPERV = 'Windows_Server-2012-R2_RTM-English-64Bit-HyperV', - WINDOWS_SERVER_2012_RTM_KOREAN_64BIT_BASE = 'Windows_Server-2012-RTM-Korean-64Bit-Base', - WINDOWS_SERVER_2012_RTM_RUSSIAN_64BIT_BASE = 'Windows_Server-2012-RTM-Russian-64Bit-Base', - WINDOWS_SERVER_2016_CHINESE_TRADITIONAL_FULL_BASE = 'Windows_Server-2016-Chinese_Traditional-Full-Base', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_WEB = 'Windows_Server-2016-English-Full-SQL_2016_SP2_Web', - WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_EXPRESS = 'Windows_Server-2016-English-Full-SQL_2017_Express', -} - -/** - * Representation of a machine to be launched - * - * Combines an AMI ID with an OS. - */ -export class MachineImage { - constructor(public readonly imageId: string, public readonly os: OperatingSystem) { + return { + imageId: ami, + userData: this.props.userData, + osType: OperatingSystemType.LINUX, + }; } } @@ -445,38 +270,4 @@ export class MachineImage { export enum OperatingSystemType { LINUX, WINDOWS, -} - -/** - * Abstraction of OS features we need to be aware of - */ -export abstract class OperatingSystem { - public abstract createUserData(scripts: string[]): string; - abstract get type(): OperatingSystemType; -} - -/** - * OS features specialized for Windows - */ -export class WindowsOS extends OperatingSystem { - public createUserData(scripts: string[]): string { - return `${scripts.join('\n')}`; - } - - get type(): OperatingSystemType { - return OperatingSystemType.WINDOWS; - } -} - -/** - * OS features specialized for Linux - */ -export class LinuxOS extends OperatingSystem { - public createUserData(scripts: string[]): string { - return '#!/bin/bash\n' + scripts.join('\n'); - } - - get type(): OperatingSystemType { - return OperatingSystemType.LINUX; - } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/lib/peer.ts b/packages/@aws-cdk/aws-ec2/lib/peer.ts new file mode 100644 index 0000000000000..2e12fd58dd4d9 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/lib/peer.ts @@ -0,0 +1,166 @@ +import { Connections, IConnectable } from "./connections"; + +/** + * Interface for classes that provide the peer-specification parts of a security group rule + */ +export interface IPeer extends IConnectable { + /** + * Whether the rule can be inlined into a SecurityGroup or not + */ + readonly canInlineRule: boolean; + + /** + * A unique identifier for this connection peer + */ + readonly uniqueId: string; + + /** + * Produce the ingress rule JSON for the given connection + */ + toIngressRuleConfig(): any; + + /** + * Produce the egress rule JSON for the given connection + */ + toEgressRuleConfig(): any; +} + +/** + * Factories for static connection peer + */ +export class Peer { + /** + * Create an IPv4 peer from a CIDR + */ + public static ipv4(cidrIp: string): IPeer { + return new CidrIPv4(cidrIp); + } + + /** + * Any IPv4 address + */ + public static anyIpv4(): IPeer { + return new AnyIPv4(); + } + + /** + * Create an IPv6 peer from a CIDR + */ + public static ipv6(cidrIp: string): IPeer { + return new CidrIPv6(cidrIp); + } + + /** + * Any IPv6 address + */ + public static anyIpv6(): IPeer { + return new AnyIPv6(); + } + + /** + * A prefix list + */ + public static prefixList(prefixListId: string): IPeer { + return new PrefixList(prefixListId); + } + + protected constructor() { + } +} + +/** + * A connection to and from a given IP range + */ +class CidrIPv4 implements IPeer { + public readonly canInlineRule = true; + public readonly connections: Connections = new Connections({ peer: this }); + public readonly uniqueId: string; + + constructor(private readonly cidrIp: string) { + this.uniqueId = cidrIp; + } + + /** + * Produce the ingress rule JSON for the given connection + */ + public toIngressRuleConfig(): any { + return { cidrIp: this.cidrIp }; + } + /** + * Produce the egress rule JSON for the given connection + */ + public toEgressRuleConfig(): any { + return { cidrIp: this.cidrIp }; + } +} + +/** + * Any IPv4 address + */ +class AnyIPv4 extends CidrIPv4 { + constructor() { + super("0.0.0.0/0"); + } +} + +/** + * A connection to a from a given IPv6 range + */ +class CidrIPv6 implements IPeer { + public readonly canInlineRule = true; + public readonly connections: Connections = new Connections({ peer: this }); + public readonly uniqueId: string; + + constructor(private readonly cidrIpv6: string) { + this.uniqueId = cidrIpv6; + } + + /** + * Produce the ingress rule JSON for the given connection + */ + public toIngressRuleConfig(): any { + return { cidrIpv6: this.cidrIpv6 }; + } + /** + * Produce the egress rule JSON for the given connection + */ + public toEgressRuleConfig(): any { + return { cidrIpv6: this.cidrIpv6 }; + } +} + +/** + * Any IPv6 address + */ +class AnyIPv6 extends CidrIPv6 { + constructor() { + super("::0/0"); + } +} + +/** + * A prefix list + * + * Prefix lists are used to allow traffic to VPC-local service endpoints. + * + * For more information, see this page: + * + * https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-endpoints.html + */ +class PrefixList implements IPeer { + public readonly canInlineRule = false; + public readonly connections: Connections = new Connections({ peer: this }); + public readonly uniqueId: string; + + constructor(private readonly prefixListId: string) { + this.uniqueId = prefixListId; + } + + public toIngressRuleConfig(): any { + return { sourcePrefixListId: this.prefixListId }; + } + + public toEgressRuleConfig(): any { + return { destinationPrefixListId: this.prefixListId }; + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/lib/port.ts b/packages/@aws-cdk/aws-ec2/lib/port.ts new file mode 100644 index 0000000000000..cd8985c4660b0 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/lib/port.ts @@ -0,0 +1,201 @@ +import { Token } from '@aws-cdk/cdk'; + +/** + * Protocol for use in Connection Rules + */ +export enum Protocol { + ALL = '-1', + TCP = 'tcp', + UDP = 'udp', + ICMP = 'icmp', + ICMPV6 = '58', +} + +/** + * Properties to create a port range + */ +export interface PortProps { + /** + * The protocol for the range + */ + readonly protocol: Protocol; + + /** + * The starting port for the range + * + * @default - Not included in the rule + */ + readonly fromPort?: number; + + /** + * The ending port for the range + * + * @default - Not included in the rule + */ + readonly toPort?: number; + + /** + * String representation for this object + */ + readonly stringRepresentation: string; +} + +/** + * Interface for classes that provide the connection-specification parts of a security group rule + */ +export class Port { + /** + * A single TCP port + */ + public static tcp(port: number): Port { + return new Port({ + protocol: Protocol.TCP, + fromPort: port, + toPort: port, + stringRepresentation: renderPort(port), + }); + } + + /** + * A TCP port range + */ + public static tcpRange(startPort: number, endPort: number) { + return new Port({ + protocol: Protocol.TCP, + fromPort: startPort, + toPort: endPort, + stringRepresentation: `${renderPort(startPort)}-${renderPort(endPort)}` + }); + } + + /** + * Any TCP traffic + */ + public static allTcp() { + return new Port({ + protocol: Protocol.TCP, + fromPort: 0, + toPort: 65535, + stringRepresentation: 'ALL PORTS', + }); + } + + /** + * A single UDP port + */ + public static udp(port: number): Port { + return new Port({ + protocol: Protocol.UDP, + fromPort: port, + toPort: port, + stringRepresentation: `UDP ${renderPort(port)}`, + }); + } + + /** + * A UDP port range + */ + public static udpRange(startPort: number, endPort: number) { + return new Port({ + protocol: Protocol.UDP, + fromPort: startPort, + toPort: endPort, + stringRepresentation: `UDP ${renderPort(startPort)}-${renderPort(endPort)}` + }); + } + + /** + * Any UDP traffic + */ + public static allUdp() { + return new Port({ + protocol: Protocol.UDP, + fromPort: 0, + toPort: 65535, + stringRepresentation: 'UDP ALL PORTS', + }); + } + + /** + * A specific combination of ICMP type and code + * + * @see https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml + */ + public static icmpTypeAndCode(type: number, code: number) { + return new Port({ + protocol: Protocol.ICMP, + fromPort: type, + toPort: code, + stringRepresentation: `ICMP Type ${type} Code ${code}` + }); + } + + /** + * All codes for a single ICMP type + */ + public static icmpType(type: number): Port { + return new Port({ + protocol: Protocol.ICMP, + fromPort: type, + toPort: -1, + stringRepresentation: `ICMP Type ${type}`, + }); + } + + /** + * ICMP ping (echo) traffic + */ + public static icmpPing() { + return Port.icmpType(8); + } + + /** + * All ICMP traffic + */ + public static allIcmp() { + return new Port({ + protocol: Protocol.ICMP, + fromPort: -1, + toPort: -1, + stringRepresentation: 'ALL ICMP', + }); + } + + /** + * All traffic + */ + public static allTraffic() { + return new Port({ + protocol: Protocol.ALL, + stringRepresentation: 'ALL TRAFFIC', + }); + } + + /** + * Whether the rule containing this port range can be inlined into a securitygroup or not. + */ + public readonly canInlineRule: boolean; + + constructor(private readonly props: PortProps) { + this.canInlineRule = !Token.isUnresolved(props.fromPort) && !Token.isUnresolved(props.toPort); + } + + /** + * Produce the ingress/egress rule JSON for the given connection + */ + public toRuleJSON(): any { + return { + ipProtocol: this.props.protocol, + fromPort: this.props.fromPort, + toPort: this.props.toPort, + }; + } + + public toString(): string { + return this.props.stringRepresentation; + } +} + +function renderPort(port: number) { + return Token.isUnresolved(port) ? `{IndirectPort}` : port.toString(); +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group-rule.ts b/packages/@aws-cdk/aws-ec2/lib/security-group-rule.ts deleted file mode 100644 index 3cea0347f1020..0000000000000 --- a/packages/@aws-cdk/aws-ec2/lib/security-group-rule.ts +++ /dev/null @@ -1,376 +0,0 @@ -import { Token } from '@aws-cdk/cdk'; -import { Connections, IConnectable } from "./connections"; - -/** - * Interface for classes that provide the peer-specification parts of a security group rule - */ -export interface ISecurityGroupRule { - /** - * Whether the rule can be inlined into a SecurityGroup or not - */ - readonly canInlineRule: boolean; - - /** - * A unique identifier for this connection peer - */ - readonly uniqueId: string; - - /** - * Produce the ingress rule JSON for the given connection - */ - toIngressRuleJSON(): any; - - /** - * Produce the egress rule JSON for the given connection - */ - toEgressRuleJSON(): any; -} - -/** - * A connection to and from a given IP range - */ -export class CidrIPv4 implements ISecurityGroupRule, IConnectable { - public readonly canInlineRule = true; - public readonly connections: Connections = new Connections({ securityGroupRule: this }); - public readonly uniqueId: string; - - constructor(private readonly cidrIp: string) { - this.uniqueId = cidrIp; - } - - /** - * Produce the ingress rule JSON for the given connection - */ - public toIngressRuleJSON(): any { - return { cidrIp: this.cidrIp }; - } - /** - * Produce the egress rule JSON for the given connection - */ - public toEgressRuleJSON(): any { - return { cidrIp: this.cidrIp }; - } -} - -/** - * Any IPv4 address - */ -export class AnyIPv4 extends CidrIPv4 { - constructor() { - super("0.0.0.0/0"); - } -} - -/** - * A connection to a from a given IPv6 range - */ -export class CidrIPv6 implements ISecurityGroupRule, IConnectable { - public readonly canInlineRule = true; - public readonly connections: Connections = new Connections({ securityGroupRule: this }); - public readonly uniqueId: string; - - constructor(private readonly cidrIpv6: string) { - this.uniqueId = cidrIpv6; - } - - /** - * Produce the ingress rule JSON for the given connection - */ - public toIngressRuleJSON(): any { - return { cidrIpv6: this.cidrIpv6 }; - } - /** - * Produce the egress rule JSON for the given connection - */ - public toEgressRuleJSON(): any { - return { cidrIpv6: this.cidrIpv6 }; - } -} - -/** - * Any IPv6 address - */ -export class AnyIPv6 extends CidrIPv6 { - constructor() { - super("::0/0"); - } -} - -/** - * A prefix list - * - * Prefix lists are used to allow traffic to VPC-local service endpoints. - * - * For more information, see this page: - * - * https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-endpoints.html - */ -export class PrefixList implements ISecurityGroupRule, IConnectable { - public readonly canInlineRule = false; - public readonly connections: Connections = new Connections({ securityGroupRule: this }); - public readonly uniqueId: string; - - constructor(private readonly prefixListId: string) { - this.uniqueId = prefixListId; - } - - public toIngressRuleJSON(): any { - return { sourcePrefixListId: this.prefixListId }; - } - - public toEgressRuleJSON(): any { - return { destinationPrefixListId: this.prefixListId }; - } -} - -/** - * Interface for classes that provide the connection-specification parts of a security group rule - */ -export interface IPortRange { - /** - * Whether the rule containing this port range can be inlined into a securitygroup or not. - */ - readonly canInlineRule: boolean; - - /** - * Produce the ingress/egress rule JSON for the given connection - */ - toRuleJSON(): any; -} - -/** - * Protocol for use in Connection Rules - */ -export enum Protocol { - ALL = '-1', - TCP = 'tcp', - UDP = 'udp', - ICMP = 'icmp', - ICMP_V6 = '58', -} - -/** - * A single TCP port - */ -export class TcpPort implements IPortRange { - public readonly canInlineRule = !Token.isUnresolved(this.port); - - constructor(private readonly port: number) { - } - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.TCP, - fromPort: this.port, - toPort: this.port - }; - } - - public toString() { - return Token.isUnresolved(this.port) ? `{IndirectPort}` : this.port.toString(); - } -} - -/** - * A TCP port range - */ -export class TcpPortRange implements IPortRange { - public readonly canInlineRule = !Token.isUnresolved(this.startPort) && !Token.isUnresolved(this.endPort); - - constructor(private readonly startPort: number, private readonly endPort: number) { - } - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.TCP, - fromPort: this.startPort, - toPort: this.endPort - }; - } - - public toString() { - return `${this.startPort}-${this.endPort}`; - } -} - -/** - * All TCP Ports - */ -export class TcpAllPorts implements IPortRange { - public readonly canInlineRule = true; - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.TCP, - fromPort: 0, - toPort: 65535 - }; - } - - public toString() { - return 'ALL PORTS'; - } -} - -/** - * A single UDP port - */ -export class UdpPort implements IPortRange { - public readonly canInlineRule = !Token.isUnresolved(this.port); - - constructor(private readonly port: number) { - } - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.UDP, - fromPort: this.port, - toPort: this.port - }; - } - - public toString() { - const port = Token.isUnresolved(this.port) ? '{IndirectPort}' : this.port; - return `UDP ${port}`; - } -} - -/** - * A UDP port range - */ -export class UdpPortRange implements IPortRange { - public readonly canInlineRule = !Token.isUnresolved(this.startPort) && !Token.isUnresolved(this.endPort); - - constructor(private readonly startPort: number, private readonly endPort: number) { - } - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.UDP, - fromPort: this.startPort, - toPort: this.endPort - }; - } - - public toString() { - return `UDP ${this.startPort}-${this.endPort}`; - } -} - -/** - * All UDP Ports - */ -export class UdpAllPorts implements IPortRange { - public readonly canInlineRule = true; - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.UDP, - fromPort: 0, - toPort: 65535 - }; - } - - public toString() { - return 'UDP ALL PORTS'; - } -} - -/** - * A set of matching ICMP Type & Code - */ -export class IcmpTypeAndCode implements IPortRange { - public readonly canInlineRule = !Token.isUnresolved(this.type) && !Token.isUnresolved(this.code); - - constructor(private readonly type: number, private readonly code: number) { - } - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.ICMP, - fromPort: this.type, - toPort: this.code - }; - } - - public toString() { - return `ICMP Type ${this.type} Code ${this.code}`; - } -} - -/** - * ICMP Ping traffic - */ -export class IcmpPing implements IPortRange { - public readonly canInlineRule = true; - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.ICMP, - fromPort: 8, - toPort: -1 - }; - } - - public toString() { - return `ICMP PING`; - } -} - -/** - * All ICMP Codes for a given ICMP Type - */ -export class IcmpAllTypeCodes implements IPortRange { - public readonly canInlineRule = !Token.isUnresolved(this.type); - - constructor(private readonly type: number) { - } - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.ICMP, - fromPort: this.type, - toPort: -1 - }; - } - - public toString() { - return `ICMP Type ${this.type}`; - } -} - -/** - * All ICMP Types & Codes - */ -export class IcmpAllTypesAndCodes implements IPortRange { - public readonly canInlineRule = true; - - public toRuleJSON(): any { - return { - ipProtocol: Protocol.ICMP, - fromPort: -1, - toPort: -1 - }; - } - - public toString() { - return 'ALL ICMP'; - } -} - -/** - * All Traffic - */ -export class AllTraffic implements IPortRange { - public readonly canInlineRule = true; - - public toRuleJSON(): any { - return { - ipProtocol: '-1', - }; - } - - public toString() { - return 'ALL TRAFFIC'; - } -} diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group.ts b/packages/@aws-cdk/aws-ec2/lib/security-group.ts index d63d2b8f187e4..eaaa1cb8d54fc 100644 --- a/packages/@aws-cdk/aws-ec2/lib/security-group.ts +++ b/packages/@aws-cdk/aws-ec2/lib/security-group.ts @@ -1,12 +1,13 @@ import { Construct, IResource, Lazy, PhysicalName, Resource, ResourceProps, Stack } from '@aws-cdk/cdk'; -import { Connections, IConnectable } from './connections'; +import { Connections } from './connections'; import { CfnSecurityGroup, CfnSecurityGroupEgress, CfnSecurityGroupIngress } from './ec2.generated'; -import { IPortRange, ISecurityGroupRule } from './security-group-rule'; +import { IPeer } from './peer'; +import { Port } from './port'; import { IVpc } from './vpc'; const SECURITY_GROUP_SYMBOL = Symbol.for('@aws-cdk/iam.SecurityGroup'); -export interface ISecurityGroup extends IResource, ISecurityGroupRule, IConnectable { +export interface ISecurityGroup extends IResource, IPeer { /** * ID for the current security group * @attribute @@ -22,7 +23,7 @@ export interface ISecurityGroup extends IResource, ISecurityGroupRule, IConnecta * peer is also a SecurityGroup, the rule object is created under the remote * SecurityGroup object. */ - addIngressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string, remoteRule?: boolean): void; + addIngressRule(peer: IPeer, connection: Port, description?: string, remoteRule?: boolean): void; /** * Add an egress rule for the current security group @@ -33,7 +34,7 @@ export interface ISecurityGroup extends IResource, ISecurityGroupRule, IConnecta * peer is also a SecurityGroup, the rule object is created under the remote * SecurityGroup object. */ - addEgressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string, remoteRule?: boolean): void; + addEgressRule(peer: IPeer, connection: Port, description?: string, remoteRule?: boolean): void; } /** @@ -51,11 +52,7 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { public readonly canInlineRule = false; public readonly connections: Connections = new Connections({ securityGroups: [this] }); - - /** - * FIXME: Where to place this?? - */ - public readonly defaultPortRange?: IPortRange; + public readonly defaultPort?: Port; constructor(scope: Construct, id: string, props?: ResourceProps) { super(scope, id, props); @@ -67,7 +64,7 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { return this.node.uniqueId; } - public addIngressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string, remoteRule?: boolean) { + public addIngressRule(peer: IPeer, connection: Port, description?: string, remoteRule?: boolean) { if (description === undefined) { description = `from ${peer.uniqueId}:${connection}`; } @@ -78,14 +75,14 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { if (scope.node.tryFindChild(id) === undefined) { new CfnSecurityGroupIngress(scope, id, { groupId: this.securityGroupId, - ...peer.toIngressRuleJSON(), + ...peer.toIngressRuleConfig(), ...connection.toRuleJSON(), description }); } } - public addEgressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string, remoteRule?: boolean) { + public addEgressRule(peer: IPeer, connection: Port, description?: string, remoteRule?: boolean) { if (description === undefined) { description = `to ${peer.uniqueId}:${connection}`; } @@ -96,18 +93,18 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { if (scope.node.tryFindChild(id) === undefined) { new CfnSecurityGroupEgress(scope, id, { groupId: this.securityGroupId, - ...peer.toEgressRuleJSON(), + ...peer.toEgressRuleConfig(), ...connection.toRuleJSON(), description }); } } - public toIngressRuleJSON(): any { + public toIngressRuleConfig(): any { return { sourceSecurityGroupId: this.securityGroupId }; } - public toEgressRuleJSON(): any { + public toEgressRuleConfig(): any { return { destinationSecurityGroupId: this.securityGroupId }; } } @@ -162,8 +159,8 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { */ function determineRuleScope( group: SecurityGroupBase, - peer: ISecurityGroupRule, - connection: IPortRange, + peer: IPeer, + connection: Port, fromTo: 'from' | 'to', remoteRule?: boolean): [SecurityGroupBase, string] { @@ -289,7 +286,7 @@ export class SecurityGroup extends SecurityGroupBase { this.addDefaultEgressRule(); } - public addIngressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string, remoteRule?: boolean) { + public addIngressRule(peer: IPeer, connection: Port, description?: string, remoteRule?: boolean) { if (!peer.canInlineRule || !connection.canInlineRule) { super.addIngressRule(peer, connection, description, remoteRule); return; @@ -300,13 +297,13 @@ export class SecurityGroup extends SecurityGroupBase { } this.addDirectIngressRule({ - ...peer.toIngressRuleJSON(), + ...peer.toIngressRuleConfig(), ...connection.toRuleJSON(), description }); } - public addEgressRule(peer: ISecurityGroupRule, connection: IPortRange, description?: string, remoteRule?: boolean) { + public addEgressRule(peer: IPeer, connection: Port, description?: string, remoteRule?: boolean) { if (this.allowAllOutbound) { // In the case of "allowAllOutbound", we don't add any more rules. There // is only one rule which allows all traffic and that subsumes any other @@ -329,7 +326,7 @@ export class SecurityGroup extends SecurityGroupBase { } const rule = { - ...peer.toEgressRuleJSON(), + ...peer.toEgressRuleConfig(), ...connection.toRuleJSON(), description }; diff --git a/packages/@aws-cdk/aws-ec2/lib/user-data.ts b/packages/@aws-cdk/aws-ec2/lib/user-data.ts new file mode 100644 index 0000000000000..47120a3aca801 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/lib/user-data.ts @@ -0,0 +1,82 @@ +import { OperatingSystemType } from "./machine-image"; + +/** + * Options when constructing UserData for Linux + */ +export interface LinuxUserDataOptions { + /** + * Shebang for the UserData script + * + * @default "#!/bin/bash" + */ + readonly shebang?: string; +} + +/** + * Instance User Data + */ +export abstract class UserData { + /** + * Create a userdata object for Linux hosts + */ + public static forLinux(options: LinuxUserDataOptions = {}): UserData { + return new LinuxUserData(options); + } + + /** + * Create a userdata object for Windows hosts + */ + public static forWindows(): UserData { + return new WindowsUserData(); + } + + public static forOperatingSystem(os: OperatingSystemType): UserData { + switch (os) { + case OperatingSystemType.LINUX: return UserData.forLinux(); + case OperatingSystemType.WINDOWS: return UserData.forWindows(); + } + } + + /** + * Add one or more commands to the user data + */ + public abstract addCommands(...commands: string[]): void; + + /** + * Render the UserData for use in a construct + */ + public abstract render(): string; +} + +class LinuxUserData extends UserData { + private readonly lines: string[] = []; + + constructor(private readonly props: LinuxUserDataOptions = {}) { + super(); + } + + public addCommands(...commands: string[]) { + this.lines.push(...commands); + } + + public render(): string { + const shebang = this.props.shebang !== undefined ? this.props.shebang : '#!/bin/bash'; + return [shebang, ...this.lines].join('\n'); + } +} + +class WindowsUserData extends UserData { + private readonly lines: string[] = []; + + constructor() { + super(); + } + + public addCommands(...commands: string[]) { + this.lines.push(...commands); + } + + public render(): string { + return `${this.lines.join('\n')}`; + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/lib/util.ts b/packages/@aws-cdk/aws-ec2/lib/util.ts index b880a4a11f236..6dc48af4350d5 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 { ISubnet, Subnet, SubnetType } from './vpc'; +import { ISubnet, SelectedSubnets, Subnet, SubnetType } from './vpc'; /** * Turn an arbitrary string into one that can be used as a CloudFormation identifier by stripping special characters @@ -106,3 +106,18 @@ export function range(n: number): number[] { } return ret; } + +/** + * Return the union of table IDs from all selected subnets + */ +export function allRouteTableIds(...ssns: SelectedSubnets[]): string[] { + const ret = new Set(); + for (const ssn of ssns) { + for (const subnet of ssn.subnets) { + if (subnet.routeTable) { + ret.add(subnet.routeTable.routeTableId); + } + } + } + return Array.from(ret); +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts index 42de37c85c24b..05d28d1825a6c 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts @@ -2,8 +2,9 @@ import iam = require('@aws-cdk/aws-iam'); import { Aws, Construct, IResource, Lazy, Resource } from '@aws-cdk/cdk'; import { Connections, IConnectable } from './connections'; import { CfnVPCEndpoint } from './ec2.generated'; +import { Port } from './port'; import { SecurityGroup } from './security-group'; -import { TcpPort } from './security-group-rule'; +import { allRouteTableIds } from './util'; import { IVpc, SubnetSelection, SubnetType } from './vpc'; /** @@ -165,7 +166,7 @@ export class GatewayVpcEndpoint extends VpcEndpoint implements IGatewayVpcEndpoi super(scope, id); const subnets = props.subnets || [{ subnetType: SubnetType.PRIVATE }]; - const routeTableIds = [...new Set(Array().concat(...subnets.map(s => props.vpc.selectSubnets(s).routeTableIds)))]; + const routeTableIds = allRouteTableIds(...subnets.map(s => props.vpc.selectSubnets(s))); if (routeTableIds.length === 0) { throw new Error(`Can't add a gateway endpoint to VPC; route table IDs are not available`); @@ -314,7 +315,7 @@ export class InterfaceVpcEndpoint extends VpcEndpoint implements IInterfaceVpcEn public readonly vpcEndpointId = attrs.vpcEndpointId; public readonly securityGroupId = attrs.securityGroupId; public readonly connections = new Connections({ - defaultPortRange: new TcpPort(attrs.port), + defaultPort: Port.tcp(attrs.port), securityGroups: [SecurityGroup.fromSecurityGroupId(this, 'SecurityGroup', attrs.securityGroupId)], }); } @@ -364,7 +365,7 @@ export class InterfaceVpcEndpoint extends VpcEndpoint implements IInterfaceVpcEn }); this.securityGroupId = securityGroup.securityGroupId; this.connections = new Connections({ - defaultPortRange: new TcpPort(props.service.port), + defaultPort: Port.tcp(props.service.port), securityGroups: [securityGroup] }); diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index b7c65cde4a86e..aa5082a4826da 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -1,19 +1,10 @@ -import { - ConcreteDependable, - Construct, - ContextProvider, - DependableTrait, - IConstruct, - IDependable, - IResource, - Resource, - Stack, - Tag } from '@aws-cdk/cdk'; +import { ConcreteDependable, Construct, ContextProvider, DependableTrait, IConstruct, + IDependable, IResource, Resource, Stack, Tag } from '@aws-cdk/cdk'; import cxapi = require('@aws-cdk/cx-api'); 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, ImportSubnetGroup, subnetId, subnetName } from './util'; +import { allRouteTableIds, defaultSubnetName, ImportSubnetGroup, subnetId, subnetName } from './util'; import { GatewayVpcEndpoint, GatewayVpcEndpointAwsService, GatewayVpcEndpointOptions } from './vpc-endpoint'; import { InterfaceVpcEndpoint, InterfaceVpcEndpointOptions } from './vpc-endpoint'; import { VpcLookupOptions } from './vpc-lookup'; @@ -38,10 +29,20 @@ export interface ISubnet extends IResource { */ readonly internetConnectivityEstablished: IDependable; + /** + * The route table for this subnet + */ + readonly routeTable?: IRouteTable; +} + +/** + * An absract route table + */ +export interface IRouteTable { /** * Route table ID */ - readonly routeTableId?: string; + readonly routeTableId: string; } export interface IVpc extends IResource { @@ -71,25 +72,14 @@ export interface IVpc extends IResource { */ readonly availabilityZones: string[]; - /** - * Region where this VPC is located - */ - readonly region: string; - /** * Identifier for the VPN gateway */ readonly vpnGatewayId?: string; - /** - * Return IDs of the subnets appropriate for the given selection strategy - * - * Requires that at least one subnet is matched, throws a descriptive - * error message otherwise. - * - * @deprecated Use selectSubnets() instead. + * Dependable that can be depended upon to force internet connectivity established on the VPC */ - selectSubnetIds(selection?: SubnetSelection): string[]; + readonly internetConnectivityEstablished: IDependable; /** * Return information on the subnets appropriate for the given selection strategy @@ -99,11 +89,6 @@ export interface IVpc extends IResource { */ selectSubnets(selection?: SubnetSelection): SelectedSubnets; - /** - * Return whether all of the given subnets are from the VPC's public subnets. - */ - isPublicSubnets(subnetIds: string[]): boolean; - /** * Adds a new VPN connection to this VPC */ @@ -206,14 +191,19 @@ export interface SelectedSubnets { readonly availabilityZones: string[]; /** - * Route table IDs of each respective subnet + * Dependency representing internet connectivity for these subnets + */ + readonly internetConnectivityEstablished: IDependable; + + /** + * Selected subnet objects */ - readonly routeTableIds: string[]; + readonly subnets: ISubnet[]; /** - * Dependency representing internet connectivity for these subnets + * Whether any of the given subnets are from the VPC's public subnets. */ - readonly internetConnectedDependency: IDependable; + readonly hasPublic: boolean; } /** @@ -254,28 +244,26 @@ abstract class VpcBase extends Resource implements IVpc { /** * Dependencies for internet connectivity */ - public readonly internetDependencies = new Array(); + public abstract readonly internetConnectivityEstablished: IDependable; /** * Dependencies for NAT connectivity */ - public readonly natDependencies = new Array(); - - public selectSubnetIds(selection?: SubnetSelection): string[] { - return this.selectSubnets(selection).subnetIds; - } + protected readonly natDependencies = new Array(); /** * Returns IDs of selected subnets */ public selectSubnets(selection: SubnetSelection = {}): SelectedSubnets { const subnets = this.selectSubnetObjects(selection); + const pubs = new Set(this.publicSubnets); return { subnetIds: subnets.map(s => s.subnetId), availabilityZones: subnets.map(s => s.availabilityZone), - routeTableIds: subnets.map(s => s.routeTableId).filter(notUndefined), // Possibly don't have this information - internetConnectedDependency: tap(new CompositeDependable(), d => subnets.forEach(s => d.add(s.internetConnectivityEstablished))), + internetConnectivityEstablished: tap(new CompositeDependable(), d => subnets.forEach(s => d.add(s.internetConnectivityEstablished))), + subnets, + hasPublic: subnets.some(s => pubs.has(s)) }; } @@ -299,21 +287,6 @@ abstract class VpcBase extends Resource implements IVpc { }); } - /** - * Return whether all of the given subnets are from the VPC's public subnets. - */ - public isPublicSubnets(subnetIds: string[]): boolean { - const pubIds = new Set(this.publicSubnets.map(n => n.subnetId)); - return subnetIds.every(pubIds.has.bind(pubIds)); - } - - /** - * The region where this VPC is defined - */ - public get region(): string { - return Stack.of(this).region; - } - /** * Return the subnets appropriate for the placement strategy */ @@ -631,6 +604,7 @@ export interface SubnetConfiguration { * VpcNetwork deploys an AWS VPC, with public and private subnets per Availability Zone. * For example: * + * ```ts * import { Vpc } from '@aws-cdk/aws-ec2' * * const vpc = new Vpc(this, { @@ -646,6 +620,7 @@ export interface SubnetConfiguration { * for (let subnet of vpc.privateSubnets) { * * } + * ``` * * @resource AWS::EC2::VPC */ @@ -757,6 +732,8 @@ export class Vpc extends VpcBase { */ public readonly vpnGatewayId?: string; + public readonly internetConnectivityEstablished: IDependable; + /** * The VPC resource */ @@ -777,6 +754,8 @@ export class Vpc extends VpcBase { */ private subnetConfiguration: SubnetConfiguration[] = []; + private readonly _internetConnectivityEstablished = new ConcreteDependable(); + /** * VpcNetwork creates a VPC that spans a whole region. * It will automatically divide the provided VPC CIDR range, and create public and private subnets per Availability Zone. @@ -799,6 +778,7 @@ export class Vpc extends VpcBase { const enableDnsHostnames = props.enableDnsHostnames == null ? true : props.enableDnsHostnames; const enableDnsSupport = props.enableDnsSupport == null ? true : props.enableDnsSupport; const instanceTenancy = props.defaultInstanceTenancy || 'default'; + this.internetConnectivityEstablished = this._internetConnectivityEstablished; // Define a VPC using the provided CIDR range this.resource = new CfnVPC(this, 'Resource', { @@ -834,7 +814,7 @@ export class Vpc extends VpcBase { if (allowOutbound) { const igw = new CfnInternetGateway(this, 'IGW', { }); - this.internetDependencies.push(igw); + this._internetConnectivityEstablished.add(igw); const att = new CfnVPCGatewayAttachment(this, 'VPCGW', { internetGatewayId: igw.ref, vpcId: this.resource.ref @@ -877,7 +857,7 @@ export class Vpc extends VpcBase { // Propagate routes on route tables associated with the right subnets const vpnRoutePropagation = props.vpnRoutePropagation || [{ subnetType: SubnetType.PRIVATE }]; - const routeTableIds = [...new Set(Array().concat(...vpnRoutePropagation.map(s => this.selectSubnets(s).routeTableIds)))]; + const routeTableIds = allRouteTableIds(...vpnRoutePropagation.map(s => this.selectSubnets(s))); const routePropagation = new CfnVPNGatewayRoutePropagation(this, 'RoutePropagation', { routeTableIds, vpnGatewayId: this.vpnGatewayId @@ -1123,9 +1103,11 @@ export class Subnet extends Resource implements ISubnet { /** * The routeTableId attached to this subnet. */ - public readonly routeTableId?: string; + public readonly routeTable: IRouteTable; - private readonly internetDependencies = new ConcreteDependable(); + public readonly internetConnectivityEstablished: IDependable; + + private readonly _internetConnectivityEstablished = new ConcreteDependable(); constructor(scope: Construct, id: string, props: SubnetProps) { super(scope, id); @@ -1150,17 +1132,15 @@ export class Subnet extends Resource implements ISubnet { const table = new CfnRouteTable(this, 'RouteTable', { vpcId: props.vpcId, }); - this.routeTableId = table.ref; + this.routeTable = { routeTableId: table.ref }; // Associate the public route table for this subnet, to this subnet new CfnSubnetRouteTableAssociation(this, 'RouteTableAssociation', { subnetId: this.subnetId, routeTableId: table.ref }); - } - public get internetConnectivityEstablished(): IDependable { - return this.internetDependencies; + this.internetConnectivityEstablished = this._internetConnectivityEstablished; } /** @@ -1172,7 +1152,7 @@ export class Subnet extends Resource implements ISubnet { */ public addDefaultInternetRoute(gatewayId: string, gatewayAttachment: IDependable) { const route = new CfnRoute(this, `DefaultRoute`, { - routeTableId: this.routeTableId!, + routeTableId: this.routeTable.routeTableId, destinationCidrBlock: '0.0.0.0/0', gatewayId }); @@ -1180,7 +1160,7 @@ export class Subnet extends Resource implements ISubnet { // Since the 'route' depends on the gateway attachment, just // depending on the route is enough. - this.internetDependencies.add(route); + this._internetConnectivityEstablished.add(route); } /** @@ -1189,11 +1169,11 @@ export class Subnet extends Resource implements ISubnet { */ public addDefaultNatRoute(natGatewayId: string) { const route = new CfnRoute(this, `DefaultRoute`, { - routeTableId: this.routeTableId!, + routeTableId: this.routeTable.routeTableId, destinationCidrBlock: '0.0.0.0/0', natGatewayId }); - this.internetDependencies.add(route); + this._internetConnectivityEstablished.add(route); } } @@ -1269,6 +1249,7 @@ class ImportedVpc extends VpcBase { public readonly isolatedSubnets: ISubnet[]; public readonly availabilityZones: string[]; public readonly vpnGatewayId?: string; + public readonly internetConnectivityEstablished: IDependable = new ConcreteDependable(); constructor(scope: Construct, id: string, props: VpcAttributes) { super(scope, id); @@ -1352,15 +1333,11 @@ function tap(x: T, fn: (x: T) => void): T { return x; } -function notUndefined(x: T | undefined): x is T { - return x !== undefined; -} - class ImportedSubnet extends Resource implements ISubnet, IPublicSubnet, IPrivateSubnet { public readonly internetConnectivityEstablished: IDependable = new ConcreteDependable(); public readonly availabilityZone: string; public readonly subnetId: string; - public readonly routeTableId?: string = undefined; + public readonly routeTable: IRouteTable; constructor(scope: Construct, id: string, attrs: SubnetAttributes) { super(scope, id); diff --git a/packages/@aws-cdk/aws-ec2/lib/vpn.ts b/packages/@aws-cdk/aws-ec2/lib/vpn.ts index 45eb809aed8da..3517ad371308a 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpn.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpn.ts @@ -4,7 +4,7 @@ import net = require('net'); import { CfnCustomerGateway, CfnVPNConnection, CfnVPNConnectionRoute } from './ec2.generated'; import { IVpc } from './vpc'; -export interface IVpnConnection extends cdk.IConstruct { +export interface IVpnConnection extends cdk.IResource { /** * The id of the VPN connection. */ @@ -98,7 +98,12 @@ export enum VpnConnectionType { DUMMY = 'dummy' } -export class VpnConnection extends cdk.Construct implements IVpnConnection { +/** + * Define a VPN Connection + * + * @resource AWS::EC2::VPNConnection + */ +export class VpnConnection extends cdk.Resource implements IVpnConnection { /** * Return the given named metric for all VPN connections in the account/region. */ @@ -116,7 +121,7 @@ export class VpnConnection extends cdk.Construct implements IVpnConnection { * @default average over 5 minutes */ public static metricAllTunnelState(props?: cloudwatch.MetricOptions): cloudwatch.Metric { - return this.metricAll('TunnelSate', { statistic: 'avg', ...props }); + return this.metricAll('TunnelState', { statistic: 'avg', ...props }); } /** diff --git a/packages/@aws-cdk/aws-ec2/lib/windows-versions.ts b/packages/@aws-cdk/aws-ec2/lib/windows-versions.ts new file mode 100644 index 0000000000000..aa89f4e6a3bed --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/lib/windows-versions.ts @@ -0,0 +1,232 @@ +/** + * The Windows version to use for the WindowsImage + */ +export enum WindowsVersion { + WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_SQL_2008_SP4_EXPRESS = 'Windows_Server-2008-SP2-English-64Bit-SQL_2008_SP4_Express', + WINDOWS_SERVER_2012_R2_RTM_CHINESE_SIMPLIFIED_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Chinese_Simplified-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_CHINESE_TRADITIONAL_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Chinese_Traditional-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_DUTCH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Dutch-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_ENTERPRISE = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP2_Enterprise', + WINDOWS_SERVER_2012_R2_RTM_HUNGARIAN_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Hungarian-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-Base', + WINDOWS_SERVER_2016_ENGLISH_CORE_CONTAINERS = 'Windows_Server-2016-English-Core-Containers', + WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_WEB = 'Windows_Server-2016-English-Core-SQL_2016_SP1_Web', + WINDOWS_SERVER_2016_GERMAL_FULL_BASE = 'Windows_Server-2016-German-Full-Base', + WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_32BIT_BASE = 'Windows_Server-2003-R2_SP2-Language_Packs-32Bit-Base', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_WEB = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2008_R2_SP3_Web', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_EXPRESS = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2012_SP4_Express', + WINDOWS_SERVER_2012_R2_SP1_PORTUGESE_BRAZIL_64BIT_CORE = 'Windows_Server-2008-R2_SP1-Portuguese_Brazil-64Bit-Core', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_STANDARD = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP2_Standard', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_EXPRESS = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP2_Express', + WINDOWS_SERVER_2012_RTM_ITALIAN_64BIT_BASE = 'Windows_Server-2012-RTM-Italian-64Bit-Base', + WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_EXPRESS = 'Windows_Server-2016-English-Core-SQL_2016_SP1_Express', + WINDOWS_SERVER_2016_ENGLISH_DEEP_LEARNING = 'Windows_Server-2016-English-Deep-Learning', + WINDOWS_SERVER_2019_ITALIAN_FULL_BASE = 'Windows_Server-2019-Italian-Full-Base', + WINDOWS_SERVER_2008_R2_SP1_KOREAN_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Korean-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_EXPRESS = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP1_Express', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_WEB = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP2_Web', + WINDOWS_SERVER_2016_JAPANESE_FULL_FQL_2016_SP2_WEB = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP2_Web', + WINDOWS_SERVER_2016_KOREAN_FULL_BASE = 'Windows_Server-2016-Korean-Full-Base', + WINDOWS_SERVER_2016_KOREAN_FULL_SQL_2016_SP2_STANDARD = 'Windows_Server-2016-Korean-Full-SQL_2016_SP2_Standard', + WINDOWS_SERVER_2016_PORTUGESE_PORTUGAL_FULL_BASE = 'Windows_Server-2016-Portuguese_Portugal-Full-Base', + WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_WEB = 'Windows_Server-2019-English-Full-SQL_2017_Web', + WINDOWS_SERVER_2019_FRENCH_FULL_BASE = 'Windows_Server-2019-French-Full-Base', + WINDOWS_SERVER_2019_KOREAN_FULL_BASE = 'Windows_Server-2019-Korean-Full-Base', + WINDOWS_SERVER_2008_R2_SP1_CHINESE_HONG_KONG_SAR_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Chinese_Hong_Kong_SAR-64Bit-Base', + WINDOWS_SERVER_2008_R2_SP1_CHINESE_PRC_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Chinese_PRC-64Bit-Base', + WINDOWS_SERVER_2012_RTM_FRENCH_64BIT_BASE = 'Windows_Server-2012-RTM-French-64Bit-Base', + WINDOWS_SERVER_2016_ENGLISH_FULL_CONTAINERS = 'Windows_Server-2016-English-Full-Containers', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_STANDARD = 'Windows_Server-2016-English-Full-SQL_2016_SP1_Standard', + WINDOWS_SERVER_2016_RUSSIAN_FULL_BASE = 'Windows_Server-2016-Russian-Full-Base', + WINDOWS_SERVER_2019_CHINESE_SIMPLIFIED_FULL_BASE = 'Windows_Server-2019-Chinese_Simplified-Full-Base', + WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_STANDARD = 'Windows_Server-2019-English-Full-SQL_2016_SP2_Standard', + WINDOWS_SERVER_2019_HUNGARIAN_FULL_BASE = 'Windows_Server-2019-Hungarian-Full-Base', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_EXPRESS = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2008_R2_SP3_Express', + WINDOWS_SERVER_2007_R2_SP1_LANGUAGE_PACKS_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Language_Packs-64Bit-Base', + WINDOWS_SERVER_2008_SP2_ENGLISH_32BIT_BASE = 'Windows_Server-2008-SP2-English-32Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2012_SP4_Enterprise', + WINDOWS_SERVER_2012_RTM_CHINESE_TRADITIONAL_64BIT_BASE = 'Windows_Server-2012-RTM-Chinese_Traditional-64Bit-Base', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2008_R2_SP3_EXPRESS = 'Windows_Server-2012-RTM-English-64Bit-SQL_2008_R2_SP3_Express', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_STANDARD = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP2_Standard', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_EXPRESS = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP2_Express', + WINDOWS_SERVER_2016_POLISH_FULL_BASE = 'Windows_Server-2016-Polish-Full-Base', + WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_WEB = 'Windows_Server-2019-English-Full-SQL_2016_SP2_Web', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_STANDARD = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP3_Standard', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_EXPRESS = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP2_Express', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_DEEP_LEARNING = 'Windows_Server-2012-R2_RTM-English-Deep-Learning', + WINDOWS_SERVER_2012_R2_RTM_GERMAN_64BIT_BASE = 'Windows_Server-2012-R2_RTM-German-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_EXPRESS = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP1_Express', + WINDOWS_SERVER_2012_R2_RTM_RUSSIAN_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Russian-64Bit-Base', + WINDOWS_SERVER_2012_RTM_CHINESE_TRADITIONAL_HONG_KONG_SAR_64BIT_BASE = 'Windows_Server-2012-RTM-Chinese_Traditional_Hong_Kong_SAR-64Bit-Base', + WINDOWS_SERVER_2012_RTM_HUNGARIAN_64BIT_BASE = 'Windows_Server-2012-RTM-Hungarian-64Bit-Base', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_STANDARD = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP3_Standard', + WINDOWS_SERVER_2019_ENGLISH_FULL_HYPERV = 'Windows_Server-2019-English-Full-HyperV', + WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_SQL_2005_SP4_EXPRESS = 'Windows_Server-2003-R2_SP2-English-64Bit-SQL_2005_SP4_Express', + WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2012_SP4_EXPRESS = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-SQL_2012_SP4_Express', + WINDOWS_SERVER_2012_RTM_GERMAN_64BIT_BASE = 'Windows_Server-2012-RTM-German-64Bit-Base', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2008_R2_SP3_STANDARD = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2008_R2_SP3_Standard', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_STANDARD = 'Windows_Server-2016-English-Full-SQL_2016_SP2_Standard', + WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_EXPRESS = 'Windows_Server-2019-English-Full-SQL_2017_Express', + WINDOWS_SERVER_2019_JAPANESE_FULL_BASE = 'Windows_Server-2019-Japanese-Full-Base', + WINDOWS_SERVER_2019_RUSSIAN_FULL_BASE = 'Windows_Server-2019-Russian-Full-Base', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_STANDARD = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP2_Standard', + WINDOWS_SERVER_2012_R2_RTM_ITALIAN_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Italian-64Bit-Base', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_BASE = 'Windows_Server-2012-RTM-English-64Bit-Base', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2008_R2_SP3_STANDARD = 'Windows_Server-2012-RTM-English-64Bit-SQL_2008_R2_SP3_Standard', + WINDOWS_SERVER_2016_ENGLISH_FULL_HYPERV = 'Windows_Server-2016-English-Full-HyperV', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2016-English-Full-SQL_2016_SP2_Enterprise', + WINDOWS_SERVER_2019_CHINESE_TRADITIONAL_FULL_BASE = 'Windows_Server-2019-Chinese_Traditional-Full-Base', + WINDOWS_SERVER_2019_ENGLISH_CORE_BASE = 'Windows_Server-2019-English-Core-Base', + WINDOWS_SERVER_2019_ENGLISH_CORE_CONTAINERSLATEST = 'Windows_Server-2019-English-Core-ContainersLatest', + WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_BASE = 'Windows_Server-2008-SP2-English-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_FRENCH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-French-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_POLISH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Polish-64Bit-Base', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_EXPRESS = 'Windows_Server-2012-RTM-English-64Bit-SQL_2012_SP4_Express', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP3_STANDARD = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP3_Standard', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_2012_SP4_STANDARD = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2012_SP4_Standard', + WINDOWS_SERVER_2016_ENGLISH_CORE_CONTAINERSLATEST = 'Windows_Server-2016-English-Core-ContainersLatest', + WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_EXPRESS = 'Windows_Server-2019-English-Full-SQL_2016_SP2_Express', + WINDOWS_SERVER_2019_TURKISH_FULL_BASE = 'Windows_Server-2019-Turkish-Full-Base', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_EXPRESS = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP2_Express', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_WEB = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP3_Web', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_WEB = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP1_Web', + WINDOWS_SERVER_2012_R2_RTM_PORTUGESE_BRAZIL_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Portuguese_Brazil-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_PORTUGESE_PORTUGAL_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Portuguese_Portugal-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_SWEDISH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Swedish-64Bit-Base', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_EXPRESS = 'Windows_Server-2016-English-Full-SQL_2016_SP1_Express', + WINDOWS_SERVER_2016_ITALIAN_FULL_BASE = 'Windows_Server-2016-Italian-Full-Base', + WINDOWS_SERVER_2016_SPANISH_FULL_BASE = 'Windows_Server-2016-Spanish-Full-Base', + WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_STANDARD = 'Windows_Server-2019-English-Full-SQL_2017_Standard', + WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_SQL_2005_SP4_STANDARD = 'Windows_Server-2003-R2_SP2-Language_Packs-64Bit-SQL_2005_SP4_Standard', + WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_STANDARD = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-SQL_2008_R2_SP3_Standard', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_STANDARD = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP1_Standard', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2007_R2_SP3_WEB = 'Windows_Server-2012-RTM-English-64Bit-SQL_2008_R2_SP3_Web', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_WEB = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP2_Web', + WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2016-English-Core-SQL_2016_SP2_Enterprise', + WINDOWS_SERVER_2016_PORTUGESE_BRAZIL_FULL_BASE = 'Windows_Server-2016-Portuguese_Brazil-Full-Base', + WINDOWS_SERVER_2019_ENGLISH_FULL_BASE = 'Windows_Server-2019-English-Full-Base', + WINDOWS_SERVER_2003_R2_SP2_ENGLISH_32BIT_BASE = 'Windows_Server-2003-R2_SP2-English-32Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_CZECH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Czech-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_STANDARD = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP1_Standard', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP2_EXPRESS = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2014_SP2_Express', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_STANDARD = 'Windows_Server-2012-RTM-English-64Bit-SQL_2012_SP4_Standard', + WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_ENTERPRISE = 'Windows_Server-2016-English-Core-SQL_2016_SP1_Enterprise', + WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_WEB = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP1_Web', + WINDOWS_SERVER_2016_SWEDISH_FULL_BASE = 'Windows_Server-2016-Swedish-Full-Base', + WINDOWS_SERVER_2016_TURKISH_FULL_BASE = 'Windows_Server-2016-Turkish-Full-Base', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_CORE_SQL_2012_SP4_STANDARD = 'Windows_Server-2008-R2_SP1-English-64Bit-Core_SQL_2012_SP4_Standard', +// tslint:disable-next-line: max-line-length + WINDOWS_SERVER_2008_R2_SP1_LANGUAGE_PACKS_64BIT_SQL_2008_R2_SP3_STANDARD = 'Windows_Server-2008-R2_SP1-Language_Packs-64Bit-SQL_2008_R2_SP3_Standard', + WINDOWS_SERVER_2012_RTM_CZECH_64BIT_BASE = 'Windows_Server-2012-RTM-Czech-64Bit-Base', + WINDOWS_SERVER_2012_RTM_TURKISH_64BIT_BASE = 'Windows_Server-2012-RTM-Turkish-64Bit-Base', + WINDOWS_SERVER_2016_DUTCH_FULL_BASE = 'Windows_Server-2016-Dutch-Full-Base', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_EXPRESS = 'Windows_Server-2016-English-Full-SQL_2016_SP2_Express', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_ENTERPRISE = 'Windows_Server-2016-English-Full-SQL_2017_Enterprise', + WINDOWS_SERVER_2016_HUNGARIAN_FULL_BASE = 'Windows_Server-2016-Hungarian-Full-Base', + WINDOWS_SERVER_2016_KOREAN_FULL_SQL_2016_SP1_STANDARD = 'Windows_Server-2016-Korean-Full-SQL_2016_SP1_Standard', + WINDOWS_SERVER_2019_SPANISH_FULL_BASE = 'Windows_Server-2019-Spanish-Full-Base', + WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_BASE = 'Windows_Server-2003-R2_SP2-English-64Bit-Base', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_BASE = 'Windows_Server-2008-R2_SP1-English-64Bit-Base', + WINDOWS_SERVER_2008_R2_SP1_LANGUAGE_PACKS_64BIT_SQL_2008_R2_SP3_EXPRESS = 'Windows_Server-2008-R2_SP1-Language_Packs-64Bit-SQL_2008_R2_SP3_Express', + WINDOWS_SERVER_2012_SP2_PORTUGESE_BRAZIL_64BIT_BASE = 'Windows_Server-2008-SP2-Portuguese_Brazil-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_WEB = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP1_Web', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP3_EXPRESS = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2014_SP3_Express', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP2_Enterprise', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_BASE = 'Windows_Server-2012-RTM-Japanese-64Bit-Base', + WINDOWS_SERVER_2019_ENGLISH_FULL_CONTAINERSLATEST = 'Windows_Server-2019-English-Full-ContainersLatest', + WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_ENTERPRISE = 'Windows_Server-2019-English-Full-SQL_2017_Enterprise', + WINDOWS_SERVER_1709_ENGLISH_CORE_CONTAINERSLATEST = 'Windows_Server-1709-English-Core-ContainersLatest', + WINDOWS_SERVER_1803_ENGLISH_CORE_BASE = 'Windows_Server-1803-English-Core-Base', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_WEB = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2012_SP4_Web', + WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-Base', + WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_SQL_2008_SP4_STANDARD = 'Windows_Server-2008-SP2-English-64Bit-SQL_2008_SP4_Standard', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-English-64Bit-Base', + WINDOWS_SERVER_2012_RTM_PORTUGESE_BRAZIL_64BIT_BASE = 'Windows_Server-2012-RTM-Portuguese_Brazil-64Bit-Base', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_WEB = 'Windows_Server-2016-English-Full-SQL_2016_SP1_Web', + WINDOWS_SERVER_2016_ENGLISH_P3 = 'Windows_Server-2016-English-P3', + WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_ENTERPRISE = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP1_Enterprise', + WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_BASE = 'Windows_Server-2003-R2_SP2-Language_Packs-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_CHINESE_TRADITIONAL_HONG_KONG_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Chinese_Traditional_Hong_Kong-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_EXPRESS = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP3_Express', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP2_Enterprise', + WINDOWS_SERVER_2012_RTM_CHINESE_SIMPLIFIED_64BIT_BASE = 'Windows_Server-2012-RTM-Chinese_Simplified-64Bit-Base', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_WEB = 'Windows_Server-2012-RTM-English-64Bit-SQL_2012_SP4_Web', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_WEB = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP3_Web', + WINDOWS_SERVER_2016_JAPANESE_FULL_BASE = 'Windows_Server-2016-Japanese-Full-Base', + WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_EXPRESS = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP1_Express', + WINDOWS_SERVER_1803_ENGLISH_CORE_CONTAINERSLATEST = 'Windows_Server-1803-English-Core-ContainersLatest', + WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2012_SP4_STANDARD = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-SQL_2012_SP4_Standard', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_CORE = 'Windows_Server-2012-R2_RTM-English-64Bit-Core', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_WEB = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP2_Web', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_ENTERPRISE = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2014_SP3_Enterprise', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_STANDARD = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP2_Standard', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_2014_SP3_WEB = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP3_Web', + WINDOWS_SERVER_2012_RTM_SWEDISH_64BIT_BASE = 'Windows_Server-2012-RTM-Swedish-64Bit-Base', + WINDOWS_SERVER_2016_CHINESE_SIMPLIFIED_FULL_BASE = 'Windows_Server-2016-Chinese_Simplified-Full-Base', + WINDOWS_SERVER_2019_POLISH_FULL_BASE = 'Windows_Server-2019-Polish-Full-Base', + WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_WEB = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-SQL_2008_R2_SP3_Web', + WINDOWS_SERVER_2008_R2_SP1_PORTUGESE_BRAZIL_64BIT_BASE = 'Windows_Server-2008-R2_SP1-Portuguese_Brazil-64Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_ENTERPRISE = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP1_Enterprise', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2016_SP2_EXPRESS = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2016_SP2_Express', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP3_EXPRESS = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP3_Express', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_STANDARD = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP2_Standard', + WINDOWS_SERVER_2016_ENGLISH_CORE_BASE = 'Windows_Server-2016-English-Core-Base', + WINDOWS_SERVER_2016_ENGLISH_FULL_BASE = 'Windows_Server-2016-English-Full-Base', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_WEB = 'Windows_Server-2016-English-Full-SQL_2017_Web', + WINDOWS_SERVER_2019_GERMAN_FULL_BASE = 'Windows_Server-2019-German-Full-Base', + WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_SQL_2005_SP4_STANDARD = 'Windows_Server-2003-R2_SP2-English-64Bit-SQL_2005_SP4_Standard', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2012_SP4_Enterprise', + WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_EXPRESS = 'Windows_Server-2008-R2_SP1-Japanese-64Bit-SQL_2008_R2_SP3_Express', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_ENTERPRISE = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP1_Enterprise', + WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_WEB = 'Windows_Server-2012-RTM-English-64Bit-SQL_2014_SP2_Web', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2008_R2_SP3_EXPRESS = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2008_R2_SP3_Express', + WINDOWS_SERVER_2016_FRENCH_FULL_BASE = 'Windows_Server-2016-French-Full-Base', + WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP2_Enterprise', + WINDOWS_SERVER_2019_CZECH_FULL_BASE = 'Windows_Server-2019-Czech-Full-Base', + WINDOWS_SERVER_1809_ENGLISH_CORE_BASE = 'Windows_Server-1809-English-Core-Base', + WINDOWS_SERVER_1809_ENGLISH_CORE_CONTAINERSLATEST = 'Windows_Server-1809-English-Core-ContainersLatest', + WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_SQL_2005_SP4_EXPRESS = 'Windows_Server-2003-R2_SP2-Language_Packs-64Bit-SQL_2005_SP4_Express', + WINDOWS_SERVER_2012_R2_RTM_TURKISH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Turkish-64Bit-Base', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2012_SP4_WEB = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2012_SP4_Web', + WINDOWS_SERVER_2012_RTM_POLISH_64BIT_BASE = 'Windows_Server-2012-RTM-Polish-64Bit-Base', + WINDOWS_SERVER_2012_RTM_SPANISH_64BIT_BASE = 'Windows_Server-2012-RTM-Spanish-64Bit-Base', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_ENTERPRISE = 'Windows_Server-2016-English-Full-SQL_2016_SP1_Enterprise', + WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_EXPRESS = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP2_Express', + WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_ENTERPRISE = 'Windows_Server-2019-English-Full-SQL_2016_SP2_Enterprise', + WINDOWS_SERVER_1709_ENGLISH_CORE_BASE = 'Windows_Server-1709-English-Core-Base', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_61BIT_SQL_2012_RTM_SP2_ENTERPRISE = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2012_RTM_SP2_Enterprise', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_STANDARD = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2012_SP4_Standard', + WINDOWS_SERVER_2008_SP2_PORTUGESE_BRAZIL_32BIT_BASE = 'Windows_Server-2008-SP2-Portuguese_Brazil-32Bit-Base', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP2_STANDARD = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2014_SP2_Standard', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2012_SP4_EXPRESS = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2012_SP4_Express', + WINDOWS_SERVER_2012_RTM_PORTUGESE_PORTUGAL_64BIT_BASE = 'Windows_Server-2012-RTM-Portuguese_Portugal-64Bit-Base', + WINDOWS_SERVER_2016_CZECH_FULL_BASE = 'Windows_Server-2016-Czech-Full-Base', + WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_STANDARD = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP1_Standard', + WINDOWS_SERVER_2019_DUTCH_FULL_BASE = 'Windows_Server-2019-Dutch-Full-Base', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_CORE = 'Windows_Server-2008-R2_SP1-English-64Bit-Core', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_WEB = 'Windows_Server-2012-R2_RTM-English-64Bit-SQL_2016_SP2_Web', + WINDOWS_SERVER_2012_R2_RTM_KOREAN_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Korean-64Bit-Base', + WINDOWS_SERVER_2012_RTM_DUTCH_64BIT_BASE = 'Windows_Server-2012-RTM-Dutch-64Bit-Base', + WINDOWS_SERVER_2016_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE = 'Windows_Server-2016-English-64Bit-SQL_2012_SP4_Enterprise', + WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_STANDARD = 'Windows_Server-2016-English-Core-SQL_2016_SP1_Standard', + WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_EXPRESS = 'Windows_Server-2016-English-Core-SQL_2016_SP2_Express', + WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_WEB = 'Windows_Server-2016-English-Core-SQL_2016_SP2_Web', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_STANDARD = 'Windows_Server-2016-English-Full-SQL_2017_Standard', + WINDOWS_SERVER_2019_PORTUGESE_BRAZIL_FULL_BASE = 'Windows_Server-2019-Portuguese_Brazil-Full-Base', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_STANDARD = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2008_R2_SP3_Standard', + WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SHAREPOINT_2010_SP2_FOUNDATION = 'Windows_Server-2008-R2_SP1-English-64Bit-SharePoint_2010_SP2_Foundation', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_P3 = 'Windows_Server-2012-R2_RTM-English-P3', + WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP3_STANDARD = 'Windows_Server-2012-R2_RTM-Japanese-64Bit-SQL_2014_SP3_Standard', + WINDOWS_SERVER_2012_R2_RTM_SPANISH_64BIT_BASE = 'Windows_Server-2012-R2_RTM-Spanish-64Bit-Base', + WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_EXPRESS = 'Windows_Server-2012-RTM-Japanese-64Bit-SQL_2014_SP3_Express', + WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_STANDARD = 'Windows_Server-2016-English-Core-SQL_2016_SP2_Standard', + WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_STANDARD = 'Windows_Server-2016-Japanese-Full-SQL_2016_SP2_Standard', + WINDOWS_SERVER_2019_PORTUGESE_PORTUGAL_FULL_BASE = 'Windows_Server-2019-Portuguese_Portugal-Full-Base', + WINDOWS_SERVER_2019_SWEDISH_FULL_BASE = 'Windows_Server-2019-Swedish-Full-Base', + WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_HYPERV = 'Windows_Server-2012-R2_RTM-English-64Bit-HyperV', + WINDOWS_SERVER_2012_RTM_KOREAN_64BIT_BASE = 'Windows_Server-2012-RTM-Korean-64Bit-Base', + WINDOWS_SERVER_2012_RTM_RUSSIAN_64BIT_BASE = 'Windows_Server-2012-RTM-Russian-64Bit-Base', + WINDOWS_SERVER_2016_CHINESE_TRADITIONAL_FULL_BASE = 'Windows_Server-2016-Chinese_Traditional-Full-Base', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_WEB = 'Windows_Server-2016-English-Full-SQL_2016_SP2_Web', + WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_EXPRESS = 'Windows_Server-2016-English-Full-SQL_2017_Express', +} diff --git a/packages/@aws-cdk/aws-ec2/package.json b/packages/@aws-cdk/aws-ec2/package.json index 5674617487f66..1208c53761a40 100644 --- a/packages/@aws-cdk/aws-ec2/package.json +++ b/packages/@aws-cdk/aws-ec2/package.json @@ -89,6 +89,8 @@ }, "awslint": { "exclude": [ + "resource-attribute:@aws-cdk/aws-ec2.ISecurityGroup.securityGroupVpcId", + "props-physical-name:@aws-cdk/aws-ec2.VpnConnectionProps", "props-physical-name:@aws-cdk/aws-ec2.GatewayVpcEndpointProps", "props-physical-name:@aws-cdk/aws-ec2.PrivateSubnetProps", "props-physical-name:@aws-cdk/aws-ec2.PublicSubnetProps", diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc.expected.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc.expected.json index fc6f104af9b79..73f724bf4e225 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc.expected.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc.expected.json @@ -510,7 +510,7 @@ "SecurityGroupIngress": [ { "CidrIp": "0.0.0.0/0", - "Description": "from 0.0.0.0/0:ICMP PING", + "Description": "from 0.0.0.0/0:ICMP Type 8", "FromPort": 8, "IpProtocol": "icmp", "ToPort": -1 @@ -557,4 +557,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts index b10c05f6ac4a9..61eee83200066 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts @@ -10,16 +10,16 @@ const vpc = new ec2.Vpc(stack, 'MyVpc'); const sg = new ec2.SecurityGroup(stack, 'SG', { vpc }); const rules = [ - new ec2.IcmpPing(), - new ec2.IcmpAllTypeCodes(128), - new ec2.IcmpAllTypesAndCodes(), - new ec2.UdpAllPorts(), - new ec2.UdpPort(123), - new ec2.UdpPortRange(800, 801), + ec2.Port.icmpPing(), + ec2.Port.icmpType(128), + ec2.Port.allIcmp(), + ec2.Port.allUdp(), + ec2.Port.udp(123), + ec2.Port.udpRange(800, 801), ]; for (const rule of rules) { - sg.addIngressRule(new ec2.AnyIPv4(), rule); + sg.addIngressRule(ec2.Peer.anyIpv4(), rule); } app.synth(); diff --git a/packages/@aws-cdk/aws-ec2/test/test.connections.ts b/packages/@aws-cdk/aws-ec2/test/test.connections.ts index 91811719f0ed0..e44aee248ad7c 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.connections.ts +++ b/packages/@aws-cdk/aws-ec2/test/test.connections.ts @@ -5,9 +5,8 @@ import { Test } from 'nodeunit'; import { Connections, IConnectable, + Port, SecurityGroup, - TcpAllPorts, - TcpPort, Vpc, } from "../lib"; @@ -24,7 +23,7 @@ export = { const conn2 = new SomethingConnectable(new Connections({ securityGroups: [sg2] })); // WHEN - conn1.connections.allowTo(conn2, new TcpPort(80), 'Test'); + conn1.connections.allowTo(conn2, Port.tcp(80), 'Test'); // THEN -- it finishes! test.done(); @@ -40,7 +39,7 @@ export = { const securityGroup = SecurityGroup.fromSecurityGroupId(stack, 'ImportedSG', 'sg-12345'); // WHEN - somethingConnectable.connections.allowTo(securityGroup, new TcpAllPorts(), 'Connect there'); + somethingConnectable.connections.allowTo(securityGroup, Port.allTcp(), 'Connect there'); // THEN: rule to generated security group to connect to imported expect(stack).to(haveResource("AWS::EC2::SecurityGroupEgress", { @@ -74,7 +73,7 @@ export = { const connections = new Connections({ securityGroups: [sg1] }); // WHEN - connections.allowFromAnyIPv4(new TcpPort(88)); + connections.allowFromAnyIPv4(Port.tcp(88)); connections.addSecurityGroup(sg2); // THEN @@ -119,7 +118,7 @@ export = { const connectable = new SomethingConnectable(connections2); // WHEN - connections1.allowTo(connectable, new TcpPort(88)); + connections1.allowTo(connectable, Port.tcp(88)); connections2.addSecurityGroup(sg3); // THEN @@ -149,7 +148,7 @@ export = { const connections = new Connections({ securityGroups: [sg1] }); // WHEN - connections.allowInternally(new TcpPort(88)); + connections.allowInternally(Port.tcp(88)); connections.addSecurityGroup(sg2); // THEN @@ -176,7 +175,7 @@ export = { const sg2 = new SecurityGroup(stack2, 'SecurityGroup', { vpc: vpc2, allowAllOutbound: false }); // WHEN - sg2.connections.allowFrom(sg1, new TcpPort(100)); + sg2.connections.allowFrom(sg1, Port.tcp(100)); // THEN -- both rules are in Stack2 ConstructNode.prepare(app.node); @@ -207,7 +206,7 @@ export = { const sg2 = new SecurityGroup(stack2, 'SecurityGroup', { vpc: vpc2, allowAllOutbound: false }); // WHEN - sg2.connections.allowTo(sg1, new TcpPort(100)); + sg2.connections.allowTo(sg1, Port.tcp(100)); // THEN -- both rules are in Stack2 ConstructNode.prepare(app.node); @@ -239,8 +238,8 @@ export = { const sg2 = new SecurityGroup(stack2, 'SecurityGroup', { vpc: vpc2, allowAllOutbound: false }); // WHEN - sg2.connections.allowFrom(sg1a, new TcpPort(100)); - sg2.connections.allowFrom(sg1b, new TcpPort(100)); + sg2.connections.allowFrom(sg1a, Port.tcp(100)); + sg2.connections.allowFrom(sg1b, Port.tcp(100)); // THEN -- both egress rules are in Stack2 ConstructNode.prepare(app.node); 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 091c6e46a3d0b..50cf725e5ada2 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.security-group.ts +++ b/packages/@aws-cdk/aws-ec2/test/test.security-group.ts @@ -1,25 +1,7 @@ import { expect, haveResource } from '@aws-cdk/assert'; import { Lazy, Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; - -import { - AllTraffic, - AnyIPv4, - AnyIPv6, - IcmpAllTypeCodes, - IcmpAllTypesAndCodes, - IcmpPing, - IcmpTypeAndCode, - PrefixList, - SecurityGroup, - TcpAllPorts, - TcpPort, - TcpPortRange, - UdpAllPorts, - UdpPort, - UdpPortRange, - Vpc -} from "../lib"; +import { Peer, Port, SecurityGroup, Vpc } from "../lib"; export = { 'security group can allows all outbound traffic by default'(test: Test) { @@ -51,7 +33,7 @@ export = { // WHEN const sg = new SecurityGroup(stack, 'SG1', { vpc, allowAllOutbound: true }); - sg.addEgressRule(new AnyIPv4(), new TcpPort(86), 'This does not show up'); + sg.addEgressRule(Peer.anyIpv4(), Port.tcp(86), 'This does not show up'); // THEN expect(stack).to(haveResource('AWS::EC2::SecurityGroup', { @@ -98,7 +80,7 @@ export = { // WHEN const sg = new SecurityGroup(stack, 'SG1', { vpc, allowAllOutbound: false }); - sg.addEgressRule(new AnyIPv4(), new TcpPort(86), 'This replaces the other one'); + sg.addEgressRule(Peer.anyIpv4(), Port.tcp(86), 'This replaces the other one'); // THEN expect(stack).to(haveResource('AWS::EC2::SecurityGroup', { @@ -124,7 +106,7 @@ export = { // WHEN const sg = new SecurityGroup(stack, 'SG1', { vpc, allowAllOutbound: false }); test.throws(() => { - sg.addEgressRule(new AnyIPv4(), new AllTraffic(), 'All traffic'); + sg.addEgressRule(Peer.anyIpv4(), Port.allTraffic(), 'All traffic'); }, /Cannot add/); test.done(); @@ -138,25 +120,25 @@ export = { const peers = [ new SecurityGroup(stack, 'PeerGroup', { vpc }), - new AnyIPv4(), - new AnyIPv6(), - new PrefixList('pl-012345'), + Peer.anyIpv4(), + Peer.anyIpv6(), + Peer.prefixList('pl-012345'), ]; const ports = [ - new TcpPort(1234), - new TcpPort(Lazy.numberValue({ produce: () => 5000 })), - new TcpAllPorts(), - new TcpPortRange(80, 90), - new UdpPort(2345), - new UdpPort(Lazy.numberValue({ produce: () => 7777 })), - new UdpAllPorts(), - new UdpPortRange(85, 95), - new IcmpTypeAndCode(5, 1), - new IcmpAllTypeCodes(8), - new IcmpAllTypesAndCodes(), - new IcmpPing(), - new AllTraffic() + Port.tcp(1234), + Port.tcp(Lazy.numberValue({ produce: () => 5000 })), + Port.allTcp(), + Port.tcpRange(80, 90), + Port.udp(2345), + Port.udp(Lazy.numberValue({ produce: () => 7777 })), + Port.allUdp(), + Port.udpRange(85, 95), + Port.icmpTypeAndCode(5, 1), + Port.icmpType(8), + Port.allIcmp(), + Port.icmpPing(), + Port.allTraffic() ]; // WHEN @@ -179,19 +161,19 @@ export = { // 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), + Port.tcp(p1), + Port.tcp(p2), + Port.tcpRange(p1, 90), + Port.tcpRange(80, p2), + Port.tcpRange(p1, p2), + Port.udp(p1), + Port.udpRange(p1, 95), + Port.udpRange(85, p2), + Port.udpRange(p1, p2), + Port.icmpTypeAndCode(p1, 1), + Port.icmpTypeAndCode(5, p1), + Port.icmpTypeAndCode(p1, p2), + Port.icmpType(p1), ]; // THEN 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 c3c12f1fb8ea0..00089d3848922 100644 --- a/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts @@ -195,7 +195,7 @@ export abstract class BaseService extends Resource // Open up security groups. For dynamic port mapping, we won't know the port range // in advance so we need to open up all ports. const port = this.taskDefinition.defaultContainer!.ingressPort; - const portRange = port === 0 ? EPHEMERAL_PORT_RANGE : new ec2.TcpPort(port); + const portRange = port === 0 ? EPHEMERAL_PORT_RANGE : ec2.Port.tcp(port); targetGroup.registerConnectable(this, portRange); return ret; @@ -394,7 +394,7 @@ export abstract class BaseService extends Resource /** * The port range to open up for dynamic port mapping */ -const EPHEMERAL_PORT_RANGE = new ec2.TcpPortRange(32768, 65535); +const EPHEMERAL_PORT_RANGE = ec2.Port.tcpRange(32768, 65535); /** * Options for enabling service discovery on an ECS service diff --git a/packages/@aws-cdk/aws-ecs/lib/cluster.ts b/packages/@aws-cdk/aws-ecs/lib/cluster.ts index fbe4e315a95f6..ae71390201604 100644 --- a/packages/@aws-cdk/aws-ecs/lib/cluster.ts +++ b/packages/@aws-cdk/aws-ecs/lib/cluster.ts @@ -251,7 +251,7 @@ export interface EcsOptimizedAmiProps { /** * Construct a Linux machine image from the latest ECS Optimized AMI published in SSM */ -export class EcsOptimizedAmi implements ec2.IMachineImageSource { +export class EcsOptimizedAmi implements ec2.IMachineImage { private readonly generation: ec2.AmazonLinuxGeneration; private readonly hwType: AmiHardwareType; @@ -285,9 +285,12 @@ export class EcsOptimizedAmi implements ec2.IMachineImageSource { /** * Return the correct image */ - public getImage(scope: Construct): ec2.MachineImage { + public getImage(scope: Construct): ec2.MachineImageConfig { const ami = ssm.StringParameter.valueForStringParameter(scope, this.amiParameterName); - return new ec2.MachineImage(ami, new ec2.LinuxOS()); + return { + imageId: ami, + osType: ec2.OperatingSystemType.LINUX + }; } } @@ -467,7 +470,7 @@ export interface AddCapacityOptions extends AddAutoScalingGroupCapacityOptions, * * @default - Amazon Linux 1 */ - readonly machineImage?: ec2.IMachineImageSource; + readonly machineImage?: ec2.IMachineImage; } export interface NamespaceOptions { diff --git a/packages/@aws-cdk/aws-eks/lib/ami.ts b/packages/@aws-cdk/aws-eks/lib/ami.ts index ba699b8300a8d..8f0eae05cf479 100644 --- a/packages/@aws-cdk/aws-eks/lib/ami.ts +++ b/packages/@aws-cdk/aws-eks/lib/ami.ts @@ -22,7 +22,7 @@ export interface EksOptimizedAmiProps { /** * Source for EKS optimized AMIs */ -export class EksOptimizedAmi extends ec2.GenericLinuxImage implements ec2.IMachineImageSource { +export class EksOptimizedAmi extends ec2.GenericLinuxImage implements ec2.IMachineImage { constructor(props: EksOptimizedAmiProps = {}) { const version = props.kubernetesVersion || LATEST_KUBERNETES_VERSION; if (!(version in EKS_AMI)) { diff --git a/packages/@aws-cdk/aws-eks/lib/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster.ts index ca09676cc7149..b6c4d1d2274dc 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster.ts @@ -223,7 +223,7 @@ export class Cluster extends Resource implements ICluster { this.connections = new ec2.Connections({ securityGroups: [securityGroup], - defaultPortRange: new ec2.TcpPort(443), // Control Plane has an HTTPS API + defaultPort: ec2.Port.tcp(443), // Control Plane has an HTTPS API }); // Get subnetIds for all selected subnets @@ -299,19 +299,19 @@ export class Cluster extends Resource implements ICluster { */ public addAutoScalingGroup(autoScalingGroup: autoscaling.AutoScalingGroup, options: AddAutoScalingGroupOptions) { // self rules - autoScalingGroup.connections.allowInternally(new ec2.AllTraffic()); + autoScalingGroup.connections.allowInternally(ec2.Port.allTraffic()); // Cluster to:nodes rules - autoScalingGroup.connections.allowFrom(this, new ec2.TcpPort(443)); - autoScalingGroup.connections.allowFrom(this, new ec2.TcpPortRange(1025, 65535)); + autoScalingGroup.connections.allowFrom(this, ec2.Port.tcp(443)); + autoScalingGroup.connections.allowFrom(this, ec2.Port.tcpRange(1025, 65535)); // Allow HTTPS from Nodes to Cluster - autoScalingGroup.connections.allowTo(this, new ec2.TcpPort(443)); + autoScalingGroup.connections.allowTo(this, ec2.Port.tcp(443)); // Allow all node outbound traffic - autoScalingGroup.connections.allowToAnyIPv4(new ec2.TcpAllPorts()); - autoScalingGroup.connections.allowToAnyIPv4(new ec2.UdpAllPorts()); - autoScalingGroup.connections.allowToAnyIPv4(new ec2.IcmpAllTypesAndCodes()); + autoScalingGroup.connections.allowToAnyIPv4(ec2.Port.allTcp()); + autoScalingGroup.connections.allowToAnyIPv4(ec2.Port.allUdp()); + autoScalingGroup.connections.allowToAnyIPv4(ec2.Port.allIcmp()); autoScalingGroup.addUserData( 'set -o xtrace', 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 399981c515093..e60dae8ac62bf 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 @@ -20,7 +20,7 @@ class EksClusterStack extends cdk.Stack { }); // Replace with desired IP - asg.connections.allowFrom(new ec2.CidrIPv4('1.2.3.4/32'), new ec2.TcpPort(22)); + asg.connections.allowFrom(ec2.Peer.ipv4('1.2.3.4/32'), ec2.Port.tcp(22)); /// !hide } } diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts index 7aa6599544057..e8d1be9124478 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.ts @@ -1,6 +1,4 @@ -import { - AnyIPv4, Connections, IConnectable, IPortRange, ISecurityGroup, - ISubnet, IVpc, SecurityGroup, TcpPort } from '@aws-cdk/aws-ec2'; +import { Connections, IConnectable, ISecurityGroup, ISubnet, IVpc, Peer, Port, SecurityGroup } from '@aws-cdk/aws-ec2'; import { Construct, Duration, Lazy, Resource } from '@aws-cdk/cdk'; import { CfnLoadBalancer } from './elasticloadbalancing.generated'; @@ -267,10 +265,10 @@ export class LoadBalancer extends Resource implements IConnectable { policyNames: listener.policyNames }); - const port = new ListenerPort(this.securityGroup, new TcpPort(listener.externalPort)); + const port = new ListenerPort(this.securityGroup, Port.tcp(listener.externalPort)); // Allow connections on the public port for all supplied peers (default: everyone) - ifUndefined(listener.allowConnectionsFrom, [new AnyIPv4()]).forEach(peer => { + ifUndefined(listener.allowConnectionsFrom, [Peer.anyIpv4()]).forEach(peer => { port.connections.allowDefaultPortFrom(peer, `Default rule allow on ${listener.externalPort}`); }); @@ -356,7 +354,7 @@ export class LoadBalancer extends Resource implements IConnectable { private allowTargetConnection(instancePort: number, target: ILoadBalancerTarget) { this.connections.allowTo( target, - new TcpPort(instancePort), + Port.tcp(instancePort), `Port ${instancePort} LB to fleet`); } } @@ -377,8 +375,8 @@ export class LoadBalancer extends Resource implements IConnectable { export class ListenerPort implements IConnectable { public readonly connections: Connections; - constructor(securityGroup: ISecurityGroup, defaultPortRange: IPortRange) { - this.connections = new Connections({ securityGroups: [securityGroup] , defaultPortRange }); + constructor(securityGroup: ISecurityGroup, defaultPort: Port) { + this.connections = new Connections({ securityGroups: [securityGroup], defaultPort }); } } diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts index 6c09efc21375b..d28f53088154c 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts @@ -15,7 +15,7 @@ new elb.LoadBalancer(stack, 'LB', { internetFacing: true, listeners: [{ externalPort: 80, - allowConnectionsFrom: [new ec2.AnyIPv4()] + allowConnectionsFrom: [ec2.Peer.anyIpv4()] }], healthCheck: { port: 80 diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts b/packages/@aws-cdk/aws-elasticloadbalancing/test/test.loadbalancer.ts index 08f9f3428910f..fac680a0d1d1e 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, Vpc } from '@aws-cdk/aws-ec2'; +import { Connections, Peer, Vpc } from '@aws-cdk/aws-ec2'; import { Duration, Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; import { ILoadBalancerTarget, LoadBalancer, LoadBalancingProtocol } from '../lib'; @@ -155,7 +155,7 @@ export = { class FakeTarget implements ILoadBalancerTarget { public readonly connections = new Connections({ - securityGroupRule: new CidrIPv4('666.666.666.666/666') + peer: Peer.ipv4('666.666.666.666/666') }); public attachToClassicLB(_loadBalancer: LoadBalancer): void { 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 ed7c60a8d2c5b..0e8071e7366a8 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts @@ -127,13 +127,13 @@ export class ApplicationListener extends BaseListener implements IApplicationLis // but adds its own default port. this.connections = new ec2.Connections({ securityGroups: props.loadBalancer.connections.securityGroups, - defaultPortRange: new ec2.TcpPort(port), + defaultPort: ec2.Port.tcp(port), }); (props.defaultTargetGroups || []).forEach(this.addDefaultTargetGroup.bind(this)); if (props.open !== false) { - this.connections.allowDefaultPortFrom(new ec2.AnyIPv4(), `Allow from anyone on port ${port}`); + this.connections.allowDefaultPortFrom(ec2.Peer.anyIpv4(), `Allow from anyone on port ${port}`); } } @@ -245,7 +245,7 @@ export class ApplicationListener extends BaseListener implements IApplicationLis * * Don't call this directly. It is called by ApplicationTargetGroup. */ - public registerConnectable(connectable: ec2.IConnectable, portRange: ec2.IPortRange): void { + public registerConnectable(connectable: ec2.IConnectable, portRange: ec2.Port): void { this.connections.allowTo(connectable, portRange, 'Load balancer to target'); } @@ -310,7 +310,7 @@ export interface IApplicationListener extends IResource, ec2.IConnectable { * * Don't call this directly. It is called by ApplicationTargetGroup. */ - registerConnectable(connectable: ec2.IConnectable, portRange: ec2.IPortRange): void; + registerConnectable(connectable: ec2.IConnectable, portRange: ec2.Port): void; } /** @@ -346,11 +346,11 @@ class ImportedApplicationListener extends Resource implements IApplicationListen this.listenerArn = props.listenerArn; - const defaultPortRange = props.defaultPort !== undefined ? new ec2.TcpPort(props.defaultPort) : undefined; + const defaultPort = props.defaultPort !== undefined ? ec2.Port.tcp(props.defaultPort) : undefined; this.connections = new ec2.Connections({ securityGroups: [ec2.SecurityGroup.fromSecurityGroupId(this, 'SecurityGroup', props.securityGroupId)], - defaultPortRange, + defaultPort, }); } @@ -410,7 +410,7 @@ class ImportedApplicationListener extends Resource implements IApplicationListen * * Don't call this directly. It is called by ApplicationTargetGroup. */ - public registerConnectable(connectable: ec2.IConnectable, portRange: ec2.IPortRange): void { + public registerConnectable(connectable: ec2.IConnectable, portRange: ec2.Port): void { this.connections.allowTo(connectable, portRange, 'Load balancer to target'); } } 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 0bc5be5b55a40..f49cb1d305a6f 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 @@ -120,8 +120,8 @@ 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) { - portRange = portRange || new ec2.TcpPort(this.defaultPort); + public registerConnectable(connectable: ec2.IConnectable, portRange?: ec2.Port) { + portRange = portRange || ec2.Port.tcp(this.defaultPort); // Notify all listeners that we already know about of this new connectable. // Then remember for new listeners that might get added later. @@ -308,7 +308,7 @@ interface ConnectableMember { /** * The port (range) the member is listening on */ - portRange: ec2.IPortRange; + portRange: ec2.Port; } /** 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 8a04ebacae7a8..3bd137260dd55 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 @@ -130,7 +130,7 @@ export abstract class BaseLoadBalancer extends Resource { const vpcSubnets = ifUndefined(baseProps.vpcSubnets, { subnetType: internetFacing ? ec2.SubnetType.PUBLIC : ec2.SubnetType.PRIVATE }); - const { subnetIds, internetConnectedDependency } = baseProps.vpc.selectSubnets(vpcSubnets); + const { subnetIds, internetConnectivityEstablished } = baseProps.vpc.selectSubnets(vpcSubnets); this.vpc = baseProps.vpc; @@ -142,7 +142,7 @@ export abstract class BaseLoadBalancer extends Resource { ...additionalProps }); if (internetFacing) { - resource.node.addDependency(internetConnectedDependency); + resource.node.addDependency(internetConnectivityEstablished); } if (baseProps.deletionProtection) { this.setAttribute('deletion_protection.enabled', 'true'); } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts index ddb45ba047259..034b79b2d6065 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts @@ -24,7 +24,7 @@ const group = listener.addTargets('Target', { targets: [new elbv2.IpTarget('10.0.1.1')] }); -group.node.addDependency(...vpc.internetDependencies); +group.node.addDependency(vpc.internetConnectivityEstablished); // The target's security group must allow being routed by the LB and the clients. diff --git a/packages/@aws-cdk/aws-lambda/package-lock.json b/packages/@aws-cdk/aws-lambda/package-lock.json index 974dbb034a5d8..d3a6068708959 100644 --- a/packages/@aws-cdk/aws-lambda/package-lock.json +++ b/packages/@aws-cdk/aws-lambda/package-lock.json @@ -1,6 +1,6 @@ { "name": "@aws-cdk/aws-lambda", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { 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 511209cffbd99..ffebc2289da5a 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.vpc-lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.vpc-lambda.ts @@ -50,7 +50,7 @@ export = { const somethingConnectable = new SomethingConnectable(new ec2.Connections({ securityGroups: [securityGroup] })); // WHEN - this.lambda.connections.allowTo(somethingConnectable, new ec2.TcpAllPorts(), 'Lambda can call connectable'); + this.lambda.connections.allowTo(somethingConnectable, ec2.Port.allTcp(), 'Lambda can call connectable'); // THEN: Lambda can connect to SomeSecurityGroup expect(this.stack).to(haveResource("AWS::EC2::SecurityGroupEgress", { @@ -82,7 +82,7 @@ export = { const somethingConnectable = new SomethingConnectable(new ec2.Connections({ securityGroups: [securityGroup] })); // WHEN - somethingConnectable.connections.allowFrom(this.lambda.connections, new ec2.TcpAllPorts(), 'Lambda can call connectable'); + somethingConnectable.connections.allowFrom(this.lambda.connections, ec2.Port.allTcp(), 'Lambda can call connectable'); // THEN: SomeSecurityGroup accepts connections from Lambda expect(stack2).to(haveResource("AWS::EC2::SecurityGroupEgress", { @@ -133,7 +133,7 @@ export = { // WHEN test.throws(() => { - lambdaFn.connections.allowToAnyIPv4(new ec2.TcpAllPorts(), 'Reach for the world Lambda!'); + lambdaFn.connections.allowToAnyIPv4(ec2.Port.allTcp(), 'Reach for the world Lambda!'); }); test.done(); diff --git a/packages/@aws-cdk/aws-rds/lib/cluster.ts b/packages/@aws-cdk/aws-rds/lib/cluster.ts index 83191a6978e96..2ee89e606cfb7 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster.ts @@ -190,10 +190,10 @@ export class DatabaseCluster extends DatabaseClusterBase { */ 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 defaultPort = ec2.Port.tcp(attrs.port); public readonly connections = new ec2.Connections({ securityGroups: [ec2.SecurityGroup.fromSecurityGroupId(this, 'SecurityGroup', attrs.securityGroupId)], - defaultPortRange: this.defaultPortRange + defaultPort: this.defaultPort }); public readonly clusterIdentifier = attrs.clusterIdentifier; public readonly instanceIdentifiers: string[] = []; @@ -344,7 +344,7 @@ export class DatabaseCluster extends DatabaseClusterBase { } // Get the actual subnet objects so we can depend on internet connectivity. - const internetConnected = props.instanceProps.vpc.selectSubnets(props.instanceProps.vpcSubnets).internetConnectedDependency; + const internetConnected = props.instanceProps.vpc.selectSubnets(props.instanceProps.vpcSubnets).internetConnectivityEstablished; for (let i = 0; i < instanceCount; i++) { const instanceIndex = i + 1; @@ -380,8 +380,8 @@ export class DatabaseCluster extends DatabaseClusterBase { this.instanceEndpoints.push(new Endpoint(instance.attrEndpointAddress, portAttribute)); } - const defaultPortRange = new ec2.TcpPort(this.clusterEndpoint.port); - this.connections = new ec2.Connections({ securityGroups: [securityGroup], defaultPortRange }); + const defaultPort = ec2.Port.tcp(this.clusterEndpoint.port); + this.connections = new ec2.Connections({ securityGroups: [securityGroup], defaultPort }); } /** diff --git a/packages/@aws-cdk/aws-rds/lib/instance.ts b/packages/@aws-cdk/aws-rds/lib/instance.ts index 71fb9811ce48c..c920e61d01d2b 100644 --- a/packages/@aws-cdk/aws-rds/lib/instance.ts +++ b/packages/@aws-cdk/aws-rds/lib/instance.ts @@ -90,10 +90,10 @@ export abstract class DatabaseInstanceBase extends Resource implements IDatabase */ public static fromDatabaseInstanceAttributes(scope: Construct, id: string, attrs: DatabaseInstanceAttributes): IDatabaseInstance { class Import extends DatabaseInstanceBase implements IDatabaseInstance { - public readonly defaultPortRange = new ec2.TcpPort(attrs.port); + public readonly defaultPort = ec2.Port.tcp(attrs.port); public readonly connections = new ec2.Connections({ securityGroups: [ec2.SecurityGroup.fromSecurityGroupId(this, 'SecurityGroup', attrs.securityGroupId)], - defaultPortRange: this.defaultPortRange + defaultPort: this.defaultPort }); public readonly instanceIdentifier = attrs.instanceIdentifier; public readonly dbInstanceEndpointAddress = attrs.instanceEndpointAddress; @@ -753,7 +753,7 @@ export class DatabaseInstance extends DatabaseInstanceSource implements IDatabas this.connections = new ec2.Connections({ securityGroups: [this.securityGroup], - defaultPortRange: new ec2.TcpPort(this.instanceEndpoint.port) + defaultPort: ec2.Port.tcp(this.instanceEndpoint.port) }); this.setLogRetention(); @@ -847,7 +847,7 @@ export class DatabaseInstanceFromSnapshot extends DatabaseInstanceSource impleme this.connections = new ec2.Connections({ securityGroups: [this.securityGroup], - defaultPortRange: new ec2.TcpPort(this.instanceEndpoint.port) + defaultPort: ec2.Port.tcp(this.instanceEndpoint.port) }); this.setLogRetention(); @@ -918,7 +918,7 @@ export class DatabaseInstanceReadReplica extends DatabaseInstanceNew implements this.connections = new ec2.Connections({ securityGroups: [this.securityGroup], - defaultPortRange: new ec2.TcpPort(this.instanceEndpoint.port) + defaultPort: ec2.Port.tcp(this.instanceEndpoint.port) }); this.setLogRetention(); diff --git a/packages/@aws-cdk/aws-rds/lib/option-group.ts b/packages/@aws-cdk/aws-rds/lib/option-group.ts index ae7f3c3a8ca01..c5aabc7460923 100644 --- a/packages/@aws-cdk/aws-rds/lib/option-group.ts +++ b/packages/@aws-cdk/aws-rds/lib/option-group.ts @@ -149,7 +149,7 @@ export class OptionGroup extends Resource implements IOptionGroup { this.optionConnections[config.name] = new ec2.Connections({ securityGroups: [securityGroup], - defaultPortRange: new ec2.TcpPort(config.port) + defaultPort: ec2.Port.tcp(config.port) }); configuration = { diff --git a/packages/@aws-cdk/aws-rds/lib/secret-rotation.ts b/packages/@aws-cdk/aws-rds/lib/secret-rotation.ts index 5bf663f6002f0..05db13f02baf0 100644 --- a/packages/@aws-cdk/aws-rds/lib/secret-rotation.ts +++ b/packages/@aws-cdk/aws-rds/lib/secret-rotation.ts @@ -96,7 +96,7 @@ export class SecretRotation extends Construct { constructor(scope: Construct, id: string, props: SecretRotationProps) { super(scope, id); - if (!props.target.connections.defaultPortRange) { + if (!props.target.connections.defaultPort) { throw new Error('The `target` connections must have a default port range.'); } 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 0dc1764e3024c..82981fc8b0810 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 @@ -14,7 +14,7 @@ const cluster = new rds.DatabaseCluster(stack, 'Database', { username: 'admin' }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpc } }); diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster.ts b/packages/@aws-cdk/aws-rds/test/integ.cluster.ts index 04c2468e91eae..5018ead694ccc 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster.ts +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster.ts @@ -26,7 +26,7 @@ const cluster = new DatabaseCluster(stack, 'Database', { password: SecretValue.plainText('7959866cacc02c2d243ecfe177464fe6'), }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC }, vpc }, diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts index b24891fd80da3..4c739ecb7cbc6 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts +++ b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts @@ -46,7 +46,7 @@ class DatabaseInstanceStack extends cdk.Stack { const instance = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.OracleSE1, licenseModel: rds.LicenseModel.BRING_YOUR_OWN_LICENSE, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MEDIUM), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MEDIUM), multiAz: true, storageType: rds.StorageType.IO1, masterUsername: 'syscdk', diff --git a/packages/@aws-cdk/aws-rds/test/test.cluster.ts b/packages/@aws-cdk/aws-rds/test/test.cluster.ts index 0161c38ff0a17..ca0832be5501a 100644 --- a/packages/@aws-cdk/aws-rds/test/test.cluster.ts +++ b/packages/@aws-cdk/aws-rds/test/test.cluster.ts @@ -20,7 +20,7 @@ export = { password: SecretValue.plainText('tooshort'), }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpc } }); @@ -59,7 +59,7 @@ export = { password: SecretValue.plainText('tooshort'), }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpc } }); @@ -93,7 +93,7 @@ export = { password: SecretValue.plainText('tooshort'), }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpc, securityGroup: sg } @@ -131,7 +131,7 @@ export = { password: SecretValue.plainText('tooshort'), }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpc }, parameterGroup: group @@ -157,7 +157,7 @@ export = { username: 'admin' }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpc } }); @@ -214,7 +214,7 @@ export = { username: 'admin' }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpc }, kmsKey: new kms.Key(stack, 'Key') @@ -251,7 +251,7 @@ export = { username: 'admin', }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), parameterGroup, vpc } @@ -280,7 +280,7 @@ export = { username: 'admin' }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpc }, }); @@ -307,7 +307,7 @@ export = { username: 'admin' }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpc }, }); diff --git a/packages/@aws-cdk/aws-rds/test/test.instance.ts b/packages/@aws-cdk/aws-rds/test/test.instance.ts index e44c343078835..7c70ad0b21423 100644 --- a/packages/@aws-cdk/aws-rds/test/test.instance.ts +++ b/packages/@aws-cdk/aws-rds/test/test.instance.ts @@ -17,7 +17,7 @@ export = { new rds.DatabaseInstance(stack, 'Instance', { engine: rds.DatabaseInstanceEngine.OracleSE1, licenseModel: rds.LicenseModel.BRING_YOUR_OWN_LICENSE, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MEDIUM), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MEDIUM), multiAz: true, storageType: rds.StorageType.IO1, masterUsername: 'syscdk', @@ -208,7 +208,7 @@ export = { // WHEN new rds.DatabaseInstance(stack, 'Database', { engine: rds.DatabaseInstanceEngine.SqlServerEE, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), masterUsername: 'syscdk', masterUserPassword: cdk.SecretValue.plainText('tooshort'), vpc, @@ -237,7 +237,7 @@ export = { new rds.DatabaseInstanceFromSnapshot(stack, 'Instance', { snapshotIdentifier: 'my-snapshot', engine: rds.DatabaseInstanceEngine.Postgres, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE), vpc }); @@ -257,7 +257,7 @@ export = { test.throws(() => new rds.DatabaseInstanceFromSnapshot(stack, 'Instance', { snapshotIdentifier: 'my-snapshot', engine: rds.DatabaseInstanceEngine.Mysql, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE), vpc, generateMasterUserPassword: true, }), /`masterUsername`.*`generateMasterUserPassword`/); @@ -271,7 +271,7 @@ export = { const vpc = new ec2.Vpc(stack, 'VPC'); const sourceInstance = new rds.DatabaseInstance(stack, 'Instance', { engine: rds.DatabaseInstanceEngine.Mysql, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), masterUsername: 'admin', vpc }); @@ -280,7 +280,7 @@ export = { new rds.DatabaseInstanceReadReplica(stack, 'ReadReplica', { sourceDatabaseInstance: sourceInstance, engine: rds.DatabaseInstanceEngine.Mysql, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE), vpc }); @@ -300,7 +300,7 @@ export = { const vpc = new ec2.Vpc(stack, 'VPC'); const instance = new rds.DatabaseInstance(stack, 'Instance', { engine: rds.DatabaseInstanceEngine.Mysql, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), masterUsername: 'admin', vpc }); @@ -367,7 +367,7 @@ export = { const vpc = new ec2.Vpc(stack, 'VPC'); const instance = new rds.DatabaseInstance(stack, 'Instance', { engine: rds.DatabaseInstanceEngine.Mysql, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), masterUsername: 'admin', vpc }); @@ -420,7 +420,7 @@ export = { // WHEN const instance = new rds.DatabaseInstance(stack, 'Instance', { engine: rds.DatabaseInstanceEngine.Mysql, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), masterUsername: 'admin', vpc }); @@ -445,7 +445,7 @@ export = { // WHEN const instance = new rds.DatabaseInstance(stack, 'Instance', { engine: rds.DatabaseInstanceEngine.Mysql, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), masterUsername: 'admin', vpc }); @@ -476,7 +476,7 @@ export = { // WHEN new rds.DatabaseInstance(stack, 'Instance', { engine: rds.DatabaseInstanceEngine.Mysql, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), masterUsername: 'admin', vpc, backupRetention: cdk.Duration.seconds(0), diff --git a/packages/@aws-cdk/aws-rds/test/test.secret-rotation.ts b/packages/@aws-cdk/aws-rds/test/test.secret-rotation.ts index 6678d9338b409..250c4535a183b 100644 --- a/packages/@aws-cdk/aws-rds/test/test.secret-rotation.ts +++ b/packages/@aws-cdk/aws-rds/test/test.secret-rotation.ts @@ -20,7 +20,7 @@ export = { username: 'admin' }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpc } }); @@ -168,7 +168,7 @@ export = { password: SecretValue.plainText('tooshort') }, instanceProps: { - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), vpc } }); @@ -210,7 +210,7 @@ export = { const vpc = new ec2.Vpc(stack, 'VPC'); const instance = new rds.DatabaseInstance(stack, 'Database', { engine: rds.DatabaseInstanceEngine.MariaDb, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), masterUsername: 'syscdk', vpc }); @@ -353,7 +353,7 @@ export = { // WHEN const instance = new rds.DatabaseInstance(stack, 'Database', { engine: rds.DatabaseInstanceEngine.SqlServerEE, - instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + instanceClass: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), masterUsername: 'syscdk', masterUserPassword: SecretValue.plainText('tooshort'), vpc diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts index de546f13c1f42..bba51a08e06f4 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 { Construct, ContextProvider, Duration, Lazy, Resource } from '@aws-cdk/cdk'; +import { Construct, ContextProvider, Duration, Lazy, Resource, Stack } from '@aws-cdk/cdk'; import cxapi = require('@aws-cdk/cx-api'); import { HostedZoneProviderProps } from './hosted-zone-provider'; import { HostedZoneAttributes, IHostedZone } from './hosted-zone-ref'; @@ -136,7 +136,7 @@ export class HostedZone extends Resource implements IHostedZone { * @param vpc the other VPC to add. */ public addVpc(vpc: ec2.IVpc) { - this.vpcs.push({ vpcId: vpc.vpcId, vpcRegion: vpc.region }); + this.vpcs.push({ vpcId: vpc.vpcId, vpcRegion: Stack.of(vpc).region }); } } diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker-train-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker-train-task.ts index 40a9ee928cd7e..4b1f38c96b7c5 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker-train-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker-train-task.ts @@ -110,7 +110,7 @@ export class SagemakerTrainTask implements ec2.IConnectable, sfn.IStepFunctionsT // set the default resource config if not defined. this.resourceConfig = props.resourceConfig || { instanceCount: 1, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.XLARGE), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.XLARGE), volumeSizeInGB: 10 }; diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker-transform-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker-transform-task.ts index 6112f4c2f46b8..8a01c6f88a2e2 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker-transform-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker-transform-task.ts @@ -118,7 +118,7 @@ export class SagemakerTransformTask implements sfn.IStepFunctionsTask { // set the default value for the transform resources this.transformResources = props.transformResources || { instanceCount: 1, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.XLARGE), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.XLARGE), }; } @@ -229,4 +229,4 @@ export class SagemakerTransformTask implements sfn.IStepFunctionsTask { return policyStatements; } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker-training-job.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker-training-job.test.ts index b0840bd8b5e16..ddff91b8b4bc5 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker-training-job.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker-training-job.test.ts @@ -78,7 +78,7 @@ test('create complex training job', () => { const kmsKey = new kms.Key(stack, 'Key'); const vpc = new ec2.Vpc(stack, "VPC"); const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', { vpc, description: 'My SG' }); - securityGroup.addIngressRule(new ec2.AnyIPv4(), new ec2.TcpPort(22), 'allow ssh access from the world'); + securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(22), 'allow ssh access from the world'); const role = new iam.Role(stack, 'Role', { assumedBy: new iam.ServicePrincipal('sagemaker.amazonaws.com'), @@ -135,7 +135,7 @@ test('create complex training job', () => { }, resourceConfig: { instanceCount: 1, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.P3, ec2.InstanceSize.XLARGE2), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.P3, ec2.InstanceSize.XLARGE2), volumeSizeInGB: 50, volumeKmsKeyId: kmsKey, }, @@ -255,7 +255,7 @@ test('pass param to training job', () => { }, resourceConfig: { instanceCount: 1, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.P3, ec2.InstanceSize.XLARGE2), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.P3, ec2.InstanceSize.XLARGE2), volumeSizeInGB: 50 }, stoppingCondition: { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker-transform-job.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker-transform-job.test.ts index 3b6fff57d20e7..d61eec4cdebc4 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker-transform-job.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sagemaker-transform-job.test.ts @@ -87,7 +87,7 @@ test('create complex transform job', () => { }, transformResources: { instanceCount: 1, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.P3, ec2.InstanceSize.XLARGE2), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.P3, ec2.InstanceSize.XLARGE2), volumeKmsKeyId: kmsKey, }, tags: { @@ -158,7 +158,7 @@ test('pass param to transform job', () => { }, transformResources: { instanceCount: 1, - instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.P3, ec2.InstanceSize.XLARGE2), + instanceType: ec2.InstanceType.of(ec2.InstanceClass.P3, ec2.InstanceSize.XLARGE2), } }) }); @@ -187,4 +187,4 @@ test('pass param to transform job', () => { } }, }); -}); \ No newline at end of file +}); diff --git a/packages/@aws-cdk/cdk/package-lock.json b/packages/@aws-cdk/cdk/package-lock.json index 4e6c5441d1fcc..e56015976b7fa 100644 --- a/packages/@aws-cdk/cdk/package-lock.json +++ b/packages/@aws-cdk/cdk/package-lock.json @@ -1,6 +1,6 @@ { "name": "@aws-cdk/cdk", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/@aws-cdk/cloudformation-diff/package-lock.json b/packages/@aws-cdk/cloudformation-diff/package-lock.json index 4b0f41a3a7324..a0ebbfa0e4c63 100644 --- a/packages/@aws-cdk/cloudformation-diff/package-lock.json +++ b/packages/@aws-cdk/cloudformation-diff/package-lock.json @@ -1,6 +1,6 @@ { "name": "@aws-cdk/cloudformation-diff", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/@aws-cdk/cx-api/package-lock.json b/packages/@aws-cdk/cx-api/package-lock.json index 0c08a619d29d9..e24d294c1bf3f 100644 --- a/packages/@aws-cdk/cx-api/package-lock.json +++ b/packages/@aws-cdk/cx-api/package-lock.json @@ -1,6 +1,6 @@ { "name": "@aws-cdk/cx-api", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/aws-cdk/package-lock.json b/packages/aws-cdk/package-lock.json index 3dc9ca939af29..38d5104b4d970 100644 --- a/packages/aws-cdk/package-lock.json +++ b/packages/aws-cdk/package-lock.json @@ -1,6 +1,6 @@ { "name": "aws-cdk", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/cdk-dasm/package-lock.json b/packages/cdk-dasm/package-lock.json index 47b64dc22cfc4..d79b9b2105f3a 100644 --- a/packages/cdk-dasm/package-lock.json +++ b/packages/cdk-dasm/package-lock.json @@ -1,6 +1,6 @@ { "name": "cdk-dasm", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/decdk/package-lock.json b/packages/decdk/package-lock.json index ba59ddef9477b..4f4d526095403 100644 --- a/packages/decdk/package-lock.json +++ b/packages/decdk/package-lock.json @@ -1,6 +1,6 @@ { "name": "decdk", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/tools/awslint/package-lock.json b/tools/awslint/package-lock.json index b60555198e198..f3eb956080594 100644 --- a/tools/awslint/package-lock.json +++ b/tools/awslint/package-lock.json @@ -1,6 +1,6 @@ { "name": "awslint", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/tools/cdk-build-tools/package-lock.json b/tools/cdk-build-tools/package-lock.json index dd452cf3c8e7f..06929ad3175f3 100644 --- a/tools/cdk-build-tools/package-lock.json +++ b/tools/cdk-build-tools/package-lock.json @@ -1,6 +1,6 @@ { "name": "cdk-build-tools", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/tools/cfn2ts/package-lock.json b/tools/cfn2ts/package-lock.json index 10acde5ca5829..9a5bf117a81dd 100644 --- a/tools/cfn2ts/package-lock.json +++ b/tools/cfn2ts/package-lock.json @@ -1,6 +1,6 @@ { "name": "cfn2ts", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": {