You can’t directly SSH into an ECS container like you would a VM, but ECS Exec lets you run commands inside your running containers without needing to build a new image or restart the task.

Let’s see ECS Exec in action. Imagine you have a web server running in an ECS Fargate task, and you want to check its access logs.

First, ensure your task definition has the enableExecuteCommand flag set to true. This is usually done in the aws_ecs_task_definition resource in Terraform or via the AWS console when creating/updating the task definition.

resource "aws_ecs_task_definition" "example" {
  family                   = "my-web-app"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = "256"
  memory                   = "512"
  execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn
  container_definitions = jsonencode([
    {
      name      = "nginx"
      image     = "nginx:latest"
      essential = true
      portMappings = [
        {
          containerPort = 80
          hostPort      = 80
        }
      ]
    }
  ])
  # This is the key for ECS Exec
  enable_execute_command = true
}

Once your task is running with this enabled, you can use the AWS CLI to connect. You’ll need the aws-cli/2.x or later and the session-manager-plugin installed.

To list your running tasks: aws ecs list-tasks --cluster <your-cluster-name> --service-name <your-service-name>

This will give you a list of task ARNs. Pick the one you want to debug.

Now, to execute a command, like ls /app: aws ecs execute-command --cluster <your-cluster-name> --task <your-task-id> --container <your-container-name> --command "ls /app"

If you want an interactive shell, use -it: aws ecs execute-command --cluster <your-cluster-name> --task <your-task-id> --container <your-container-name> --command "sh" -it

This opens a shell session directly inside your container. You can then navigate directories, inspect files, and run diagnostic commands as if you were logged in. For our web server example, you could check /var/log/nginx/access.log.

The magic behind ECS Exec is that it leverages the Systems Manager (SSM) Agent. When enableExecuteCommand is true, AWS injects a special SSM Agent into your container’s runtime environment. This agent establishes a secure tunnel back to AWS, allowing SSM to proxy your commands and interact with the agent. It doesn’t require opening inbound ports on your task or modifying your container image with SSH daemons.

The primary benefit is ephemeral debugging. You can inspect the state of a container at a specific moment without the overhead of building new images, pushing them, updating the service, and waiting for new tasks to start. It’s invaluable for troubleshooting configuration issues, checking file permissions, or verifying application state in a production environment.

What most people miss is how tightly integrated ECS Exec is with IAM. The ecs:ExecuteCommand permission is what grants the ability to initiate these sessions. Furthermore, the task’s execution role needs permissions to communicate with SSM. Specifically, the role requires policies that allow ssmmessages:* and ssm:* actions. Without these, the SSM agent within the container cannot establish the necessary outbound connections to AWS Systems Manager, and your execute-command calls will fail with permission errors, even if the task definition has enableExecuteCommand set to true.

The next hurdle you’ll face is managing security and auditing these interactive sessions.

Want structured learning?

Take the full Ecs course →