我是AWS CDK的新手,在实现我能够在AWS控制台上成功实现的东西时遇到了问题
这是我设置的事件规则{
"$or": [{
"detail.distance": [{
"numeric": [">=", 0]
}]
}, {
"detail.duration": [{
"numeric": [">=", 0]
}]
}],
"replay-name": [{
"exists": true
}]
}
当我试图在CDK实现这一点我可以看到它在设置事件模式方面的局限性
https://docs.aws.amazon.com/cdk/api/v1/python/aws_cdk.aws_events/EventPattern.html
我正在尝试:
cfn_rule = aws_events.CfnRule(
self,
id=f"{stack_id}-rule-to-invoke-lambda",
name="rule-to-invoke-lambda",
event_bus_name=event_bus.event_bus_name,
event_pattern=aws_events.EventPattern(
source=["mts-simulation"], #toDo Have to add the pattern but unable to design it
),
targets=[
aws_events.CfnRule.TargetProperty(
arn=lambda_function.function_arn, #coming in from function parameter
id=f"{stack_id}-target-to-lambda-function",
input_transformer=aws_events.CfnRule.InputTransformerProperty(
input_template='{"uptime":"<detail-uptime>",'
' "distance": "<detail-distance>",'
'"duration": "<detail-duration>","timestamp": "<timestamp>"}',
input_paths_map={
"timestamp": "$.time",
"detail-uptime": "$.detail.system_uptime",
"detail-distance": "$.detail.distance",
"detail-duration": "$.detail.duration",
},
),
)
],
)
这可能是基本的,但目前坚持使用它。谁能有点耐心帮帮我吗?
根据Scott Hsieh的回答编辑:
错过了两件事:
- 将其关联到现有的事件总线
{
"detail": {
"replay-name": [{
"exists": true
}],
"$or": [{
"distance": [{
"numeric": [">=", 0]
}]
}, {
"duration": [{
"numeric": [">=", 0]
}]
}]
},
"source": ["mts-simulation"]
}
此规则失败,因为"replay-name"在json事件的细节部分之外的一个事件。
例如:事件=
{ "field1":"value",
"field2":"value",
detail:{ "distance":"value",
"duration":"value"
}
}
AWS CDK结构简介
CfnRule是一个L1结构,又名CFN资源。在大多数情况下,您可以为CDK应用程序选择L2结构,因为内置的L2结构通常是为大多数通用场景而精心设计的。您还可以意识到,在设置属性方面,使用L1构造通常比使用L2构造花费更多的精力。现在,作为一个初学者,我建议你一开始忽略L3结构,当你对CDK有了更深入的了解时,你会遇到L3。要了解详细信息,请阅读本文档。
在Python中使用AWS CDK实现事件规则
回到你的问题,它看起来像是一个事件将触发Lambda函数的情况,而你想用基于Python的CDK来管理这个流。从EventPattern
的文档中可以看到:
根据您的意图,我相信下面的代码片段可以满足您的需求:该类只能与
Rule
类一起使用。特别是,不要使用它与CfnRule
类:你的模式将无法正确渲染。在CfnRule
类中,像直接编写CloudFormation时那样编写模式。
.
.
import aws_cdk.aws_events as events
import aws_cdk.aws_events_targets as targets
.
.
.
"""
Python version: Python 3.11.2
CDK version: 2.73.0 (build 43e681e)
"""
rule = events.Rule(self, "rule",
rule_name="rule-to-invoke-lambda",
event_pattern=events.EventPattern(
source=["mts-simulation"],
detail={
"$or": [
{"distance": [{"numeric": [">=", 0]}]},
{"duration": [{"numeric": [">=", 0]}]}
],
"replay-name": [{"exists": True}]
}
)
)
rule.add_target(targets.LambdaFunction(lambda_function,
event=events.RuleTargetInput.from_object({
"uptime": events.EventField.from_path("$.detail.system_uptime"),
"distance": events.EventField.from_path("$.detail.distance"),
"duration": events.EventField.from_path("$.detail.duration"),
"timestamp": events.EventField.from_path("$.detail.time")
})
))
CloudFormation JSON Output
合成后,您的CFN JSON输出将类似于以下内容:
"ruleF2C1DCDC": {
"Type": "AWS::Events::Rule",
"Properties": {
"EventPattern": {
"detail": {
"$or": [
{
"distance": [
{
"numeric": [
">=",
0
]
}
]
},
{
"duration": [
{
"numeric": [
">=",
0
]
}
]
}
],
"replay-name": [
{
"exists": true
}
]
},
"source": [
"mts-simulation"
]
},
"Name": "rule-to-invoke-lambda",
"State": "ENABLED",
"Targets": [
{
"Arn": {
"Fn::GetAtt": [
"LambdaFunctionBF21E41F",
"Arn"
]
},
"Id": "Target0",
"InputTransformer": {
"InputPathsMap": {
"detail-system_uptime": "$.detail.system_uptime",
"detail-distance": "$.detail.distance",
"detail-duration": "$.detail.duration",
"detail-time": "$.detail.time"
},
"InputTemplate": "{"uptime":<detail-system_uptime>,"distance":<detail-distance>,"duration":<detail-duration>,"timestamp":<detail-time>}"
}
}
]
},
"Metadata": {
"aws:cdk:path": "EventLambdaStack/rule/Resource"
}
}
反馈在将来使用CDK管理AWS基础设施时,CDK文档中的示例将很有价值,因为在某些情况下,CloudFormation中的配置和通过CDK api进行的设置可能会有很大的不同。您可以使用最小代码片段来检查L2 api和CFN配置的差异。最后,试着弄清楚哪些L2组件是为Amazon EventBridge制作的,以及它在CDK中的可用目标。祝你在CDK之旅中好运。
上面的答案很好。但似乎没能满足我的要求。以下是我的解决方案:
cfn_rule = aws_events.CfnRule(
self,
id=f"{stack_id}-invoke-lambda-read-file",
name="rule-to-invoke-lambda-read-file",
event_bus_name=event_bus.event_bus_name,
event_pattern={"$or":[{"detail.distance":[{"numeric":[">=",0]}]},{"detail.duration":[{"numeric":[">=",0]}]}],"replay-name":[{"exists":True}]},
targets=[
aws_events.CfnRule.TargetProperty(
arn=lambda_function.function_arn,
id=f"{stack_id}-invoke-lambda-read-file",
你可以看到,我将event_pattern作为一个字典显式地传递。
希望能有所帮助。