aws/aws-cdk

(events): EventBusPolicy fails with circular reference if PolicyStatement is not already resolved to JSON

Open

#24,031 opened on Feb 6, 2023

View on GitHub
 (8 comments) (1 reaction) (0 assignees)TypeScript (10,710 stars) (3,530 forks)batch import
@aws-cdk/aws-iambugdocumentationeffort/smallgood first issuep2

Description

Describe the bug

When creating a PolicyStatement object that grants permissions to a principal, CDK throws an error with circular dependency on grantPrincipal method.

A PolicyStatement could be required when trying to give cross-account permissions in a ResourcePolicy.

Expected Behavior

Policy is created successfully and principal is granted as specified.

Current Behavior

Error throw when trying to synth any stack that contains the issue:

Error: Resolution error: Resolution error: Unable to resolve object tree with circular reference. Path: /Resources/${Token[EventbusPolicyTestStack.CFN.LogicalID.25]}/Properties/policyDocument/_principals/array/0/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal/grantPrincipal..
    at resolve (/Users/neovasili/workspace/lab/eventbus-policy-test/node_modules/aws-cdk-lib/core/lib/private/resolve.js:1:1073)
    at Object.resolve (/Users/neovasili/workspace/lab/eventbus-policy-test/node_modules/aws-cdk-lib/core/lib/private/resolve.js:1:892)
    at resolve (/Users/neovasili/workspace/lab/eventbus-policy-test/node_modules/aws-cdk-lib/core/lib/private/resolve.js:1:2755)
    at Object.resolve (/Users/neovasili/workspace/lab/eventbus-policy-test/node_modules/aws-cdk-lib/core/lib/private/resolve.js:1:892)
    at resolve (/Users/neovasili/workspace/lab/eventbus-policy-test/node_modules/aws-cdk-lib/core/lib/private/resolve.js:1:2755)
    at Object.resolve (/Users/neovasili/workspace/lab/eventbus-policy-test/node_modules/aws-cdk-lib/core/lib/private/resolve.js:1:892)
    at resolve (/Users/neovasili/workspace/lab/eventbus-policy-test/node_modules/aws-cdk-lib/core/lib/private/resolve.js:1:2755)
    at Object.resolve (/Users/neovasili/workspace/lab/eventbus-policy-test/node_modules/aws-cdk-lib/core/lib/private/resolve.js:1:892)
    at resolve (/Users/neovasili/workspace/lab/eventbus-policy-test/node_modules/aws-cdk-lib/core/lib/private/resolve.js:1:2755)
    at Object.resolve (/Users/neovasili/workspace/lab/eventbus-policy-test/node_modules/aws-cdk-lib/core/lib/private/resolve.js:1:892)

Reproduction Steps

Here is a minimum Stack definition using EventBusPolicy that reproduces the issue when trying to do cdk ls or cdk synth:

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as iam from "aws-cdk-lib/aws-iam";
import * as events from "aws-cdk-lib/aws-events";

export class EventbusPolicyTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const defaultEventBus = events.EventBus.fromEventBusName(this, "Default", "default");

    new events.EventBusPolicy(this, "MyPolicy", {
      eventBus: defaultEventBus,
      statementId: "MyStatement",
      statement: new iam.PolicyStatement({
        principals: [
          new iam.AccountPrincipal("123456789010"),
        ],
        actions: [
          "events:PutEvents",
        ],
        resources: [
          defaultEventBus.eventBusArn,
        ],
      }),
    });
  }
}

Another example:

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as iam from "aws-cdk-lib/aws-iam";
import * as events from "aws-cdk-lib/aws-events";

export class EventbusPolicyTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const defaultEventBus = events.EventBus.fromEventBusName(this, "Default", "default");
    const policyFromJson = iam.PolicyStatement.fromJson({
      Principal: {
        AWS: "123456789010",
      },
      Action: [
        "events:PutEvents",
      ],
      Resource: [
        defaultEventBus.eventBusArn,
      ],
    });
    new events.EventBusPolicy(this, "MyPolicy", {
      eventBus: defaultEventBus,
      statementId: "MyStatement",
      statement: policyFromJson,
    });
  }
}

Another one for BucketPolicy:

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as iam from "aws-cdk-lib/aws-iam";

export class EventbusPolicyTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const policyFromJson = iam.PolicyStatement.fromJson({
      Principal: {
        AWS: "123456789010",
      },
      Action: [
        "events:PutEvents",
      ],
      Resource: [
        defaultEventBus.eventBusArn,
      ],
    });
    const testBucket = new s3.Bucket(this, "MyTestBucket");
    new s3.CfnBucketPolicy(this, "CFN", {
      bucket: testBucket.bucketName,
      policyDocument: policyFromJson,
    });
  }
}

Possible Solution

No response

Additional Information/Context

In the case of EventBusPolicy is possible to pass principal in a different way using L1 construct that does not cause the issue:

new events.CfnEventBusPolicy(this, "MyPolicy", {
    statementId: "MyStatement",
    action: "events:PutEvents",
    principal: "123456789010",
});

CDK CLI Version

2.63.2 (build e08e34a)

Framework Version

No response

Node.js Version

v16.14.2

OS

Mac Ventura/Monterrey

Language

Typescript

Language Version

any version >= 4.6.x

Other information

No response

Contributor guide

(events): EventBusPolicy fails with circular reference if PolicyStatement is not already resolved to JSON · aws/aws-cdk#24031 | Good First Issue