skip to Main Content

I’m trying to replicate an extremely basic manually configured AWS ECS Fargate deployment of a single container using CloudFormation. Looks like I’m almost there; the resulting stack spins up a container I can access. But there are no logs.

I compared my manual task (created via the UI) and the CloudFormation one, and added an identical log configuration to the container definition, but simply changing the log group from /ecs/foo to /ecs/bar:

LogConfiguration:
  LogDriver: awslogs
  Options:
    awslogs-create-group: true
    awslogs-group: '/ecs/bar'
    awslogs-region: !Ref AWS::Region
    awslogs-stream-prefix: 'ecs'

But now the the task fails to start a container. It gives an error like this:

Resourceinitializationerror: failed to validate logger args: create stream has been retried 1 times: failed to create Cloudwatch log group: AccessDeniedException: User: arn:aws:sts::…:assumed-role/ecsTaskExecutionRole/… is not authorized to perform: logs:CreateLogGroup on resource: arn:aws:logs:us-east-1:…:log-group:/ecs/bar:log-stream: because no identity-based policy allows the logs:CreateLogGroup action status code: 400, request id: … : exit status 1

One documentation page mentions this logs:CreateLogGroup permission, and says:

To use the awslogs-create-group option, add logs:CreateLogGroup as an inline IAM policy.

But what I don’t understand is how my CloudFormation template differs from the stack manually created via the UI. By looking at the generated template for the manually-created stack, it appears both task definitions indicate the ecsTaskExecutionRole. My CloudFormation template task definition has this:

ExecutionRoleArn: 'arn:aws:iam::…:role/ecsTaskExecutionRole'

How was the manually-created stack able to create the log group, but my standalone from-scratch CloudFormation template could not? Where would I indicate the logs:CreateLogGroup permission? The manually-created stack doesn’t seem to indicate any inline policy. (Admittedly for some reason the manually-created task definition doesn’t seem to use a CloudFormation stack, so maybe it has some hidden settings I’m not seeing in the UI.)

2

Answers


  1. Chosen as BEST ANSWER

    If I want the task to automatically create a log group dynamically using awslogs-create-group, it appears that the correct approach is to have an IAM policy that includes the logs:CreateLogGroup permission, as mentioned at Using the awslogs log driver. (I still don't understand how creating the task definition manually in the UI resulted in the log group getting created.) Another page related to ECS resource initialization errors says I need to "add logs:CreateLogGroup as an inline IAM policy", but no one has been able to provide an example of how to do that in CloudFormation. I'm sure I could figure it out …

    However rather than having the service dynamically create a log group, it seems to me better practice to declare and configure the AWS::Logs::LogGroup resource in the CloudFormation template itself. (Thanks to the AWS CloudFormation - Beginner to Advanced (Hands-On Guide) Udemy course for inspiring this approach.) Thus I would declare the log group like this in CloudFormation:

    BarLogGroup:
      Type: AWS::Logs::LogGroup
      DeletionPolicy: Retain
      Properties: 
        LogGroupName: '/ecs/bar'
    

    Then to avoid duplication, reference the log group in the log configuration:

    LogConfiguration:
      LogDriver: awslogs
      Options:
        awslogs-group: !Ref BarLogGroup
        awslogs-region: !Ref AWS::Region
        awslogs-stream-prefix: 'ecs'
    

    This gets around the problem of runtime permissions and dynamic creation altogether. The log group is a resource, too, and since the task depends on it we might as well describe it declaratively with the other resources. This way log group creation depends on permissions of the role creating the stack, not the task itself, which seems more appropriate.

    (I've added a deletion policy, assuming you want to keep the logs even if you delete/recreate the stack.)

    After making the above changes, my CloudFormation EC Fargate stack now runs and produces logs just like the manually created stack, so this approach is a success.


  2. ecsTaskExecutionRole should be assigned to TaskRoleArn, not to ExecutionRoleArn.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search