Skip to content
This repository has been archived by the owner on Nov 27, 2023. It is now read-only.

Commit

Permalink
Only consider public subnets
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <[email protected]>
  • Loading branch information
ndeloof committed Dec 15, 2020
1 parent 99de963 commit b9a3025
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 4 deletions.
1 change: 1 addition & 0 deletions ecs/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type API interface {
CheckVPC(ctx context.Context, vpcID string) error
GetDefaultVPC(ctx context.Context) (string, error)
GetSubNets(ctx context.Context, vpcID string) ([]awsResource, error)
IsPublicSubnet(ctx context.Context, vpcID string, subNetID string) (bool, error)
GetRoleArn(ctx context.Context, name string) (string, error)
StackExists(ctx context.Context, name string) (bool, error)
CreateStack(ctx context.Context, name string, region string, template []byte) error
Expand Down
18 changes: 15 additions & 3 deletions ecs/awsResources.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,22 @@ func (b *ecsAPIService) parseVPCExtension(ctx context.Context, project *types.Pr
if err != nil {
return "", nil, err
}
if len(subNets) < 2 {
return "", nil, fmt.Errorf("VPC %s should have at least 2 associated subnets in different availability zones", vpc)

var publicSubNets []awsResource
for _, subNet := range subNets {
isPublic, err := b.aws.IsPublicSubnet(ctx, vpc, subNet.ID())
if err != nil {
return "", nil, err
}
if isPublic {
publicSubNets = append(publicSubNets, subNet)
}
}

if len(publicSubNets) < 2 {
return "", nil, fmt.Errorf("VPC %s should have at least 2 associated public subnets in different availability zones", vpc)
}
return vpc, subNets, nil
return vpc, publicSubNets, nil
}

func (b *ecsAPIService) parseLoadBalancerExtension(ctx context.Context, project *types.Project) (awsResource, string, error) {
Expand Down
18 changes: 17 additions & 1 deletion ecs/aws_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions ecs/cloudformation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,8 @@ func useDefaultVPC(m *MockAPIMockRecorder) {
existingAWSResource{id: "subnet1"},
existingAWSResource{id: "subnet2"},
}, nil)
m.IsPublicSubnet(gomock.Any(), "subnet1").Return(true, nil)
m.IsPublicSubnet(gomock.Any(), "subnet2").Return(true, nil)
}

func useGPU(m *MockAPIMockRecorder) {
Expand Down
31 changes: 31 additions & 0 deletions ecs/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,37 @@ func (s sdk) GetSubNets(ctx context.Context, vpcID string) ([]awsResource, error
return ids, nil
}

func (s sdk) IsPublicSubnet(ctx context.Context, vpcID string, subNetID string) (bool, error) {
tables, err := s.EC2.DescribeRouteTablesWithContext(ctx, &ec2.DescribeRouteTablesInput{
Filters: []*ec2.Filter{
{
Name: aws.String("association.subnet-id"),
Values: []*string{aws.String(subNetID)},
},
},
})
if err != nil {
return false, err
}
if len(tables.RouteTables) == 0 {
// If a subnet is not explicitly associated with any route table, it is implicitly associated with the main route table.
// https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-route-tables.html
return true, nil
}
for _, routeTable := range tables.RouteTables {
for _, route := range routeTable.Routes {
if aws.StringValue(route.State) != "active" {
continue
}
if strings.HasPrefix(aws.StringValue(route.GatewayId), "igw-") {
// Connected to an internet Gateway
return true, nil
}
}
}
return false, nil
}

func (s sdk) GetRoleArn(ctx context.Context, name string) (string, error) {
role, err := s.IAM.GetRoleWithContext(ctx, &iam.GetRoleInput{
RoleName: aws.String(name),
Expand Down

0 comments on commit b9a3025

Please sign in to comment.