@@ -101,7 +101,7 @@ var checkCommand = &cobra.Command{ // nolint:gochecknoglobals
101101 if err != nil {
102102 return fmt .Errorf ("❌ Nodes never got ready: %v" , err )
103103 }
104- log .Infof ("✅ EC2 Instances are now running successfully" )
104+ log .Info ("✅ EC2 Instances are now running successfully" )
105105
106106 log .Infof ("ℹ️ Connecting to SSM..." )
107107 err = ensureSessionManagerIsUp (cmd .Context (), ssmClient )
@@ -268,7 +268,12 @@ func validateSubnets(cmd *cobra.Command, args []string) error {
268268func launchInstances (ctx context.Context , ec2Client * ec2.Client , subnets []string , profileArn * string ) ([]string , error ) {
269269 var instanceIds []string
270270 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 )
272277 if err != nil {
273278 return nil , fmt .Errorf ("❌ Failed to launch instances in subnet %s: %v" , subnet , err )
274279 }
@@ -279,7 +284,7 @@ func launchInstances(ctx context.Context, ec2Client *ec2.Client, subnets []strin
279284 return instanceIds , nil
280285}
281286
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 ) {
283288 regionalAMI , err := findUbuntuAMI (ctx , ec2Client )
284289 if err != nil {
285290 return "" , err
@@ -295,18 +300,13 @@ func launchInstanceInSubnet(ctx context.Context, ec2Client *ec2.Client, subnetID
295300 userDataEncoded := base64 .StdEncoding .EncodeToString ([]byte (userData ))
296301
297302 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 ),
310310 IamInstanceProfile : & types.IamInstanceProfileSpecification {
311311 Arn : instanceProfileName ,
312312 },
@@ -426,6 +426,64 @@ func fetchResultsForInstance(ctx context.Context, svc *ssm.Client, instanceId, c
426426 })
427427}
428428
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+
429487func cleanup (ctx context.Context , svc * ec2.Client , iamsvc * iam.Client ) {
430488 if len (InstanceIds ) > 0 {
431489 _ , err := svc .TerminateInstances (ctx , & ec2.TerminateInstancesInput {
@@ -442,11 +500,10 @@ func cleanup(ctx context.Context, svc *ec2.Client, iamsvc *iam.Client) {
442500 log .WithError (err ).WithField ("rolename" , role ).Warnf ("Failed to cleanup role, please cleanup manually" )
443501 }
444502
445- iamsvc .RemoveRoleFromInstanceProfile (ctx , & iam.RemoveRoleFromInstanceProfileInput {
503+ _ , err = iamsvc .RemoveRoleFromInstanceProfile (ctx , & iam.RemoveRoleFromInstanceProfileInput {
446504 RoleName : aws .String (role ),
447505 InstanceProfileName : aws .String (InstanceProfile ),
448506 })
449-
450507 if err != nil {
451508 log .WithError (err ).WithField ("roleName" , role ).WithField ("profileName" , InstanceProfile ).Warnf ("Failed to remove role from instance profile" )
452509 }
@@ -465,6 +522,24 @@ func cleanup(ctx context.Context, svc *ec2.Client, iamsvc *iam.Client) {
465522 log .WithError (err ).WithField ("instanceProfile" , InstanceProfile ).Warnf ("Failed to clean up instance profile, please cleanup manually" )
466523 }
467524 }
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+ }
468543}
469544
470545func createIAMRoleAndAttachPolicy (ctx context.Context , svc * iam.Client ) (* iam_types.Role , error ) {
0 commit comments