aws-cdk
aws-cdk copied to clipboard
(aws-events-targets): Use custom resource policy for CloudWatch Log Group event target
General Issue
CloudWatch Log Group event target always creates resource Policy
The Question
When I deploy a stack using the following code, CDK is automatically creating a custom resource to create a CloudWatch resource policy and results in hitting the maximum CloudWatch resource policies of 10 per region:
test_fanout_event_log_group = LogGroup(stack, "TestFanout", retention=RetentionDays.ONE_DAY)
test_fanout_event_rule = Rule(stack, "TestFanoutRule",
event_pattern=EventPattern(
source=['bb.identity-provider-test'],
detail_type=['Identity Provider Created']
),
event_bus=event_bus,
)
test_fanout_event_rule.add_target(
CloudWatchLogGroup(test_fanout_event_log_group)
)
I'm wondering if there is a way to use an existing CloudWatch resource policy instead of having one generated automatically.
CDK CLI Version
1.124.0
Framework Version
No response
Node.js Version
No response
OS
No response
Language
Python
Language Version
3.8.12
Other information
No response
I just ran into this exact problem too..
It seems like its hard coded in aws-events-targets/lib/log_group.js
to have one policy per rule.
Yeah, this is pretty hardcoded in. Any workarounds to this would be quite a hassle
https://github.com/aws/aws-cdk/blob/1d3883a32fd05878ac43d6e236f5b446096f3ed3/packages/%40aws-cdk/aws-events-targets/lib/log-group.ts#L31-L59
I will mark this as a feature request. Thanks for submitting this issue
I am marking this issue as p2, which means that we are unable to work on this immediately.
We use +1s to help prioritize our work, and are happy to revaluate this issue based on community feedback. You can reach out to the cdk.dev community on Slack to solicit support for reprioritization. We are also always welcome to contributions 😃
+1
+1 We are hitting 10 policies limit too. The policy is not required to put logs because we actually forked the CloudWatchLogGroup
target class (v2.5.0) and removed the policy setup :
import { ArnFormat, aws_events, aws_logs, Stack } from 'aws-cdk-lib';
import { bindBaseTargetConfig, TargetBaseProps } from 'aws-cdk-lib/aws-events-targets';
/**
* Customize the CloudWatch LogGroup Event Target
*/
export interface LogGroupNoPolicyProps extends TargetBaseProps {
/**
* The event to send to the CloudWatch LogGroup
*
* This will be the event logged into the CloudWatch LogGroup
*
* @default - the entire EventBridge event
*/
readonly event?: aws_events.RuleTargetInput;
}
/**
* Use an AWS CloudWatch LogGroup as an event rule target, but don't apply a policy.
*/
export class CloudWatchLogGroupNoPolicy implements aws_events.IRuleTarget {
constructor(private readonly logGroup: aws_logs.ILogGroup, private readonly props: LogGroupNoPolicyProps = {}) {}
/**
* Returns a RuleTarget that can be used to log an event into a CloudWatch LogGroup
*/
public bind(_rule: aws_events.IRule, _id?: string): aws_events.RuleTargetConfig {
const logGroupStack = Stack.of(this.logGroup);
return {
...bindBaseTargetConfig(this.props),
arn: logGroupStack.formatArn({
service: 'logs',
resource: 'log-group',
arnFormat: ArnFormat.COLON_RESOURCE_NAME,
resourceName: this.logGroup.logGroupName,
}),
input: this.props.event,
targetResource: this.logGroup,
};
}
}
It actually works and logs are still being streamed from the eventbus to the log-group. If you think that adding a flag in the options to opt-in or opt-out the auto policy generation would be a good solution I can try to open a PR 😃
+1
+1
+1
+1
+1
+1
As a workaround, you can transform rule construct to Cfn and add target to Cfn resource directly
const cloudWatchCfnTarget: events.CfnRule.TargetProperty = {
arn: yourEventLogGroup.logGroupArn,
id: 'Target0',
};
const cfnRule = eventBusRule.node.defaultChild as events.CfnRule;
cfnRule.targets = [cloudWatchCfnTarget];
NOTE: Your log group name should start with /aws/events
otherwise without a policy it will not push logs
+1
+1
+1
+1
+1
+1
We already have a shared logs resource policy that grants events.amazonaws.com
permission to write logs. As a workaround, I am removing the policy with the following at the end of the stack:
const logGroupPolicies = this.node.children
.filter((child) => child.node.id.startsWith("EventsLogGroupPolicy"))
.map((child) => child.node.id);
logGroupPolicies.forEach((id) => this.node.tryRemoveChild(id));
Any updates on fixing this within CDK and without workarounds?