9

After i create a cloud-watch event rule i am trying to add a target to it but i am unable to add a input transformation. Previously the add target had the props allowed for input transformation but it does not anymore.

codeBuildRule.addTarget(new SnsTopic(props.topic));

The aws cdk page provides this solution but i dont exactly understand what it says

You can add additional targets, with optional input transformer using eventRule.addTarget(target[, input]). For example, we can add a SNS topic target which formats a human-readable message for the commit.

aksyuma
  • 2,957
  • 1
  • 15
  • 29
mohantyArpit
  • 373
  • 4
  • 9

3 Answers3

14

You should specify the message prop and use RuleTargetInput static methods. Some of these methods can use strings returned by EventField.fromPath():

// From a path
codeBuildRule.addTarget(new SnsTopic(props.topic, {
  message: events.RuleTargetInput.fromEventPath('$.detail')
}));

// Custom object
codeBuildRule.addTarget(new SnsTopic(props.topic, {
  message: RuleTargetInput.fromObject({
    foo: EventField.fromPath('$.detail.bar')
  })
}));
jogold
  • 6,667
  • 23
  • 41
  • 2
    In my case with a lambda as a target I had to use the **event** prop: `rule.addTarget(new LambdaFunction(lambdaFunction, {event: RuleTargetInput.fromObject({customEvent: 'Hello'})}));` – Diego Jun 22 '21 at 16:38
6

I had the same question trying to implement this tutorial in CDK: Tutorial: Set up a CloudWatch Events rule to receive email notifications for pipeline state changes

I found this helpful as well: Detect and react to changes in pipeline state with Amazon CloudWatch Events

NOTE: I could not get it to work using the Pipeline's class method onStateChange().

I ended up writing a Rule:

const topic = new Topic(this, 'topic', {topicName: 'codepipeline-notes-failure',
});

const description = `Generated by the CDK for stack: ${this.stackName}`;
new Rule(this, 'failed', {
  description: description,
  eventPattern: {
    detail: {state: ['FAILED'], pipeline: ['notes']},
    detailType: ['CodePipeline Pipeline Execution State Change'],
    source: ['aws.codepipeline'],
  },
  targets: [
    new SnsTopic(topic, {
      message: RuleTargetInput.fromText(
        `The Pipeline '${EventField.fromPath('$.detail.pipeline')}' has ${EventField.fromPath(
          '$.detail.state',
        )}`,
      ),
    }),
  ],
});

After implementing, if you navigate to Amazon EventBridge -> Rules, then select the rule, then select the Target(s) and then click View Details you will see the Target Details with the Input transformer & InputTemplate.

Input transformer: {"InputPathsMap":{"detail-pipeline":"$.detail.pipeline","detail-state":"$.detail.state"},"InputTemplate":"\"The Pipeline '<detail-pipeline>' has <detail-state>\""}

bravogolfgolf
  • 357
  • 2
  • 11
  • It appears with "\" in the events->rules->target message. How to avoid this? – Mikasa Dec 06 '20 at 02:05
  • 2
    thank you. python version of the above code:-- yourRule.add_target(target=targets.SnsTopic(topic=snstopicName, message=events.RuleTargetInput.from_text(f"""The job with name {events.EventField.from_path('$.detail.jobName')} failed with the the job run id {events.EventField.from_path('$.detail.jobRunId')}. add more if you want to """ ))) – Pruthvi Raj Mar 01 '21 at 21:06
  • @PruthviRaj could you make a new answer with the python version – Khan Apr 17 '21 at 15:05
  • How about a string with new-lines? – JakeTheSnake May 19 '21 at 20:03
0

This would work for CDK Python. CodeBuild to SNS notifications.

sns_topic = sns.Topic(...)
codebuild_project = codebuild.Project(...)
sns_topic.grant_publish(codebuild_project)
codebuild_project.on_build_failed(
            f'rule-on-failed',
            target=events_targets.SnsTopic(
                sns_topic,
                message=events.RuleTargetInput.from_multiline_text(
                    f"""
                    Name: {events.EventField.from_path('$.detail.project-name')} 
                    State: {events.EventField.from_path('$.detail.build-status')}
                    Build: {events.EventField.from_path('$.detail.build-id')}
                    Account: {events.EventField.from_path('$.account')}
                """
                )
            )
        )

Credits to @pruthvi-raj comment on an answer above

Anatol Bivol
  • 890
  • 7
  • 20