Skip to content

Commit 5760fb3

Browse files
committed
add security group
1 parent eee1352 commit 5760fb3

File tree

2 files changed

+93
-18
lines changed

2 files changed

+93
-18
lines changed

gitpod-network-check/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ A CLI to check if your network setup is suitable for the installation of Gitpod.
66

77
1. Download the `gitpod-network-check` binary using:
88
```
9-
curl -L "https://github.com/gitpod-io/enterprise-deployment-toolkit/releases/download/v0.1.1/enterprise-deployment-toolkit_$(uname -s -m | awk '{print $1"_"$2}').tar.gz" | tar -xz
9+
curl -L "https://github.com/gitpod-io/enterprise-deployment-toolkit/releases/download/v0.1.2/enterprise-deployment-toolkit_$(uname -s -m | awk '{print $1"_"$2}').tar.gz" | tar -xz
1010
```
1111

1212
You can also download and untar the binary directly from the Github releases page [here](https://github.com/gitpod-io/enterprise-deployment-toolkit/releases/latest)

gitpod-network-check/cmd/checks.go

+92-17
Original file line numberDiff line numberDiff line change
@@ -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 {
268268
func 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+
429487
func 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

470545
func createIAMRoleAndAttachPolicy(ctx context.Context, svc *iam.Client) (*iam_types.Role, error) {

0 commit comments

Comments
 (0)