diff --git a/.viperlightignore b/.viperlightignore index a2cc9688c..07288d8e8 100644 --- a/.viperlightignore +++ b/.viperlightignore @@ -30,8 +30,8 @@ source/patterns/@aws-solutions-constructs/aws-lambda-step-function/test/lambda-s source/patterns/@aws-solutions-constructs/aws-lambda-stepfunctions/test/lambda-stepfunctions.test.ts:130 source/patterns/@aws-solutions-constructs/aws-events-rule-sns/test/events-rule-sns-topic.test.ts:255 source/patterns/@aws-solutions-constructs/aws-eventbridge-sns/test/eventbridge-sns-topic.test.ts:255 -source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/events-rule-sqs-queue.test.ts:131 -source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/eventbridge-sqs-queue.test.ts:131 +source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/events-rule-sqs-queue.test.ts:143 +source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/eventbridge-sqs-queue.test.ts:143 source/patterns/@aws-solutions-constructs/aws-dynamodb-stream-lambda/test/dynamodb-stream-lambda.test.ts:105 source/patterns/@aws-solutions-constructs/aws-dynamodbstreams-lambda/test/dynamodbstreams-lambda.test.ts:105 source/patterns/@aws-solutions-constructs/aws-apigateway-iot/README.md:39 diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-lambda/README.md b/source/patterns/@aws-solutions-constructs/aws-eventbridge-lambda/README.md index de5b4488a..c6d5f4014 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-lambda/README.md +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-lambda/README.md @@ -69,7 +69,7 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| -|eventBus|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| +|eventBus?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| |eventsRule|[`events.Rule`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.Rule.html)|Returns an instance of events.Rule created by the construct| |lambdaFunction|[`lambda.Function`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-lambda.Function.html)|Returns an instance of lambda.Function created by the construct| diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sns/README.md b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sns/README.md index cd423c116..e868f9e8e 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sns/README.md +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sns/README.md @@ -80,7 +80,7 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| -|eventBus|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| +|eventBus?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| |eventsRule|[`events.Rule`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.Rule.html)|Returns an instance of events.Rule created by the construct| |snsTopic|[`sns.Topic`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-sns.Topic.html)|Returns an instance of sns.Topic created by the construct| |encryptionKey?|[`kms.Key`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-kms.Key.html)|Returns an instance of kms Key used for the SNS Topic.| diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/README.md b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/README.md index 724ec532b..aaa533ce0 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/README.md +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/README.md @@ -67,6 +67,8 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| +|existingEventBusInterface?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)| Optional user-provided custom EventBus for construct to use. Providing both this and `eventBusProps` results an error.| +|eventBusProps?|[`events.EventBusProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.EventBusProps.html)|Optional user-provided properties to override the default properties when creating a custom EventBus. Setting this value to `{}` will create a custom EventBus using all default properties. If neither this nor `existingEventBusInterface` is provided the construct will use the `default` EventBus. Providing both this and `existingEventBusInterface` results an error.| |eventRuleProps|[`events.RuleProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.RuleProps.html)|User provided eventRuleProps to override the defaults. | |existingQueueObj?|[`sqs.Queue`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-sqs.Queue.html)|An optional, existing SQS queue to be used instead of the default queue. Providing both this and `queueProps` will cause an error.| |queueProps?|[`sqs.QueueProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-sqs.QueueProps.html)|User provided props to override the default props for the SQS Queue. | @@ -82,6 +84,7 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| +|eventBus?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| |eventsRule|[`events.Rule`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.Rule.html)|Returns an instance of events.Rule created by the construct| |sqsQueue|[`sqs.Queue`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-sqs.Queue.html)|Returns an instance of sqs.Queue created by the construct| |encryptionKey?|[`kms.Key`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-kms.Key.html)|Returns an instance of kms Key used for the SQS queue.| diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/lib/index.ts index 3a7c2f694..7c69305f7 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/lib/index.ts @@ -24,72 +24,85 @@ import { overrideProps } from '@aws-solutions-constructs/core'; * @summary The properties for the EventbridgeToSqs Construct */ export interface EventbridgeToSqsProps { + /** + * Existing instance of a custom EventBus. + * + * @default - None + */ + readonly existingEventBusInterface?: events.IEventBus; + /** + * A new custom EventBus is created with provided props. + * + * @default - None + */ + readonly eventBusProps?: events.EventBusProps; /** * User provided eventRuleProps to override the defaults * * @default - None */ - readonly eventRuleProps: events.RuleProps + readonly eventRuleProps: events.RuleProps; /** * Existing instance of SQS queue object, providing both this and queueProps will cause an error. * * @default - None */ - readonly existingQueueObj?: sqs.Queue, + readonly existingQueueObj?: sqs.Queue; /** * User provided props to override the default props for the SQS queue. * * @default - Default props are used */ - readonly queueProps?: sqs.QueueProps, + readonly queueProps?: sqs.QueueProps; /** * Whether to grant additional permissions to the Lambda function enabling it to purge the SQS queue. * * @default - "false", disabled by default. */ - readonly enableQueuePurging?: boolean, + readonly enableQueuePurging?: boolean; /** * Optional user provided properties for the dead letter queue * * @default - Default props are used */ - readonly deadLetterQueueProps?: sqs.QueueProps, + readonly deadLetterQueueProps?: sqs.QueueProps; /** * Whether to deploy a secondary queue to be used as a dead letter queue. * * @default - true. */ - readonly deployDeadLetterQueue?: boolean, + readonly deployDeadLetterQueue?: boolean; /** * The number of times a message can be unsuccessfully dequeued before being moved to the dead-letter queue. * * @default - required field if deployDeadLetterQueue=true. */ - readonly maxReceiveCount?: number, + readonly maxReceiveCount?: number; /** * Use a KMS Key, either managed by this CDK app, or imported. If importing an encryption key, it must be specified in * the encryptionKey property for this construct. * * @default - true (encryption enabled, managed by this CDK app). */ - readonly enableEncryptionWithCustomerManagedKey?: boolean + readonly enableEncryptionWithCustomerManagedKey?: boolean; /** * An optional, imported encryption key to encrypt the SQS queue, and SNS Topic. * * @default - not specified. */ - readonly encryptionKey?: kms.Key + readonly encryptionKey?: kms.Key; /** * Optional user-provided props to override the default props for the encryption key. * * @default - Default props are used. */ - readonly encryptionKeyProps?: kms.KeyProps + readonly encryptionKeyProps?: kms.KeyProps; } export class EventbridgeToSqs extends Construct { public readonly sqsQueue: sqs.Queue; public readonly deadLetterQueue?: sqs.DeadLetterQueue; + public readonly eventBus?: events.IEventBus; public readonly eventsRule: events.Rule; public readonly encryptionKey?: kms.IKey; @@ -136,7 +149,13 @@ export class EventbridgeToSqs extends Construct { }) }; - const defaultEventsRuleProps = defaults.DefaultEventsRuleProps([sqsEventTarget]); + // build an event bus if existingEventBus is provided or eventBusProps are provided + this.eventBus = defaults.buildEventBus(this, { + existingEventBusInterface: props.existingEventBusInterface, + eventBusProps: props.eventBusProps + }); + + const defaultEventsRuleProps = defaults.DefaultEventsRuleProps([sqsEventTarget], this.eventBus); const eventsRuleProps = overrideProps(defaultEventsRuleProps, props.eventRuleProps, true); this.eventsRule = new events.Rule(this, 'EventsRule', eventsRuleProps); diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/__snapshots__/eventbridge-sqs-queue.test.js.snap b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/__snapshots__/eventbridge-sqs-queue.test.js.snap index f2bc05910..8cf4e5a06 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/__snapshots__/eventbridge-sqs-queue.test.js.snap +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/__snapshots__/eventbridge-sqs-queue.test.js.snap @@ -1,9 +1,1177 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`check eventbus property, snapshot & eventbus exists 1`] = ` +Object { + "Resources": Object { + "testeventbridgesqsnewbusCustomEventBus7799DF2B": Object { + "Properties": Object { + "Name": "testeventbridgesqsnewbusCustomEventBus19F2F64B", + }, + "Type": "AWS::Events::EventBus", + }, + "testeventbridgesqsnewbusEncryptionKeyC054EABF": Object { + "DeletionPolicy": "Retain", + "Properties": Object { + "EnableKeyRotation": true, + "KeyPolicy": Object { + "Statement": Array [ + Object { + "Action": Array [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": "*", + }, + Object { + "Action": Array [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": "*", + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::KMS::Key", + "UpdateReplacePolicy": "Retain", + }, + "testeventbridgesqsnewbusEventsRuleF2643721": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testeventbridgesqsnewbusCustomEventBus7799DF2B", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsnewbusqueue662F5BAB", + "Arn", + ], + }, + "Id": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsnewbusqueue662F5BAB", + "QueueName", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testeventbridgesqsnewbusdeadLetterQueue780165C7": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": "alias/aws/sqs", + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testeventbridgesqsnewbusdeadLetterQueuePolicy5C43CFAB": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsnewbusdeadLetterQueue780165C7", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsnewbusdeadLetterQueue780165C7", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testeventbridgesqsnewbusdeadLetterQueue780165C7", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + "testeventbridgesqsnewbusqueue662F5BAB": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsnewbusEncryptionKeyC054EABF", + "Arn", + ], + }, + "RedrivePolicy": Object { + "deadLetterTargetArn": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsnewbusdeadLetterQueue780165C7", + "Arn", + ], + }, + "maxReceiveCount": 15, + }, + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testeventbridgesqsnewbusqueuePolicyDE8209E1": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsnewbusqueue662F5BAB", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsnewbusqueue662F5BAB", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + Object { + "Action": Array [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsnewbusqueue662F5BAB", + "Arn", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testeventbridgesqsnewbusqueue662F5BAB", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + }, +} +`; + +exports[`check multiple constructs in a single stack 1`] = ` +Object { + "Resources": Object { + "testneweventbridgesqs1CustomEventBus8325C352": Object { + "Properties": Object { + "Name": "testneweventbridgesqs1CustomEventBusA5003CBC", + }, + "Type": "AWS::Events::EventBus", + }, + "testneweventbridgesqs1EncryptionKey3A3D74F8": Object { + "DeletionPolicy": "Retain", + "Properties": Object { + "EnableKeyRotation": true, + "KeyPolicy": Object { + "Statement": Array [ + Object { + "Action": Array [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": "*", + }, + Object { + "Action": Array [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": "*", + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::KMS::Key", + "UpdateReplacePolicy": "Retain", + }, + "testneweventbridgesqs1EventsRule2E263936": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testneweventbridgesqs1CustomEventBus8325C352", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs1queue330A3071", + "Arn", + ], + }, + "Id": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs1queue330A3071", + "QueueName", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testneweventbridgesqs1deadLetterQueueE1549281": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": "alias/aws/sqs", + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testneweventbridgesqs1deadLetterQueuePolicy86E53DD1": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs1deadLetterQueueE1549281", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs1deadLetterQueueE1549281", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testneweventbridgesqs1deadLetterQueueE1549281", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + "testneweventbridgesqs1queue330A3071": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs1EncryptionKey3A3D74F8", + "Arn", + ], + }, + "RedrivePolicy": Object { + "deadLetterTargetArn": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs1deadLetterQueueE1549281", + "Arn", + ], + }, + "maxReceiveCount": 15, + }, + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testneweventbridgesqs1queuePolicy9CD02502": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs1queue330A3071", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs1queue330A3071", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + Object { + "Action": Array [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs1queue330A3071", + "Arn", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testneweventbridgesqs1queue330A3071", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + "testneweventbridgesqs2CustomEventBusDA6122E8": Object { + "Properties": Object { + "Name": "testneweventbridgesqs2CustomEventBus95F2705A", + }, + "Type": "AWS::Events::EventBus", + }, + "testneweventbridgesqs2EncryptionKey0FBD0AC0": Object { + "DeletionPolicy": "Retain", + "Properties": Object { + "EnableKeyRotation": true, + "KeyPolicy": Object { + "Statement": Array [ + Object { + "Action": Array [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": "*", + }, + Object { + "Action": Array [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": "*", + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::KMS::Key", + "UpdateReplacePolicy": "Retain", + }, + "testneweventbridgesqs2EventsRule2060C024": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testneweventbridgesqs2CustomEventBusDA6122E8", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs2queueE4D7A411", + "Arn", + ], + }, + "Id": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs2queueE4D7A411", + "QueueName", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testneweventbridgesqs2deadLetterQueueC5C6F498": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": "alias/aws/sqs", + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testneweventbridgesqs2deadLetterQueuePolicy2824F886": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs2deadLetterQueueC5C6F498", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs2deadLetterQueueC5C6F498", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testneweventbridgesqs2deadLetterQueueC5C6F498", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + "testneweventbridgesqs2queueE4D7A411": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs2EncryptionKey0FBD0AC0", + "Arn", + ], + }, + "RedrivePolicy": Object { + "deadLetterTargetArn": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs2deadLetterQueueC5C6F498", + "Arn", + ], + }, + "maxReceiveCount": 15, + }, + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testneweventbridgesqs2queuePolicy611821E2": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs2queueE4D7A411", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs2queueE4D7A411", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + Object { + "Action": Array [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventbridgesqs2queueE4D7A411", + "Arn", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testneweventbridgesqs2queueE4D7A411", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + }, +} +`; + exports[`snapshot test EventbridgeToSqs default params 1`] = ` Object { "Resources": Object { - "testeventbridgesqsEncryptionKey811BDC23": Object { + "testeventbridgesqsEncryptionKey811BDC23": Object { + "DeletionPolicy": "Retain", + "Properties": Object { + "EnableKeyRotation": true, + "KeyPolicy": Object { + "Statement": Array [ + Object { + "Action": Array [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": "*", + }, + Object { + "Action": Array [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": "*", + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::KMS::Key", + "UpdateReplacePolicy": "Retain", + }, + "testeventbridgesqsEventsRule66E44184": Object { + "Properties": Object { + "ScheduleExpression": "rate(5 minutes)", + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsqueue21FF6EBA", + "Arn", + ], + }, + "Id": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsqueue21FF6EBA", + "QueueName", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testeventbridgesqsdeadLetterQueueF5B377E2": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": "alias/aws/sqs", + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testeventbridgesqsdeadLetterQueuePolicy74A33822": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsdeadLetterQueueF5B377E2", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsdeadLetterQueueF5B377E2", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testeventbridgesqsdeadLetterQueueF5B377E2", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + "testeventbridgesqsqueue21FF6EBA": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsEncryptionKey811BDC23", + "Arn", + ], + }, + "RedrivePolicy": Object { + "deadLetterTargetArn": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsdeadLetterQueueF5B377E2", + "Arn", + ], + }, + "maxReceiveCount": 15, + }, + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testeventbridgesqsqueuePolicy2E375B6A": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsqueue21FF6EBA", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsqueue21FF6EBA", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + Object { + "Action": Array [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventbridgesqsqueue21FF6EBA", + "Arn", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testeventbridgesqsqueue21FF6EBA", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + }, +} +`; + +exports[`snapshot test EventbridgeToSqs existing event bus params 1`] = ` +Object { + "Resources": Object { + "testexistingeventbridgesqsEncryptionKey5B28D4E1": Object { "DeletionPolicy": "Retain", "Properties": Object { "EnableKeyRotation": true, @@ -68,21 +1236,28 @@ Object { "Type": "AWS::KMS::Key", "UpdateReplacePolicy": "Retain", }, - "testeventbridgesqsEventsRule66E44184": Object { + "testexistingeventbridgesqsEventsRule91D26531": Object { "Properties": Object { - "ScheduleExpression": "rate(5 minutes)", + "EventBusName": Object { + "Ref": "testexistingeventbusC6E4A2D0", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, "State": "ENABLED", "Targets": Array [ Object { "Arn": Object { "Fn::GetAtt": Array [ - "testeventbridgesqsqueue21FF6EBA", + "testexistingeventbridgesqsqueue3A4B6717", "Arn", ], }, "Id": Object { "Fn::GetAtt": Array [ - "testeventbridgesqsqueue21FF6EBA", + "testexistingeventbridgesqsqueue3A4B6717", "QueueName", ], }, @@ -91,7 +1266,7 @@ Object { }, "Type": "AWS::Events::Rule", }, - "testeventbridgesqsdeadLetterQueueF5B377E2": Object { + "testexistingeventbridgesqsdeadLetterQueueD3B506FC": Object { "DeletionPolicy": "Delete", "Properties": Object { "KmsMasterKeyId": "alias/aws/sqs", @@ -99,7 +1274,7 @@ Object { "Type": "AWS::SQS::Queue", "UpdateReplacePolicy": "Delete", }, - "testeventbridgesqsdeadLetterQueuePolicy74A33822": Object { + "testexistingeventbridgesqsdeadLetterQueuePolicy54BD6A69": Object { "Properties": Object { "PolicyDocument": Object { "Statement": Array [ @@ -134,7 +1309,7 @@ Object { }, "Resource": Object { "Fn::GetAtt": Array [ - "testeventbridgesqsdeadLetterQueueF5B377E2", + "testexistingeventbridgesqsdeadLetterQueueD3B506FC", "Arn", ], }, @@ -153,7 +1328,7 @@ Object { }, "Resource": Object { "Fn::GetAtt": Array [ - "testeventbridgesqsdeadLetterQueueF5B377E2", + "testexistingeventbridgesqsdeadLetterQueueD3B506FC", "Arn", ], }, @@ -164,25 +1339,25 @@ Object { }, "Queues": Array [ Object { - "Ref": "testeventbridgesqsdeadLetterQueueF5B377E2", + "Ref": "testexistingeventbridgesqsdeadLetterQueueD3B506FC", }, ], }, "Type": "AWS::SQS::QueuePolicy", }, - "testeventbridgesqsqueue21FF6EBA": Object { + "testexistingeventbridgesqsqueue3A4B6717": Object { "DeletionPolicy": "Delete", "Properties": Object { "KmsMasterKeyId": Object { "Fn::GetAtt": Array [ - "testeventbridgesqsEncryptionKey811BDC23", + "testexistingeventbridgesqsEncryptionKey5B28D4E1", "Arn", ], }, "RedrivePolicy": Object { "deadLetterTargetArn": Object { "Fn::GetAtt": Array [ - "testeventbridgesqsdeadLetterQueueF5B377E2", + "testexistingeventbridgesqsdeadLetterQueueD3B506FC", "Arn", ], }, @@ -192,7 +1367,7 @@ Object { "Type": "AWS::SQS::Queue", "UpdateReplacePolicy": "Delete", }, - "testeventbridgesqsqueuePolicy2E375B6A": Object { + "testexistingeventbridgesqsqueuePolicyE422CDEB": Object { "Properties": Object { "PolicyDocument": Object { "Statement": Array [ @@ -227,7 +1402,7 @@ Object { }, "Resource": Object { "Fn::GetAtt": Array [ - "testeventbridgesqsqueue21FF6EBA", + "testexistingeventbridgesqsqueue3A4B6717", "Arn", ], }, @@ -246,7 +1421,7 @@ Object { }, "Resource": Object { "Fn::GetAtt": Array [ - "testeventbridgesqsqueue21FF6EBA", + "testexistingeventbridgesqsqueue3A4B6717", "Arn", ], }, @@ -264,7 +1439,7 @@ Object { }, "Resource": Object { "Fn::GetAtt": Array [ - "testeventbridgesqsqueue21FF6EBA", + "testexistingeventbridgesqsqueue3A4B6717", "Arn", ], }, @@ -274,12 +1449,18 @@ Object { }, "Queues": Array [ Object { - "Ref": "testeventbridgesqsqueue21FF6EBA", + "Ref": "testexistingeventbridgesqsqueue3A4B6717", }, ], }, "Type": "AWS::SQS::QueuePolicy", }, + "testexistingeventbusC6E4A2D0": Object { + "Properties": Object { + "Name": "testexistingeventbus", + }, + "Type": "AWS::Events::EventBus", + }, }, } `; diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/eventbridge-sqs-queue.test.ts b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/eventbridge-sqs-queue.test.ts index de2468fe9..1dd1b4733 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/eventbridge-sqs-queue.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/eventbridge-sqs-queue.test.ts @@ -27,6 +27,18 @@ function deployNewStack(stack: cdk.Stack) { return new EventbridgeToSqs(stack, 'test-eventbridge-sqs', props); } +function deployStackWithNewEventBus(stack: cdk.Stack) { + const props: EventbridgeToSqsProps = { + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {} + }; + return new EventbridgeToSqs(stack, 'test-eventbridge-sqs-new-bus', props); +} + test('snapshot test EventbridgeToSqs default params', () => { const stack = new cdk.Stack(); deployNewStack(stack); @@ -322,4 +334,91 @@ test('check properties', () => { expect(construct.sqsQueue !== null); expect(construct.encryptionKey !== null); expect(construct.deadLetterQueue !== null); +}); + +test('check eventbus property, snapshot & eventbus exists', () => { + const stack = new cdk.Stack(); + const construct: EventbridgeToSqs = deployStackWithNewEventBus(stack); + + expect(construct.eventsRule !== null); + expect(construct.sqsQueue !== null); + expect(construct.encryptionKey !== null); + expect(construct.deadLetterQueue !== null); + expect(construct.eventBus !== null); + + // Validate snapshot + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); + // Check whether eventbus exists + expect(stack).toHaveResource('AWS::Events::EventBus'); +}); + +test('check exception while passing existingEventBus & eventBusProps', () => { + const stack = new cdk.Stack(); + + const props: EventbridgeToSqsProps = { + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {}, + existingEventBusInterface: new events.EventBus(stack, `test-existing-new-eventbus`, {}) + }; + + try { + new EventbridgeToSqs(stack, 'test-eventbridge-sqs', props); + } catch (e) { + expect(e).toBeInstanceOf(Error); + } +}); + +test('snapshot test EventbridgeToSqs existing event bus params', () => { + const stack = new cdk.Stack(); + const props: EventbridgeToSqsProps = { + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + existingEventBusInterface: new events.EventBus(stack, `test-existing-eventbus`, {}) + }; + new EventbridgeToSqs(stack, 'test-existing-eventbridge-sqs', props); + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); +}); + +test('check custom event bus resource with props when deploy:true', () => { + const stack = new cdk.Stack(); + + const props: EventbridgeToSqsProps = { + eventBusProps: { + eventBusName: 'testcustomeventbus' + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + } + }; + new EventbridgeToSqs(stack, 'test-new-eventbridge-sqs', props); + + expect(stack).toHaveResource('AWS::Events::EventBus', { + Name: 'testcustomeventbus' + }); +}); + +test('check multiple constructs in a single stack', () => { + const stack = new cdk.Stack(); + + const props: EventbridgeToSqsProps = { + eventBusProps: {}, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + } + }; + new EventbridgeToSqs(stack, 'test-new-eventbridge-sqs1', props); + new EventbridgeToSqs(stack, 'test-new-eventbridge-sqs2', props); + + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); }); \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-existing-eventbus.expected.json b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-existing-eventbus.expected.json new file mode 100644 index 000000000..826cec7df --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-existing-eventbus.expected.json @@ -0,0 +1,150 @@ +{ + "Resources": { + "MyKey6AB29FA6": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "EnableKeyRotation": true + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "MyQueueE6CA6235": { + "Type": "AWS::SQS::Queue", + "Properties": { + "KmsMasterKeyId": { + "Fn::GetAtt": [ + "MyKey6AB29FA6", + "Arn" + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "MyQueuePolicy6BBEDDAC": { + "Type": "AWS::SQS::QueuePolicy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl" + ], + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + }, + "Resource": { + "Fn::GetAtt": [ + "MyQueueE6CA6235", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Queues": [ + { + "Ref": "MyQueueE6CA6235" + } + ] + } + }, + "existingeventbusA5B80487": { + "Type": "AWS::Events::EventBus", + "Properties": { + "Name": "eventbridgeexistingeventbusexistingeventbus41AE8F43" + } + }, + "constructEventsRule43880ADB": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventBusName": { + "Ref": "existingeventbusA5B80487" + }, + "EventPattern": { + "source": [ + "solutionsconstructs" + ] + }, + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Fn::GetAtt": [ + "MyQueueE6CA6235", + "Arn" + ] + }, + "Id": { + "Fn::GetAtt": [ + "MyQueueE6CA6235", + "QueueName" + ] + } + } + ] + } + } + } +} \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-existing-eventbus.ts b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-existing-eventbus.ts new file mode 100644 index 000000000..fad5c0807 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-existing-eventbus.ts @@ -0,0 +1,43 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import { EventbridgeToSqsProps, EventbridgeToSqs } from '../lib'; +import * as events from '@aws-cdk/aws-events'; +import { App, Stack } from '@aws-cdk/core'; +import * as sqs from '@aws-cdk/aws-sqs'; +import * as kms from '@aws-cdk/aws-kms'; +import { generateIntegStackName } from '@aws-solutions-constructs/core'; + +const app = new App(); +const stack = new Stack(app, generateIntegStackName(__filename)); + +const existingQueueObj = new sqs.Queue(stack, 'MyQueue', { + encryption: sqs.QueueEncryption.KMS, + encryptionMasterKey: new kms.Key(stack, 'MyKey', { + enableKeyRotation: true + }), +}); + +const existingEventBus = new events.EventBus(stack, 'existing-event-bus', {}); +const props: EventbridgeToSqsProps = { + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + existingQueueObj, + existingEventBusInterface: existingEventBus +}; + +new EventbridgeToSqs(stack, 'construct', props); +app.synth(); \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-new-eventbus.expected.json b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-new-eventbus.expected.json new file mode 100644 index 000000000..8c44e9d83 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-new-eventbus.expected.json @@ -0,0 +1,294 @@ +{ + "Resources": { + "constructdeadLetterQueueD87A77D4": { + "Type": "AWS::SQS::Queue", + "Properties": { + "KmsMasterKeyId": "alias/aws/sqs" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "constructdeadLetterQueuePolicyBA602BC6": { + "Type": "AWS::SQS::QueuePolicy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": { + "Fn::GetAtt": [ + "constructdeadLetterQueueD87A77D4", + "Arn" + ] + }, + "Sid": "QueueOwnerOnlyAccess" + }, + { + "Action": "SQS:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false" + } + }, + "Effect": "Deny", + "Principal": { + "AWS": "*" + }, + "Resource": { + "Fn::GetAtt": [ + "constructdeadLetterQueueD87A77D4", + "Arn" + ] + }, + "Sid": "HttpsOnly" + } + ], + "Version": "2012-10-17" + }, + "Queues": [ + { + "Ref": "constructdeadLetterQueueD87A77D4" + } + ] + } + }, + "constructEncryptionKey9426451E": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "EnableKeyRotation": true + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "constructqueue481DC1EC": { + "Type": "AWS::SQS::Queue", + "Properties": { + "KmsMasterKeyId": { + "Fn::GetAtt": [ + "constructEncryptionKey9426451E", + "Arn" + ] + }, + "RedrivePolicy": { + "deadLetterTargetArn": { + "Fn::GetAtt": [ + "constructdeadLetterQueueD87A77D4", + "Arn" + ] + }, + "maxReceiveCount": 15 + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "constructqueuePolicy5B0256B1": { + "Type": "AWS::SQS::QueuePolicy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": { + "Fn::GetAtt": [ + "constructqueue481DC1EC", + "Arn" + ] + }, + "Sid": "QueueOwnerOnlyAccess" + }, + { + "Action": "SQS:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false" + } + }, + "Effect": "Deny", + "Principal": { + "AWS": "*" + }, + "Resource": { + "Fn::GetAtt": [ + "constructqueue481DC1EC", + "Arn" + ] + }, + "Sid": "HttpsOnly" + }, + { + "Action": [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl" + ], + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + }, + "Resource": { + "Fn::GetAtt": [ + "constructqueue481DC1EC", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Queues": [ + { + "Ref": "constructqueue481DC1EC" + } + ] + } + }, + "constructCustomEventBusA674C94A": { + "Type": "AWS::Events::EventBus", + "Properties": { + "Name": "eventbridgeneweventbusconstructCustomEventBusB03DAAB5" + } + }, + "constructEventsRule43880ADB": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventBusName": { + "Ref": "constructCustomEventBusA674C94A" + }, + "EventPattern": { + "source": [ + "solutionsconstructs" + ] + }, + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Fn::GetAtt": [ + "constructqueue481DC1EC", + "Arn" + ] + }, + "Id": { + "Fn::GetAtt": [ + "constructqueue481DC1EC", + "QueueName" + ] + } + } + ] + } + } + } +} \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-new-eventbus.ts b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-new-eventbus.ts new file mode 100644 index 000000000..998f247a1 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-sqs/test/integ.eventbridge-new-eventbus.ts @@ -0,0 +1,31 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import { EventbridgeToSqsProps, EventbridgeToSqs } from '../lib'; +import { App, Stack } from '@aws-cdk/core'; +import { generateIntegStackName } from '@aws-solutions-constructs/core'; + +const app = new App(); +const stack = new Stack(app, generateIntegStackName(__filename)); + +const props: EventbridgeToSqsProps = { + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {} +}; + +new EventbridgeToSqs(stack, 'construct', props); +app.synth(); \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/README.md b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/README.md index 4cfceeda0..85b530f23 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/README.md +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/README.md @@ -60,6 +60,8 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| |stateMachineProps|[`sfn.StateMachineProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-stepfunctions.StateMachineProps.html)|Optional user provided props to override the default props for sfn.StateMachine| +|existingEventBusInterface?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)| Optional user-provided custom EventBus for construct to use. Providing both this and `eventBusProps` results an error.| +|eventBusProps?|[`events.EventBusProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.EventBusProps.html)|Optional user-provided properties to override the default properties when creating a custom EventBus. Setting this value to `{}` will create a custom EventBus using all default properties. If neither this nor `existingEventBusInterface` is provided the construct will use the `default` EventBus. Providing both this and `existingEventBusInterface` results an error.| |eventRuleProps|[`events.RuleProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.RuleProps.html)|User provided eventRuleProps to override the defaults| |createCloudWatchAlarms|`boolean`|Whether to create recommended CloudWatch alarms| |logGroupProps?|[`logs.LogGroupProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.LogGroupProps.html)|User provided props to override the default props for for the CloudWatchLogs LogGroup.| @@ -68,6 +70,7 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| +|eventBus?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| |eventsRule|[`events.Rule`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.Rule.html)|Returns an instance of events.Rule created by the construct| |stateMachine|[`sfn.StateMachine`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-stepfunctions.StateMachine.html)|Returns an instance of sfn.StateMachine created by the construct| |stateMachineLogGroup|[`logs.ILogGroup`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.ILogGroup.html)|Returns an instance of the ILogGroup created by the construct for StateMachine| diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/lib/index.ts index 4b7444e60..111adc6a3 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/lib/index.ts @@ -25,30 +25,42 @@ import * as logs from '@aws-cdk/aws-logs'; * @summary The properties for the EventbridgeToStepfunctions Construct */ export interface EventbridgeToStepfunctionsProps { + /** + * Existing instance of a custom EventBus. + * + * @default - None + */ + readonly existingEventBusInterface?: events.IEventBus; + /** + * A new custom EventBus is created with provided props. + * + * @default - None + */ + readonly eventBusProps?: events.EventBusProps; /** * User provided StateMachineProps to override the defaults * * @default - None */ - readonly stateMachineProps: sfn.StateMachineProps, + readonly stateMachineProps: sfn.StateMachineProps; /** * User provided eventRuleProps to override the defaults * * @default - None */ - readonly eventRuleProps: events.RuleProps, + readonly eventRuleProps: events.RuleProps; /** * Whether to create recommended CloudWatch alarms * * @default - Alarms are created */ - readonly createCloudWatchAlarms?: boolean, + readonly createCloudWatchAlarms?: boolean; /** * User provided props to override the default props for the CloudWatchLogs LogGroup. * * @default - Default props are used */ - readonly logGroupProps?: logs.LogGroupProps + readonly logGroupProps?: logs.LogGroupProps; } export class EventbridgeToStepfunctions extends Construct { @@ -56,6 +68,7 @@ export class EventbridgeToStepfunctions extends Construct { public readonly stateMachineLogGroup: logs.ILogGroup; public readonly eventsRule: events.Rule; public readonly cloudwatchAlarms?: cloudwatch.Alarm[]; + public readonly eventBus?: events.IEventBus; /** * @summary Constructs a new instance of the EventbridgeToStepfunctions class. @@ -88,8 +101,14 @@ export class EventbridgeToStepfunctions extends Construct { }) }; + // build an event bus if existingEventBus is provided or eventBusProps are provided + this.eventBus = defaults.buildEventBus(this, { + existingEventBusInterface: props.existingEventBusInterface, + eventBusProps: props.eventBusProps + }); + // Defaults props for the Events - const defaultEventsRuleProps = defaults.DefaultEventsRuleProps([stateMachine]); + const defaultEventsRuleProps = defaults.DefaultEventsRuleProps([stateMachine], this.eventBus); // Override the defaults with the user provided props const eventsRuleProps = overrideProps(defaultEventsRuleProps, props.eventRuleProps, true); // Create the Events Rule for the State Machine diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/__snapshots__/eventbridge-stepfunctions.test.js.snap b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/__snapshots__/eventbridge-stepfunctions.test.js.snap index 62c363444..2693f0507 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/__snapshots__/eventbridge-stepfunctions.test.js.snap +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/__snapshots__/eventbridge-stepfunctions.test.js.snap @@ -1,5 +1,868 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`check eventbus property, snapshot & eventbus exists 1`] = ` +Object { + "Resources": Object { + "testeventbridgestepfunctionseventbusCustomEventBus543EEB31": Object { + "Properties": Object { + "Name": "testeventbridgestepfunctionseventbusCustomEventBus1261A8B4", + }, + "Type": "AWS::Events::EventBus", + }, + "testeventbridgestepfunctionseventbusEventsRuleA633C307": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testeventbridgestepfunctionseventbusCustomEventBus543EEB31", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Ref": "testeventbridgestepfunctionseventbusStateMachineECEE5C4A", + }, + "Id": "Target0", + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testeventbridgestepfunctionseventbusEventsRuleRoleA8F42A12", + "Arn", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testeventbridgestepfunctionseventbusEventsRuleRoleA8F42A12": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testeventbridgestepfunctionseventbusEventsRuleRoleDefaultPolicyB510931A": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": Object { + "Ref": "testeventbridgestepfunctionseventbusStateMachineECEE5C4A", + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testeventbridgestepfunctionseventbusEventsRuleRoleDefaultPolicyB510931A", + "Roles": Array [ + Object { + "Ref": "testeventbridgestepfunctionseventbusEventsRuleRoleA8F42A12", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testeventbridgestepfunctionseventbusExecutionAbortedAlarm7A3F86E8": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testeventbridgestepfunctionseventbusStateMachineECEE5C4A", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testeventbridgestepfunctionseventbusExecutionFailedAlarmB2601715": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testeventbridgestepfunctionseventbusStateMachineECEE5C4A", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testeventbridgestepfunctionseventbusExecutionThrottledAlarm2C8AB2F2": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testeventbridgestepfunctionseventbusStateMachineECEE5C4A", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testeventbridgestepfunctionseventbusStateMachineECEE5C4A": Object { + "DependsOn": Array [ + "testeventbridgestepfunctionseventbusStateMachineRoleDefaultPolicyCC309240", + "testeventbridgestepfunctionseventbusStateMachineRoleC63D8370", + ], + "Properties": Object { + "DefinitionString": "{\\"StartAt\\":\\"StartState\\",\\"States\\":{\\"StartState\\":{\\"Type\\":\\"Pass\\",\\"End\\":true}}}", + "LoggingConfiguration": Object { + "Destinations": Array [ + Object { + "CloudWatchLogsLogGroup": Object { + "LogGroupArn": Object { + "Fn::GetAtt": Array [ + "testeventbridgestepfunctionseventbusStateMachineLogGroupF3B6B238", + "Arn", + ], + }, + }, + }, + ], + "Level": "ERROR", + }, + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testeventbridgestepfunctionseventbusStateMachineRoleC63D8370", + "Arn", + ], + }, + }, + "Type": "AWS::StepFunctions::StateMachine", + }, + "testeventbridgestepfunctionseventbusStateMachineLogGroupF3B6B238": Object { + "DeletionPolicy": "Retain", + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely", + }, + Object { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)", + }, + ], + }, + }, + "Properties": Object { + "LogGroupName": "/aws/vendedlogs/states/defaulttesteventbridgestepfunctionseventbusstatemachinelog3ade1833cd96", + }, + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + }, + "testeventbridgestepfunctionseventbusStateMachineRoleC63D8370": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": Object { + "Fn::Join": Array [ + "", + Array [ + "states.", + Object { + "Ref": "AWS::Region", + }, + ".amazonaws.com", + ], + ], + }, + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testeventbridgestepfunctionseventbusStateMachineRoleDefaultPolicyCC309240": Object { + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations", + }, + ], + }, + }, + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries", + ], + "Effect": "Allow", + "Resource": "*", + }, + Object { + "Action": Array [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":logs:", + Object { + "Ref": "AWS::Region", + }, + ":", + Object { + "Ref": "AWS::AccountId", + }, + ":*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testeventbridgestepfunctionseventbusStateMachineRoleDefaultPolicyCC309240", + "Roles": Array [ + Object { + "Ref": "testeventbridgestepfunctionseventbusStateMachineRoleC63D8370", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + }, +} +`; + +exports[`check multiple constructs in a single stack 1`] = ` +Object { + "Resources": Object { + "testneweventbridgestepfunctions1CustomEventBus3267BF12": Object { + "Properties": Object { + "Name": "testneweventbridgestepfunctions1CustomEventBusFDAEC555", + }, + "Type": "AWS::Events::EventBus", + }, + "testneweventbridgestepfunctions1EventsRule75C4711B": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testneweventbridgestepfunctions1CustomEventBus3267BF12", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Ref": "testneweventbridgestepfunctions1StateMachine79D48A86", + }, + "Id": "Target0", + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testneweventbridgestepfunctions1EventsRuleRole6CAB7254", + "Arn", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testneweventbridgestepfunctions1EventsRuleRole6CAB7254": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testneweventbridgestepfunctions1EventsRuleRoleDefaultPolicy699CFB6B": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": Object { + "Ref": "testneweventbridgestepfunctions1StateMachine79D48A86", + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testneweventbridgestepfunctions1EventsRuleRoleDefaultPolicy699CFB6B", + "Roles": Array [ + Object { + "Ref": "testneweventbridgestepfunctions1EventsRuleRole6CAB7254", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testneweventbridgestepfunctions1ExecutionAbortedAlarm1221BC23": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventbridgestepfunctions1StateMachine79D48A86", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventbridgestepfunctions1ExecutionFailedAlarm78F34B69": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventbridgestepfunctions1StateMachine79D48A86", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventbridgestepfunctions1ExecutionThrottledAlarm835AE392": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventbridgestepfunctions1StateMachine79D48A86", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventbridgestepfunctions1StateMachine79D48A86": Object { + "DependsOn": Array [ + "testneweventbridgestepfunctions1StateMachineRoleDefaultPolicy5A42DEA7", + "testneweventbridgestepfunctions1StateMachineRoleE21F8DEE", + ], + "Properties": Object { + "DefinitionString": "{\\"StartAt\\":\\"StartState1\\",\\"States\\":{\\"StartState1\\":{\\"Type\\":\\"Pass\\",\\"End\\":true}}}", + "LoggingConfiguration": Object { + "Destinations": Array [ + Object { + "CloudWatchLogsLogGroup": Object { + "LogGroupArn": Object { + "Fn::GetAtt": Array [ + "testneweventbridgestepfunctions1StateMachineLogGroup4E3B02FA", + "Arn", + ], + }, + }, + }, + ], + "Level": "ERROR", + }, + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testneweventbridgestepfunctions1StateMachineRoleE21F8DEE", + "Arn", + ], + }, + }, + "Type": "AWS::StepFunctions::StateMachine", + }, + "testneweventbridgestepfunctions1StateMachineLogGroup4E3B02FA": Object { + "DeletionPolicy": "Retain", + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely", + }, + Object { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)", + }, + ], + }, + }, + "Properties": Object { + "LogGroupName": "/aws/vendedlogs/states/defaulttestneweventbridgestepfunctions1statemachinelog97c1ffa93355", + }, + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + }, + "testneweventbridgestepfunctions1StateMachineRoleDefaultPolicy5A42DEA7": Object { + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations", + }, + ], + }, + }, + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries", + ], + "Effect": "Allow", + "Resource": "*", + }, + Object { + "Action": Array [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":logs:", + Object { + "Ref": "AWS::Region", + }, + ":", + Object { + "Ref": "AWS::AccountId", + }, + ":*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testneweventbridgestepfunctions1StateMachineRoleDefaultPolicy5A42DEA7", + "Roles": Array [ + Object { + "Ref": "testneweventbridgestepfunctions1StateMachineRoleE21F8DEE", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testneweventbridgestepfunctions1StateMachineRoleE21F8DEE": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": Object { + "Fn::Join": Array [ + "", + Array [ + "states.", + Object { + "Ref": "AWS::Region", + }, + ".amazonaws.com", + ], + ], + }, + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testneweventbridgestepfunctions2CustomEventBusA77E5098": Object { + "Properties": Object { + "Name": "testneweventbridgestepfunctions2CustomEventBusDA330C9F", + }, + "Type": "AWS::Events::EventBus", + }, + "testneweventbridgestepfunctions2EventsRule8926D086": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testneweventbridgestepfunctions2CustomEventBusA77E5098", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Ref": "testneweventbridgestepfunctions2StateMachineAD0DC5E7", + }, + "Id": "Target0", + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testneweventbridgestepfunctions2EventsRuleRole6E867C4F", + "Arn", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testneweventbridgestepfunctions2EventsRuleRole6E867C4F": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testneweventbridgestepfunctions2EventsRuleRoleDefaultPolicy812687BD": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": Object { + "Ref": "testneweventbridgestepfunctions2StateMachineAD0DC5E7", + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testneweventbridgestepfunctions2EventsRuleRoleDefaultPolicy812687BD", + "Roles": Array [ + Object { + "Ref": "testneweventbridgestepfunctions2EventsRuleRole6E867C4F", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testneweventbridgestepfunctions2ExecutionAbortedAlarm738FE6FC": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventbridgestepfunctions2StateMachineAD0DC5E7", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventbridgestepfunctions2ExecutionFailedAlarm4DFA599B": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventbridgestepfunctions2StateMachineAD0DC5E7", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventbridgestepfunctions2ExecutionThrottledAlarm03E964B2": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventbridgestepfunctions2StateMachineAD0DC5E7", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventbridgestepfunctions2StateMachineAD0DC5E7": Object { + "DependsOn": Array [ + "testneweventbridgestepfunctions2StateMachineRoleDefaultPolicy46E34E47", + "testneweventbridgestepfunctions2StateMachineRoleA4B88ACC", + ], + "Properties": Object { + "DefinitionString": "{\\"StartAt\\":\\"StartState2\\",\\"States\\":{\\"StartState2\\":{\\"Type\\":\\"Pass\\",\\"End\\":true}}}", + "LoggingConfiguration": Object { + "Destinations": Array [ + Object { + "CloudWatchLogsLogGroup": Object { + "LogGroupArn": Object { + "Fn::GetAtt": Array [ + "testneweventbridgestepfunctions2StateMachineLogGroupC4B1019B", + "Arn", + ], + }, + }, + }, + ], + "Level": "ERROR", + }, + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testneweventbridgestepfunctions2StateMachineRoleA4B88ACC", + "Arn", + ], + }, + }, + "Type": "AWS::StepFunctions::StateMachine", + }, + "testneweventbridgestepfunctions2StateMachineLogGroupC4B1019B": Object { + "DeletionPolicy": "Retain", + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely", + }, + Object { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)", + }, + ], + }, + }, + "Properties": Object { + "LogGroupName": "/aws/vendedlogs/states/defaulttestneweventbridgestepfunctions2statemachinelogfb5fb852e9ef", + }, + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + }, + "testneweventbridgestepfunctions2StateMachineRoleA4B88ACC": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": Object { + "Fn::Join": Array [ + "", + Array [ + "states.", + Object { + "Ref": "AWS::Region", + }, + ".amazonaws.com", + ], + ], + }, + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testneweventbridgestepfunctions2StateMachineRoleDefaultPolicy46E34E47": Object { + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations", + }, + ], + }, + }, + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries", + ], + "Effect": "Allow", + "Resource": "*", + }, + Object { + "Action": Array [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":logs:", + Object { + "Ref": "AWS::Region", + }, + ":", + Object { + "Ref": "AWS::AccountId", + }, + ":*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testneweventbridgestepfunctions2StateMachineRoleDefaultPolicy46E34E47", + "Roles": Array [ + Object { + "Ref": "testneweventbridgestepfunctions2StateMachineRoleA4B88ACC", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + }, +} +`; + exports[`snapshot test EventbridgeToStepfunctions default params 1`] = ` Object { "Resources": Object { @@ -276,3 +1139,293 @@ Object { }, } `; + +exports[`snapshot test EventbridgeToStepfunctions existing event bus params 1`] = ` +Object { + "Resources": Object { + "testexistingeventbridgestepfunctionsEventsRuleA20DE119": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testexistingneweventbusB9898D2B", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Ref": "testexistingeventbridgestepfunctionsStateMachine86B15A44", + }, + "Id": "Target0", + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testexistingeventbridgestepfunctionsEventsRuleRole27A71B6C", + "Arn", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testexistingeventbridgestepfunctionsEventsRuleRole27A71B6C": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testexistingeventbridgestepfunctionsEventsRuleRoleDefaultPolicy8EC02AA4": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": Object { + "Ref": "testexistingeventbridgestepfunctionsStateMachine86B15A44", + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testexistingeventbridgestepfunctionsEventsRuleRoleDefaultPolicy8EC02AA4", + "Roles": Array [ + Object { + "Ref": "testexistingeventbridgestepfunctionsEventsRuleRole27A71B6C", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testexistingeventbridgestepfunctionsExecutionAbortedAlarmBE39DD0B": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testexistingeventbridgestepfunctionsStateMachine86B15A44", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testexistingeventbridgestepfunctionsExecutionFailedAlarm1375C3D6": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testexistingeventbridgestepfunctionsStateMachine86B15A44", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testexistingeventbridgestepfunctionsExecutionThrottledAlarm9180B0CE": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testexistingeventbridgestepfunctionsStateMachine86B15A44", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testexistingeventbridgestepfunctionsStateMachine86B15A44": Object { + "DependsOn": Array [ + "testexistingeventbridgestepfunctionsStateMachineRoleDefaultPolicy37FA170E", + "testexistingeventbridgestepfunctionsStateMachineRole43DDAE0D", + ], + "Properties": Object { + "DefinitionString": "{\\"StartAt\\":\\"StartState\\",\\"States\\":{\\"StartState\\":{\\"Type\\":\\"Pass\\",\\"End\\":true}}}", + "LoggingConfiguration": Object { + "Destinations": Array [ + Object { + "CloudWatchLogsLogGroup": Object { + "LogGroupArn": Object { + "Fn::GetAtt": Array [ + "testexistingeventbridgestepfunctionsStateMachineLogGroup491A5CAE", + "Arn", + ], + }, + }, + }, + ], + "Level": "ERROR", + }, + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testexistingeventbridgestepfunctionsStateMachineRole43DDAE0D", + "Arn", + ], + }, + }, + "Type": "AWS::StepFunctions::StateMachine", + }, + "testexistingeventbridgestepfunctionsStateMachineLogGroup491A5CAE": Object { + "DeletionPolicy": "Retain", + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely", + }, + Object { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)", + }, + ], + }, + }, + "Properties": Object { + "LogGroupName": "/aws/vendedlogs/states/defaulttestexistingeventbridgestepfunctionsstatemachinelog9db3ac073f4e", + }, + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + }, + "testexistingeventbridgestepfunctionsStateMachineRole43DDAE0D": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": Object { + "Fn::Join": Array [ + "", + Array [ + "states.", + Object { + "Ref": "AWS::Region", + }, + ".amazonaws.com", + ], + ], + }, + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testexistingeventbridgestepfunctionsStateMachineRoleDefaultPolicy37FA170E": Object { + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations", + }, + ], + }, + }, + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries", + ], + "Effect": "Allow", + "Resource": "*", + }, + Object { + "Action": Array [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":logs:", + Object { + "Ref": "AWS::Region", + }, + ":", + Object { + "Ref": "AWS::AccountId", + }, + ":*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testexistingeventbridgestepfunctionsStateMachineRoleDefaultPolicy37FA170E", + "Roles": Array [ + Object { + "Ref": "testexistingeventbridgestepfunctionsStateMachineRole43DDAE0D", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testexistingneweventbusB9898D2B": Object { + "Properties": Object { + "Name": "testexistingneweventbus", + }, + "Type": "AWS::Events::EventBus", + }, + }, +} +`; diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/eventbridge-stepfunctions.test.ts b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/eventbridge-stepfunctions.test.ts index 5ac45de0c..c0de3bd61 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/eventbridge-stepfunctions.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/eventbridge-stepfunctions.test.ts @@ -35,6 +35,25 @@ function deployNewStateMachine(stack: cdk.Stack) { return new EventbridgeToStepfunctions(stack, 'test-eventbridge-stepfunctions', props); } +function deployNewStateMachineAndEventBus(stack: cdk.Stack) { + + const startState = new sfn.Pass(stack, 'StartState'); + + const props: EventbridgeToStepfunctionsProps = { + stateMachineProps: { + definition: startState + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {} + }; + + return new EventbridgeToStepfunctions(stack, 'test-eventbridge-stepfunctions-eventbus', props); +} + test('snapshot test EventbridgeToStepfunctions default params', () => { const stack = new cdk.Stack(); deployNewStateMachine(stack); @@ -118,4 +137,125 @@ test('check properties with no CW Alarms', () => { expect(construct.stateMachine !== null); expect(construct.eventsRule !== null); expect(construct.stateMachineLogGroup !== null); +}); + +test('check eventbus property, snapshot & eventbus exists', () => { + const stack = new cdk.Stack(); + + const construct: EventbridgeToStepfunctions = deployNewStateMachineAndEventBus(stack); + + expect(construct.cloudwatchAlarms !== null); + expect(construct.stateMachine !== null); + expect(construct.eventsRule !== null); + expect(construct.stateMachineLogGroup !== null); + expect(construct.eventBus !== null); + + // Validate snapshot + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); + // Check whether eventbus exists + expect(stack).toHaveResource('AWS::Events::EventBus'); +}); + +test('check exception while passing existingEventBus & eventBusProps', () => { + const stack = new cdk.Stack(); + const startState = new sfn.Pass(stack, 'StartState'); + + const props: EventbridgeToStepfunctionsProps = { + stateMachineProps: { + definition: startState + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {}, + existingEventBusInterface: new events.EventBus(stack, `test-existing-new-eventbus`, {}) + }; + + try { + new EventbridgeToStepfunctions(stack, 'test-eventbridge-stepfunctions', props); + } catch (e) { + expect(e).toBeInstanceOf(Error); + } +}); + +test('snapshot test EventbridgeToStepfunctions existing event bus params', () => { + const stack = new cdk.Stack(); + const startState = new sfn.Pass(stack, 'StartState'); + + const props: EventbridgeToStepfunctionsProps = { + stateMachineProps: { + definition: startState + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {}, + existingEventBusInterface: new events.EventBus(stack, `test-existing-new-eventbus`, {}) + }; + + new EventbridgeToStepfunctions(stack, 'test-existing-eventbridge-stepfunctions', props); + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); +}); + +test('check custom event bus resource with props when deploy:true', () => { + const stack = new cdk.Stack(); + const startState = new sfn.Pass(stack, 'StartState'); + + const props: EventbridgeToStepfunctionsProps = { + stateMachineProps: { + definition: startState + }, + eventBusProps: { + eventBusName: 'testcustomeventbus' + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + } + }; + new EventbridgeToStepfunctions(stack, 'test-new-eventbridge-stepfunctions', props); + + expect(stack).toHaveResource('AWS::Events::EventBus', { + Name: 'testcustomeventbus' + }); +}); + +test('check multiple constructs in a single stack', () => { + const stack = new cdk.Stack(); + const startState1 = new sfn.Pass(stack, 'StartState1'); + + const props1: EventbridgeToStepfunctionsProps = { + stateMachineProps: { + definition: startState1 + }, + eventBusProps: {}, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + } + }; + + const startState2 = new sfn.Pass(stack, 'StartState2'); + + const props2: EventbridgeToStepfunctionsProps = { + stateMachineProps: { + definition: startState2 + }, + eventBusProps: {}, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + } + }; + new EventbridgeToStepfunctions(stack, 'test-new-eventbridge-stepfunctions1', props1); + new EventbridgeToStepfunctions(stack, 'test-new-eventbridge-stepfunctions2', props2); + + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); }); \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-existing-eventbus.expected.json b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-existing-eventbus.expected.json new file mode 100644 index 000000000..2a54b78b7 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-existing-eventbus.expected.json @@ -0,0 +1,499 @@ +{ + "Resources": { + "LambdaFunctionServiceRole0C4CDE0B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/lambda/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "LambdaFunctionServiceRolePolicy" + } + ] + } + }, + "LambdaFunctionServiceRoleDefaultPolicy126C8897": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTraceSegments", + "xray:PutTelemetryRecords" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "LambdaFunctionServiceRoleDefaultPolicy126C8897", + "Roles": [ + { + "Ref": "LambdaFunctionServiceRole0C4CDE0B" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W12", + "reason": "Lambda needs the following minimum required permissions to send trace data to X-Ray and access ENIs in a VPC." + } + ] + } + } + }, + "LambdaFunctionBF21E41F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3Bucket1F467BCC" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872" + } + ] + } + ] + } + ] + ] + } + }, + "Role": { + "Fn::GetAtt": [ + "LambdaFunctionServiceRole0C4CDE0B", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "Handler": "index.handler", + "Runtime": "nodejs12.x", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "LambdaFunctionServiceRoleDefaultPolicy126C8897", + "LambdaFunctionServiceRole0C4CDE0B" + ], + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W58", + "reason": "Lambda functions has the required permission to write CloudWatch Logs. It uses custom policy instead of arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole with tighter permissions." + }, + { + "id": "W89", + "reason": "This is not a rule for the general case, just for specific use cases/industries" + }, + { + "id": "W92", + "reason": "Impossible for us to define the correct concurrency for clients" + } + ] + } + } + }, + "existingeventbusA5B80487": { + "Type": "AWS::Events::EventBus", + "Properties": { + "Name": "eventbridgestepfunctionsexistingeventbusexistingeventbusDB14A441" + } + }, + "testeventbridgestepfunctionsneweventbusconstructStateMachineLogGroup6DC6AD59": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "LogGroupName": "/aws/vendedlogs/states/eventbridgestepfunctionsexistingeventbustesteventbridgestepfunctionsneweventbusconstructstatemachinelogac9442d7e2fa" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete", + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely" + }, + { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)" + } + ] + } + } + }, + "testeventbridgestepfunctionsneweventbusconstructStateMachineRole88F30AE1": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "states.", + { + "Ref": "AWS::Region" + }, + ".amazonaws.com" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "testeventbridgestepfunctionsneweventbusconstructStateMachineRoleDefaultPolicy24AE094F": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries" + ], + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + } + }, + { + "Action": [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "testeventbridgestepfunctionsneweventbusconstructStateMachineRoleDefaultPolicy24AE094F", + "Roles": [ + { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachineRole88F30AE1" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations" + } + ] + } + } + }, + "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "RoleArn": { + "Fn::GetAtt": [ + "testeventbridgestepfunctionsneweventbusconstructStateMachineRole88F30AE1", + "Arn" + ] + }, + "DefinitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"StartState\",\"States\":{\"StartState\":{\"Type\":\"Pass\",\"Next\":\"LambdaTask\"},\"LambdaTask\":{\"End\":true,\"Retry\":[{\"ErrorEquals\":[\"Lambda.ServiceException\",\"Lambda.AWSLambdaException\",\"Lambda.SdkClientException\"],\"IntervalSeconds\":2,\"MaxAttempts\":6,\"BackoffRate\":2}],\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::lambda:invoke\",\"Parameters\":{\"FunctionName\":\"", + { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + }, + "\",\"Payload.$\":\"$\"}}},\"TimeoutSeconds\":300}" + ] + ] + }, + "LoggingConfiguration": { + "Destinations": [ + { + "CloudWatchLogsLogGroup": { + "LogGroupArn": { + "Fn::GetAtt": [ + "testeventbridgestepfunctionsneweventbusconstructStateMachineLogGroup6DC6AD59", + "Arn" + ] + } + } + } + ], + "Level": "ERROR" + } + }, + "DependsOn": [ + "testeventbridgestepfunctionsneweventbusconstructStateMachineRoleDefaultPolicy24AE094F", + "testeventbridgestepfunctionsneweventbusconstructStateMachineRole88F30AE1" + ] + }, + "testeventbridgestepfunctionsneweventbusconstructEventsRuleRoleA589CEFC": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "testeventbridgestepfunctionsneweventbusconstructEventsRuleRoleDefaultPolicyDEB2E89C": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609" + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "testeventbridgestepfunctionsneweventbusconstructEventsRuleRoleDefaultPolicyDEB2E89C", + "Roles": [ + { + "Ref": "testeventbridgestepfunctionsneweventbusconstructEventsRuleRoleA589CEFC" + } + ] + } + }, + "testeventbridgestepfunctionsneweventbusconstructEventsRule471B9F20": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventBusName": { + "Ref": "existingeventbusA5B80487" + }, + "EventPattern": { + "source": [ + "solutionsconstructs" + ] + }, + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609" + }, + "Id": "Target0", + "RoleArn": { + "Fn::GetAtt": [ + "testeventbridgestepfunctionsneweventbusconstructEventsRuleRoleA589CEFC", + "Arn" + ] + } + } + ] + } + }, + "testeventbridgestepfunctionsneweventbusconstructExecutionFailedAlarmF5234856": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609" + } + } + ], + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1 + } + }, + "testeventbridgestepfunctionsneweventbusconstructExecutionThrottledAlarm08AFD5C8": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609" + } + } + ], + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1 + } + }, + "testeventbridgestepfunctionsneweventbusconstructExecutionAbortedAlarmAA68F975": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609" + } + } + ], + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1 + } + } + }, + "Parameters": { + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3Bucket1F467BCC": { + "Type": "String", + "Description": "S3 bucket for asset \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + }, + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872": { + "Type": "String", + "Description": "S3 key for asset version \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + }, + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cArtifactHash00A70A91": { + "Type": "String", + "Description": "Artifact hash for asset \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + } + } +} \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-existing-eventbus.ts b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-existing-eventbus.ts new file mode 100644 index 000000000..00c0f626b --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-existing-eventbus.ts @@ -0,0 +1,58 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +/// !cdk-integ * +import { App, Stack, RemovalPolicy } from "@aws-cdk/core"; +import { EventbridgeToStepfunctions, EventbridgeToStepfunctionsProps } from "../lib"; +import { Duration } from '@aws-cdk/core'; +import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; +import * as lambda from '@aws-cdk/aws-lambda'; +import { deployLambdaFunction } from '@aws-solutions-constructs/core'; +import * as stepfunctions from '@aws-cdk/aws-stepfunctions'; +import { generateIntegStackName } from '@aws-solutions-constructs/core'; +import { EventBus } from "@aws-cdk/aws-events"; + +const app = new App(); +const stack = new Stack(app, generateIntegStackName(__filename)); + +const submitLambda = deployLambdaFunction(stack, { + runtime: lambda.Runtime.NODEJS_12_X, + code: lambda.Code.fromAsset(`${__dirname}/lambda`), + handler: 'index.handler' +}); + +const submitJob = new tasks.LambdaInvoke(stack, 'LambdaTask', { + lambdaFunction: submitLambda +}); +const startState = new stepfunctions.Pass(stack, 'StartState'); +startState.next(submitJob); + +const existingEventBus = new EventBus(stack, `existing-event-bus`, {}); +const props: EventbridgeToStepfunctionsProps = { + stateMachineProps: { + definition: startState, + timeout: Duration.minutes(5) + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + existingEventBusInterface: existingEventBus, + logGroupProps: { + removalPolicy: RemovalPolicy.DESTROY + }, +}; + +new EventbridgeToStepfunctions(stack, 'test-eventbridge-stepfunctions-new-eventbus-construct', props); +app.synth(); diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-new-eventbus.expected.json b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-new-eventbus.expected.json new file mode 100644 index 000000000..ad889f8fc --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-new-eventbus.expected.json @@ -0,0 +1,499 @@ +{ + "Resources": { + "LambdaFunctionServiceRole0C4CDE0B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/lambda/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "LambdaFunctionServiceRolePolicy" + } + ] + } + }, + "LambdaFunctionServiceRoleDefaultPolicy126C8897": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTraceSegments", + "xray:PutTelemetryRecords" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "LambdaFunctionServiceRoleDefaultPolicy126C8897", + "Roles": [ + { + "Ref": "LambdaFunctionServiceRole0C4CDE0B" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W12", + "reason": "Lambda needs the following minimum required permissions to send trace data to X-Ray and access ENIs in a VPC." + } + ] + } + } + }, + "LambdaFunctionBF21E41F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3Bucket1F467BCC" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872" + } + ] + } + ] + } + ] + ] + } + }, + "Role": { + "Fn::GetAtt": [ + "LambdaFunctionServiceRole0C4CDE0B", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "Handler": "index.handler", + "Runtime": "nodejs12.x", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "LambdaFunctionServiceRoleDefaultPolicy126C8897", + "LambdaFunctionServiceRole0C4CDE0B" + ], + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W58", + "reason": "Lambda functions has the required permission to write CloudWatch Logs. It uses custom policy instead of arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole with tighter permissions." + }, + { + "id": "W89", + "reason": "This is not a rule for the general case, just for specific use cases/industries" + }, + { + "id": "W92", + "reason": "Impossible for us to define the correct concurrency for clients" + } + ] + } + } + }, + "testeventbridgestepfunctionsneweventbusconstructStateMachineLogGroup6DC6AD59": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "LogGroupName": "/aws/vendedlogs/states/eventbridgestepfunctionsneweventbustesteventbridgestepfunctionsneweventbusconstructstatemachinelog651032919fdf" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete", + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely" + }, + { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)" + } + ] + } + } + }, + "testeventbridgestepfunctionsneweventbusconstructStateMachineRole88F30AE1": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "states.", + { + "Ref": "AWS::Region" + }, + ".amazonaws.com" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "testeventbridgestepfunctionsneweventbusconstructStateMachineRoleDefaultPolicy24AE094F": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries" + ], + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + } + }, + { + "Action": [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "testeventbridgestepfunctionsneweventbusconstructStateMachineRoleDefaultPolicy24AE094F", + "Roles": [ + { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachineRole88F30AE1" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations" + } + ] + } + } + }, + "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "RoleArn": { + "Fn::GetAtt": [ + "testeventbridgestepfunctionsneweventbusconstructStateMachineRole88F30AE1", + "Arn" + ] + }, + "DefinitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"StartState\",\"States\":{\"StartState\":{\"Type\":\"Pass\",\"Next\":\"LambdaTask\"},\"LambdaTask\":{\"End\":true,\"Retry\":[{\"ErrorEquals\":[\"Lambda.ServiceException\",\"Lambda.AWSLambdaException\",\"Lambda.SdkClientException\"],\"IntervalSeconds\":2,\"MaxAttempts\":6,\"BackoffRate\":2}],\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::lambda:invoke\",\"Parameters\":{\"FunctionName\":\"", + { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + }, + "\",\"Payload.$\":\"$\"}}},\"TimeoutSeconds\":300}" + ] + ] + }, + "LoggingConfiguration": { + "Destinations": [ + { + "CloudWatchLogsLogGroup": { + "LogGroupArn": { + "Fn::GetAtt": [ + "testeventbridgestepfunctionsneweventbusconstructStateMachineLogGroup6DC6AD59", + "Arn" + ] + } + } + } + ], + "Level": "ERROR" + } + }, + "DependsOn": [ + "testeventbridgestepfunctionsneweventbusconstructStateMachineRoleDefaultPolicy24AE094F", + "testeventbridgestepfunctionsneweventbusconstructStateMachineRole88F30AE1" + ] + }, + "testeventbridgestepfunctionsneweventbusconstructEventsRuleRoleA589CEFC": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "testeventbridgestepfunctionsneweventbusconstructEventsRuleRoleDefaultPolicyDEB2E89C": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609" + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "testeventbridgestepfunctionsneweventbusconstructEventsRuleRoleDefaultPolicyDEB2E89C", + "Roles": [ + { + "Ref": "testeventbridgestepfunctionsneweventbusconstructEventsRuleRoleA589CEFC" + } + ] + } + }, + "testeventbridgestepfunctionsneweventbusconstructCustomEventBusB298D5B4": { + "Type": "AWS::Events::EventBus", + "Properties": { + "Name": "eventbridgestepfunctionsneweventbustesteventbridgestepfunctionsneweventbusconstructCustomEventBus19132B7D" + } + }, + "testeventbridgestepfunctionsneweventbusconstructEventsRule471B9F20": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventBusName": { + "Ref": "testeventbridgestepfunctionsneweventbusconstructCustomEventBusB298D5B4" + }, + "EventPattern": { + "source": [ + "solutionsconstructs" + ] + }, + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609" + }, + "Id": "Target0", + "RoleArn": { + "Fn::GetAtt": [ + "testeventbridgestepfunctionsneweventbusconstructEventsRuleRoleA589CEFC", + "Arn" + ] + } + } + ] + } + }, + "testeventbridgestepfunctionsneweventbusconstructExecutionFailedAlarmF5234856": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609" + } + } + ], + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1 + } + }, + "testeventbridgestepfunctionsneweventbusconstructExecutionThrottledAlarm08AFD5C8": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609" + } + } + ], + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1 + } + }, + "testeventbridgestepfunctionsneweventbusconstructExecutionAbortedAlarmAA68F975": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventbridgestepfunctionsneweventbusconstructStateMachine5B0C5609" + } + } + ], + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1 + } + } + }, + "Parameters": { + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3Bucket1F467BCC": { + "Type": "String", + "Description": "S3 bucket for asset \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + }, + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872": { + "Type": "String", + "Description": "S3 key for asset version \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + }, + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cArtifactHash00A70A91": { + "Type": "String", + "Description": "Artifact hash for asset \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + } + } +} \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-new-eventbus.ts b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-new-eventbus.ts new file mode 100644 index 000000000..dddbc179c --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-stepfunctions/test/integ.eventbridge-stepfunctions-new-eventbus.ts @@ -0,0 +1,56 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +/// !cdk-integ * +import { App, Stack, RemovalPolicy } from "@aws-cdk/core"; +import { EventbridgeToStepfunctions, EventbridgeToStepfunctionsProps } from "../lib"; +import { Duration } from '@aws-cdk/core'; +import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; +import * as lambda from '@aws-cdk/aws-lambda'; +import { deployLambdaFunction } from '@aws-solutions-constructs/core'; +import * as stepfunctions from '@aws-cdk/aws-stepfunctions'; +import { generateIntegStackName } from '@aws-solutions-constructs/core'; + +const app = new App(); +const stack = new Stack(app, generateIntegStackName(__filename)); + +const submitLambda = deployLambdaFunction(stack, { + runtime: lambda.Runtime.NODEJS_12_X, + code: lambda.Code.fromAsset(`${__dirname}/lambda`), + handler: 'index.handler' +}); + +const submitJob = new tasks.LambdaInvoke(stack, 'LambdaTask', { + lambdaFunction: submitLambda +}); +const startState = new stepfunctions.Pass(stack, 'StartState'); +startState.next(submitJob); + +const props: EventbridgeToStepfunctionsProps = { + stateMachineProps: { + definition: startState, + timeout: Duration.minutes(5) + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {}, + logGroupProps: { + removalPolicy: RemovalPolicy.DESTROY + }, +}; + +new EventbridgeToStepfunctions(stack, 'test-eventbridge-stepfunctions-new-eventbus-construct', props); +app.synth(); diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-lambda/README.md b/source/patterns/@aws-solutions-constructs/aws-events-rule-lambda/README.md index a4ca1110f..00f9e3618 100644 --- a/source/patterns/@aws-solutions-constructs/aws-events-rule-lambda/README.md +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-lambda/README.md @@ -71,7 +71,7 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| -|eventBus|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| +|eventBus?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| |eventsRule|[`events.Rule`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.Rule.html)|Returns an instance of events.Rule created by the construct| |lambdaFunction|[`lambda.Function`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-lambda.Function.html)|Returns an instance of lambda.Function created by the construct| diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-sns/README.md b/source/patterns/@aws-solutions-constructs/aws-events-rule-sns/README.md index 51986af1e..7d4b3836d 100644 --- a/source/patterns/@aws-solutions-constructs/aws-events-rule-sns/README.md +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-sns/README.md @@ -81,7 +81,7 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| -|eventBus|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| +|eventBus?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| |eventsRule|[`events.Rule`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.Rule.html)|Returns an instance of events.Rule created by the construct| |snsTopic|[`sns.Topic`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-sns.Topic.html)|Returns an instance of sns.Topic created by the construct| |encryptionKey?|[`kms.Key`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-kms.Key.html)|Returns an instance of kms Key used for the SNS Topic.| diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/README.md b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/README.md index 48e76fcfc..17b49af5b 100644 --- a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/README.md +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/README.md @@ -69,6 +69,8 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| +|existingEventBusInterface?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)| Optional user-provided custom EventBus for construct to use. Providing both this and `eventBusProps` results an error.| +|eventBusProps?|[`events.EventBusProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.EventBusProps.html)|Optional user-provided properties to override the default properties when creating a custom EventBus. Setting this value to `{}` will create a custom EventBus using all default properties. If neither this nor `existingEventBusInterface` is provided the construct will use the `default` EventBus. Providing both this and `existingEventBusInterface` results an error.| |eventRuleProps|[`events.RuleProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.RuleProps.html)|User provided eventRuleProps to override the defaults. | |existingQueueObj?|[`sqs.Queue`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-sqs.Queue.html)|An optional, existing SQS queue to be used instead of the default queue. Providing both this and `queueProps` will cause an error.| |queueProps?|[`sqs.QueueProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-sqs.QueueProps.html)|User provided props to override the default props for the SQS Queue. | @@ -84,6 +86,7 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| +|eventBus?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| |eventsRule|[`events.Rule`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.Rule.html)|Returns an instance of events.Rule created by the construct| |sqsQueue|[`sqs.Queue`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-sqs.Queue.html)|Returns an instance of sqs.Queue created by the construct| |encryptionKey?|[`kms.Key`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-kms.Key.html)|Returns an instance of kms Key used for the SQS queue.| diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/lib/index.ts index 5a392b944..20c20f1d8 100644 --- a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/lib/index.ts @@ -22,67 +22,79 @@ import { EventbridgeToSqs } from '@aws-solutions-constructs/aws-eventbridge-sqs' * @summary The properties for the EventsRuleToSqs Construct */ export interface EventsRuleToSqsProps { + /** + * Existing instance of a custom EventBus. + * + * @default - None + */ + readonly existingEventBusInterface?: events.IEventBus; + /** + * A new custom EventBus is created with provided props. + * + * @default - None + */ + readonly eventBusProps?: events.EventBusProps; /** * User provided eventRuleProps to override the defaults * * @default - None */ - readonly eventRuleProps: events.RuleProps + readonly eventRuleProps: events.RuleProps; /** * Existing instance of SQS queue object, providing both this and queueProps will cause an error. * * @default - None */ - readonly existingQueueObj?: sqs.Queue, + readonly existingQueueObj?: sqs.Queue; /** * User provided props to override the default props for the SQS queue. * * @default - Default props are used */ - readonly queueProps?: sqs.QueueProps, + readonly queueProps?: sqs.QueueProps; /** * Whether to grant additional permissions to the Lambda function enabling it to purge the SQS queue. * * @default - "false", disabled by default. */ - readonly enableQueuePurging?: boolean, + readonly enableQueuePurging?: boolean; /** * Optional user provided properties for the dead letter queue * * @default - Default props are used */ - readonly deadLetterQueueProps?: sqs.QueueProps, + readonly deadLetterQueueProps?: sqs.QueueProps; /** * Whether to deploy a secondary queue to be used as a dead letter queue. * * @default - true. */ - readonly deployDeadLetterQueue?: boolean, + readonly deployDeadLetterQueue?: boolean; /** * The number of times a message can be unsuccessfully dequeued before being moved to the dead-letter queue. * * @default - required field if deployDeadLetterQueue=true. */ - readonly maxReceiveCount?: number, + readonly maxReceiveCount?: number; /** * Use a KMS Key, either managed by this CDK app, or imported. If importing an encryption key, it must be specified in * the encryptionKey property for this construct. * * @default - true (encryption enabled, managed by this CDK app). */ - readonly enableEncryptionWithCustomerManagedKey?: boolean + readonly enableEncryptionWithCustomerManagedKey?: boolean; /** * An optional, imported encryption key to encrypt the SQS queue, and SNS Topic. * * @default - not specified. */ - readonly encryptionKey?: kms.Key + readonly encryptionKey?: kms.Key; /** * Optional user-provided props to override the default props for the encryption key. * * @default - Default props are used. */ - readonly encryptionKeyProps?: kms.KeyProps + readonly encryptionKeyProps?: kms.KeyProps; } export class EventsRuleToSqs extends Construct { @@ -90,6 +102,7 @@ export class EventsRuleToSqs extends Construct { public readonly deadLetterQueue?: sqs.DeadLetterQueue; public readonly eventsRule: events.Rule; public readonly encryptionKey?: kms.IKey; + public readonly eventBus?: events.IEventBus; /** * @summary Constructs a new instance of the EventsRuleToSqs class. @@ -108,5 +121,6 @@ export class EventsRuleToSqs extends Construct { this.deadLetterQueue = wrappedConstruct.deadLetterQueue; this.eventsRule = wrappedConstruct.eventsRule; this.encryptionKey = wrappedConstruct.encryptionKey; + this.eventBus = wrappedConstruct.eventBus; } } \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/__snapshots__/events-rule-sqs-queue.test.js.snap b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/__snapshots__/events-rule-sqs-queue.test.js.snap index e0de163ba..4063f966f 100644 --- a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/__snapshots__/events-rule-sqs-queue.test.js.snap +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/__snapshots__/events-rule-sqs-queue.test.js.snap @@ -1,9 +1,1183 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`check eventbus property, snapshot & eventbus exists 1`] = ` +Object { + "Resources": Object { + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedCustomEventBus29FCEF5E": Object { + "Properties": Object { + "Name": "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedCustomEventBus7A98350A", + }, + "Type": "AWS::Events::EventBus", + }, + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedEncryptionKeyF5E6BEBF": Object { + "DeletionPolicy": "Retain", + "Properties": Object { + "EnableKeyRotation": true, + "KeyPolicy": Object { + "Statement": Array [ + Object { + "Action": Array [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": "*", + }, + Object { + "Action": Array [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": "*", + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::KMS::Key", + "UpdateReplacePolicy": "Retain", + }, + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedEventsRule06176ECD": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedCustomEventBus29FCEF5E", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedqueue9D5164C2", + "Arn", + ], + }, + "Id": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedqueue9D5164C2", + "QueueName", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappeddeadLetterQueue1A7A6517": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": "alias/aws/sqs", + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappeddeadLetterQueuePolicy975CA53B": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappeddeadLetterQueue1A7A6517", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappeddeadLetterQueue1A7A6517", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappeddeadLetterQueue1A7A6517", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedqueue9D5164C2": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedEncryptionKeyF5E6BEBF", + "Arn", + ], + }, + "RedrivePolicy": Object { + "deadLetterTargetArn": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappeddeadLetterQueue1A7A6517", + "Arn", + ], + }, + "maxReceiveCount": 15, + }, + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedqueuePolicyDFD135EE": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedqueue9D5164C2", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedqueue9D5164C2", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + Object { + "Action": Array [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedqueue9D5164C2", + "Arn", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testeventsrulesqsnewbustesteventsrulesqsnewbuswrappedqueue9D5164C2", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + }, +} +`; + +exports[`check multiple constructs in a single stack 1`] = ` +Object { + "Resources": Object { + "testneweventsrulesqs1testneweventsrulesqs1wrappedCustomEventBus9D02CFA6": Object { + "Properties": Object { + "Name": "testneweventsrulesqs1testneweventsrulesqs1wrappedCustomEventBusEC6121F4", + }, + "Type": "AWS::Events::EventBus", + }, + "testneweventsrulesqs1testneweventsrulesqs1wrappedEncryptionKey863D30E3": Object { + "DeletionPolicy": "Retain", + "Properties": Object { + "EnableKeyRotation": true, + "KeyPolicy": Object { + "Statement": Array [ + Object { + "Action": Array [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": "*", + }, + Object { + "Action": Array [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": "*", + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::KMS::Key", + "UpdateReplacePolicy": "Retain", + }, + "testneweventsrulesqs1testneweventsrulesqs1wrappedEventsRule016672B3": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testneweventsrulesqs1testneweventsrulesqs1wrappedCustomEventBus9D02CFA6", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs1testneweventsrulesqs1wrappedqueueD6E123E2", + "Arn", + ], + }, + "Id": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs1testneweventsrulesqs1wrappedqueueD6E123E2", + "QueueName", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testneweventsrulesqs1testneweventsrulesqs1wrappeddeadLetterQueueDBE8CACA": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": "alias/aws/sqs", + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testneweventsrulesqs1testneweventsrulesqs1wrappeddeadLetterQueuePolicy420A14F0": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs1testneweventsrulesqs1wrappeddeadLetterQueueDBE8CACA", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs1testneweventsrulesqs1wrappeddeadLetterQueueDBE8CACA", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testneweventsrulesqs1testneweventsrulesqs1wrappeddeadLetterQueueDBE8CACA", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + "testneweventsrulesqs1testneweventsrulesqs1wrappedqueueD6E123E2": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs1testneweventsrulesqs1wrappedEncryptionKey863D30E3", + "Arn", + ], + }, + "RedrivePolicy": Object { + "deadLetterTargetArn": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs1testneweventsrulesqs1wrappeddeadLetterQueueDBE8CACA", + "Arn", + ], + }, + "maxReceiveCount": 15, + }, + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testneweventsrulesqs1testneweventsrulesqs1wrappedqueuePolicy8D992E2C": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs1testneweventsrulesqs1wrappedqueueD6E123E2", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs1testneweventsrulesqs1wrappedqueueD6E123E2", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + Object { + "Action": Array [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs1testneweventsrulesqs1wrappedqueueD6E123E2", + "Arn", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testneweventsrulesqs1testneweventsrulesqs1wrappedqueueD6E123E2", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + "testneweventsrulesqs2testneweventsrulesqs2wrappedCustomEventBusA8D31D69": Object { + "Properties": Object { + "Name": "testneweventsrulesqs2testneweventsrulesqs2wrappedCustomEventBusA0895C25", + }, + "Type": "AWS::Events::EventBus", + }, + "testneweventsrulesqs2testneweventsrulesqs2wrappedEncryptionKeyE63D6087": Object { + "DeletionPolicy": "Retain", + "Properties": Object { + "EnableKeyRotation": true, + "KeyPolicy": Object { + "Statement": Array [ + Object { + "Action": Array [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": "*", + }, + Object { + "Action": Array [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": "*", + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::KMS::Key", + "UpdateReplacePolicy": "Retain", + }, + "testneweventsrulesqs2testneweventsrulesqs2wrappedEventsRule2C8B47C2": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testneweventsrulesqs2testneweventsrulesqs2wrappedCustomEventBusA8D31D69", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs2testneweventsrulesqs2wrappedqueue8496F5CD", + "Arn", + ], + }, + "Id": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs2testneweventsrulesqs2wrappedqueue8496F5CD", + "QueueName", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testneweventsrulesqs2testneweventsrulesqs2wrappeddeadLetterQueueA3699350": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": "alias/aws/sqs", + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testneweventsrulesqs2testneweventsrulesqs2wrappeddeadLetterQueuePolicyB13FA08A": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs2testneweventsrulesqs2wrappeddeadLetterQueueA3699350", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs2testneweventsrulesqs2wrappeddeadLetterQueueA3699350", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testneweventsrulesqs2testneweventsrulesqs2wrappeddeadLetterQueueA3699350", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + "testneweventsrulesqs2testneweventsrulesqs2wrappedqueue8496F5CD": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs2testneweventsrulesqs2wrappedEncryptionKeyE63D6087", + "Arn", + ], + }, + "RedrivePolicy": Object { + "deadLetterTargetArn": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs2testneweventsrulesqs2wrappeddeadLetterQueueA3699350", + "Arn", + ], + }, + "maxReceiveCount": 15, + }, + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testneweventsrulesqs2testneweventsrulesqs2wrappedqueuePolicy74546DC4": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs2testneweventsrulesqs2wrappedqueue8496F5CD", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs2testneweventsrulesqs2wrappedqueue8496F5CD", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + Object { + "Action": Array [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testneweventsrulesqs2testneweventsrulesqs2wrappedqueue8496F5CD", + "Arn", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testneweventsrulesqs2testneweventsrulesqs2wrappedqueue8496F5CD", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + }, +} +`; + exports[`snapshot test EventsRuleToSqs default params 1`] = ` Object { "Resources": Object { - "testeventsrulesqstesteventsrulesqswrappedEncryptionKey55835B42": Object { + "testeventsrulesqstesteventsrulesqswrappedEncryptionKey55835B42": Object { + "DeletionPolicy": "Retain", + "Properties": Object { + "EnableKeyRotation": true, + "KeyPolicy": Object { + "Statement": Array [ + Object { + "Action": Array [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": "*", + }, + Object { + "Action": Array [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": "*", + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::KMS::Key", + "UpdateReplacePolicy": "Retain", + }, + "testeventsrulesqstesteventsrulesqswrappedEventsRuleC8FC3158": Object { + "Properties": Object { + "ScheduleExpression": "rate(5 minutes)", + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + "Arn", + ], + }, + "Id": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + "QueueName", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueue6B3B63F7": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": "alias/aws/sqs", + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueuePolicy543CB683": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueue6B3B63F7", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueue6B3B63F7", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueue6B3B63F7", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B": Object { + "DeletionPolicy": "Delete", + "Properties": Object { + "KmsMasterKeyId": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqstesteventsrulesqswrappedEncryptionKey55835B42", + "Arn", + ], + }, + "RedrivePolicy": Object { + "deadLetterTargetArn": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueue6B3B63F7", + "Arn", + ], + }, + "maxReceiveCount": 15, + }, + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "testeventsrulesqstesteventsrulesqswrappedqueuePolicy8E19BB24": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + "Arn", + ], + }, + "Sid": "QueueOwnerOnlyAccess", + }, + Object { + "Action": "SQS:*", + "Condition": Object { + "Bool": Object { + "aws:SecureTransport": "false", + }, + }, + "Effect": "Deny", + "Principal": Object { + "AWS": "*", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + "Arn", + ], + }, + "Sid": "HttpsOnly", + }, + Object { + "Action": Array [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + ], + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + "Resource": Object { + "Fn::GetAtt": Array [ + "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + "Arn", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "Queues": Array [ + Object { + "Ref": "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + }, + ], + }, + "Type": "AWS::SQS::QueuePolicy", + }, + }, +} +`; + +exports[`snapshot test EventsRuleToSqs existing event bus params 1`] = ` +Object { + "Resources": Object { + "testexistingeventbusC6E4A2D0": Object { + "Properties": Object { + "Name": "testexistingeventbus", + }, + "Type": "AWS::Events::EventBus", + }, + "testexistingeventsrulesqstestexistingeventsrulesqswrappedEncryptionKeyF56A8317": Object { "DeletionPolicy": "Retain", "Properties": Object { "EnableKeyRotation": true, @@ -68,21 +1242,28 @@ Object { "Type": "AWS::KMS::Key", "UpdateReplacePolicy": "Retain", }, - "testeventsrulesqstesteventsrulesqswrappedEventsRuleC8FC3158": Object { + "testexistingeventsrulesqstestexistingeventsrulesqswrappedEventsRuleD53151C0": Object { "Properties": Object { - "ScheduleExpression": "rate(5 minutes)", + "EventBusName": Object { + "Ref": "testexistingeventbusC6E4A2D0", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, "State": "ENABLED", "Targets": Array [ Object { "Arn": Object { "Fn::GetAtt": Array [ - "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + "testexistingeventsrulesqstestexistingeventsrulesqswrappedqueue2D3A6826", "Arn", ], }, "Id": Object { "Fn::GetAtt": Array [ - "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + "testexistingeventsrulesqstestexistingeventsrulesqswrappedqueue2D3A6826", "QueueName", ], }, @@ -91,7 +1272,7 @@ Object { }, "Type": "AWS::Events::Rule", }, - "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueue6B3B63F7": Object { + "testexistingeventsrulesqstestexistingeventsrulesqswrappeddeadLetterQueueE2FC125B": Object { "DeletionPolicy": "Delete", "Properties": Object { "KmsMasterKeyId": "alias/aws/sqs", @@ -99,7 +1280,7 @@ Object { "Type": "AWS::SQS::Queue", "UpdateReplacePolicy": "Delete", }, - "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueuePolicy543CB683": Object { + "testexistingeventsrulesqstestexistingeventsrulesqswrappeddeadLetterQueuePolicy481EEFB5": Object { "Properties": Object { "PolicyDocument": Object { "Statement": Array [ @@ -134,7 +1315,7 @@ Object { }, "Resource": Object { "Fn::GetAtt": Array [ - "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueue6B3B63F7", + "testexistingeventsrulesqstestexistingeventsrulesqswrappeddeadLetterQueueE2FC125B", "Arn", ], }, @@ -153,7 +1334,7 @@ Object { }, "Resource": Object { "Fn::GetAtt": Array [ - "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueue6B3B63F7", + "testexistingeventsrulesqstestexistingeventsrulesqswrappeddeadLetterQueueE2FC125B", "Arn", ], }, @@ -164,25 +1345,25 @@ Object { }, "Queues": Array [ Object { - "Ref": "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueue6B3B63F7", + "Ref": "testexistingeventsrulesqstestexistingeventsrulesqswrappeddeadLetterQueueE2FC125B", }, ], }, "Type": "AWS::SQS::QueuePolicy", }, - "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B": Object { + "testexistingeventsrulesqstestexistingeventsrulesqswrappedqueue2D3A6826": Object { "DeletionPolicy": "Delete", "Properties": Object { "KmsMasterKeyId": Object { "Fn::GetAtt": Array [ - "testeventsrulesqstesteventsrulesqswrappedEncryptionKey55835B42", + "testexistingeventsrulesqstestexistingeventsrulesqswrappedEncryptionKeyF56A8317", "Arn", ], }, "RedrivePolicy": Object { "deadLetterTargetArn": Object { "Fn::GetAtt": Array [ - "testeventsrulesqstesteventsrulesqswrappeddeadLetterQueue6B3B63F7", + "testexistingeventsrulesqstestexistingeventsrulesqswrappeddeadLetterQueueE2FC125B", "Arn", ], }, @@ -192,7 +1373,7 @@ Object { "Type": "AWS::SQS::Queue", "UpdateReplacePolicy": "Delete", }, - "testeventsrulesqstesteventsrulesqswrappedqueuePolicy8E19BB24": Object { + "testexistingeventsrulesqstestexistingeventsrulesqswrappedqueuePolicy181CF4C8": Object { "Properties": Object { "PolicyDocument": Object { "Statement": Array [ @@ -227,7 +1408,7 @@ Object { }, "Resource": Object { "Fn::GetAtt": Array [ - "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + "testexistingeventsrulesqstestexistingeventsrulesqswrappedqueue2D3A6826", "Arn", ], }, @@ -246,7 +1427,7 @@ Object { }, "Resource": Object { "Fn::GetAtt": Array [ - "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + "testexistingeventsrulesqstestexistingeventsrulesqswrappedqueue2D3A6826", "Arn", ], }, @@ -264,7 +1445,7 @@ Object { }, "Resource": Object { "Fn::GetAtt": Array [ - "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + "testexistingeventsrulesqstestexistingeventsrulesqswrappedqueue2D3A6826", "Arn", ], }, @@ -274,7 +1455,7 @@ Object { }, "Queues": Array [ Object { - "Ref": "testeventsrulesqstesteventsrulesqswrappedqueue3820F81B", + "Ref": "testexistingeventsrulesqstestexistingeventsrulesqswrappedqueue2D3A6826", }, ], }, diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/events-rule-sqs-queue.test.ts b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/events-rule-sqs-queue.test.ts index 4ef573eff..b81264eed 100644 --- a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/events-rule-sqs-queue.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/events-rule-sqs-queue.test.ts @@ -27,6 +27,18 @@ function deployNewStack(stack: cdk.Stack) { return new EventsRuleToSqs(stack, 'test-events-rule-sqs', props); } +function deployStackWithNewEventBus(stack: cdk.Stack) { + const props: EventsRuleToSqsProps = { + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {} + }; + return new EventsRuleToSqs(stack, 'test-eventsrule-sqs-new-bus', props); +} + test('snapshot test EventsRuleToSqs default params', () => { const stack = new cdk.Stack(); deployNewStack(stack); @@ -322,4 +334,91 @@ test('check properties', () => { expect(construct.sqsQueue !== null); expect(construct.encryptionKey !== null); expect(construct.deadLetterQueue !== null); +}); + +test('check eventbus property, snapshot & eventbus exists', () => { + const stack = new cdk.Stack(); + const construct: EventsRuleToSqs = deployStackWithNewEventBus(stack); + + expect(construct.eventsRule !== null); + expect(construct.sqsQueue !== null); + expect(construct.encryptionKey !== null); + expect(construct.deadLetterQueue !== null); + expect(construct.eventBus !== null); + + // Validate snapshot + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); + // Check whether eventbus exists + expect(stack).toHaveResource('AWS::Events::EventBus'); +}); + +test('check exception while passing existingEventBus & eventBusProps', () => { + const stack = new cdk.Stack(); + + const props: EventsRuleToSqsProps = { + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {}, + existingEventBusInterface: new events.EventBus(stack, `test-existing-new-eventbus`, {}) + }; + + try { + new EventsRuleToSqs(stack, 'test-eventsrule-sqs', props); + } catch (e) { + expect(e).toBeInstanceOf(Error); + } +}); + +test('snapshot test EventsRuleToSqs existing event bus params', () => { + const stack = new cdk.Stack(); + const props: EventsRuleToSqsProps = { + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + existingEventBusInterface: new events.EventBus(stack, `test-existing-eventbus`, {}) + }; + new EventsRuleToSqs(stack, 'test-existing-eventsrule-sqs', props); + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); +}); + +test('check custom event bus resource with props when deploy:true', () => { + const stack = new cdk.Stack(); + + const props: EventsRuleToSqsProps = { + eventBusProps: { + eventBusName: 'testcustomeventbus' + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + } + }; + new EventsRuleToSqs(stack, 'test-new-eventsrule-sqs', props); + + expect(stack).toHaveResource('AWS::Events::EventBus', { + Name: 'testcustomeventbus' + }); +}); + +test('check multiple constructs in a single stack', () => { + const stack = new cdk.Stack(); + + const props: EventsRuleToSqsProps = { + eventBusProps: {}, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + } + }; + new EventsRuleToSqs(stack, 'test-new-eventsrule-sqs1', props); + new EventsRuleToSqs(stack, 'test-new-eventsrule-sqs2', props); + + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); }); \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-existing-bus.expected.json b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-existing-bus.expected.json new file mode 100644 index 000000000..5b95e1764 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-existing-bus.expected.json @@ -0,0 +1,150 @@ +{ + "Resources": { + "MyKey6AB29FA6": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "EnableKeyRotation": true + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "MyQueueE6CA6235": { + "Type": "AWS::SQS::Queue", + "Properties": { + "KmsMasterKeyId": { + "Fn::GetAtt": [ + "MyKey6AB29FA6", + "Arn" + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "MyQueuePolicy6BBEDDAC": { + "Type": "AWS::SQS::QueuePolicy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl" + ], + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + }, + "Resource": { + "Fn::GetAtt": [ + "MyQueueE6CA6235", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Queues": [ + { + "Ref": "MyQueueE6CA6235" + } + ] + } + }, + "existingeventbusA5B80487": { + "Type": "AWS::Events::EventBus", + "Properties": { + "Name": "eventsruleexistingbusexistingeventbusE1A2652B" + } + }, + "constructconstructwrappedEventsRuleCFCBC820": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventBusName": { + "Ref": "existingeventbusA5B80487" + }, + "EventPattern": { + "source": [ + "solutionsconstructs" + ] + }, + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Fn::GetAtt": [ + "MyQueueE6CA6235", + "Arn" + ] + }, + "Id": { + "Fn::GetAtt": [ + "MyQueueE6CA6235", + "QueueName" + ] + } + } + ] + } + } + } +} \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-existing-bus.ts b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-existing-bus.ts new file mode 100644 index 000000000..764aee469 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-existing-bus.ts @@ -0,0 +1,43 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import { EventsRuleToSqsProps, EventsRuleToSqs } from '../lib'; +import * as events from '@aws-cdk/aws-events'; +import { App, Stack } from '@aws-cdk/core'; +import * as sqs from '@aws-cdk/aws-sqs'; +import * as kms from '@aws-cdk/aws-kms'; +import { generateIntegStackName } from '@aws-solutions-constructs/core'; + +const app = new App(); +const stack = new Stack(app, generateIntegStackName(__filename)); + +const existingQueueObj = new sqs.Queue(stack, 'MyQueue', { + encryption: sqs.QueueEncryption.KMS, + encryptionMasterKey: new kms.Key(stack, 'MyKey', { + enableKeyRotation: true + }), +}); + +const existingEventBus = new events.EventBus(stack, 'existing-event-bus', {}); +const props: EventsRuleToSqsProps = { + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + existingQueueObj, + existingEventBusInterface: existingEventBus +}; + +new EventsRuleToSqs(stack, 'construct', props); +app.synth(); \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-new-bus.expected.json b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-new-bus.expected.json new file mode 100644 index 000000000..01f6cea1e --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-new-bus.expected.json @@ -0,0 +1,294 @@ +{ + "Resources": { + "ersqsersqswrappeddeadLetterQueueDA0DC0E2": { + "Type": "AWS::SQS::Queue", + "Properties": { + "KmsMasterKeyId": "alias/aws/sqs" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ersqsersqswrappeddeadLetterQueuePolicy95833FD0": { + "Type": "AWS::SQS::QueuePolicy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": { + "Fn::GetAtt": [ + "ersqsersqswrappeddeadLetterQueueDA0DC0E2", + "Arn" + ] + }, + "Sid": "QueueOwnerOnlyAccess" + }, + { + "Action": "SQS:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false" + } + }, + "Effect": "Deny", + "Principal": { + "AWS": "*" + }, + "Resource": { + "Fn::GetAtt": [ + "ersqsersqswrappeddeadLetterQueueDA0DC0E2", + "Arn" + ] + }, + "Sid": "HttpsOnly" + } + ], + "Version": "2012-10-17" + }, + "Queues": [ + { + "Ref": "ersqsersqswrappeddeadLetterQueueDA0DC0E2" + } + ] + } + }, + "ersqsersqswrappedEncryptionKeyB90DDAF7": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:GenerateDataKey", + "kms:TagResource", + "kms:UntagResource" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "EnableKeyRotation": true + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "ersqsersqswrappedqueue77F78672": { + "Type": "AWS::SQS::Queue", + "Properties": { + "KmsMasterKeyId": { + "Fn::GetAtt": [ + "ersqsersqswrappedEncryptionKeyB90DDAF7", + "Arn" + ] + }, + "RedrivePolicy": { + "deadLetterTargetArn": { + "Fn::GetAtt": [ + "ersqsersqswrappeddeadLetterQueueDA0DC0E2", + "Arn" + ] + }, + "maxReceiveCount": 15 + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ersqsersqswrappedqueuePolicy1DDD6C29": { + "Type": "AWS::SQS::QueuePolicy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:RemovePermission", + "sqs:AddPermission", + "sqs:SetQueueAttributes" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": { + "Fn::GetAtt": [ + "ersqsersqswrappedqueue77F78672", + "Arn" + ] + }, + "Sid": "QueueOwnerOnlyAccess" + }, + { + "Action": "SQS:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false" + } + }, + "Effect": "Deny", + "Principal": { + "AWS": "*" + }, + "Resource": { + "Fn::GetAtt": [ + "ersqsersqswrappedqueue77F78672", + "Arn" + ] + }, + "Sid": "HttpsOnly" + }, + { + "Action": [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl" + ], + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + }, + "Resource": { + "Fn::GetAtt": [ + "ersqsersqswrappedqueue77F78672", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Queues": [ + { + "Ref": "ersqsersqswrappedqueue77F78672" + } + ] + } + }, + "ersqsersqswrappedCustomEventBus58DA49B4": { + "Type": "AWS::Events::EventBus", + "Properties": { + "Name": "eventsrulenewbusersqsersqswrappedCustomEventBusC1530AC9" + } + }, + "ersqsersqswrappedEventsRule6C5B7B89": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventBusName": { + "Ref": "ersqsersqswrappedCustomEventBus58DA49B4" + }, + "EventPattern": { + "source": [ + "solutionsconstructs" + ] + }, + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Fn::GetAtt": [ + "ersqsersqswrappedqueue77F78672", + "Arn" + ] + }, + "Id": { + "Fn::GetAtt": [ + "ersqsersqswrappedqueue77F78672", + "QueueName" + ] + } + } + ] + } + } + } +} \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-new-bus.ts b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-new-bus.ts new file mode 100644 index 000000000..113ac1a97 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-sqs/test/integ.events-rule-new-bus.ts @@ -0,0 +1,31 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import { EventsRuleToSqsProps, EventsRuleToSqs } from '../lib'; +import { App, Stack } from '@aws-cdk/core'; +import { generateIntegStackName } from '@aws-solutions-constructs/core'; + +const app = new App(); +const stack = new Stack(app, generateIntegStackName(__filename)); + +const props: EventsRuleToSqsProps = { + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {} +}; + +new EventsRuleToSqs(stack, 'ersqs', props); +app.synth(); \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/README.md b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/README.md index 319f3fd9f..4e39286d1 100644 --- a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/README.md +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/README.md @@ -62,6 +62,8 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| |stateMachineProps|[`sfn.StateMachineProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-stepfunctions.StateMachineProps.html)|Optional user provided props to override the default props for sfn.StateMachine| +|existingEventBusInterface?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)| Optional user-provided custom EventBus for construct to use. Providing both this and `eventBusProps` results an error.| +|eventBusProps?|[`events.EventBusProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.EventBusProps.html)|Optional user-provided properties to override the default properties when creating a custom EventBus. Setting this value to `{}` will create a custom EventBus using all default properties. If neither this nor `existingEventBusInterface` is provided the construct will use the `default` EventBus. Providing both this and `existingEventBusInterface` results an error.| |eventRuleProps|[`events.RuleProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.RuleProps.html)|User provided eventRuleProps to override the defaults| |createCloudWatchAlarms|`boolean`|Whether to create recommended CloudWatch alarms| |logGroupProps?|[`logs.LogGroupProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.LogGroupProps.html)|User provided props to override the default props for for the CloudWatchLogs LogGroup.| @@ -70,6 +72,7 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| +|eventBus?|[`events.IEventBus`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.IEventBus.html)|Returns the instance of events.IEventBus used by the construct| |eventsRule|[`events.Rule`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.Rule.html)|Returns an instance of events.Rule created by the construct| |stateMachine|[`sfn.StateMachine`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-stepfunctions.StateMachine.html)|Returns an instance of sfn.StateMachine created by the construct| |stateMachineLogGroup|[`logs.ILogGroup`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.ILogGroup.html)|Returns an instance of the ILogGroup created by the construct for StateMachine| diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/lib/index.ts index d349c3a5d..574345829 100644 --- a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/lib/index.ts @@ -23,30 +23,42 @@ import * as logs from '@aws-cdk/aws-logs'; * @summary The properties for the EventsRuleToStepFunction Construct */ export interface EventsRuleToStepFunctionProps { + /** + * Existing instance of a custom EventBus. + * + * @default - None + */ + readonly existingEventBusInterface?: events.IEventBus; + /** + * A new custom EventBus is created with provided props. + * + * @default - None + */ + readonly eventBusProps?: events.EventBusProps; /** * User provided StateMachineProps to override the defaults * * @default - None */ - readonly stateMachineProps: sfn.StateMachineProps, + readonly stateMachineProps: sfn.StateMachineProps; /** * User provided eventRuleProps to override the defaults * * @default - None */ - readonly eventRuleProps: events.RuleProps, + readonly eventRuleProps: events.RuleProps; /** * Whether to create recommended CloudWatch alarms * * @default - Alarms are created */ - readonly createCloudWatchAlarms?: boolean, + readonly createCloudWatchAlarms?: boolean; /** * User provided props to override the default props for the CloudWatchLogs LogGroup. * * @default - Default props are used */ - readonly logGroupProps?: logs.LogGroupProps + readonly logGroupProps?: logs.LogGroupProps; } export class EventsRuleToStepFunction extends Construct { @@ -54,6 +66,7 @@ export class EventsRuleToStepFunction extends Construct { public readonly stateMachineLogGroup: logs.ILogGroup; public readonly eventsRule: events.Rule; public readonly cloudwatchAlarms?: cloudwatch.Alarm[]; + public readonly eventBus?: events.IEventBus; /** * @summary Constructs a new instance of the EventsRuleToStepFunction class. @@ -71,5 +84,6 @@ export class EventsRuleToStepFunction extends Construct { this.stateMachineLogGroup = wrappedConstruct.stateMachineLogGroup; this.eventsRule = wrappedConstruct.eventsRule; this.cloudwatchAlarms = wrappedConstruct.cloudwatchAlarms; + this.eventBus = wrappedConstruct.eventBus; } } \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/__snapshots__/events-rule-step-function.test.js.snap b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/__snapshots__/events-rule-step-function.test.js.snap index 6af96fd69..64ee4fd0a 100644 --- a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/__snapshots__/events-rule-step-function.test.js.snap +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/__snapshots__/events-rule-step-function.test.js.snap @@ -1,5 +1,868 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`check eventbus property, snapshot & eventbus exists 1`] = ` +Object { + "Resources": Object { + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedCustomEventBusA80A6AE6": Object { + "Properties": Object { + "Name": "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedCustomEventBus9374EFBE", + }, + "Type": "AWS::Events::EventBus", + }, + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedEventsRule5AF7B7F9": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedCustomEventBusA80A6AE6", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Ref": "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachine434BD3C9", + }, + "Id": "Target0", + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedEventsRuleRole87D54C4C", + "Arn", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedEventsRuleRole87D54C4C": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedEventsRuleRoleDefaultPolicyCE20CB1C": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": Object { + "Ref": "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachine434BD3C9", + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedEventsRuleRoleDefaultPolicyCE20CB1C", + "Roles": Array [ + Object { + "Ref": "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedEventsRuleRole87D54C4C", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedExecutionAbortedAlarm573E02EB": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachine434BD3C9", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedExecutionFailedAlarm2613A16E": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachine434BD3C9", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedExecutionThrottledAlarmBDF47911": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachine434BD3C9", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachine434BD3C9": Object { + "DependsOn": Array [ + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachineRoleDefaultPolicy36BEF6F1", + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachineRole24A13831", + ], + "Properties": Object { + "DefinitionString": "{\\"StartAt\\":\\"StartState\\",\\"States\\":{\\"StartState\\":{\\"Type\\":\\"Pass\\",\\"End\\":true}}}", + "LoggingConfiguration": Object { + "Destinations": Array [ + Object { + "CloudWatchLogsLogGroup": Object { + "LogGroupArn": Object { + "Fn::GetAtt": Array [ + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachineLogGroupFB62D721", + "Arn", + ], + }, + }, + }, + ], + "Level": "ERROR", + }, + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachineRole24A13831", + "Arn", + ], + }, + }, + "Type": "AWS::StepFunctions::StateMachine", + }, + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachineLogGroupFB62D721": Object { + "DeletionPolicy": "Retain", + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely", + }, + Object { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)", + }, + ], + }, + }, + "Properties": Object { + "LogGroupName": "/aws/vendedlogs/states/defaulttesteventrulesstepfunctionseventbuswrappedstatemachinelog9d0089f8aa0c", + }, + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + }, + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachineRole24A13831": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": Object { + "Fn::Join": Array [ + "", + Array [ + "states.", + Object { + "Ref": "AWS::Region", + }, + ".amazonaws.com", + ], + ], + }, + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachineRoleDefaultPolicy36BEF6F1": Object { + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations", + }, + ], + }, + }, + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries", + ], + "Effect": "Allow", + "Resource": "*", + }, + Object { + "Action": Array [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":logs:", + Object { + "Ref": "AWS::Region", + }, + ":", + Object { + "Ref": "AWS::AccountId", + }, + ":*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachineRoleDefaultPolicy36BEF6F1", + "Roles": Array [ + Object { + "Ref": "testeventrulesstepfunctionseventbustesteventrulesstepfunctionseventbuswrappedStateMachineRole24A13831", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + }, +} +`; + +exports[`check multiple constructs in a single stack 1`] = ` +Object { + "Resources": Object { + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedCustomEventBusD8193D14": Object { + "Properties": Object { + "Name": "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedCustomEventBus811D23A6", + }, + "Type": "AWS::Events::EventBus", + }, + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedEventsRule70206C5C": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedCustomEventBusD8193D14", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Ref": "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachine9BCFD286", + }, + "Id": "Target0", + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedEventsRuleRole4D263A39", + "Arn", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedEventsRuleRole4D263A39": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedEventsRuleRoleDefaultPolicy0EBFE184": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": Object { + "Ref": "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachine9BCFD286", + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedEventsRuleRoleDefaultPolicy0EBFE184", + "Roles": Array [ + Object { + "Ref": "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedEventsRuleRole4D263A39", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedExecutionAbortedAlarmBAA68B71": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachine9BCFD286", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedExecutionFailedAlarmA2BFF049": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachine9BCFD286", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedExecutionThrottledAlarm0B7ABDD5": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachine9BCFD286", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachine9BCFD286": Object { + "DependsOn": Array [ + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachineRoleDefaultPolicyD0996880", + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachineRole8997E8A1", + ], + "Properties": Object { + "DefinitionString": "{\\"StartAt\\":\\"StartState1\\",\\"States\\":{\\"StartState1\\":{\\"Type\\":\\"Pass\\",\\"End\\":true}}}", + "LoggingConfiguration": Object { + "Destinations": Array [ + Object { + "CloudWatchLogsLogGroup": Object { + "LogGroupArn": Object { + "Fn::GetAtt": Array [ + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachineLogGroupC572A3F3", + "Arn", + ], + }, + }, + }, + ], + "Level": "ERROR", + }, + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachineRole8997E8A1", + "Arn", + ], + }, + }, + "Type": "AWS::StepFunctions::StateMachine", + }, + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachineLogGroupC572A3F3": Object { + "DeletionPolicy": "Retain", + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely", + }, + Object { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)", + }, + ], + }, + }, + "Properties": Object { + "LogGroupName": "/aws/vendedlogs/states/defaulttestneweventsrulestepfunctions1wrappedstatemachinelogae8b8f8756a7", + }, + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + }, + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachineRole8997E8A1": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": Object { + "Fn::Join": Array [ + "", + Array [ + "states.", + Object { + "Ref": "AWS::Region", + }, + ".amazonaws.com", + ], + ], + }, + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachineRoleDefaultPolicyD0996880": Object { + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations", + }, + ], + }, + }, + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries", + ], + "Effect": "Allow", + "Resource": "*", + }, + Object { + "Action": Array [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":logs:", + Object { + "Ref": "AWS::Region", + }, + ":", + Object { + "Ref": "AWS::AccountId", + }, + ":*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachineRoleDefaultPolicyD0996880", + "Roles": Array [ + Object { + "Ref": "testneweventsrulestepfunctions1testneweventsrulestepfunctions1wrappedStateMachineRole8997E8A1", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedCustomEventBus4CD087AA": Object { + "Properties": Object { + "Name": "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedCustomEventBus21A7EEDC", + }, + "Type": "AWS::Events::EventBus", + }, + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedEventsRule4712CD41": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedCustomEventBus4CD087AA", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Ref": "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachine12C67230", + }, + "Id": "Target0", + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedEventsRuleRole5D364ED6", + "Arn", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedEventsRuleRole5D364ED6": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedEventsRuleRoleDefaultPolicy2F13E3B2": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": Object { + "Ref": "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachine12C67230", + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedEventsRuleRoleDefaultPolicy2F13E3B2", + "Roles": Array [ + Object { + "Ref": "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedEventsRuleRole5D364ED6", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedExecutionAbortedAlarm04F6AF08": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachine12C67230", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedExecutionFailedAlarm7C8C3E4C": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachine12C67230", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedExecutionThrottledAlarm5D0A68C6": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachine12C67230", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachine12C67230": Object { + "DependsOn": Array [ + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachineRoleDefaultPolicy036B7586", + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachineRole2ED2E3B8", + ], + "Properties": Object { + "DefinitionString": "{\\"StartAt\\":\\"StartState2\\",\\"States\\":{\\"StartState2\\":{\\"Type\\":\\"Pass\\",\\"End\\":true}}}", + "LoggingConfiguration": Object { + "Destinations": Array [ + Object { + "CloudWatchLogsLogGroup": Object { + "LogGroupArn": Object { + "Fn::GetAtt": Array [ + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachineLogGroup59D986DB", + "Arn", + ], + }, + }, + }, + ], + "Level": "ERROR", + }, + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachineRole2ED2E3B8", + "Arn", + ], + }, + }, + "Type": "AWS::StepFunctions::StateMachine", + }, + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachineLogGroup59D986DB": Object { + "DeletionPolicy": "Retain", + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely", + }, + Object { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)", + }, + ], + }, + }, + "Properties": Object { + "LogGroupName": "/aws/vendedlogs/states/defaulttestneweventsrulestepfunctions2wrappedstatemachinelogf3fa199ba576", + }, + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + }, + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachineRole2ED2E3B8": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": Object { + "Fn::Join": Array [ + "", + Array [ + "states.", + Object { + "Ref": "AWS::Region", + }, + ".amazonaws.com", + ], + ], + }, + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachineRoleDefaultPolicy036B7586": Object { + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations", + }, + ], + }, + }, + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries", + ], + "Effect": "Allow", + "Resource": "*", + }, + Object { + "Action": Array [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":logs:", + Object { + "Ref": "AWS::Region", + }, + ":", + Object { + "Ref": "AWS::AccountId", + }, + ":*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachineRoleDefaultPolicy036B7586", + "Roles": Array [ + Object { + "Ref": "testneweventsrulestepfunctions2testneweventsrulestepfunctions2wrappedStateMachineRole2ED2E3B8", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + }, +} +`; + exports[`snapshot test EventsRuleToStepFunction default params 1`] = ` Object { "Resources": Object { @@ -276,3 +1139,293 @@ Object { }, } `; + +exports[`snapshot test EventsRuleToStepfunctions existing event bus params 1`] = ` +Object { + "Resources": Object { + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedEventsRuleC9B681F5": Object { + "Properties": Object { + "EventBusName": Object { + "Ref": "testexistingneweventbusB9898D2B", + }, + "EventPattern": Object { + "source": Array [ + "solutionsconstructs", + ], + }, + "State": "ENABLED", + "Targets": Array [ + Object { + "Arn": Object { + "Ref": "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachine5D46233F", + }, + "Id": "Target0", + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedEventsRuleRole5A613617", + "Arn", + ], + }, + }, + ], + }, + "Type": "AWS::Events::Rule", + }, + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedEventsRuleRole5A613617": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": "events.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedEventsRuleRoleDefaultPolicyF26F34F2": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": Object { + "Ref": "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachine5D46233F", + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedEventsRuleRoleDefaultPolicyF26F34F2", + "Roles": Array [ + Object { + "Ref": "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedEventsRuleRole5A613617", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedExecutionAbortedAlarm501E521F": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachine5D46233F", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedExecutionFailedAlarm34F832F4": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachine5D46233F", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedExecutionThrottledAlarmBB941DB3": Object { + "Properties": Object { + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "Dimensions": Array [ + Object { + "Name": "StateMachineArn", + "Value": Object { + "Ref": "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachine5D46233F", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1, + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachine5D46233F": Object { + "DependsOn": Array [ + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachineRoleDefaultPolicy8FD41E5E", + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachineRole17CEE97B", + ], + "Properties": Object { + "DefinitionString": "{\\"StartAt\\":\\"StartState\\",\\"States\\":{\\"StartState\\":{\\"Type\\":\\"Pass\\",\\"End\\":true}}}", + "LoggingConfiguration": Object { + "Destinations": Array [ + Object { + "CloudWatchLogsLogGroup": Object { + "LogGroupArn": Object { + "Fn::GetAtt": Array [ + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachineLogGroup03F5535A", + "Arn", + ], + }, + }, + }, + ], + "Level": "ERROR", + }, + "RoleArn": Object { + "Fn::GetAtt": Array [ + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachineRole17CEE97B", + "Arn", + ], + }, + }, + "Type": "AWS::StepFunctions::StateMachine", + }, + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachineLogGroup03F5535A": Object { + "DeletionPolicy": "Retain", + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely", + }, + Object { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)", + }, + ], + }, + }, + "Properties": Object { + "LogGroupName": "/aws/vendedlogs/states/defaulttestexistingeventsrulestepfunctionswrappedstatemachinelog5a1e69f0fce9", + }, + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + }, + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachineRole17CEE97B": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "Service": Object { + "Fn::Join": Array [ + "", + Array [ + "states.", + Object { + "Ref": "AWS::Region", + }, + ".amazonaws.com", + ], + ], + }, + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachineRoleDefaultPolicy8FD41E5E": Object { + "Metadata": Object { + "cfn_nag": Object { + "rules_to_suppress": Array [ + Object { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations", + }, + ], + }, + }, + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries", + ], + "Effect": "Allow", + "Resource": "*", + }, + Object { + "Action": Array [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":logs:", + Object { + "Ref": "AWS::Region", + }, + ":", + Object { + "Ref": "AWS::AccountId", + }, + ":*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachineRoleDefaultPolicy8FD41E5E", + "Roles": Array [ + Object { + "Ref": "testexistingeventsrulestepfunctionstestexistingeventsrulestepfunctionswrappedStateMachineRole17CEE97B", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "testexistingneweventbusB9898D2B": Object { + "Properties": Object { + "Name": "testexistingneweventbus", + }, + "Type": "AWS::Events::EventBus", + }, + }, +} +`; diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/events-rule-step-function.test.ts b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/events-rule-step-function.test.ts index 6a0bb9474..bb8138c05 100644 --- a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/events-rule-step-function.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/events-rule-step-function.test.ts @@ -35,6 +35,25 @@ function deployNewStateMachine(stack: cdk.Stack) { return new EventsRuleToStepFunction(stack, 'test-events-rule-step-function', props); } +function deployNewStateMachineAndEventBus(stack: cdk.Stack) { + + const startState = new sfn.Pass(stack, 'StartState'); + + const props: EventsRuleToStepFunctionProps = { + stateMachineProps: { + definition: startState + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {} + }; + + return new EventsRuleToStepFunction(stack, 'test-eventrules-stepfunctions-eventbus', props); +} + test('snapshot test EventsRuleToStepFunction default params', () => { const stack = new cdk.Stack(); deployNewStateMachine(stack); @@ -118,4 +137,125 @@ test('check properties with no CW Alarms', () => { expect(construct.stateMachine !== null); expect(construct.eventsRule !== null); expect(construct.stateMachineLogGroup !== null); +}); + +test('check eventbus property, snapshot & eventbus exists', () => { + const stack = new cdk.Stack(); + + const construct: EventsRuleToStepFunction = deployNewStateMachineAndEventBus(stack); + + expect(construct.cloudwatchAlarms !== null); + expect(construct.stateMachine !== null); + expect(construct.eventsRule !== null); + expect(construct.stateMachineLogGroup !== null); + expect(construct.eventBus !== null); + + // Validate snapshot + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); + // Check whether eventbus exists + expect(stack).toHaveResource('AWS::Events::EventBus'); +}); + +test('check exception while passing existingEventBus & eventBusProps', () => { + const stack = new cdk.Stack(); + const startState = new sfn.Pass(stack, 'StartState'); + + const props: EventsRuleToStepFunctionProps = { + stateMachineProps: { + definition: startState + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {}, + existingEventBusInterface: new events.EventBus(stack, `test-existing-new-eventbus`, {}) + }; + + try { + new EventsRuleToStepFunction(stack, 'test-eventsrule-stepfunctions', props); + } catch (e) { + expect(e).toBeInstanceOf(Error); + } +}); + +test('snapshot test EventsRuleToStepfunctions existing event bus params', () => { + const stack = new cdk.Stack(); + const startState = new sfn.Pass(stack, 'StartState'); + + const props: EventsRuleToStepFunctionProps = { + stateMachineProps: { + definition: startState + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {}, + existingEventBusInterface: new events.EventBus(stack, `test-existing-new-eventbus`, {}) + }; + + new EventsRuleToStepFunction(stack, 'test-existing-eventsrule-stepfunctions', props); + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); +}); + +test('check custom event bus resource with props when deploy:true', () => { + const stack = new cdk.Stack(); + const startState = new sfn.Pass(stack, 'StartState'); + + const props: EventsRuleToStepFunctionProps = { + stateMachineProps: { + definition: startState + }, + eventBusProps: { + eventBusName: 'testcustomeventbus' + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + } + }; + new EventsRuleToStepFunction(stack, 'test-new-eventsrule-stepfunctions', props); + + expect(stack).toHaveResource('AWS::Events::EventBus', { + Name: 'testcustomeventbus' + }); +}); + +test('check multiple constructs in a single stack', () => { + const stack = new cdk.Stack(); + const startState1 = new sfn.Pass(stack, 'StartState1'); + + const props1: EventsRuleToStepFunctionProps = { + stateMachineProps: { + definition: startState1 + }, + eventBusProps: {}, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + } + }; + + const startState2 = new sfn.Pass(stack, 'StartState2'); + + const props2: EventsRuleToStepFunctionProps = { + stateMachineProps: { + definition: startState2 + }, + eventBusProps: {}, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + } + }; + new EventsRuleToStepFunction(stack, 'test-new-eventsrule-stepfunctions1', props1); + new EventsRuleToStepFunction(stack, 'test-new-eventsrule-stepfunctions2', props2); + + expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); }); \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-existing-eventbus.expected.json b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-existing-eventbus.expected.json new file mode 100644 index 000000000..f4a41c02f --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-existing-eventbus.expected.json @@ -0,0 +1,499 @@ +{ + "Resources": { + "LambdaFunctionServiceRole0C4CDE0B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/lambda/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "LambdaFunctionServiceRolePolicy" + } + ] + } + }, + "LambdaFunctionServiceRoleDefaultPolicy126C8897": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTraceSegments", + "xray:PutTelemetryRecords" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "LambdaFunctionServiceRoleDefaultPolicy126C8897", + "Roles": [ + { + "Ref": "LambdaFunctionServiceRole0C4CDE0B" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W12", + "reason": "Lambda needs the following minimum required permissions to send trace data to X-Ray and access ENIs in a VPC." + } + ] + } + } + }, + "LambdaFunctionBF21E41F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3Bucket1F467BCC" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872" + } + ] + } + ] + } + ] + ] + } + }, + "Role": { + "Fn::GetAtt": [ + "LambdaFunctionServiceRole0C4CDE0B", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "Handler": "index.handler", + "Runtime": "nodejs12.x", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "LambdaFunctionServiceRoleDefaultPolicy126C8897", + "LambdaFunctionServiceRole0C4CDE0B" + ], + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W58", + "reason": "Lambda functions has the required permission to write CloudWatch Logs. It uses custom policy instead of arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole with tighter permissions." + }, + { + "id": "W89", + "reason": "This is not a rule for the general case, just for specific use cases/industries" + }, + { + "id": "W92", + "reason": "Impossible for us to define the correct concurrency for clients" + } + ] + } + } + }, + "existingeventbusA5B80487": { + "Type": "AWS::Events::EventBus", + "Properties": { + "Name": "eventsrulestepfunctionsexistingeventbusexistingeventbus1ED36585" + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineLogGroup5EE95752": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "LogGroupName": "/aws/vendedlogs/states/eventsrulestepfunctionsexistingeventbustesteventsrulestepfunctionsneweventbusconstructwrappedstatemachinelog43b70fb6cbef" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete", + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely" + }, + { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)" + } + ] + } + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRole164E896E": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "states.", + { + "Ref": "AWS::Region" + }, + ".amazonaws.com" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRoleDefaultPolicy1A3825B6": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries" + ], + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + } + }, + { + "Action": [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "rulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRoleDefaultPolicy1A3825B6", + "Roles": [ + { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRole164E896E" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations" + } + ] + } + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "RoleArn": { + "Fn::GetAtt": [ + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRole164E896E", + "Arn" + ] + }, + "DefinitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"StartState\",\"States\":{\"StartState\":{\"Type\":\"Pass\",\"Next\":\"LambdaTask\"},\"LambdaTask\":{\"End\":true,\"Retry\":[{\"ErrorEquals\":[\"Lambda.ServiceException\",\"Lambda.AWSLambdaException\",\"Lambda.SdkClientException\"],\"IntervalSeconds\":2,\"MaxAttempts\":6,\"BackoffRate\":2}],\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::lambda:invoke\",\"Parameters\":{\"FunctionName\":\"", + { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + }, + "\",\"Payload.$\":\"$\"}}},\"TimeoutSeconds\":300}" + ] + ] + }, + "LoggingConfiguration": { + "Destinations": [ + { + "CloudWatchLogsLogGroup": { + "LogGroupArn": { + "Fn::GetAtt": [ + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineLogGroup5EE95752", + "Arn" + ] + } + } + } + ], + "Level": "ERROR" + } + }, + "DependsOn": [ + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRoleDefaultPolicy1A3825B6", + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRole164E896E" + ] + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRuleRoleEAAE2E76": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRuleRoleDefaultPolicyF5BF6008": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B" + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "tsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRuleRoleDefaultPolicyF5BF6008", + "Roles": [ + { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRuleRoleEAAE2E76" + } + ] + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRule4D5AF227": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventBusName": { + "Ref": "existingeventbusA5B80487" + }, + "EventPattern": { + "source": [ + "solutionsconstructs" + ] + }, + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B" + }, + "Id": "Target0", + "RoleArn": { + "Fn::GetAtt": [ + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRuleRoleEAAE2E76", + "Arn" + ] + } + } + ] + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedExecutionFailedAlarm021FECF4": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B" + } + } + ], + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1 + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedExecutionThrottledAlarmFFC1C9DA": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B" + } + } + ], + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1 + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedExecutionAbortedAlarmF3A957F6": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B" + } + } + ], + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1 + } + } + }, + "Parameters": { + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3Bucket1F467BCC": { + "Type": "String", + "Description": "S3 bucket for asset \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + }, + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872": { + "Type": "String", + "Description": "S3 key for asset version \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + }, + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cArtifactHash00A70A91": { + "Type": "String", + "Description": "Artifact hash for asset \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + } + } +} \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-existing-eventbus.ts b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-existing-eventbus.ts new file mode 100644 index 000000000..e7a33f33c --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-existing-eventbus.ts @@ -0,0 +1,58 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +/// !cdk-integ * +import { App, Stack, RemovalPolicy } from "@aws-cdk/core"; +import { EventsRuleToStepFunction, EventsRuleToStepFunctionProps } from "../lib"; +import { Duration } from '@aws-cdk/core'; +import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; +import * as lambda from '@aws-cdk/aws-lambda'; +import { deployLambdaFunction } from '@aws-solutions-constructs/core'; +import * as stepfunctions from '@aws-cdk/aws-stepfunctions'; +import { generateIntegStackName } from '@aws-solutions-constructs/core'; +import { EventBus } from "@aws-cdk/aws-events"; + +const app = new App(); +const stack = new Stack(app, generateIntegStackName(__filename)); + +const submitLambda = deployLambdaFunction(stack, { + runtime: lambda.Runtime.NODEJS_12_X, + code: lambda.Code.fromAsset(`${__dirname}/lambda`), + handler: 'index.handler' +}); + +const submitJob = new tasks.LambdaInvoke(stack, 'LambdaTask', { + lambdaFunction: submitLambda +}); +const startState = new stepfunctions.Pass(stack, 'StartState'); +startState.next(submitJob); + +const existingEventBus = new EventBus(stack, `existing-event-bus`, {}); +const props: EventsRuleToStepFunctionProps = { + stateMachineProps: { + definition: startState, + timeout: Duration.minutes(5) + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + existingEventBusInterface: existingEventBus, + logGroupProps: { + removalPolicy: RemovalPolicy.DESTROY + }, +}; + +new EventsRuleToStepFunction(stack, 'test-eventsrule-stepfunctions-new-eventbus-construct', props); +app.synth(); diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-new-eventbus.expected.json b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-new-eventbus.expected.json new file mode 100644 index 000000000..97603f021 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-new-eventbus.expected.json @@ -0,0 +1,499 @@ +{ + "Resources": { + "LambdaFunctionServiceRole0C4CDE0B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/lambda/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "LambdaFunctionServiceRolePolicy" + } + ] + } + }, + "LambdaFunctionServiceRoleDefaultPolicy126C8897": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTraceSegments", + "xray:PutTelemetryRecords" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "LambdaFunctionServiceRoleDefaultPolicy126C8897", + "Roles": [ + { + "Ref": "LambdaFunctionServiceRole0C4CDE0B" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W12", + "reason": "Lambda needs the following minimum required permissions to send trace data to X-Ray and access ENIs in a VPC." + } + ] + } + } + }, + "LambdaFunctionBF21E41F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3Bucket1F467BCC" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872" + } + ] + } + ] + } + ] + ] + } + }, + "Role": { + "Fn::GetAtt": [ + "LambdaFunctionServiceRole0C4CDE0B", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "Handler": "index.handler", + "Runtime": "nodejs12.x", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "LambdaFunctionServiceRoleDefaultPolicy126C8897", + "LambdaFunctionServiceRole0C4CDE0B" + ], + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W58", + "reason": "Lambda functions has the required permission to write CloudWatch Logs. It uses custom policy instead of arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole with tighter permissions." + }, + { + "id": "W89", + "reason": "This is not a rule for the general case, just for specific use cases/industries" + }, + { + "id": "W92", + "reason": "Impossible for us to define the correct concurrency for clients" + } + ] + } + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineLogGroup5EE95752": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "LogGroupName": "/aws/vendedlogs/states/eventsrulestepfunctionsneweventbustesteventsrulestepfunctionsneweventbusconstructwrappedstatemachinelog7010377640a2" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete", + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W86", + "reason": "Retention period for CloudWatchLogs LogGroups are set to 'Never Expire' to preserve customer data indefinitely" + }, + { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)" + } + ] + } + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRole164E896E": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "states.", + { + "Ref": "AWS::Region" + }, + ".amazonaws.com" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRoleDefaultPolicy1A3825B6": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries" + ], + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + } + }, + { + "Action": [ + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "rulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRoleDefaultPolicy1A3825B6", + "Roles": [ + { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRole164E896E" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W12", + "reason": "The 'LogDelivery' actions do not support resource-level authorizations" + } + ] + } + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "RoleArn": { + "Fn::GetAtt": [ + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRole164E896E", + "Arn" + ] + }, + "DefinitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"StartState\",\"States\":{\"StartState\":{\"Type\":\"Pass\",\"Next\":\"LambdaTask\"},\"LambdaTask\":{\"End\":true,\"Retry\":[{\"ErrorEquals\":[\"Lambda.ServiceException\",\"Lambda.AWSLambdaException\",\"Lambda.SdkClientException\"],\"IntervalSeconds\":2,\"MaxAttempts\":6,\"BackoffRate\":2}],\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::lambda:invoke\",\"Parameters\":{\"FunctionName\":\"", + { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + }, + "\",\"Payload.$\":\"$\"}}},\"TimeoutSeconds\":300}" + ] + ] + }, + "LoggingConfiguration": { + "Destinations": [ + { + "CloudWatchLogsLogGroup": { + "LogGroupArn": { + "Fn::GetAtt": [ + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineLogGroup5EE95752", + "Arn" + ] + } + } + } + ], + "Level": "ERROR" + } + }, + "DependsOn": [ + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRoleDefaultPolicy1A3825B6", + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachineRole164E896E" + ] + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRuleRoleEAAE2E76": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRuleRoleDefaultPolicyF5BF6008": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B" + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "tsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRuleRoleDefaultPolicyF5BF6008", + "Roles": [ + { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRuleRoleEAAE2E76" + } + ] + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedCustomEventBus5015FEDD": { + "Type": "AWS::Events::EventBus", + "Properties": { + "Name": "eventsrulestepfunctionsneweventbustesteventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedCustomEventBus8E386F00" + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRule4D5AF227": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventBusName": { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedCustomEventBus5015FEDD" + }, + "EventPattern": { + "source": [ + "solutionsconstructs" + ] + }, + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B" + }, + "Id": "Target0", + "RoleArn": { + "Fn::GetAtt": [ + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedEventsRuleRoleEAAE2E76", + "Arn" + ] + } + } + ] + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedExecutionFailedAlarm021FECF4": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that failed exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B" + } + } + ], + "MetricName": "ExecutionsFailed", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1 + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedExecutionThrottledAlarmFFC1C9DA": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that throttled exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B" + } + } + ], + "MetricName": "ExecutionThrottled", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Sum", + "Threshold": 1 + } + }, + "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedExecutionAbortedAlarmF3A957F6": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "EvaluationPeriods": 1, + "AlarmDescription": "Alarm for the number of executions that aborted exceeded the threshold of 1. ", + "Dimensions": [ + { + "Name": "StateMachineArn", + "Value": { + "Ref": "testeventsrulestepfunctionsneweventbusconstructtesteventsrulestepfunctionsneweventbusconstructwrappedStateMachine61D05A7B" + } + } + ], + "MetricName": "ExecutionsAborted", + "Namespace": "AWS/States", + "Period": 300, + "Statistic": "Maximum", + "Threshold": 1 + } + } + }, + "Parameters": { + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3Bucket1F467BCC": { + "Type": "String", + "Description": "S3 bucket for asset \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + }, + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cS3VersionKey9E4F7872": { + "Type": "String", + "Description": "S3 key for asset version \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + }, + "AssetParameters42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198cArtifactHash00A70A91": { + "Type": "String", + "Description": "Artifact hash for asset \"42a35bbf0dec9ef0ac5b0dde87e71a1b8929e8d2d178dd09ccfb2c928ec0198c\"" + } + } +} \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-new-eventbus.ts b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-new-eventbus.ts new file mode 100644 index 000000000..b4ecf72d5 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-events-rule-step-function/test/integ.events-rule-stepfunctions-new-eventbus.ts @@ -0,0 +1,56 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +/// !cdk-integ * +import { App, Stack, RemovalPolicy } from "@aws-cdk/core"; +import { EventsRuleToStepFunction, EventsRuleToStepFunctionProps } from "../lib"; +import { Duration } from '@aws-cdk/core'; +import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; +import * as lambda from '@aws-cdk/aws-lambda'; +import { deployLambdaFunction } from '@aws-solutions-constructs/core'; +import * as stepfunctions from '@aws-cdk/aws-stepfunctions'; +import { generateIntegStackName } from '@aws-solutions-constructs/core'; + +const app = new App(); +const stack = new Stack(app, generateIntegStackName(__filename)); + +const submitLambda = deployLambdaFunction(stack, { + runtime: lambda.Runtime.NODEJS_12_X, + code: lambda.Code.fromAsset(`${__dirname}/lambda`), + handler: 'index.handler' +}); + +const submitJob = new tasks.LambdaInvoke(stack, 'LambdaTask', { + lambdaFunction: submitLambda +}); +const startState = new stepfunctions.Pass(stack, 'StartState'); +startState.next(submitJob); + +const props: EventsRuleToStepFunctionProps = { + stateMachineProps: { + definition: startState, + timeout: Duration.minutes(5) + }, + eventRuleProps: { + eventPattern: { + source: ['solutionsconstructs'] + } + }, + eventBusProps: {}, + logGroupProps: { + removalPolicy: RemovalPolicy.DESTROY + }, +}; + +new EventsRuleToStepFunction(stack, 'test-eventsrule-stepfunctions-new-eventbus-construct', props); +app.synth();