Browse Source

custom extension to select existing VPC and SecurityGroups

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 5 years ago
parent
commit
b702065075

+ 14 - 12
ecs/pkg/amazon/cloudformation.go

@@ -57,11 +57,11 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
 	*/
 	template.Parameters[ParameterSubnet1Id] = cloudformation.Parameter{
 		Type:        "AWS::EC2::Subnet::Id",
-		Description: "SubnetId,for Availability Zone 1 in the region in your VPC",
+		Description: "SubnetId, for Availability Zone 1 in the region in your VPC",
 	}
 	template.Parameters[ParameterSubnet2Id] = cloudformation.Parameter{
 		Type:        "AWS::EC2::Subnet::Id",
-		Description: "SubnetId,for Availability Zone 1 in the region in your VPC",
+		Description: "SubnetId, for Availability Zone 2 in the region in your VPC",
 	}
 
 	// Create Cluster is `ParameterClusterName` parameter is not set
@@ -79,10 +79,9 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
 	}
 	cluster := cloudformation.If("CreateCluster", cloudformation.Ref("Cluster"), cloudformation.Ref(ParameterClusterName))
 
+	networks := map[string]string{}
 	for _, net := range project.Networks {
-		for k, v := range convertNetwork(project, net, cloudformation.Ref(ParameterVPCId)) {
-			template.Resources[k] = v
-		}
+		networks[net.Name] = convertNetwork(project, net, cloudformation.Ref(ParameterVPCId), template)
 	}
 
 	logGroup := fmt.Sprintf("/docker-compose/%s", project.Name)
@@ -166,8 +165,7 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
 
 		serviceSecurityGroups := []string{}
 		for net := range service.Networks {
-			logicalName := networkResourceName(project, net)
-			serviceSecurityGroups = append(serviceSecurityGroups, cloudformation.Ref(logicalName))
+			serviceSecurityGroups = append(serviceSecurityGroups, networks[net])
 		}
 
 		desiredCount := 1
@@ -213,8 +211,12 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err
 	return template, nil
 }
 
-func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc string) map[string]cloudformation.Resource {
-	resources := map[string]cloudformation.Resource{}
+func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc string, template *cloudformation.Template) string {
+	if sg, ok := net.Extras[ExtensionSecurityGroup]; ok {
+		logrus.Debugf("Security Group for network %q set by user to %q", net.Name, sg)
+		return sg.(string)
+	}
+
 	var ingresses []ec2.SecurityGroup_Ingress
 	if !net.Internal {
 		for _, service := range project.Services {
@@ -233,7 +235,7 @@ func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc strin
 	}
 
 	securityGroup := networkResourceName(project, net.Name)
-	resources[securityGroup] = &ec2.SecurityGroup{
+	template.Resources[securityGroup] = &ec2.SecurityGroup{
 		GroupDescription:     fmt.Sprintf("%s %s Security Group", project.Name, net.Name),
 		GroupName:            securityGroup,
 		SecurityGroupIngress: ingresses,
@@ -251,14 +253,14 @@ func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc strin
 	}
 
 	ingress := securityGroup + "Ingress"
-	resources[ingress] = &ec2.SecurityGroupIngress{
+	template.Resources[ingress] = &ec2.SecurityGroupIngress{
 		Description:           fmt.Sprintf("Allow communication within network %s", net.Name),
 		IpProtocol:            "-1", // all protocols
 		GroupId:               cloudformation.Ref(securityGroup),
 		SourceSecurityGroupId: cloudformation.Ref(securityGroup),
 	}
 
-	return resources
+	return cloudformation.Ref(securityGroup)
 }
 
 func networkResourceName(project *compose.Project, network string) string {

+ 1 - 1
ecs/pkg/amazon/convert.go

@@ -318,7 +318,7 @@ func getImage(image string) string {
 func getRepoCredentials(service types.ServiceConfig) *ecs.TaskDefinition_RepositoryCredentials {
 	// extract registry and namespace string from image name
 	for key, value := range service.Extras {
-		if key == "x-aws-pull_credentials" {
+		if key == ExtensionPullCredentials {
 			return &ecs.TaskDefinition_RepositoryCredentials{CredentialsParameter: value.(string)}
 		}
 	}

+ 2 - 2
ecs/pkg/amazon/testdata/simple/simple-cloudformation-conversion.golden

@@ -16,11 +16,11 @@
       "Type": "String"
     },
     "ParameterSubnet1Id": {
-      "Description": "SubnetId,for Availability Zone 1 in the region in your VPC",
+      "Description": "SubnetId, for Availability Zone 1 in the region in your VPC",
       "Type": "AWS::EC2::Subnet::Id"
     },
     "ParameterSubnet2Id": {
-      "Description": "SubnetId,for Availability Zone 1 in the region in your VPC",
+      "Description": "SubnetId, for Availability Zone 2 in the region in your VPC",
       "Type": "AWS::EC2::Subnet::Id"
     },
     "ParameterVPCId": {

+ 2 - 2
ecs/pkg/amazon/testdata/simple/simple-cloudformation-with-overrides-conversion.golden

@@ -16,11 +16,11 @@
       "Type": "String"
     },
     "ParameterSubnet1Id": {
-      "Description": "SubnetId,for Availability Zone 1 in the region in your VPC",
+      "Description": "SubnetId, for Availability Zone 1 in the region in your VPC",
       "Type": "AWS::EC2::Subnet::Id"
     },
     "ParameterSubnet2Id": {
-      "Description": "SubnetId,for Availability Zone 1 in the region in your VPC",
+      "Description": "SubnetId, for Availability Zone 2 in the region in your VPC",
       "Type": "AWS::EC2::Subnet::Id"
     },
     "ParameterVPCId": {

+ 9 - 12
ecs/pkg/amazon/up.go

@@ -59,18 +59,15 @@ func (c *client) ComposeUp(ctx context.Context, project *compose.Project) error
 }
 
 func (c client) GetVPC(ctx context.Context, project *compose.Project) (string, error) {
-	//check compose file for the default external network
-	if net, ok := project.Networks["default"]; ok {
-		if net.External.External {
-			vpc := net.Name
-			ok, err := c.api.VpcExists(ctx, vpc)
-			if err != nil {
-				return "", err
-			}
-			if !ok {
-				return "", fmt.Errorf("VPC does not exist: %s", vpc)
-			}
-			return vpc, nil
+	//check compose file for custom VPC selected
+	if vpc, ok := project.Extras[ExtensionVPC]; ok {
+		vpcID := vpc.(string)
+		ok, err := c.api.VpcExists(ctx, vpcID)
+		if err != nil {
+			return "", err
+		}
+		if !ok {
+			return "", fmt.Errorf("VPC does not exist: %s", vpc)
 		}
 	}
 	defaultVPC, err := c.api.GetDefaultVPC(ctx)

+ 7 - 0
ecs/pkg/amazon/x.go

@@ -0,0 +1,7 @@
+package amazon
+
+const (
+	ExtensionSecurityGroup   = "x-aws-securitygroup"
+	ExtensionVPC             = "x-aws-vpc"
+	ExtensionPullCredentials = "x-aws-pull_credentials"
+)