aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.71k stars 3.94k forks source link

aws_cdk.aws_cloudfront.experimental: cyclic reference if role is passed #19416

Open iwanbolzern opened 2 years ago

iwanbolzern commented 2 years ago

What is the problem?

If a role is passed to EdgeFunction created in a stack located outside of us-east-1 it will result in a cyclic dependency error.

Reproduction Steps

try to deploy the following stack to a location outside us-east-1:

class LambdaEdgeStack(BaseStack):

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

        # create edge function execution role
        lambda_edge_execution_role_policy = Policy(
            self, 'frontend-edge-lambda-policy',
            policy_name='frontend-edge-lambda-policy',
            statements=[
                aws_iam.PolicyStatement(
                    resources=[
                        "arn:aws:logs:*:*:*"
                    ],
                    actions=["logs:CreateLogGroup",
                             "logs:CreateLogStream",
                             "logs:PutLogEvents"]
                )
            ])

        lambda_edge_s3_policy = Policy(
            self, 'frontend-edge-lambda-s3-policy',
            policy_name='frontend-edge-lambda-s3-policy',
            statements=[
                aws_iam.PolicyStatement(
                    resources=[
                        f'arn:aws:s3:::{self.config.frontend_bucket_name}',
                        f'arn:aws:s3:::{self.config.frontend_bucket_name}/*',
                    ],
                    actions=['s3:Get*',
                             's3:List*',
                             's3-object-lambda:Get*',
                             's3-object-lambda:List*']
                )
            ])

        lambda_service_role = Role(
            self, 'edge-lambda-role',
            role_name='edge-lambda-role',
            assumed_by=aws_iam.CompositePrincipal(
                aws_iam.ServicePrincipal("lambda.amazonaws.com")
            ))
        lambda_service_role.attach_inline_policy(lambda_edge_execution_role_policy)
        lambda_service_role.attach_inline_policy(lambda_edge_s3_policy)

        # create edge function
        lambda_code_path = Path(__file__).parent / '../resources/kms_lambda_edge'
        self.edge_lambda = EdgeFunction(self, "sigv4-req-to-s3",
                                        runtime=Runtime.NODEJS_12_X,
                                        handler="index.handler",
                                        code=Code.from_asset(str(lambda_code_path)),
                                        role=lambda_service_role)

What did you expect to happen?

That the role is detached from the original stack an re-attached to the on-demand created us-east-1 stack.

What actually happened?

jsii.errors.JavaScriptError:
  Error: 'EdgeLambda' depends on 'edge-lambda-stack-c8d3ca2e2477a28d9d4f54c5c27d9241b592f0a31e' (dependency added using stack.addDependency()). Adding this dependency ("edge-lambda-stack-c8d3ca2e2477a28d9d4f54c5c27d9241b592f0a31e/sigv4-req-to-s3/Resource" depends on "EdgeLambda/edge-
lambda-role/Resource") would create a cyclic reference.

CDK CLI Version

2.16.0

Framework Version

No response

Node.js Version

v16.13.0

OS

Windows

Language

Python

Language Version

Python 3.9.6

Other information

No response

ryparker commented 2 years ago

Hey @iwanbolzern 👋🏻

Although that error message is not very helpful, Edge Lambdas are only supported in us-east-1.

Are you able to reproduce this in the us-east-1 region? If not, then we should at least improve the error messaging to make this region requirement more clear.

iwanbolzern commented 2 years ago

Hi @ryparker,

Thank you for your response and explanations!

I know that lambda@edge is only supported in the us-east-1 region. But in my understand of the source code it should "dynamically" create a stack in us-east-1 and then use cross-region ssm resolution to export the Arn of the function. And if somebody is using this configuration and passing a role, the mentioned exception occur.