Skip to content

Commit

Permalink
feat(scheduler-targets): step function start execution target (#27424)
Browse files Browse the repository at this point in the history
A StepFunctionStartExecution ScheduleTarget was implemented similar to the already existing [LambdaInvoke](https://github.com/aws/aws-cdk/blob/b2a895ef285e5451e64c21e179172e998c479582/packages/%40aws-cdk/aws-scheduler-targets-alpha/lib/lambda-invoke.ts#L8) target.

I've added an integration test, which will trigger an eventbridge schedule once. This schedule has a step function as a target. The step function creates a parameter with a given value, which will get verified by the test

Closes #27377 

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
WtfJoke committed Oct 11, 2023
1 parent 61be7a6 commit 3a87141
Show file tree
Hide file tree
Showing 15 changed files with 35,577 additions and 1 deletion.
41 changes: 41 additions & 0 deletions packages/@aws-cdk/aws-scheduler-targets-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ number of supported AWS Services.
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)

## Invoke a Lambda function

Expand Down Expand Up @@ -61,3 +62,43 @@ const schedule = new Schedule(this, 'Schedule', {
target
});
```

## Start an AWS Step Function

Use the `StepFunctionsStartExecution` target to start a new execution on a StepFunction.

The code snippet below creates an event rule with a Step Function as a target
called every hour by Event Bridge Scheduler with a custom payload.

```ts
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';

const payload = {
Name: "MyParameter",
Value: '🌥️',
};

const putParameterStep = new tasks.CallAwsService(this, 'PutParameter', {
service: 'ssm',
action: 'putParameter',
iamResources: ['*'],
parameters: {
"Name.$": '$.Name',
"Value.$": '$.Value',
Type: 'String',
Overwrite: true,
},
});

const stateMachine = new sfn.StateMachine(this, 'StateMachine', {
definitionBody: sfn.DefinitionBody.fromChainable(putParameterStep)
});

new Schedule(this, 'Schedule', {
schedule: ScheduleExpression.rate(Duration.hours(1)),
target: new targets.StepFunctionsStartExecution(stateMachine, {
input: ScheduleTargetInput.fromObject(payload),
}),
});
```
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-scheduler-targets-alpha/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './target';
export * from './lambda-invoke';
export * from './lambda-invoke';
export * from './stepfunctions-start-execution';
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { IScheduleTarget, ISchedule } from '@aws-cdk/aws-scheduler-alpha';
import { Names } from 'aws-cdk-lib';
import { IRole } from 'aws-cdk-lib/aws-iam';
import { IStateMachine } from 'aws-cdk-lib/aws-stepfunctions';
import { ScheduleTargetBase, ScheduleTargetBaseProps } from './target';
import { sameEnvDimension } from './util';

/**
* Use an AWS Step function as a target for AWS EventBridge Scheduler.
*/
export class StepFunctionsStartExecution extends ScheduleTargetBase implements IScheduleTarget {
constructor(
private readonly stateMachine: IStateMachine,
private readonly props: ScheduleTargetBaseProps,
) {
super(props, stateMachine.stateMachineArn);
}

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

if (!sameEnvDimension(stateMachineEnv.account, schedule.env.account)) {
throw new Error(`Cannot assign stateMachine in account ${stateMachineEnv.account} to the schedule ${Names.nodeUniqueId(schedule.node)} in account ${schedule.env.region}. Both the schedule and the stateMachine must be in the same account.`);
}

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

this.stateMachine.grantStartExecution(role);
}
}
Loading

0 comments on commit 3a87141

Please sign in to comment.