@@ -101,7 +101,7 @@ var checkCommand = &cobra.Command{ // nolint:gochecknoglobals
101
101
if err != nil {
102
102
return fmt .Errorf ("❌ Nodes never got ready: %v" , err )
103
103
}
104
- log .Infof ("✅ EC2 Instances are now running successfully" )
104
+ log .Info ("✅ EC2 Instances are now running successfully" )
105
105
106
106
log .Infof ("ℹ️ Connecting to SSM..." )
107
107
err = ensureSessionManagerIsUp (cmd .Context (), ssmClient )
@@ -268,7 +268,12 @@ func validateSubnets(cmd *cobra.Command, args []string) error {
268
268
func launchInstances (ctx context.Context , ec2Client * ec2.Client , subnets []string , profileArn * string ) ([]string , error ) {
269
269
var instanceIds []string
270
270
for _ , subnet := range subnets {
271
- instanceId , err := launchInstanceInSubnet (ctx , ec2Client , subnet , profileArn )
271
+ secGroup , err := createSecurityGroups (ctx , ec2Client , subnet )
272
+ if err != nil {
273
+ return nil , fmt .Errorf ("❌ failed to create security group: %v" , err )
274
+ }
275
+ SecurityGroups = append (SecurityGroups , secGroup )
276
+ instanceId , err := launchInstanceInSubnet (ctx , ec2Client , subnet , secGroup , profileArn )
272
277
if err != nil {
273
278
return nil , fmt .Errorf ("❌ Failed to launch instances in subnet %s: %v" , subnet , err )
274
279
}
@@ -279,7 +284,7 @@ func launchInstances(ctx context.Context, ec2Client *ec2.Client, subnets []strin
279
284
return instanceIds , nil
280
285
}
281
286
282
- func launchInstanceInSubnet (ctx context.Context , ec2Client * ec2.Client , subnetID string , instanceProfileName * string ) (string , error ) {
287
+ func launchInstanceInSubnet (ctx context.Context , ec2Client * ec2.Client , subnetID , secGroupId string , instanceProfileName * string ) (string , error ) {
283
288
regionalAMI , err := findUbuntuAMI (ctx , ec2Client )
284
289
if err != nil {
285
290
return "" , err
@@ -295,18 +300,13 @@ func launchInstanceInSubnet(ctx context.Context, ec2Client *ec2.Client, subnetID
295
300
userDataEncoded := base64 .StdEncoding .EncodeToString ([]byte (userData ))
296
301
297
302
input := & ec2.RunInstancesInput {
298
- ImageId : aws .String (regionalAMI ), // Example AMI ID, replace with an actual one
299
- InstanceType : types .InstanceTypeT2Micro ,
300
- MaxCount : aws .Int32 (1 ),
301
- MinCount : aws .Int32 (1 ),
302
- UserData : & userDataEncoded ,
303
- NetworkInterfaces : []types.InstanceNetworkInterfaceSpecification {
304
- {
305
- DeviceIndex : aws .Int32 (0 ), // Primary network interface
306
- SubnetId : aws .String (subnetID ),
307
- AssociatePublicIpAddress : aws .Bool (true ),
308
- },
309
- },
303
+ ImageId : aws .String (regionalAMI ), // Example AMI ID, replace with an actual one
304
+ InstanceType : types .InstanceTypeT2Micro ,
305
+ MaxCount : aws .Int32 (1 ),
306
+ MinCount : aws .Int32 (1 ),
307
+ UserData : & userDataEncoded ,
308
+ SecurityGroupIds : []string {secGroupId },
309
+ SubnetId : aws .String (subnetID ),
310
310
IamInstanceProfile : & types.IamInstanceProfileSpecification {
311
311
Arn : instanceProfileName ,
312
312
},
@@ -426,6 +426,64 @@ func fetchResultsForInstance(ctx context.Context, svc *ssm.Client, instanceId, c
426
426
})
427
427
}
428
428
429
+ func createSecurityGroups (ctx context.Context , svc * ec2.Client , subnetID string ) (string , error ) {
430
+ // Describe the subnet to find the VPC ID
431
+ describeSubnetsInput := & ec2.DescribeSubnetsInput {
432
+ SubnetIds : []string {subnetID },
433
+ }
434
+
435
+ describeSubnetsOutput , err := svc .DescribeSubnets (ctx , describeSubnetsInput )
436
+ if err != nil {
437
+ return "" , fmt .Errorf ("Failed to describe subnet: %v" , err )
438
+ }
439
+
440
+ if len (describeSubnetsOutput .Subnets ) == 0 {
441
+ return "" , fmt .Errorf ("No subnets found with ID: %s" , subnetID )
442
+ }
443
+
444
+ vpcID := describeSubnetsOutput .Subnets [0 ].VpcId
445
+
446
+ // Create the security group
447
+ createSGInput := & ec2.CreateSecurityGroupInput {
448
+ Description : aws .String ("EC2 security group allowing all HTTPS outgoing traffic" ),
449
+ GroupName : aws .String (fmt .Sprintf ("EC2-security-group-nc-%s" , subnetID )),
450
+ VpcId : vpcID ,
451
+ }
452
+
453
+ createSGOutput , err := svc .CreateSecurityGroup (ctx , createSGInput )
454
+ if err != nil {
455
+ log .Fatalf ("Failed to create security group: %v" , err )
456
+ }
457
+
458
+ sgID := createSGOutput .GroupId
459
+ log .Infof ("ℹ️ Created security group with ID: %s" , * sgID )
460
+
461
+ // Authorize HTTPS outbound traffic
462
+ authorizeEgressInput := & ec2.AuthorizeSecurityGroupEgressInput {
463
+ GroupId : sgID ,
464
+ IpPermissions : []types.IpPermission {
465
+ {
466
+ IpProtocol : aws .String ("tcp" ),
467
+ FromPort : aws .Int32 (443 ),
468
+ ToPort : aws .Int32 (443 ),
469
+ IpRanges : []types.IpRange {
470
+ {
471
+ CidrIp : aws .String ("0.0.0.0/0" ),
472
+ Description : aws .String ("Allow all outbound HTTPS traffic" ),
473
+ },
474
+ },
475
+ },
476
+ },
477
+ }
478
+
479
+ _ , err = svc .AuthorizeSecurityGroupEgress (ctx , authorizeEgressInput )
480
+ if err != nil {
481
+ log .Fatalf ("Failed to authorize security group egress: %v" , err )
482
+ }
483
+
484
+ return * sgID , nil
485
+ }
486
+
429
487
func cleanup (ctx context.Context , svc * ec2.Client , iamsvc * iam.Client ) {
430
488
if len (InstanceIds ) > 0 {
431
489
_ , err := svc .TerminateInstances (ctx , & ec2.TerminateInstancesInput {
@@ -442,11 +500,10 @@ func cleanup(ctx context.Context, svc *ec2.Client, iamsvc *iam.Client) {
442
500
log .WithError (err ).WithField ("rolename" , role ).Warnf ("Failed to cleanup role, please cleanup manually" )
443
501
}
444
502
445
- iamsvc .RemoveRoleFromInstanceProfile (ctx , & iam.RemoveRoleFromInstanceProfileInput {
503
+ _ , err = iamsvc .RemoveRoleFromInstanceProfile (ctx , & iam.RemoveRoleFromInstanceProfileInput {
446
504
RoleName : aws .String (role ),
447
505
InstanceProfileName : aws .String (InstanceProfile ),
448
506
})
449
-
450
507
if err != nil {
451
508
log .WithError (err ).WithField ("roleName" , role ).WithField ("profileName" , InstanceProfile ).Warnf ("Failed to remove role from instance profile" )
452
509
}
@@ -465,6 +522,24 @@ func cleanup(ctx context.Context, svc *ec2.Client, iamsvc *iam.Client) {
465
522
log .WithError (err ).WithField ("instanceProfile" , InstanceProfile ).Warnf ("Failed to clean up instance profile, please cleanup manually" )
466
523
}
467
524
}
525
+
526
+ log .Info ("Cleaning up: Waiting for 1 minute so network interfaces are deleted" )
527
+ time .Sleep (time .Minute )
528
+
529
+ if len (SecurityGroups ) > 0 {
530
+ for _ , sg := range SecurityGroups {
531
+ deleteSGInput := & ec2.DeleteSecurityGroupInput {
532
+ GroupId : aws .String (sg ),
533
+ }
534
+
535
+ _ , err := svc .DeleteSecurityGroup (ctx , deleteSGInput )
536
+ if err != nil {
537
+ log .WithError (err ).WithField ("securityGroup" , sg ).Warnf ("Failed to clean up security group, please cleanup manually" )
538
+ }
539
+
540
+ }
541
+
542
+ }
468
543
}
469
544
470
545
func createIAMRoleAndAttachPolicy (ctx context.Context , svc * iam.Client ) (* iam_types.Role , error ) {
0 commit comments