Skip to content

Logs: Faulty Resource Policy generated #17544

@ezra-agathos

Description

@ezra-agathos

What is the problem?

I'm attempting to create a simple stack that houses a task definition for some fargate tasks.
When I add a logging configuration to a container definition inside, a resource policy is added in the generated cf template:

  "Resources": {
    "ecsstackloggroupPolicy0078989C": {
      "Type": "AWS::Logs::ResourcePolicy",
      "Properties": {
        "PolicyDocument": "{\"Statement\":[{\"Action\":[\"logs:CreateLogStream\",\"logs:PutLogEvents\"],\"Effect\":\"Allow\",\"Principal\":
        ...
        ...

Reproduction Steps

from aws_cdk import (
    core as cdk,
    aws_ecs as ecs,
    aws_iam as iam,
    aws_ecr as ecr,
    aws_logs as logs,
)
REGION="us-east-2"
FAMILY="example"
TASK_ARN="arn:aws:iam::<example existing iam role arn>"
EXEC_ARN="arn:aws:iam::<example existing iam role arn>"
ECR_PIPELINE_ARN="arn:aws:ecr:<example existing ECR arn>"
LOG_GROUP_ARN="arn:aws:logs:<example existing log group arn>"
class EcsStack(cdk.Stack):

    def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # reference execution role
        exec_role = iam.Role.from_role_arn(
            self,
            'fargate-exec-role',
            EXEC_ARN,
            mutable=False
        )

        # reference task role
        task_role = iam.Role.from_role_arn(
            self,
            'fargate-task-role',
            TASK_ARN,
            mutable=False
        )

        # reference pipeline ecr image
        repo = ecr.Repository.from_repository_arn(
            self,
            'repo',
            ECR_PIPELINE_ARN
        )

        image = ecs.ContainerImage.from_ecr_repository(
            repo,
            'image-name'
        )
        
        # logging
        log_group = logs.LogGroup.from_log_group_arn(
            self,
            'ecs-stack-log-group',
            log_group_arn=LOG_GROUP_ARN
        )
        log_driver = ecs.LogDriver.aws_logs(
            stream_prefix="test",
            log_group=log_group
        )

        # construct base task definition
        base_def = ecs.TaskDefinition(
            self,
            'base-definition',
            family=FAMILY,
            execution_role=exec_role,
            task_role=task_role,
            compatibility=ecs.Compatibility.FARGATE,
            cpu='512',
            memory_mib='1024'
        )
        base_def.add_container(
            id='pipeline',
            container_name='pipeline',
            image=image,
            cpu=512,
            memory_limit_mib=1024,
            memory_reservation_mib=512,
            essential=True,
            environment=[],
            secrets=[],
            logging=log_driver
        )

What did you expect to happen?

I was attempting to generate a template that behaved similarly to a CF template I've written below.

When deployed, a task definition with a single container definition is created, with references to the pre-existing resources I've specified using ARNs.

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "TaskDefinition": {
            "Type": "AWS::ECS::TaskDefinition",
            "Properties": {
                "Family": "test-deploy-definition",
                "ExecutionRoleArn": "...",
                "TaskRoleArn": "...",
                "RequiresCompatibilities": [
                    "FARGATE"
                ],
                "Cpu": "512",
                "Memory": "1024",
                "NetworkMode": "awsvpc",
                "ContainerDefinitions": [
                    {
                        "Name": "...",
                        "Image": "...",
                        "Command": [],
                        "EntryPoint": [],
                        "MountPoints": [],
                        "Cpu": 512,
                        "Memory": 1024,
                        "MemoryReservation": 512,
                        "PortMappings": [],
                        "Essential": true,
                        "Environment": [
                        ],
                        "Secrets": [],
                        "LogConfiguration": {
                            "LogDriver": "awslogs",
                            "Options": {
                              "awslogs-group": "/test/log",
                              "awslogs-region": "us-east-2",
                              "awslogs-stream-prefix": "test"
                            }
                    
                        }
                    }
                ]
            }
        }
    }

What actually happened?

  1. The resource policy request generates an error:
11:06:15 AM | CREATE_FAILED        | AWS::Logs::ResourcePolicy | ecsstackloggroupPolicy0078989C
Resource handler returned message: "Invalid request provided: AWS::Logs::ResourcePolicy" (RequestToken: 24b0df2b-73fa-056d-4371-7b19f637cb1c, HandlerErrorCode: InvalidRequest)

        new ResourcePolicy (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/jsii-kernel-RXZcI5/node_modules/@aws-cdk/aws-logs/lib/policy.js:17:9)
        \_ Import.addToResourcePolicy (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/jsii-kernel-RXZcI5/node_modules/@aws-cdk/aws-logs/lib/log-group.js:125:27)
        \_ Function.addToPrincipalOrResource (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/jsii-kernel-RXZcI5/node_modules/@aws-cdk/aws-iam/lib/grant.js:70:49)
        \_ Import.grant (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/jsii-kernel-RXZcI5/node_modules/@aws-cdk/aws-logs/lib/log-group.js:97:26)
        \_ Import.grantWrite (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/jsii-kernel-RXZcI5/node_modules/@aws-cdk/aws-logs/lib/log-group.js:89:21)
        \_ AwsLogDriver.bind (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/jsii-kernel-RXZcI5/node_modules/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.js:48:23)
        \_ new ContainerDefinition (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/jsii-kernel-RXZcI5/node_modules/@aws-cdk/aws-ecs/lib/container-definition.js:114:50)
        \_ TaskDefinition.addContainer (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/jsii-kernel-RXZcI5/node_modules/@aws-cdk/aws-ecs/lib/base/task-definition.js:265:16)
        \_ /private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/tmpp_n4_w2q/lib/program.js:8248:134
        \_ Kernel._wrapSandboxCode (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/tmpp_n4_w2q/lib/program.js:8860:24)
        \_ /private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/tmpp_n4_w2q/lib/program.js:8248:107
        \_ Kernel._ensureSync (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/tmpp_n4_w2q/lib/program.js:8841:28)
        \_ Kernel.invoke (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/tmpp_n4_w2q/lib/program.js:8248:34)
        \_ KernelHost.processRequest (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/tmpp_n4_w2q/lib/program.js:9757:36)
        \_ KernelHost.run (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/tmpp_n4_w2q/lib/program.js:9720:22)
        \_ Immediate._onImmediate (/private/var/folders/d4/lz99k_413039dlfrmtm3zb9h0000gn/T/tmpp_n4_w2q/lib/program.js:9721:46)
        \_ processImmediate (internal/timers.js:461:21)


 ❌  EcsStack failed: Error: The stack named EcsStack failed to deploy: UPDATE_ROLLBACK_COMPLETE
...
  1. It is unclear if this resource policy was even required, given that the defined task and execution roles have necessary log permissions. The documentation does not explain why this is generated in the first place when a logging configuration is attached to the container definition.

CDK CLI Version

1.132.0 (build 5c75891)

Framework Version

No response

Node.js Version

v12.21.0

OS

MacOS Catalina 10.15.7

Language

Python

Language Version

3.9.6

Other information

Our AWS account is controlled by a information security service provider - I thought that perhaps this was a personal account permissions issue. However, the error is InvalidRequest and not AccessDenied so I'm gut checking here first.

Metadata

Metadata

Assignees

Labels

@aws-cdk/aws-logsRelated to Amazon CloudWatch LogsbugThis issue is a bug.p1

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions