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 34462984f87fe..fc8ff9c4720ba 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -153,7 +153,8 @@ export class AutoScalingGroup extends cdk.Construct implements ec2.IClassicLoadB private readonly userDataLines = new Array(); private readonly autoScalingGroup: cloudformation.AutoScalingGroupResource; - private readonly securityGroup: ec2.SecurityGroup; + private readonly securityGroup: ec2.SecurityGroupRef; + private readonly securityGroups: ec2.SecurityGroupRef[] = []; private readonly loadBalancerNames: cdk.Token[] = []; constructor(parent: cdk.Construct, name: string, props: AutoScalingGroupProps) { @@ -161,6 +162,7 @@ export class AutoScalingGroup extends cdk.Construct implements ec2.IClassicLoadB this.securityGroup = new ec2.SecurityGroup(this, 'InstanceSecurityGroup', { vpc: props.vpc }); this.connections = new ec2.Connections({ securityGroup: this.securityGroup }); + this.securityGroups.push(this.securityGroup); if (props.allowAllOutbound !== false) { this.connections.allowTo(new ec2.AnyIPv4(), new ec2.AllConnections(), 'Outbound traffic allowed by default'); @@ -177,12 +179,13 @@ export class AutoScalingGroup extends cdk.Construct implements ec2.IClassicLoadB // use delayed evaluation const machineImage = props.machineImage.getImage(this); const userDataToken = new cdk.Token(() => new cdk.FnBase64((machineImage.os.createUserData(this.userDataLines)))); + const securityGroupsToken = new cdk.Token(() => this.securityGroups.map(sg => sg.securityGroupId)); const launchConfig = new cloudformation.LaunchConfigurationResource(this, 'LaunchConfig', { imageId: machineImage.imageId, keyName: props.keyName, instanceType: props.instanceType.toString(), - securityGroups: [this.securityGroup.securityGroupId], + securityGroups: securityGroupsToken, iamInstanceProfile: iamProfile.ref, userData: userDataToken }); @@ -227,6 +230,16 @@ export class AutoScalingGroup extends cdk.Construct implements ec2.IClassicLoadB this.applyUpdatePolicies(props); } + /** + * Add the security group to all instances via the launch configuration + * security groups array. + * + * @param securityGroup: The SecurityGroupRef to add + */ + public addSecurityGroup(securityGroup: ec2.SecurityGroupRef): void { + this.securityGroups.push(securityGroup); + } + public attachToClassicLB(loadBalancer: ec2.ClassicLoadBalancer): void { this.loadBalancerNames.push(loadBalancer.loadBalancerName); } 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 ac649bbacfd6c..d65dcde85487f 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 @@ -332,6 +332,30 @@ export = { test.done(); }, + 'can add Security Group to Fleet'(test: Test) { + // GIVEN + const stack = new cdk.Stack(undefined, 'MyStack', { env: { region: 'us-east-1', account: '1234' }}); + const vpc = mockVpc(stack); + + // WHEN + const asg = new autoscaling.AutoScalingGroup(stack, 'MyFleet', { + instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.Micro), + machineImage: new ec2.AmazonLinuxImage(), + vpc, + }); + asg.addSecurityGroup(mockSecurityGroup(stack)); + expect(stack).to(haveResource("AWS::AutoScaling::LaunchConfiguration", { + SecurityGroups: [ + { + "Fn::GetAtt": [ + "MyFleetInstanceSecurityGroup774E8234", + "GroupId" + ] + }, + 'most-secure'], + })); + test.done(); + }, }; function mockVpc(stack: cdk.Stack) { @@ -342,3 +366,9 @@ function mockVpc(stack: cdk.Stack) { privateSubnetIds: [ new ec2.SubnetId('pri1') ], }); } + +function mockSecurityGroup(stack: cdk.Stack) { + return ec2.SecurityGroupRef.import(stack, 'MySG', { + securityGroupId: new ec2.SecurityGroupId('most-secure'), + }); +}