Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(scheduler-targets-alpha): SnsPublish scheduler target #27838

Merged
merged 24 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b858864
add sns-publish for scheduler-targets
Oct 29, 2023
6fc3d6c
add unit tests for valid conditions
Oct 31, 2023
7120ec4
add unit tests
Nov 2, 2023
b323246
unit test ok
Nov 2, 2023
74a786f
update integ test
Nov 4, 2023
efcbc06
Merge branch 'main' of github.com:ymhiroki/aws-cdk into scheduler-tar…
Nov 4, 2023
ed540ec
integ test ok
Nov 4, 2023
d5e47e7
Merge branch 'main' of github.com:ymhiroki/aws-cdk into scheduler-tar…
Nov 7, 2023
788d5a1
update unit test
Nov 7, 2023
8f6c5b2
add unit test for imported topic
Nov 7, 2023
0e2bafe
update unit test
Nov 7, 2023
150ea10
fix typo
Nov 7, 2023
efbc9ac
Merge branch 'main' into scheduler-targets-snspublish
ymhiroki Nov 7, 2023
e86a878
add default value for ScheduleTargetBaseProps
Nov 9, 2023
7044203
Merge branch 'scheduler-targets-snspublish' of github.com:ymhiroki/aw…
Nov 9, 2023
e3f405f
Merge branch 'main' into scheduler-targets-snspublish
ymhiroki Nov 9, 2023
f745f15
update README
Nov 9, 2023
b235e77
Merge branch 'scheduler-targets-snspublish' of github.com:ymhiroki/aw…
Nov 9, 2023
a1af754
Merge branch 'main' into scheduler-targets-snspublish
ymhiroki Nov 19, 2023
09c9713
Merge branch 'main' into scheduler-targets-snspublish
ymhiroki Nov 23, 2023
5e8b671
Merge branch 'main' into scheduler-targets-snspublish
vinayak-kukreja Nov 28, 2023
c9523fe
Merge branch 'main' into scheduler-targets-snspublish
vinayak-kukreja Nov 29, 2023
8c8742b
run integ test
vinayak-kukreja Nov 29, 2023
c86928b
Merge branch 'main' into scheduler-targets-snspublish
mergify[bot] Nov 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions packages/@aws-cdk/aws-scheduler-targets-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The following targets are supported:
1. `targets.LambdaInvoke`: [Invoke an AWS Lambda function](#invoke-a-lambda-function))
2. `targets.StepFunctionsStartExecution`: [Start an AWS Step Function](#start-an-aws-step-function)
3. `targets.CodeBuildStartBuild`: [Start a CodeBuild job](#start-a-codebuild-job)
4. `targets.SnsPublish`: [Publish messages to an Amazon SNS topic](#publish-messages-to-an-amazon-sns-topic)

## Invoke a Lambda function

Expand Down Expand Up @@ -121,3 +122,29 @@ new Schedule(this, 'Schedule', {
target: new targets.CodeBuildStartBuild(project),
});
```

## Publish messages to an Amazon SNS topic

Use the `SnsPublish` target to publish messages to an Amazon SNS topic.

The code snippets below create create an event rule with a Amazon SNS topic as a target.
It's called every hour by Amazon Event Bridge Scheduler with custom payload.

```ts
import * as sns from 'aws-cdk-lib/aws-sns';

const topic = new sns.Topic(this, 'Topic', {});

const payload = {
message: 'Hello scheduler!',
};

const target = new targets.SnsPublish(topic, {
input: ScheduleTargetInput.fromObject(payload),
});

new Schedule(this, 'Schedule', {
schedule: ScheduleExpression.rate(Duration.hours(1)),
target,
});
```
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-scheduler-targets-alpha/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './target';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please sort these alphabetically?

export * from './lambda-invoke';
export * from './stepfunctions-start-execution';
export * from './sns-publish';
export * from './codebuild-start-build';
37 changes: 37 additions & 0 deletions packages/@aws-cdk/aws-scheduler-targets-alpha/lib/sns-publish.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ISchedule, IScheduleTarget } from '@aws-cdk/aws-scheduler-alpha';
import { Names } from 'aws-cdk-lib';
import { IRole } from 'aws-cdk-lib/aws-iam';
import * as sns from 'aws-cdk-lib/aws-sns';
import { ScheduleTargetBase, ScheduleTargetBaseProps } from './target';
import { sameEnvDimension } from './util';

/**
* Use an Amazon SNS topic as a target for AWS EventBridge Scheduler.
*/
export class SnsPublish extends ScheduleTargetBase implements IScheduleTarget {
constructor(
private readonly topic: sns.ITopic,
private readonly props: ScheduleTargetBaseProps,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private readonly props: ScheduleTargetBaseProps,
private readonly props: ScheduleTargetBaseProps = {},

Let's add a default value to simplify initialization when no props are needed.
Can you please then update all the SnsPublish(topic, {}) to SnsPublish(topic) in this PR?

Copy link
Contributor Author

@ymhiroki ymhiroki Nov 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your advice! I've updated them.

) {
super(props, topic.topicArn);
}

protected addTargetActionToRole(schedule: ISchedule, role: IRole): void {
// Check if target and schedule are in the region
if (!sameEnvDimension(this.topic.env.region, schedule.env.region)) {
throw new Error(`Cannot assign topic in region ${this.topic.env.region} to the schedule ${Names.nodeUniqueId(schedule.node)} in region ${schedule.env.region}. Both the schedule and the topic must be in the same region.`);
}

// Check if target and schedule are in the same account
if (!sameEnvDimension(this.topic.env.account, schedule.env.account)) {
throw new Error(`Cannot assign topic in account ${this.topic.env.account} to the schedule ${Names.nodeUniqueId(schedule.node)} in account ${role.env.account}. Both the schedule and the topic must be in the same account.`);
}

// Check if target and role are in the same account
if (this.props.role && !sameEnvDimension(this.props.role.env.account, this.topic.env.account)) {
throw new Error(`Cannot grant permission to execution role in account ${this.props.role.env.account} to publish to target ${Names.nodeUniqueId(this.topic.node)} in account ${this.topic.env.account}. Both the target and the execution role must be in the same account.`);
}

this.topic.grantPublish(role);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
{
"Resources": {
"TopicBFC7AF6E": {
"Type": "AWS::SNS::Topic"
},
"Queue4A7E3555": {
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"QueuePolicy25439813": {
"Type": "AWS::SQS::QueuePolicy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:SendMessage",
"Condition": {
"ArnEquals": {
"aws:SourceArn": {
"Ref": "TopicBFC7AF6E"
}
}
},
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Resource": {
"Fn::GetAtt": [
"Queue4A7E3555",
"Arn"
]
}
}
],
"Version": "2012-10-17"
},
"Queues": [
{
"Ref": "Queue4A7E3555"
}
]
}
},
"QueueAwsSchedulerTargetsSnsPublishTopicCB9BF6E1C346AD60": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
"Fn::GetAtt": [
"Queue4A7E3555",
"Arn"
]
},
"Protocol": "sqs",
"RawMessageDelivery": true,
"TopicArn": {
"Ref": "TopicBFC7AF6E"
}
},
"DependsOn": [
"QueuePolicy25439813"
]
},
"Schedule83A77FD1": {
"Type": "AWS::Scheduler::Schedule",
"Properties": {
"FlexibleTimeWindow": {
"Mode": "OFF"
},
"ScheduleExpression": "rate(1 minute)",
"ScheduleExpressionTimezone": "Etc/UTC",
"State": "ENABLED",
"Target": {
"Arn": {
"Ref": "TopicBFC7AF6E"
},
"Input": "\"Hello, Scheduler!\"",
"RetryPolicy": {
"MaximumEventAgeInSeconds": 86400,
"MaximumRetryAttempts": 185
},
"RoleArn": {
"Fn::GetAtt": [
"SchedulerRoleForTarget1441a743A31888",
"Arn"
]
}
}
}
},
"SchedulerRoleForTarget1441a743A31888": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": {
"Ref": "AWS::AccountId"
}
}
},
"Effect": "Allow",
"Principal": {
"Service": "scheduler.amazonaws.com"
}
}
],
"Version": "2012-10-17"
}
}
},
"SchedulerRoleForTarget1441a7DefaultPolicy885B6BFD": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sns:Publish",
"Effect": "Allow",
"Resource": {
"Ref": "TopicBFC7AF6E"
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "SchedulerRoleForTarget1441a7DefaultPolicy885B6BFD",
"Roles": [
{
"Ref": "SchedulerRoleForTarget1441a743A31888"
}
]
}
}
},
"Outputs": {
"ExportsOutputRefQueue4A7E3555425E8BD3": {
"Value": {
"Ref": "Queue4A7E3555"
},
"Export": {
"Name": "AwsSchedulerTargetsSnsPublish:ExportsOutputRefQueue4A7E3555425E8BD3"
}
}
},
"Parameters": {
"BootstrapVersion": {
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "/cdk-bootstrap/hnb659fds/version",
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
}
},
"Rules": {
"CheckBootstrapVersion": {
"Assertions": [
{
"Assert": {
"Fn::Not": [
{
"Fn::Contains": [
[
"1",
"2",
"3",
"4",
"5"
],
{
"Ref": "BootstrapVersion"
}
]
}
]
},
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
}
]
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading