Repository navigation
Releases: oablab/ecsctl
Release list
v0.13.0
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: trueValidation 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 execandecsctl logresolved 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 declaresdependsOn, which in the init-container pattern is the application.ecsctl updatestill 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 theexport→ edit →applyworkflow instead of refusing without a path forward.- The JSON schema required
spec.image, which every multi-container spec legitimately omits.schemas/service.schema.jsonnow requires eitherimageorcontainers, 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
v0.12.0
v0.11.1
What's New in v0.11.1
Fixes
ecsctl logno longer prints nothing during task replacement — when the newest task is PENDING/PROVISIONING (Fargate Spot churn / deploy) and its log stream has no events yet,lognow falls back to the previous task's stream with stderr diagnostics instead of silently exiting.log -fkeeps polling on an empty or not-yet-created stream instead of dying; a missing log group still fails fast. EmptyGetLogEventspages are paged past (nonterminal-page safe), and fallback request fan-out is bounded. (#53)
Full Changelog
v0.11.0
release: v0.11.0 - feat(restart): --recreate stop-then-start deployments (#48) - docs: README split into brief demo + docs/getting-started.md (#50) - docs: fix stale library version reference
v0.10.0
What's New
Schedule Subcommand
ecsctl schedule create|list|delete— manage recurring ECS scaling schedules via EventBridge Scheduler- Universal target (no Lambda needed), cron/rate/at expressions, timezone support
- Configurable schedule group name and IAM role ARN via config.toml
Library API Foundations (for oabctl)
Config::load_from(path)— custom config locations for downstream consumers#[non_exhaustive]on public structs — safe future evolutionCreateScheduleOpts::new().with_name_prefix().with_description_prefix()builder patternclapmoved to optionalclifeature flag (default-features = falsefor library use)futuresreplaced with lighterfutures-utilaws-sdk-ecstest-util moved to dev-dependencies
Breaking Changes
scaleno longer setsforce_new_deployment(true)— userestartfor rolling restarts--with-scheduleflag removed fromscale— useecsctl schedule createinstead- Command functions now require
&Configparameter (library API change)
Fixes
--waitnow prints warning when used with multi-target groups (instead of silent skip)- Schedule overwrite prints explicit warning
- Partition validation includes aws-iso and aws-iso-b
- Dead code removed (schedule_exists function)
Documentation
- README: Limitations section for schedule feature (DLQ, AAS conflict)
- README: "Using as a Library" section with module classification
- Library-safe vs CLI-grade boundary clearly documented
v0.9.1
v0.9.0
What's New in v0.9.0
✨ Alias Groups (@group)
Batch operations on named sets of aliases:
# ~/.ecsctl/config.toml
[groups]
all = ["chaodu", "koudu", "juedu", "kongming", "xiaoqiao", "..."]
small = ["kongming", "xiaoqiao", "guanyu", "zhaoyun", "zhangfei"]ecsctl scale @small 0 # stop all lightweight bots
ecsctl scale @all 1 # bring up entire fleet
ecsctl restart @all # rolling restart✨ Scale Command (group-aware)
ecsctl scale chaodu 2 # single alias
ecsctl scale @medium 1 # entire group
ecsctl scale chaodu 3 --wait # wait for stabilizationChanges
restartnow supports@groupsyntaxscalecommand added with group support- Config: new
[groups]section for defining alias sets - Count validation: rejects negative values
Full Changelog: v0.8.1...v0.9.0
v0.8.1
v0.8.0
What's New
ecsctl get --all— Fleet-wide overview table showing all aliased services (NAME, STATUS, CPU, MEM, CAPACITY, IMAGE, TASKS)ecsctl get --all --watch— Live auto-refresh every 5s with graceful Ctrl+C shutdown- Rolling update awareness — REPLACING/DRAINING status during deployments
- Robust flag validation —
--watchrequires--all,--outputincompatible with--all,nameconflicts with--all - Fatal error handling — Watch mode exits cleanly on expired credentials or network failures instead of spinning
v0.7.1
fix(sync): use temp file for download instead of pipe (#31) ECS exec SSM sessions don't support piping tar output directly to curl. Write to a temp file first, then upload to S3. Co-authored-by: chaodu-agent <chaodu-agent@users.noreply.github.com>