0

I need to create EventBridge Rule detecting stopped ECS Task and sending info to SNS Topic.

  • When I create the Rule manually, it works
  • When I create the same rule via Pulumi, it does not work - it does not match any events

They are both exactly the same. I even compared the exported CloudFormation template, they are both the same. What can be different and how can I spot or fix the difference?

Here's the CF template:

AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template for EventBridge Rule ecsSlackAlertsEventRule
Resources:
  Rule88730153:
    Type: AWS::Events::Rule
    Properties:
      Name: ecsSlackAlertsEventRule
      EventPattern: >-
        {"detail":{"clusterArn":["arn:aws:ecs:us-west-2:xxxxxxxxxxx:cluster/ecs-14f72ee"],"lastStatus":["STOPPED"]},"detailType":["ECS
        Task State Change"],"source":["aws.ecs"]}
      State: ENABLED
      EventBusName: default
      Targets:
        - Id: xxxxxxxxxxx-ad6a-46d2-912f-071ec8da74f2
          Arn:
            Fn::Sub: >-
              arn:${AWS::Partition}:sns:${AWS::Region}:${AWS::AccountId}:ecs-slack-notifications
Parameters: {}

And the Pulumi code:

    const ecsAlertEventRule = new aws.cloudwatch.EventRule("ecsSlackAlertsEventRule", {
      name: "ecsSlackAlertsEventRule",
      eventBusName: "default",
      eventPattern: ecsCluster.arn.apply(arn => {
        return JSON.stringify({
          source: ["aws.ecs"],
          detailType: ["ECS Task State Change"],
          detail: {
            clusterArn: [arn],
            lastStatus: ["STOPPED"],
          }
        })
      }),
    });
    const ecsAlertEventTarget = new aws.cloudwatch.EventTarget("ecsSlackAlertsEventTarget", {
      rule: ecsAlertEventRule.name,
      arn: slackNotificationsSNSTopic.arn,
    });

1 Answer 1

0

I finally found out! When created manually, AWS silently adds policy to SNS topic to allow the Event Rule to write to the Topic. Pulumi does not do that and you need to add the policy explicitly.

const snsPolicy = new aws.sns.TopicPolicy("mySnsPolicy", {
    arn: snsTopic.arn,
    policy: snsTopic.arn.apply(arn => JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Effect: "Allow",
            Principal: { Service: "events.amazonaws.com" },
            Action: "sns:Publish",
            Resource: arn,
        }],
    })),
});
Sign up to request clarification or add additional context in comments.

1 Comment

Correct, when done through the console, EventBridge adds the necessary permissions as convenience - programmatically through APIs this has to be done explicitly. Take a look at serverlessland.com/patterns for more inspiration.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.