diff --git a/ecs/pkg/amazon/backend/cloudformation.go b/ecs/pkg/amazon/backend/cloudformation.go index 482cf1212..aa43dbe98 100644 --- a/ecs/pkg/amazon/backend/cloudformation.go +++ b/ecs/pkg/amazon/backend/cloudformation.go @@ -119,10 +119,7 @@ func (b Backend) Convert(project *types.Project) (*cloudformation.Template, erro project.Secrets[i] = s } - logGroup := fmt.Sprintf("/docker-compose/%s", project.Name) - template.Resources["LogGroup"] = &logs.LogGroup{ - LogGroupName: logGroup, - } + createLogGroup(project, template) // Private DNS namespace will allow DNS name for the services to be ..local createCloudMap(project, template) @@ -190,7 +187,7 @@ func (b Backend) Convert(project *types.Project) (*cloudformation.Template, erro dependsOn = append(dependsOn, serviceResourceName(dependency)) } - minPercent, maxPercent, err := b.computeRollingUpdateLimits(service) + minPercent, maxPercent, err := computeRollingUpdateLimits(service) if err != nil { return nil, err } @@ -237,7 +234,19 @@ func (b Backend) Convert(project *types.Project) (*cloudformation.Template, erro return template, nil } -func (b Backend) computeRollingUpdateLimits(service types.ServiceConfig) (int, int, error) { +func createLogGroup(project *types.Project, template *cloudformation.Template) { + retention := 0 + if v, ok := project.Extensions[compose.ExtensionRetention]; ok { + retention = v.(int) + } + logGroup := fmt.Sprintf("/docker-compose/%s", project.Name) + template.Resources["LogGroup"] = &logs.LogGroup{ + LogGroupName: logGroup, + RetentionInDays: retention, + } +} + +func computeRollingUpdateLimits(service types.ServiceConfig) (int, int, error) { maxPercent := 200 minPercent := 100 if service.Deploy == nil || service.Deploy.UpdateConfig == nil { diff --git a/ecs/pkg/amazon/backend/cloudformation_test.go b/ecs/pkg/amazon/backend/cloudformation_test.go index 84ddf5308..f2a735c51 100644 --- a/ecs/pkg/amazon/backend/cloudformation_test.go +++ b/ecs/pkg/amazon/backend/cloudformation_test.go @@ -11,6 +11,7 @@ import ( "github.com/awslabs/goformation/v4/cloudformation/ecs" "github.com/awslabs/goformation/v4/cloudformation/elasticloadbalancingv2" "github.com/awslabs/goformation/v4/cloudformation/iam" + "github.com/awslabs/goformation/v4/cloudformation/logs" "github.com/compose-spec/compose-go/cli" "github.com/compose-spec/compose-go/loader" "github.com/compose-spec/compose-go/types" @@ -26,6 +27,25 @@ func TestSimpleConvert(t *testing.T) { golden.Assert(t, result, expected) } +func TestLogging(t *testing.T) { + template := convertYaml(t, "test", ` +services: + foo: + image: hello_world + logging: + options: + awslogs-datetime-pattern: "FOO" + +x-aws-logs_retention: 10 +`) + def := template.Resources["FooTaskDefinition"].(*ecs.TaskDefinition) + logging := def.ContainerDefinitions[0].LogConfiguration + assert.Equal(t, logging.Options["awslogs-datetime-pattern"], "FOO") + + logGroup := template.Resources["LogGroup"].(*logs.LogGroup) + assert.Equal(t, logGroup.RetentionInDays, 10) +} + func TestEnvFile(t *testing.T) { template := convertYaml(t, "test", ` services: @@ -36,8 +56,15 @@ services: `) def := template.Resources["FooTaskDefinition"].(*ecs.TaskDefinition) env := def.ContainerDefinitions[0].Environment - assert.Equal(t, env[0].Name, "FOO") - assert.Equal(t, env[0].Value, "BAR") + var found bool + for _, pair := range env { + if pair.Name == "FOO" { + assert.Equal(t, pair.Value, "BAR") + found = true + } + } + assert.Check(t, found, "environment variable FOO not set") + } func TestEnvFileAndEnv(t *testing.T) { diff --git a/ecs/pkg/amazon/backend/compatibility.go b/ecs/pkg/amazon/backend/compatibility.go index 02ef5e508..d217ca48f 100644 --- a/ecs/pkg/amazon/backend/compatibility.go +++ b/ecs/pkg/amazon/backend/compatibility.go @@ -27,14 +27,16 @@ var compatibleComposeAttributes = []string{ "services.entrypoint", "services.environment", "services.env_file", - "service.image", - "services.init", "services.healthcheck", "services.healthcheck.interval", "services.healthcheck.retries", "services.healthcheck.start_period", "services.healthcheck.test", "services.healthcheck.timeout", + "services.image", + "services.init", + "services.logging", + "services.logging.options", "services.networks", "services.ports", "services.ports.mode", @@ -77,3 +79,9 @@ func (c *FargateCompatibilityChecker) CheckCapAdd(service *types.ServiceConfig) } service.CapAdd = add } + +func (c *FargateCompatibilityChecker) CheckLoggingDriver(config *types.LoggingConfig) { + if config.Driver != "" && config.Driver != "awslogs" { + c.Unsupported("services.logging.driver %s is not supported", config.Driver) + } +} diff --git a/ecs/pkg/amazon/backend/convert.go b/ecs/pkg/amazon/backend/convert.go index b130d51a8..2056dad4f 100644 --- a/ecs/pkg/amazon/backend/convert.go +++ b/ecs/pkg/amazon/backend/convert.go @@ -44,14 +44,7 @@ func Convert(project *types.Project, service types.ServiceConfig) (*ecs.TaskDefi fmt.Sprintf(" %s.local", project.Name), })) - logConfiguration := &ecs.TaskDefinition_LogConfiguration{ - LogDriver: ecsapi.LogDriverAwslogs, - Options: map[string]string{ - "awslogs-region": cloudformation.Ref("AWS::Region"), - "awslogs-group": cloudformation.Ref("LogGroup"), - "awslogs-stream-prefix": project.Name, - }, - } + logConfiguration := getLogConfiguration(service, project) var ( containers []ecs.TaskDefinition_ContainerDefinition @@ -222,6 +215,26 @@ func createEnvironment(project *types.Project, service types.ServiceConfig) ([]e return pairs, nil } +func getLogConfiguration(service types.ServiceConfig, project *types.Project) *ecs.TaskDefinition_LogConfiguration { + options := map[string]string{ + "awslogs-region": cloudformation.Ref("AWS::Region"), + "awslogs-group": cloudformation.Ref("LogGroup"), + "awslogs-stream-prefix": project.Name, + } + if service.Logging != nil { + for k, v := range service.Logging.Options { + if strings.HasPrefix(k, "awslogs-") { + options[k] = v + } + } + } + logConfiguration := &ecs.TaskDefinition_LogConfiguration{ + LogDriver: ecsapi.LogDriverAwslogs, + Options: options, + } + return logConfiguration +} + func toTags(labels types.Labels) []tags.Tag { t := []tags.Tag{} for n, v := range labels { diff --git a/ecs/pkg/compose/x.go b/ecs/pkg/compose/x.go index 44ebfae96..63f2e30e7 100644 --- a/ecs/pkg/compose/x.go +++ b/ecs/pkg/compose/x.go @@ -9,4 +9,5 @@ const ( ExtensionKeys = "x-aws-keys" ExtensionMinPercent = "x-aws-min_percent" ExtensionMaxPercent = "x-aws-max_percent" + ExtensionRetention = "x-aws-logs_retention" )