Effortless AWS Fargate Debugging: How to Access Running Tasks

Often, I find myself trying to debug a running AWS Fargate task by pushing new Docker images and figuring things out by trial and error. If you find yourself in a similar situation, I have good news for you. There is a much easier way to debug a running AWS Fargate task. Since March 2021, AWS Fargate supports the use of an execute command. In this post, I will show you how to use this feature to enable it for a running AWS Fargate task.

A technical illustration of a laptop with a magnifying glass and cloud over it.
Looking through a magnifying glass in your AWS Fargate Tasks

Prerequisites

  • AWS CLI installed and configured. You can find the installation instructions here. Since executeCommand is not yet available in the AWS Management Console, we need the CLI to configure and utilize this feature.

Step-by-Step IAM Permission Setup

First, you need to configure the right IAM permissions for your own user and the task execution role. The permissions required by the user are the ability to use the executeCommand action on a specific task. The permissions required by the task execution role are the ability to use the session manager to communicate with the user.

User Role

The specific action is ecs:ExecuteCommand. An example for this policy is:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecs:ExecuteCommand"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/tag-key": "tag-value",
                    "StringEquals": {
                        "ecs:container-name": "<container_name>"
                    }
                }
            },
            "Resource":"arn:aws:ecs:<region>:<aws_account_id>:cluster/<cluster_name>"
        }
    ]
}

Scoping down the permissions to a specific container or tag value is optional but considered best practice according to AWS’s official documentation1. If you do not want to scope down the permissions you can remove the Condition block from the policy. The Resource is the ARN of the cluster you want to execute the command on. You can find the ARN of your cluster in the AWS Management Console under ECS.

Task Execution Role

The execute command feature uses the session manager under the hood. Therefore, you need to authorize the task to use specific session manager actions. You can do this by adding the following policy to your task execution role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Resource": "*"
        }
    ]
}

Configure the task definition

We are now ready to change the configuration of the task definition. We first want to make sure we can read the value of the executeCommand parameter.

Read the value of the executeCommand parameter

aws ecs describe-tasks \
    --cluster <cluster> \
    --region <region> \
    --tasks <task>

This command takes the following parameters:

  1. cluster: The name of the cluster the task is running on. You can see this in the AWS Management Console under ECS.
  2. region: The region the cluster is running in. For example eu-west-1.
  3. task: The id of the task you want to debug. You can find this in the AWS Management Console under the ECS Cluster. For example 7930a157464d443895b3cca145ae13cc

The command will output the configuration JSON. We are interested in the enableExecuteCommand parameter. If this parameter is set to true, we can use the execute command feature. If it is set to false, we need to change the ECS service to enable this feature.

Enable the executeCommand parameter

aws ecs update-service \
    --cluster <cluster> \
    --task-definition <task definition \
    --service <service> \
    --enable-execute-command \
    --region <region>

This command takes the following parameters:

  1. cluster: The name of the cluster the task is running on. You can see this in the AWS Management Console under ECS.
  2. task-definition: The name of the task definition. You can see this in the AWS Management Console under ECS.
  3. service: The name of the service. You can see this in the AWS Management Console under ECS.
  4. region: The region the cluster is running in. For example eu-west-1.

Make sure you use the name of the resource not the ARN. For example my-service instead of arn:aws:ecs:eu-west-1:123456789012:service/my-service.

Execute the command

We are now ready to execute the command on the running task. We can do this by using the following command:

aws ecs execute-command \
    --cluster <cluster> \
    --task <task> \
    --container <container> \
    --command <command> \
    --interactive \
    --region <region>

This command takes the following parameters:

  1. cluster: The name of the cluster the task is running on. You can see this in the AWS Management Console under ECS.
  2. task: The id of the task. For example 7930a157464d443895b3cca145ae13cc
  3. container: The name of the container you want to execute the command on. You can see this in the AWS Management Console under ECS.
  4. command: The command you want to execute. For example sh.
  5. interactive: This flag indicates that you want to execute an interactive command.
  6. region: The region the cluster is running in. For example eu-west-1.

This command will execute the command on the running task and start a shell into the container. You can use this shell to debug the running task. Note that AWS Fargate is a stateless service. This means that if you restart the task the changes you made will be lost.

Conclusion

In this guide, we’ve walked through a more efficient method to debug AWS Fargate tasks. By using the execute command feature, you can save time and avoid the hassle of trial and error by pushing new Docker images.

Have questions or experiences to share?

Drop them in the comments below!

Hi there 👋

My name is Joeri Smits and I write about technical stuff on this website. If you have an exciting new project or just want to share thoughts, feel free to reach out to me on LinkedIn!