diff --git a/ecs/README.md b/ecs/README.md index afa354d3e..c0cb834b5 100644 --- a/ecs/README.md +++ b/ecs/README.md @@ -55,11 +55,9 @@ according to the networks declared in Compose model. Doing so, services attached communicate together, while services from distinct SecurityGroups can't. We just can't set service aliasses per network. A CloudMap private namespace is created for application as `{project}.local`. Services get registered so that we -get service discovery and DNS round-robin (equivalent for Compose's `endpoint_mode: dnsrr`). Hostname-only service -discovery is enabled by running application containers with `LOCALDOMAIN={project}.local` -(see [resolv.conf(5)](http://man7.org/linux/man-pages/man5/resolv.conf.5.html)). This works out-of-the-box for -debian-based Docker images. Alpine images have to include a tiny entrypoint script to replicate this feature: +get service discovery and DNS round-robin (equivalent for Compose's `endpoint_mode: dnsrr`). Docker images SHOULD +include a tiny entrypoint script to replicate this feature: ```shell script -if [ $LOCALDOMAIN ]; then echo "search ${LOCALDOMAIN}" >> /etc/resolv.conf; fi +if [ ! -z LOCALDOMAIN ]; then echo "search ${LOCALDOMAIN}" >> /etc/resolv.conf; fi ``` diff --git a/ecs/pkg/amazon/cloudformation.go b/ecs/pkg/amazon/cloudformation.go index ebd948aff..a9642a6a1 100644 --- a/ecs/pkg/amazon/cloudformation.go +++ b/ecs/pkg/amazon/cloudformation.go @@ -5,6 +5,8 @@ import ( "regexp" "strings" + "github.com/compose-spec/compose-go/types" + "github.com/sirupsen/logrus" cloudmapapi "github.com/aws/aws-sdk-go/service/servicediscovery" @@ -77,9 +79,10 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err } cluster := cloudformation.If("CreateCluster", cloudformation.Ref("Cluster"), cloudformation.Ref(ParameterClusterName)) - for net := range project.Networks { - name, resource := convertNetwork(project, net, cloudformation.Ref(ParameterVPCId)) - template.Resources[name] = resource + for _, net := range project.Networks { + for k, v := range convertNetwork(project, net, cloudformation.Ref(ParameterVPCId)) { + template.Resources[k] = v + } } logGroup := fmt.Sprintf("/docker-compose/%s", project.Name) @@ -204,25 +207,28 @@ func (c client) Convert(project *compose.Project) (*cloudformation.Template, err return template, nil } -func convertNetwork(project *compose.Project, net string, vpc string) (string, cloudformation.Resource) { +func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc string) map[string]cloudformation.Resource { + resources := map[string]cloudformation.Resource{} var ingresses []ec2.SecurityGroup_Ingress - for _, service := range project.Services { - if _, ok := service.Networks[net]; ok { - for _, port := range service.Ports { - ingresses = append(ingresses, ec2.SecurityGroup_Ingress{ - CidrIp: "0.0.0.0/0", - Description: fmt.Sprintf("%s:%d/%s", service.Name, port.Target, port.Protocol), - FromPort: int(port.Target), - IpProtocol: strings.ToUpper(port.Protocol), - ToPort: int(port.Target), - }) + if !net.Internal { + for _, service := range project.Services { + if _, ok := service.Networks[net.Name]; ok { + for _, port := range service.Ports { + ingresses = append(ingresses, ec2.SecurityGroup_Ingress{ + CidrIp: "0.0.0.0/0", + Description: fmt.Sprintf("%s:%d/%s", service.Name, port.Target, port.Protocol), + FromPort: int(port.Target), + IpProtocol: strings.ToUpper(port.Protocol), + ToPort: int(port.Target), + }) + } } } } - securityGroup := networkResourceName(project, net) - resource := &ec2.SecurityGroup{ - GroupDescription: fmt.Sprintf("%s %s Security Group", project.Name, net), + securityGroup := networkResourceName(project, net.Name) + resources[securityGroup] = &ec2.SecurityGroup{ + GroupDescription: fmt.Sprintf("%s %s Security Group", project.Name, net.Name), GroupName: securityGroup, SecurityGroupIngress: ingresses, VpcId: vpc, @@ -233,11 +239,20 @@ func convertNetwork(project *compose.Project, net string, vpc string) (string, c }, { Key: NetworkTag, - Value: net, + Value: net.Name, }, }, } - return securityGroup, resource + + ingress := securityGroup + "Ingress" + 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 } func networkResourceName(project *compose.Project, network string) string { diff --git a/ecs/pkg/amazon/testdata/simple/simple-cloudformation-conversion.golden b/ecs/pkg/amazon/testdata/simple/simple-cloudformation-conversion.golden index 677c3483e..613aba14b 100644 --- a/ecs/pkg/amazon/testdata/simple/simple-cloudformation-conversion.golden +++ b/ecs/pkg/amazon/testdata/simple/simple-cloudformation-conversion.golden @@ -232,6 +232,19 @@ } }, "Type": "AWS::EC2::SecurityGroup" + }, + "TestSimpleConvertDefaultNetworkIngress": { + "Properties": { + "Description": "Allow communication within network default", + "GroupId": { + "Ref": "TestSimpleConvertDefaultNetwork" + }, + "IpProtocol": "-1", + "SourceSecurityGroupId": { + "Ref": "TestSimpleConvertDefaultNetwork" + } + }, + "Type": "AWS::EC2::SecurityGroupIngress" } } } diff --git a/ecs/pkg/amazon/testdata/simple/simple-cloudformation-with-overrides-conversion.golden b/ecs/pkg/amazon/testdata/simple/simple-cloudformation-with-overrides-conversion.golden index b81f63512..0e506fce8 100644 --- a/ecs/pkg/amazon/testdata/simple/simple-cloudformation-with-overrides-conversion.golden +++ b/ecs/pkg/amazon/testdata/simple/simple-cloudformation-with-overrides-conversion.golden @@ -232,6 +232,19 @@ } }, "Type": "AWS::EC2::SecurityGroup" + }, + "TestSimpleWithOverridesDefaultNetworkIngress": { + "Properties": { + "Description": "Allow communication within network default", + "GroupId": { + "Ref": "TestSimpleWithOverridesDefaultNetwork" + }, + "IpProtocol": "-1", + "SourceSecurityGroupId": { + "Ref": "TestSimpleWithOverridesDefaultNetwork" + } + }, + "Type": "AWS::EC2::SecurityGroupIngress" } } } diff --git a/ecs/pkg/amazon/up.go b/ecs/pkg/amazon/up.go index e3297249d..23517a118 100644 --- a/ecs/pkg/amazon/up.go +++ b/ecs/pkg/amazon/up.go @@ -54,6 +54,7 @@ func (c *client) ComposeUp(ctx context.Context, project *compose.Project) error return err } + fmt.Println() return c.WaitStackCompletion(ctx, project.Name, StackCreate) } diff --git a/ecs/pkg/compose/normalize.go b/ecs/pkg/compose/normalize.go index 0061a1f1f..861d146f3 100644 --- a/ecs/pkg/compose/normalize.go +++ b/ecs/pkg/compose/normalize.go @@ -49,5 +49,34 @@ func Normalize(model *types.Config) error { } model.Services[i] = s } + + for i, n := range model.Networks { + if n.Name == "" { + n.Name = i + model.Networks[i] = n + } + } + + for i, v := range model.Volumes { + if v.Name == "" { + v.Name = i + model.Volumes[i] = v + } + } + + for i, c := range model.Configs { + if c.Name == "" { + c.Name = i + model.Configs[i] = c + } + } + + for i, s := range model.Secrets { + if s.Name == "" { + s.Name = i + model.Secrets[i] = s + } + } + return nil }