Implementing event bridge rule onto aws CDK

huangapple go评论69阅读模式
英文:

Implementing event bridge rule onto aws CDK

问题

I am new to AWS CDK and have an issue implementing what I was able to implement on the AWS console successfully.

This is the event rule that I have set up:

{
    "$or": [{
        "detail.distance": [{
            "numeric": [">=", 0]
        }]
    }, {
        "detail.duration": [{
            "numeric": [">=", 0]
        }]
    }],
    "replay-name": [{
        "exists": true
    }]
}

When I am trying to implement this in CDK, I could see the limitation it has with setting up an event pattern.

Here is the link to the AWS CDK documentation for EventPattern.

What I am trying:

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",
                },
            ),
        )
    ],
)

This could be elementary, but I'm currently stuck with it. Could anyone have a bit of patience and help me out with it?

Edited after implementing the answer from Scott Hsieh:

Missing out on 2 things:

  1. Associating it with an existing event bus.
  2. The rule is failing because "replay-name" is outside the "detail" part of a JSON event. For example:
{
    "field1": "value",
    "field2": "value",
    "detail": {
        "distance": "value",
        "duration": "value"
    }
}
英文:

I am new to AWS CDK and have a issue implementing what I was able to implement on the AWS console successfully

this is the event rule that I have setup {

&quot;$or&quot;: [{
      &quot;detail.distance&quot;: [{
        &quot;numeric&quot;: [&quot;&gt;=&quot;, 0]
      }]
    }, {
      &quot;detail.duration&quot;: [{
        &quot;numeric&quot;: [&quot;&gt;=&quot;, 0]
      }]
    }],
    &quot;replay-name&quot;: [{
      &quot;exists&quot;: true
    }]
    
  }

When I am trying to implement this in CDK
I could see the limitation it has with setting up event pattern

https://docs.aws.amazon.com/cdk/api/v1/python/aws_cdk.aws_events/EventPattern.html

what i am trying:

cfn_rule = aws_events.CfnRule(
    self,
    id=f&quot;{stack_id}-rule-to-invoke-lambda&quot;,
    name=&quot;rule-to-invoke-lambda&quot;,
    event_bus_name=event_bus.event_bus_name,
    event_pattern=aws_events.EventPattern(
        source=[&quot;mts-simulation&quot;], #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&quot;{stack_id}-target-to-lambda-function&quot;,
            input_transformer=aws_events.CfnRule.InputTransformerProperty(
                input_template=&#39;{&quot;uptime&quot;:&quot;&lt;detail-uptime&gt;&quot;,&#39;
                &#39; &quot;distance&quot;: &quot;&lt;detail-distance&gt;&quot;,&#39;
                &#39;&quot;duration&quot;: &quot;&lt;detail-duration&gt;&quot;,&quot;timestamp&quot;: &quot;&lt;timestamp&gt;&quot;}&#39;,
                input_paths_map={
                    &quot;timestamp&quot;: &quot;$.time&quot;,
                    &quot;detail-uptime&quot;: &quot;$.detail.system_uptime&quot;,
                    &quot;detail-distance&quot;: &quot;$.detail.distance&quot;,
                    &quot;detail-duration&quot;: &quot;$.detail.duration&quot;,
                    
                },
            ),
        )
    ],
)

This could be elementary but currently stuck with it.
Could anyone have bit of patient and help me out of it?

Edited after implementing the answer from Scott Hsieh:

Missing out on 2 things:

  1. associating it to an exiting event bus
    2.

    {
    "detail": {
    "replay-name": [{
    "exists": true
    }],
    "$or": [{
    "distance": [{
    "numeric": [">=", 0]
    }]
    }, {
    "duration": [{
    "numeric": [">=", 0]
    }]
    }]
    },
    "source": ["mts-simulation"]
    }

this rule is failing because "replay-name" is flowing into a event outside detail part of the a json event.

for example:
event =

{ &quot;field1&quot;:&quot;value&quot;,
    &quot;field2&quot;:&quot;value&quot;,
    detail:{ &quot;distance&quot;:&quot;value&quot;,
    &quot;duration&quot;:&quot;value&quot;
    }    
    }

答案1

得分: 1

以下是您要翻译的内容:

Brief to AWS CDK Constructs

CfnRule is a L1 construct a.k.a CFN resources. In most cases you choose L2 constructs for your CDK application since built-in L2 constructs are usually crafted with intention for most general scenarios. You can also realize that using L1 constrcuts usually takes more effort regarding setting attributes than L2 constructs. For now, as a beginner, I would suggest you neglect L3 constructs at first, you come to meet up L3 when you are more advanced with CDK. For detail, you can read through this documentation.

Implementing an Event Rule with AWS CDK in Python

Back to your question, it looks like a case where an event will trigger a Lambda function and you want to manage this flow with CDK based on Python. As you can see from the documentation of EventPattern:
> Important: this class can only be used with a Rule class. In particular, do not use it with CfnRule class: your pattern will not be rendered correctly. In a CfnRule class, write the pattern as you normally would when directly writing CloudFormation.

With your intention, I believe the following snippet can fit your needs:

.
.
import aws_cdk.aws_events as events
import aws_cdk.aws_events_targets as targets
.
.
.
&quot;&quot;&quot;
Python version: Python 3.11.2
CDK version: 2.73.0 (build 43e681e)
&quot;&quot;&quot;
rule = events.Rule(self, &quot;rule&quot;,
    rule_name=&quot;rule-to-invoke-lambda&quot;,
    event_pattern=events.EventPattern(
        source=[&quot;mts-simulation&quot;],
        detail={&quot;$or&quot;: [
            {&quot;distance&quot;: [{&quot;numeric&quot;: [&quot;&gt;=&quot;, 0]}]},
            {&quot;duration&quot;: [{&quot;numeric&quot;: [&quot;&gt;=&quot;, 0]}]}
        ],
        &quot;replay-name&quot;: [{&quot;exists&quot;: True}]
        }
    )
)
rule.add_target(targets.LambdaFunction(lambda_function,
    event=events.RuleTargetInput.from_object({
            &quot;uptime&quot;: events.EventField.from_path(&quot;$.detail.system_uptime&quot;),
            &quot;distance&quot;: events.EventField.from_path(&quot;$.detail.distance&quot;),
            &quot;duration&quot;: events.EventField.from_path(&quot;$.detail.duration&quot;),
            &quot;timestamp&quot;: events.EventField.from_path(&quot;$.detail.time&quot;)
        })
))

CloudFormation JSON Output

After synthesizing, your CFN JSON output will be similar as the following:

&quot;ruleF2C1DCDC&quot;: {
   &quot;Type&quot;: &quot;AWS::Events::Rule&quot;,
   &quot;Properties&quot;: {
    &quot;EventPattern&quot;: {
     &quot;detail&quot;: {
      &quot;$or&quot;: [
       {
        &quot;distance&quot;: [
         {
          &quot;numeric&quot;: [
           &quot;&gt;=&quot;,
           0
          ]
         }
        ]
       },
       {
        &quot;duration&quot;: [
         {
          &quot;numeric&quot;: [
           &quot;&gt;=&quot;,
           0
          ]
         }
        ]
       }
      ],
      &quot;replay-name&quot;: [
       {
        &quot;exists&quot;: true
       }
      ]
     },
     &quot;source&quot;: [
      &quot;mts-simulation&quot;
     ]
    },
    &quot;Name&quot;: &quot;rule-to-invoke-lambda&quot;,
    &quot;State&quot;: &quot;ENABLED&quot;,
    &quot;Targets&quot;: [
     {
      &quot;Arn&quot;: {
       &quot;Fn::GetAtt&quot;: [
        &quot;LambdaFunctionBF21E41F&quot;,
        &quot;Arn&quot;
       ]
      },
      &quot;Id&quot;: &quot;Target0&quot;,
      &quot;InputTransformer&quot;: {
       &quot;InputPathsMap&quot;: {
        &quot;detail-system_uptime&quot;: &quot;$.detail.system_uptime&quot;,
        &quot;detail-distance&quot;: &quot;$.detail.distance&quot;,
        &quot;detail-duration&quot;: &quot;$.detail.duration&quot;,
        &quot;detail-time&quot;: &quot;$.detail.time&quot;
       },
       &quot;InputTemplate&quot;: &quot;{\&quot;uptime\&quot;:&lt;detail-system_uptime&gt;,\&quot;distance\&quot;:&lt;detail-distance&gt;,\&quot;duration\&quot;:&lt;detail-duration&gt;,\&quot;timestamp\&quot;:&lt;detail-time&gt;}&quot;
      }
     }
    ]
   },
   &quot;Metadata&quot;: {
    &quot;aws:cdk:path&quot;: &quot;EventLambdaStack/rule/Resource&quot;
   }
  }

Feedback

In the future when managing AWS infrastructure with CDK, examples in CDK documentation would be valuable since in some cases, configuration in CloudFormation and setting via CDK APIs can differ a bit much. You can use the minimal snippet to check the difference of the L2 APIs and CFN configuration. In the end, try to figure out what L2 components are crafted for Amazon EventBridge and its available targets in CDK. Good luck on your CDK journey.

英文:

Brief to AWS CDK Constructs

CfnRule is a L1 construct a.k.a CFN resources. In most cases you choose L2 constructs for your CDK application since built-in L2 constructs are usually crafted with intention for most general scenarios. You can also realize that using L1 constrcuts usually takes more effort regarding setting attributes than L2 constructs. For now, as a beginner, I would suggest you neglect L3 constructs at first, you come to meet up L3 when you are more advanced with CDK. For detail, you can read through this documentation.

Implementing an Event Rule with AWS CDK in Python

Back to your question, it looks like a case where an event will trigger a Lambda function and you want to manage this flow with CDK based on Python. As you can see from the documentation of EventPattern:
> Important: this class can only be used with a Rule class. In particular, do not use it with CfnRule class: your pattern will not be rendered correctly. In a CfnRule class, write the pattern as you normally would when directly writing CloudFormation.

With your intention, I believe the following snippet can fit your needs:

.
.
import aws_cdk.aws_events as events
import aws_cdk.aws_events_targets as targets
.
.
.
&quot;&quot;&quot;
Python version: Python 3.11.2
CDK version: 2.73.0 (build 43e681e)
&quot;&quot;&quot;
rule = events.Rule(self, &quot;rule&quot;,
    rule_name=&quot;rule-to-invoke-lambda&quot;,
    event_pattern=events.EventPattern(
        source=[&quot;mts-simulation&quot;],
        detail={
            &quot;$or&quot;: [
                {&quot;distance&quot;: [{&quot;numeric&quot;: [&quot;&gt;=&quot;, 0]}]},
                {&quot;duration&quot;: [{&quot;numeric&quot;: [&quot;&gt;=&quot;, 0]}]}
            ],
            &quot;replay-name&quot;: [{&quot;exists&quot;: True}]
        }
    )
)
rule.add_target(targets.LambdaFunction(lambda_function,
    event=events.RuleTargetInput.from_object({
            &quot;uptime&quot;: events.EventField.from_path(&quot;$.detail.system_uptime&quot;),
            &quot;distance&quot;: events.EventField.from_path(&quot;$.detail.distance&quot;),
            &quot;duration&quot;: events.EventField.from_path(&quot;$.detail.duration&quot;),
            &quot;timestamp&quot;: events.EventField.from_path(&quot;$.detail.time&quot;)
        })
))

CloudFormation JSON Output

After synthesizing, your CFN JSON output will be similar as the following:

&quot;ruleF2C1DCDC&quot;: {
   &quot;Type&quot;: &quot;AWS::Events::Rule&quot;,
   &quot;Properties&quot;: {
    &quot;EventPattern&quot;: {
     &quot;detail&quot;: {
      &quot;$or&quot;: [
       {
        &quot;distance&quot;: [
         {
          &quot;numeric&quot;: [
           &quot;&gt;=&quot;,
           0
          ]
         }
        ]
       },
       {
        &quot;duration&quot;: [
         {
          &quot;numeric&quot;: [
           &quot;&gt;=&quot;,
           0
          ]
         }
        ]
       }
      ],
      &quot;replay-name&quot;: [
       {
        &quot;exists&quot;: true
       }
      ]
     },
     &quot;source&quot;: [
      &quot;mts-simulation&quot;
     ]
    },
    &quot;Name&quot;: &quot;rule-to-invoke-lambda&quot;,
    &quot;State&quot;: &quot;ENABLED&quot;,
    &quot;Targets&quot;: [
     {
      &quot;Arn&quot;: {
       &quot;Fn::GetAtt&quot;: [
        &quot;LambdaFunctionBF21E41F&quot;,
        &quot;Arn&quot;
       ]
      },
      &quot;Id&quot;: &quot;Target0&quot;,
      &quot;InputTransformer&quot;: {
       &quot;InputPathsMap&quot;: {
        &quot;detail-system_uptime&quot;: &quot;$.detail.system_uptime&quot;,
        &quot;detail-distance&quot;: &quot;$.detail.distance&quot;,
        &quot;detail-duration&quot;: &quot;$.detail.duration&quot;,
        &quot;detail-time&quot;: &quot;$.detail.time&quot;
       },
       &quot;InputTemplate&quot;: &quot;{\&quot;uptime\&quot;:&lt;detail-system_uptime&gt;,\&quot;distance\&quot;:&lt;detail-distance&gt;,\&quot;duration\&quot;:&lt;detail-duration&gt;,\&quot;timestamp\&quot;:&lt;detail-time&gt;}&quot;
      }
     }
    ]
   },
   &quot;Metadata&quot;: {
    &quot;aws:cdk:path&quot;: &quot;EventLambdaStack/rule/Resource&quot;
   }
  }

Feedback

In the future when managing AWS infrastructure with CDK, examples in CDK documentation would be valuable since in some cases, configuration in CloudFormation and setting via CDK APIs can differ a bit much. You can use the minimal snippet to check the difference of the L2 APIs and CFN configuration. In the end, try to figure out what L2 components are crafted for Amazon EventBridge and its available targets in CDK. Good luck on your CDK journey.

答案2

得分: 0

The above answer is great. But didn't seem to figure that out for my requirement.
Here is what worked out for me:

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",
as you could see I am passing event_patter as a dictionary explicitly.

hope it helps.

英文:

The above answer is great. But didn't seem to figure that out for my requirement.
Here is what worked out for me:

cfn_rule = aws_events.CfnRule(
self,
id=f&quot;{stack_id}-invoke-lambda-read-file&quot;,
name=&quot;rule-to-invoke-lambda-read-file&quot;,
event_bus_name=event_bus.event_bus_name,
event_pattern={&quot;$or&quot;:[{&quot;detail.distance&quot;:[{&quot;numeric&quot;:[&quot;&gt;=&quot;,0]}]},{&quot;detail.duration&quot;:[{&quot;numeric&quot;:[&quot;&gt;=&quot;,0]}]}],&quot;replay-name&quot;:[{&quot;exists&quot;:True}]},
targets=[
aws_events.CfnRule.TargetProperty(
arn=lambda_function.function_arn,
id=f&quot;{stack_id}-invoke-lambda-read-file&quot;,

as you could see I am passing event_patter as an dictionary explicitly.

hope it helps.

huangapple
  • 本文由 发表于 2023年4月10日 18:44:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75976403.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定