events: using fromObject does not maintain keys in inputTransformer
Describe the bug
creating a rule target using fromObject does not preserve the key names, but rather generates a key from the values in the input paths. using L1 CfnRule works as expected
import * as cdk from "aws-cdk-lib";
import * as events from "aws-cdk-lib/aws-events";
import * as targets from "aws-cdk-lib/aws-events-targets";
import * as sqs from "aws-cdk-lib/aws-sqs";
import { Construct } from "constructs";
export class BugfixEventbridgeStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
let inputPathsMap = {
myName: events.EventField.fromPath("$.detail.name"),
myUUID: events.EventField.fromPath("$.detail.uuid"),
};
const queue = new sqs.Queue(this, "myQueue");
new events.CfnRule(this, "myCFNrule", {
name: "myCFNrule",
eventPattern: {
source: ["aws.ec2"]
},
state: "ENABLED",
targets: [
{
arn: queue.queueArn,
id: "shared-sqs-cfn",
inputTransformer: {
inputTemplate: JSON.stringify(inputPathsMap),
inputPathsMap: inputPathsMap,
},
},
],
});
const cdkRule = new events.Rule(this, "myCDKrule", {
ruleName: 'myCDKrule',
eventPattern: {
source: ["aws.ec2"]
}
});
cdkRule.addTarget(new targets.SqsQueue(queue, {
message: events.RuleTargetInput.fromObject(inputPathsMap)
}));
}
}
Regression Issue
- [ ] Select this option if this issue appears to be a regression.
Last Known Working CDK Version
No response
Expected Behavior
InputPathsMap is the same for myCFNrule and myCDKrule, using the key/value pairs provided in inputPathsMap
Current Behavior
using the L2 construct (fromObject), keys provided in inputPathsMap are overwritten with system-generated keys. from cdk synth:
myCFNrule:
Type: AWS::Events::Rule
Properties:
EventPattern:
source:
- aws.ec2
Name: myCFNrule
State: ENABLED
Targets:
- Arn:
Fn::GetAtt:
- myQueue4FDFF71C
- Arn
Id: shared-sqs-cfn
InputTransformer:
InputPathsMap:
myName: $.detail.name
myUUID: $.detail.uuid
InputTemplate: '{"myName":"$.detail.name","myUUID":"$.detail.uuid"}'
Metadata:
aws:cdk:path: BugfixEventbridgeStack/myCFNrule
myCDKruleB18813AA:
Type: AWS::Events::Rule
Properties:
EventPattern:
source:
- aws.ec2
Name: myCDKrule
State: ENABLED
Targets:
- Arn:
Fn::GetAtt:
- myQueue4FDFF71C
- Arn
Id: Target0
InputTransformer:
InputPathsMap:
detail-name: $.detail.name
detail-uuid: $.detail.uuid
InputTemplate: '{"myName":<detail-name>,"myUUID":<detail-uuid>}'
Metadata:
aws:cdk:path: BugfixEventbridgeStack/myCDKrule/Resource
Reproduction Steps
run the code provided in issue description
Possible Solution
No response
Additional Information/Context
same issue occurs whether using events.RuleTargetInput.fromObject(inputPathsMap) or events.RuleTargetInput.fromText(JSON.stringify(inputPathsMap))
CDK CLI Version
2.1004.0 (build f0ad96e)
Framework Version
No response
Node.js Version
v23.9.0
OS
Windows
Language
TypeScript
Language Version
[email protected], [email protected]
Other information
No response
Current/Expected Behavior
Technical Analysis
The issue occurs in the implementation of FieldAwareEventInput class, which handles the RuleTargetInput.fromObject() method. When binding the input to a rule target, the class extracts event field path references and creates a mapping from generated keys to the actual JSON paths.
The key generation logic appears to create keys based on the path itself rather than preserving the original object keys from the user's input. This is likely because:
- The
FieldAwareEventInputclass processes the object recursively to findEventFieldinstances - When it encounters an
EventField, it generates a key based on the path rather than using the original key from the user's object - This results in the system-generated keys like
detail-nameinstead of user-provided keys likemyName
The main problematic code is likely in the implementation of the bind method in the FieldAwareEventInput class.
- When extracting fields from the object, the code only collects the
EventFieldinstances but doesn't track which object keys they were associated with. - When generating the
inputPathsMap, the code creates arbitrary keys likefield1,field2, etc., instead of using the original keys from the user's object (likemyName,myUUID).
For a complete fix, the FieldAwareEventInput class would need to be modified to:
- Track original key-to-field associations when extracting fields
- Use those original keys when generating the inputPathsMap instead of creating new keys
- Handle cases where the original keys might be nested in a complex object structure
This would make the behavior consistent between the L1 and L2 constructs and provide a more intuitive API for users.