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.57k stars 3.88k forks source link

elasticloadbalancing: allow logAccessLogs on environment agnostic stack #27432

Open Mahoney opened 12 months ago

Mahoney commented 12 months ago

Describe the feature

Currently BaseLoadBalancer.logAccessLogs requires that the Stack has a specific region specified on the Environment.

This seems a pretty arbitrary limitation - why should this be necessary? Looking at the code, it seems to be in order to set a principal, but other logging constructs like flowLog allow specifying roles, and indeed if the region doesn't resolve to an account in BaseLoadBalancer.resourcePolicyPrincipal it just returns iam.ServicePrincipal('logdelivery.elasticloadbalancing.amazonaws.com'), so why shouldn't it do that if the region is unresolved too, as it's only using the region to find an account?

Use Case

I want to enable access logging on an ALB created in an environment agnostic stack, which seems a reasonable thing to do.

Proposed Solution

Change https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts#L306-L309 as so:

    const region = Stack.of(this).region;
    if (Token.isUnresolved(region)) {
      return new iam.ServicePrincipal('logdelivery.elasticloadbalancing.amazonaws.com');
    }

Other Information

Context - we can't set a region. In our case we have a CDK setup that has been running fine for over a year. A PEN test has flagged that we should have access logs for our ALBs. We have a Product Stack as part of our Stack, and setting a region on the Environment for the Stack completely breaks it; if I set just a region I get this:

Error: Stack "my-stack/my-product" cannot reference {my-stack/my-stack-vpc/publicSubnet1/Subnet[Ref]} in stack "my-stack". Cross stack references are only supported for stacks deployed to the same environment or between nested stacks and their parent stack. Set crossRegionReferences=true to enable cross region references

(I am setting crossRegionReferences(true))

If I set a region and an account I get this:

Resolution error: Cannot generate a physical name for my-stack/my-product/my-stack-my-product-ecs-service-task-def/ExecutionRole, because the region is un-resolved or missing.

There seems no way to specify an environment on a product stack.

So currently I'm completely stymied. I guess I'll just have to set up the access logging manually as a handcrafted little snowflake.

Acknowledgements

CDK version used

2.99.1

Environment details (OS name and version, etc.)

macOs & linux

peterwoodworth commented 12 months ago

Thanks for the detailed report. It makes sense, I don't see why your proposed solution wouldn't work

tmokmss commented 10 months ago

@Mahoney According to the doc, the elb-account-id is necessary for older regions, so we cannot easily synthesize env-agnostic templates with elb access logging. See this comment for more detail: https://github.com/aws/aws-cdk/pull/27938#discussion_r1392028248

I think the problem we need to really solve is the below; how the region is missing where you specified it explicitly?

Resolution error: Cannot generate a physical name for my-stack/my-product/my-stack-my-product-ecs-service-task-def/ExecutionRole, because the region is un-resolved or missing.

CaptnMichi commented 1 month ago

We're facing the same issue here. I want to enable access logging on a ALB in us-east-2 with a bucket in us-east-2. When i set the region on stack level, other stacks that inherit this stack will break with

Error: Stack "<stack>" cannot reference {<stack-name>/nginxDeliveryStream/firehoseDeliveryStream[Arn]} in stack "<another-stack>". Cross stack references are only supported for stacks deployed to the same environment or between nested stacks and their parent stack. Set crossRegionReferences=true to enable cross region references

aws-cdk-lib": "^2.150.0