Skip to content

v0.13.0

Latest

Choose a tag to compare

@github-actions github-actions released this 17 Aug 21:09

Sidecar container support for apply and export.

A multi-container task definition — an init container that prepares a shared volume, a network sidecar, and a hardened application container that waits for the init container to finish — is now expressible as a spec instead of hand-assembled aws ecs register-task-definition JSON.

New spec fields

Per container, inside spec.containers[]:

Field Purpose
user Run as a specific uid. ECS has no task-level user, so a root init container beside a non-root app container needs this per container.
readonlyRootFilesystem
entryPoint Override the image's ENTRYPOINT, not just command.
dependsOn Startup ordering — START, SUCCESS or COMPLETE — against another container in the same task.
linuxParameters.capabilitiesDrop Validated against the capability names ECS accepts.
mountPoints containerPath → volume name, or {sourceVolume, readOnly}.

At task level:

Field Purpose
volumes Ephemeral ECS-managed scratch, or an efs block for a persistent file system.

Example

apiVersion: ecsctl/v1
kind: Service
metadata:
  name: my-app
  cluster: prod
spec:
  cpu: "1024"
  memory: "2048"
  volumes:
    - name: workspace
  containers:
    - name: init-perms
      image: my-app:latest
      essential: false          # required: AWS refuses a SUCCESS dependency
      user: "0"                 # on an essential container
      entryPoint: ["/bin/sh", "-c"]
      command: ["chown 1000:1000 /workspace"]
      mountPoints:
        /workspace: workspace
    - name: app
      image: my-app:latest
      essential: true
      user: "1000"
      readonlyRootFilesystem: true
      linuxParameters:
        capabilitiesDrop: ["ALL"]
      dependsOn:
        - containerName: init-perms
          condition: SUCCESS
      mountPoints:
        /workspace: workspace
        /config:
          sourceVolume: workspace
          readOnly: true

Validation moved earlier

Combinations AWS rejects are now refused locally, with the offending value named, before any API call: unknown or duplicate container and volume names, self-dependencies, dependency cycles (the error prints the actual cycle path), SUCCESS/COMPLETE against an essential: true target, a task with no essential container, unrecognised capability names, EFS iam without transit encryption, an accessPointId conflicting with rootDirectory, and spec-level container fields left alongside containers[] where they would previously have been silently dropped.

export round-trips the new fields

ecsctl export reads all of the above back, and its output is a spec apply accepts. Where a task definition cannot be represented losslessly, export refuses rather than degrading silently — Docker volumes, FSx for Windows, host bind mounts with a source path, EBS volumes configured at launch, and capabilities this spec cannot validate. A dependsOn: HEALTHY condition is dropped with a warning, because healthCheck is not yet configurable here.

Fixes

  • ecsctl exec and ecsctl log resolved to a network sidecar rather than the application in a multi-container task, silently running commands in the wrong container. They now prefer the essential container that declares dependsOn, which in the init-container pattern is the application.
  • ecsctl update still refuses multi-container services — it rebuilds the task definition from the flat single-container fields and would drop the rest — but its error now spells out the export → edit → apply workflow instead of refusing without a path forward.
  • The JSON schema required spec.image, which every multi-container spec legitimately omits. schemas/service.schema.json now requires either image or containers, and CI validates representative specs against it so the schema and the parser cannot drift apart again.

Compatibility

Every new field is optional with a serde default. Existing single-container specs parse, validate and export exactly as before, asserted by test. ecsctl update behaviour for single-container services is unchanged.

Full detail: #55