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(iot): add action to start Step Functions State Machine #26059

Merged
merged 7 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
18 changes: 18 additions & 0 deletions packages/@aws-cdk/aws-iot-actions-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,24 @@ const topicRule = new iot.TopicRule(this, 'TopicRule', {
});
```

## Start Step Functions State Machine

The code snippet below creates an AWS IoT Rule that starts a Step Functions State Machine
when it is triggered.

```ts
const stateMachine = new stepfunctions.StateMachine(this, 'SM', {
definitionBody: stepfunctions.DefinitionBody.fromChainable(new stepfunctions.Wait(this, 'Hello', { time: stepfunctions.WaitTime.duration(Duration.seconds(10)) })),
});

new iot.TopicRule(this, 'TopicRule', {
sql: iot.IotSql.fromStringAsVer20160323("SELECT * FROM 'device/+/data'"),
actions: [
new actions.StepFunctionsStateMachineAction(stateMachine),
],
});
```

## Change the state of an Amazon CloudWatch alarm

The code snippet below creates an AWS IoT Rule that changes the state of an Amazon CloudWatch alarm when it is triggered:
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-iot-actions-alpha/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export * from './lambda-function-action';
export * from './s3-put-object-action';
export * from './sqs-queue-action';
export * from './sns-topic-action';
export * from './step-functions-state-machine-action';
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import * as iam from 'aws-cdk-lib/aws-iam';
import * as iot from '@aws-cdk/aws-iot-alpha';
import * as stepfunctions from 'aws-cdk-lib/aws-stepfunctions';
import { CommonActionProps } from './common-action-props';
import { singletonActionRole } from './private/role';
import { ArnFormat, Stack } from 'aws-cdk-lib';

/**
* Configuration properties of an action for the Step Functions State Machine.
*/
export interface StepFunctionsStateMachineActionProps extends CommonActionProps {
/**
* Name of the state machine execution prefix.
* The name given to the state machine execution consists of this prefix followed by a UUID. Step Functions creates a unique name for each state machine execution if one is not provided.
*
* @see https://docs.aws.amazon.com/iot/latest/developerguide/stepfunctions-rule-action.html#stepfunctions-rule-action-parameters
*
* @default: None - Step Functions creates a unique name for each state machine execution if one is not provided.
*/
readonly executionNamePrefix?: string;
}

/**
* The action to put the record from an MQTT message to the Step Functions State Machine.
*/
export class StepFunctionsStateMachineAction implements iot.IAction {
private readonly executionNamePrefix?: string;
private readonly role?: iam.IRole;

/**
* @param stateMachine The Step Functions Start Machine which shoud be executed.
* @param props Optional properties to not use default
*/
constructor(private readonly stateMachine: stepfunctions.IStateMachine, props?: StepFunctionsStateMachineActionProps) {
this.executionNamePrefix = props?.executionNamePrefix;
this.role = props?.role;
}

/**
* @internal
*/
public _bind(rule: iot.ITopicRule): iot.ActionConfig {
const role = this.role ?? singletonActionRole(rule);
const stateMachineName = Stack.of(this.stateMachine).splitArn(this.stateMachine.stateMachineArn, ArnFormat.COLON_RESOURCE_NAME).resourceName;

if (!stateMachineName) {
throw new Error(`No state machine name found in ARN: '${this.stateMachine.stateMachineArn}'`);
}

role.addToPrincipalPolicy(new iam.PolicyStatement({
actions: ['states:StartExecution'],
resources: [this.stateMachine.stateMachineArn],
}));

return {
configuration: {
stepFunctions: {
stateMachineName,
executionNamePrefix: this.executionNamePrefix,
roleArn: role.roleArn,
},
},
};
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-iot-actions-alpha/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"@aws-cdk/aws-iot-alpha": "0.0.0",
"@aws-cdk/aws-iotevents-alpha": "0.0.0",
"@aws-cdk/aws-kinesisfirehose-alpha": "0.0.0",
"@aws-cdk/aws-kinesisfirehose-destinations-alpha": "0.0.0",
"aws-cdk-lib": "^0.0.0",
"constructs": "^10.0.0"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// Fixture with packages imported, but nothing else
import { Stack } from 'aws-cdk-lib';
import { Stack, Duration } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as actions from '@aws-cdk/aws-iot-actions-alpha';
import * as iot from '@aws-cdk/aws-iot-alpha';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as stepfunctions from 'aws-cdk-lib/aws-stepfunctions';

class Fixture extends Stack {
constructor(scope: Construct, id: string) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":"32.0.0"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "32.0.0",
"testCases": {
"state-machine-integtest/DefaultTest": {
"stacks": [
"test-step-functions-start-state-machine-action-stack"
],
"assertionStack": "state-machine-integtest/DefaultTest/DeployAssert",
"assertionStackName": "statemachineintegtestDefaultTestDeployAssert1FAFBF55"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
{
"version": "32.0.0",
"artifacts": {
"test-step-functions-start-state-machine-action-stack.assets": {
"type": "cdk:asset-manifest",
"properties": {
"file": "test-step-functions-start-state-machine-action-stack.assets.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
}
},
"test-step-functions-start-state-machine-action-stack": {
"type": "aws:cloudformation:stack",
"environment": "aws://unknown-account/unknown-region",
"properties": {
"templateFile": "test-step-functions-start-state-machine-action-stack.template.json",
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2a9785d0602d38f259eb92a63ba9ecfd1092a72904af9e5e265db24a5d7a78ab.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
"test-step-functions-start-state-machine-action-stack.assets"
],
"lookupRole": {
"arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}",
"requiresBootstrapStackVersion": 8,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
}
},
"dependencies": [
"test-step-functions-start-state-machine-action-stack.assets"
],
"metadata": {
"/test-step-functions-start-state-machine-action-stack/TopicRule/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "TopicRule40A4EA44"
}
],
"/test-step-functions-start-state-machine-action-stack/TopicRule/TopicRuleActionRole/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "TopicRuleTopicRuleActionRole246C4F77"
}
],
"/test-step-functions-start-state-machine-action-stack/TopicRule/TopicRuleActionRole/DefaultPolicy/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "TopicRuleTopicRuleActionRoleDefaultPolicy99ADD687"
}
],
"/test-step-functions-start-state-machine-action-stack/SM/Role/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "SMRole49C19C48"
}
],
"/test-step-functions-start-state-machine-action-stack/SM/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "SM934E715A"
}
],
"/test-step-functions-start-state-machine-action-stack/BootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "BootstrapVersion"
}
],
"/test-step-functions-start-state-machine-action-stack/CheckBootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "CheckBootstrapVersion"
}
]
},
"displayName": "test-step-functions-start-state-machine-action-stack"
},
"statemachineintegtestDefaultTestDeployAssert1FAFBF55.assets": {
"type": "cdk:asset-manifest",
"properties": {
"file": "statemachineintegtestDefaultTestDeployAssert1FAFBF55.assets.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
}
},
"statemachineintegtestDefaultTestDeployAssert1FAFBF55": {
"type": "aws:cloudformation:stack",
"environment": "aws://unknown-account/unknown-region",
"properties": {
"templateFile": "statemachineintegtestDefaultTestDeployAssert1FAFBF55.template.json",
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
"statemachineintegtestDefaultTestDeployAssert1FAFBF55.assets"
],
"lookupRole": {
"arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}",
"requiresBootstrapStackVersion": 8,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
}
},
"dependencies": [
"statemachineintegtestDefaultTestDeployAssert1FAFBF55.assets"
],
"metadata": {
"/state-machine-integtest/DefaultTest/DeployAssert/BootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "BootstrapVersion"
}
],
"/state-machine-integtest/DefaultTest/DeployAssert/CheckBootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "CheckBootstrapVersion"
}
]
},
"displayName": "state-machine-integtest/DefaultTest/DeployAssert"
},
"Tree": {
"type": "cdk:tree",
"properties": {
"file": "tree.json"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "32.0.0",
"files": {
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
"source": {
"path": "statemachineintegtestDefaultTestDeployAssert1FAFBF55.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"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."
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "32.0.0",
"files": {
"2a9785d0602d38f259eb92a63ba9ecfd1092a72904af9e5e265db24a5d7a78ab": {
"source": {
"path": "test-step-functions-start-state-machine-action-stack.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "2a9785d0602d38f259eb92a63ba9ecfd1092a72904af9e5e265db24a5d7a78ab.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Loading