compose-cli icon indicating copy to clipboard operation
compose-cli copied to clipboard

ECS integration sets TaskRoleArn: null, doesn't work with ECS Exec

Open adair-kovac opened this issue 3 years ago • 7 comments
trafficstars

Description

I'm trying to use ECS Exec to connect to a Fargate container created with the docker compose ecs integration. According to ECS Exec documentation, you need to specify --enable-execute-command for a task. Unfortunately, there's no mention of ECS Exec in the docker compose ECS features.

As a result, I've tried using the aws ecs update-service command to add --enable-execute-command. When I provide the full task definition ARN, it fails on:

An error occurred (InvalidParameterException) when calling the UpdateService operation: The service couldn't be updated because a valid taskRoleArn is not being used. Specify a valid task role in your task definition and try again.

Looking at the task definition json, it includes

  "taskRoleArn": null,

and again I don't see any way to explicitly provide this in the ECS compose features doc.

Is there a way to provide a non-null taskRoleArn, or a more direct way to use ECS Exec with a docker compose fargate container? Is setting a null taskRoleArn the expected/desired behavior of this feature?

Output of docker-compose --version:

docker-compose version 1.29.2, build 5becea4c

Output of docker version:

Docker version 20.10.8, build 3967b7d

adair-kovac avatar Dec 13 '21 22:12 adair-kovac

You may want to to try docker compose v2 to fix this.

bounlu avatar Dec 15 '21 06:12 bounlu

I'm experiencing the same issue.

❯ aws ecs update-service --service <service> --cluster <cluster> --enable-execute-command

An error occurred (InvalidParameterException) when calling the UpdateService operation: The service couldn't be updated because a valid taskRoleArn is not being used. Specify a valid task role in your task definition and try again.
❯ docker compose version
Docker Compose version dev
❯ docker version
Client:
 Cloud integration: v1.0.22
 Version:           20.10.11
 API version:       1.41
 Go version:        go1.16.10
 Git commit:        dea9396
 Built:             Thu Nov 18 00:36:09 2021
 OS/Arch:           darwin/amd64
 Context:           staging
 Experimental:      true
...

christopher-haueter avatar Dec 16 '21 22:12 christopher-haueter

Are you providing it with your service?

services:
  web:
    # ...
    x-aws-policies:
      - arn:aws:iam::<ACC_ID>:policy/DockerExecRole

My policy for reference:

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

Also when updating the service, you need to force a new deployment

aws ecs update-service \
    --service <service> \
    --cluster <cluster> \
    --enable-execute-command \
    --force-new-deployment

andrekrosby92 avatar Jan 02 '22 10:01 andrekrosby92

This is not an issue with compose-cli. You need to provide a "Task role" for a Task Definition (this is different than the "Task execution role"). This can be done by first going to IAM

IAM role creation

  1. IAM > roles > create role
  2. custom trust policy > copy + paste
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ecs-tasks.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
  1. Add permission > Create Policy
  2. JSON > replace YOUR_REGION_HERE & YOUR_ACCOUNT_ID_HERE & CLUSTER_NAME > copy + paste
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:DescribeLogGroups"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:DescribeLogStreams",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:YOUR_REGION_HERE:YOUR_ACCOUNT_ID_HERE:log-group:/aws/ecs/CLUSTER_NAME:*"
        }
    ]
}
  1. Give it a name
  2. go back to Add permissions > search by name > check > Next
  3. Give a role name > create role

ECS new task

  1. go back to ECS > go to task definition and create a new revision
  2. select your new role for "Task role" (different than "Task execution role") > update Task definition
  3. go to your service > update > ensure revision is set to latest > finish update of the service
  4. current task and it should auto provision your new task with its new role.
  5. try again

Commands I used to exec in

enables execute command

aws ecs update-service --cluster CLUSTER_NAME --service SERVICE_NAME --region REGION --enable-execute-command --force-new-deployment

adds ARN to environment for easier cli. Does assume only 1 task running for the service, otherwise just manually go to ECS and grab arn and set them for your cli

TASK_ARN=$(aws ecs list-tasks --cluster CLUSTER_NAME --service SERVICE_NAME --region REGION --output text --query 'taskArns[0]')

see the task,

aws ecs describe-tasks --cluster CLUSTER_NAME --region REGION --tasks $TASK_ARN

exec in

aws ecs execute-command --region REGION --cluster CLUSTER_NAME --task $TASK_ARN --container CONTAINER --command "sh" --interactive

CodaBool avatar Mar 25 '22 16:03 CodaBool

Is there a way to modify the compose.yml to enable the execute command (EnableExecuteCommand: true) for one or more services in lieu of running the update-service command and forcing a new deployment?

It seems a bit wonky (if I understand correctly) that I have to write a configuration, spin up the service, then add additional configuration/restart the service with a command.

Isn't this the sort of thing the overlay capability is for? I struggle to find an exhaustive list of supported overlays and/or a methodology I could use to infer overlays that aren't explicitly laid out.

MrChrisRodriguez avatar Apr 20 '22 22:04 MrChrisRodriguez

@andrekrosby92 Thanks, your steps worked for me.

I really wish I could enable exec in my docker-compose.yml instead of having to explicitly enable it with aws ecs ... --enable-execute-command.

chingc avatar May 16 '22 19:05 chingc

Hello all. I know this ain't native to the docker toolset, but in the meantime / instead, see if x-ecs.EnableExecuteCommand could work for you?

JohnPreston avatar May 17 '22 07:05 JohnPreston

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Nov 13 '22 09:11 stale[bot]

This issue has been automatically closed because it had not recent activity during the stale period.

stale[bot] avatar Jan 08 '23 04:01 stale[bot]