Use AWS ECS execute command to access a container on AWS Fargate and EC2

Use AWS ECS execute command to access a container on AWS Fargate and EC2

To access an Amazon ECS container on AWS Fargate or Amazon EC2, you need to enable ECS Exec on the task definition of your containers. Next update the task IAM role to include the required SSM permissions. Then run the AWS ECS execute command in the AWS CLI to log in to the Amazon ECS container.

When you’re using the AWS CLI to connect to a container, make sure to log in to the specified AWS CLI profile. Otherwise, you can’t run any AWS CLI commands on your AWS account.

Here are the steps to access an Amazon Elastic Container Service (ECS) container using AWS ECS execute command on the AWS CLI.

Table of Contents

How to connect to an Amazon ECS container using AWS ECS execute command

Amazon ECS Exec allows you to access a container running on an Amazon EC2 instance or AWS Fargate using the AWS CLI. This means you don’t need to use SSH with a complicated VPN setup in order to access the container in the Cloud anymore.

Instead, AWS makes use of an existing technology called AWS Systems Manager (SSM) Session Manager and IAM policies to allow developers to access running containers directly from the command-line interface.

The same technology is being used to allow access to EC2 instances without having to use the SSH protocol.

1. Verify if ECS Exec is enabled on an ECS task

There is a useful tool called Amazon ECS Exec Checker that allows you to check and validate if your ECS service/task is already able to run ECS Exec. The example below shows a task that isn’t capable of running ECS Exec.

Running Amazon ECS Exec Checker on an ECS task which shows ECS Exec is disabledRunning Amazon ECS Exec Checker on an ECS task which shows ECS Exec is disabled

But if your ECS task passes the test, you can skip steps 1-4 and immediately move on to step 5 of this guide to run the ECS exec command to log in to your container.

2. Install the session manager plugin for AWS CLI

The session manager plugin is an add-on for your AWS CLI that allows you to connect to EC2 instances or AWS Fargate.

To install the session manager plugin on windows, download and install this executable:

https://s3.amazonaws.com/session-manager-downloads/plugin/latest/windows/SessionManagerPluginSetup.exe

To install the session manager plugin on macOS and Linux, use homebrew:

brew install --cask session-manager-plugin

3. Add SSM permissions to the task IAM role

You should add the following policy to your existing ECS task IAM role. This grants permission for the ECS task to connect with the SSM Session Manager service.

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

4. Add ECS ExecuteCommand permission to your IAM role

Make sure your IAM role contains a policy that allows the action ecs:ExecuteCommand. Otherwise, you’re not able to run aws ecs execute-command in the AWS CLI in order to access the running container.

Add the following policy to your IAM role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "User access to ECS ExecuteCommand",
            "Effect": "Allow",
            "Action": "ecs:ExecuteCommand",
            "Resource": "*"
        }
    ]
}

5. Enable ECS Exec for your ECS task and services

AWS ECS execute command allows you to run a command remotely from your terminal on a container within a task in AWS.

But before you can do that, you need to enable the ECS Exec feature on existing and new ECS tasks and services by using the parameter --enable-execute-command.

To enable ECS Exec on an existing ECS service run:

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

To enable ECS Exec on a new ECS service, run:

aws ecs create-service \
    --cluster <cluster-name> \
    --task-definition <task-definition-name> \
    --service-name <service-name> \
    --desired-count 1 \
    --enable-execute-command

To verify if a task has ExecuteCommand enabled you can run the aws ecs describe-tasks command to check its configuration:

aws ecs describe-tasks --cluster example-cluster --tasks 

5210107e30a9470b9b093d1fb72e8d6a

If everything went well, you’ll receive the following output with enableExecuteCommand set to true:

{
    "tasks": [
        {
            "attachments": [...],
            "attributes": [
                {
                    "name": "ecs.cpu-architecture",
                    "value": "x86_64"
                }
            ],
            "availabilityZone": "eu-west-1b",
            "clusterArn": "arn:aws:ecs:eu-west-1:123456789012:cluster/example-cluster",
            "connectivity": "CONNECTED",
            "connectivityAt": "2022-06-22T11:53:36.154000+02:00",
            "containers": [
                {
                    "containerArn": "arn:aws:ecs:eu-west-1:123456789012:container/example-cluster/5210107e30a9470b9b>
                    "taskArn": "arn:aws:ecs:eu-west-1:123456789012:task/example-cluster/5210107e30a9470b9b093d1fb72e>
                    "name": "exampletaskContainerDefinition",
                    "image": "123456789012.dkr.ecr.eu-west-1.amazonaws.com/cdk-hnb659fds-container-assets-123456789012-eu-west-1:b9f191a6ee986261f27aa2695932f>
                    "imageDigest": "sha256:efcad1c554084dcae8a1fdbbb7645c9973798c61e35ee44404a4488b11a31db4",
                    "runtimeId": "5210107e30a9470b9b093d1fb72e8d6a-3215916765",
                    "lastStatus": "RUNNING",
                    "networkBindings": [],
                    "networkInterfaces": [...],
                    "healthStatus": "UNKNOWN",
                    "managedAgents": [
                        {
                            "lastStartedAt": "2022-06-22T11:54:02.349000+02:00",
                            "name": "ExecuteCommandAgent",
                            "lastStatus": "RUNNING"
                        }
                    ],
                    "cpu": "0"
                }
            ],
            "cpu": "1024",
            "createdAt": "2022-06-22T11:53:32.857000+02:00",
            "desiredStatus": "RUNNING",
            "enableExecuteCommand": true,
            "group": "service:exampletask",
            "healthStatus": "UNKNOWN",
            "lastStatus": "RUNNING",
            "launchType": "FARGATE",
            "memory": "2048",
            "overrides": {
                "containerOverrides": [
                    {
                        "name": "exampletaskContainerDefinition"
                    }
                ],
                "inferenceAcceleratorOverrides": []
            },
            "platformVersion": "1.4.0",
            "platformFamily": "Linux",
            "pullStartedAt": "2022-06-22T11:53:44.292000+02:00",
            "pullStoppedAt": "2022-06-22T11:53:53.637000+02:00",
            "startedAt": "2022-06-22T11:54:38.514000+02:00",
            "startedBy": "ecs-svc/0693543628378788598",
            "tags": [],
            "taskArn": "arn:aws:ecs:eu-west-1:123456789012:task/example-cluster/5210107e30a9470b9b093d1fb72e8d6a",
            "taskDefinitionArn": "arn:aws:ecs:eu-west-1:123456789012:task-definition/exampletask:3",
            "version": 4,
            "ephemeralStorage": {
                "sizeInGiB": 20
            }
        }
    ],
    "failures": []
}

6. Log in to the container using ECS exec

So once all the permissions have been set and the ECS Exec feature enabled on the ECS services and tasks, then you can proceed to log in to the container.

Run the aws ecs execute command with the task id and container name to log in.

aws ecs execute-command --cluster <cluster-name> \
    --task <task-id> \
    --container <container-name> \
    --interactive \
    --command "/bin/sh"

This is the output you’ll see when you’re executing aws ecs execute-command on an actual running container.

aws ecs execute-command --cluster example-cluster \
    --task 0b9b093d1fb72e8d6a5210107e30a947 \
    --container exampletask \
    --command "/bin/sh" \
    --interactive

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
Starting session with SessionId: ecs-execute-command-05913e4a1d0e32636
/ #

Now that you’re logged into the ECS container, you can interactively run commands to gather data or change configurations.

Conclusion

In this article, you’ve learned how to enable ECS Exec on your Amazon ECS services and tasks so that you can access a container on AWS Fargate or Amazon EC2.

To make it possible to access your container, you need to install the session manager plugin, add SSM permissions to the ECS task IAM role, and then update your ECS service or task with --enable-execute-command to enable ECS Exec.

Now you can run the aws ecs execute command in your AWS CLI to access your ECS containers.

Troubleshooting

How to fix ExecuteCommand operation: Unable to start session because the container doesn’t exist

If you get the following error with the ExecuteCommand operation:

An error occurred (InvalidParameterException) when calling the ExecuteCommand operation: Unable to start session because the container doesn’t exist. Specify a valid container and try again.

Then you’ve used the wrong container name for that specific task id. To fix this error, run the aws ecs describe-tasks command with the --tasks flag to find the container name of that specific task id.

aws ecs describe-tasks --cluster example-cluster --tasks 

5210107e30a9470b9b093d1fb72e8d6a

From the output of the command, look for the overrides property. Here you’ll find the name of the container e.g.

"overrides": {
    "containerOverrides": [
        {
            "name": "web"
        }
    ],
    "inferenceAcceleratorOverrides": []
},