Amazon ECS Exec — Shell Access to Fargate and EC2 Containers

Amazon ECS Exec gives interactive shell or single-command access to running ECS containers (both Fargate and EC2 launch types) directly from the AWS CLI — no bastion, no SSH daemon, no inbound security-group rules. Announced in March 2021, it channels sessions through AWS Systems Manager (SSM) Session Manager plumbing: an SSM agent sidecar (the ExecuteCommandAgent) runs inside the task, and the CLI speaks to it over the SSM messages channel. It exists for debugging and operations, but enabling interactive shells in production containers is broadly considered not a best practice — and from a security-review perspective it’s a lateral-movement primitive granted entirely by IAM.

How it works

  1. Enablement flag: --enable-execute-command must be set at service/task level (create-service, update-service, or run-task). It can only be turned on for new tasks — enabling it on an existing service requires a redeployment.
  2. Task role permissions: the task’s IAM role must allow the SSM messages channel actions: ssmmessages:CreateControlChannel, ssmmessages:CreateDataChannel, ssmmessages:OpenControlChannel, ssmmessages:OpenDataChannel.
  3. Caller permissions: the principal invoking the shell needs ecs:ExecuteCommand on the task (plus ecs:DescribeTasks for discovery; a narrowly-scoped policy pins both to the cluster/task ARNs rather than *).
  4. Prerequisites: Fargate platform version 1.4.0+ (or EC2 launch type with a supported ECS agent), the Session Manager plugin installed locally, and Linux containers for /bin/sh-style shells (Windows containers are supported with PowerShell on newer agents).

Commands

Enable on an existing service (forces new tasks on next deployment):

aws ecs update-service \
    --cluster $ECS_CLUSTER \
    --service $ECS_SERVICE \
    --task-definition $ECS_TASK \
    --enable-execute-command \
    --desired-count 1

Verify the agent is running (ExecuteCommandAgent status in the task description):

aws ecs describe-tasks --cluster $ECS_CLUSTER --tasks $TASK_ID

Pop an interactive shell:

aws ecs execute-command \
    --cluster $ECS_CLUSTER \
    --task $TASK_ID \
    --container $CONTAINER_NAME \
    --interactive \
    --command "/bin/sh"

Security-relevant properties

  • All-IAM authorization: no SSH keys, no network path — whoever can call ecs:ExecuteCommand gets a shell. In a compromised-credential scenario this turns an IAM foothold into container-level code execution; scope the action tightly and monitor its use.
  • Auditability: sessions can be logged to S3/CloudWatch via Session Manager logging, and every execute-command call lands in CloudTrail. AWS deliberately chose SSM over raw SSH partly for this trail.
  • Egress-only networking: the agent dials out to SSM endpoints; containers in private subnets without inbound rules remain reachable, which is convenient for ops and meaningful for threat modeling.
  • ECS Exec vs. SSH over Session Manager to EC2: same SSM substrate, different target (container task vs. instance OS).

Sources

Related: aws-ssm-ssh, aws-sigv4-api-flooding, dcerpc