diff --git a/.viperlightignore b/.viperlightignore index a97ed0ddc..8122c4ee1 100644 --- a/.viperlightignore +++ b/.viperlightignore @@ -10,7 +10,8 @@ source/patterns/@aws-solutions-constructs/aws-apigateway-lambda/test/integ.exist source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/integ.no-arguments.expected.json:204 CODE_OF_CONDUCT.md:4 CONTRIBUTING.md:236 -source/patterns/@aws-solutions-constructs/core/test/step-function-helper.test.ts:118 +source/patterns/@aws-solutions-constructs/core/test/step-function-helper.test.ts:114 +source/patterns/@aws-solutions-constructs/core/test/step-function-helper.test.ts:124 source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/test.kinesisstream-gluejob.test.ts:126 source/patterns/@aws-solutions-constructs/aws-lambda-sqs/test/integ.deployFunction.expected.json:112 source/patterns/@aws-solutions-constructs/aws-lambda-sqs/test/integ.existingFunction.expected.json:112 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 d28a45938..7fd1c2790 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 @@ -70,7 +70,7 @@ _Parameters_ |:-------------|:----------------|-----------------| |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.LogGroup`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.LogGroup.html)|Returns an instance of the LogGroup created by the construct for StateMachine| +|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| |cloudwatchAlarms?|[`cloudwatch.Alarm[]`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-cloudwatch.Alarm.html)|Returns a list of cloudwatch.Alarm created by the construct| ## Default settings 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 75a7168d0..07c2ce6ca 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 @@ -52,7 +52,7 @@ export interface EventsRuleToStepFunctionProps { export class EventsRuleToStepFunction extends Construct { public readonly stateMachine: sfn.StateMachine; - public readonly stateMachineLogGroup: logs.LogGroup; + public readonly stateMachineLogGroup: logs.ILogGroup; public readonly eventsRule: events.Rule; public readonly cloudwatchAlarms?: cloudwatch.Alarm[]; diff --git a/source/patterns/@aws-solutions-constructs/aws-lambda-step-function/README.md b/source/patterns/@aws-solutions-constructs/aws-lambda-step-function/README.md index af20d0c8d..8ad25cfcb 100644 --- a/source/patterns/@aws-solutions-constructs/aws-lambda-step-function/README.md +++ b/source/patterns/@aws-solutions-constructs/aws-lambda-step-function/README.md @@ -74,7 +74,7 @@ _Parameters_ |:-------------|:----------------|-----------------| |lambdaFunction|[`lambda.Function`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-lambda.Function.html)|Returns an instance of the Lambda function created by the pattern.| |stateMachine|[`sfn.StateMachine`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-stepfunctions.StateMachine.html)|Returns an instance of StateMachine created by the construct.| -|stateMachineLogGroup|[`logs.LogGroup`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.LogGroup.html)|Returns an instance of the LogGroup created by the construct for StateMachine| +|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| |cloudwatchAlarms?|[`cloudwatch.Alarm[]`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-cloudwatch.Alarm.html)|Returns a list of alarms created by the construct. ## Default settings diff --git a/source/patterns/@aws-solutions-constructs/aws-lambda-step-function/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-lambda-step-function/lib/index.ts index 3376f7eec..e35f56aee 100644 --- a/source/patterns/@aws-solutions-constructs/aws-lambda-step-function/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-lambda-step-function/lib/index.ts @@ -67,7 +67,7 @@ export interface LambdaToStepFunctionProps { export class LambdaToStepFunction extends Construct { public readonly lambdaFunction: lambda.Function; public readonly stateMachine: sfn.StateMachine; - public readonly stateMachineLogGroup: logs.LogGroup; + public readonly stateMachineLogGroup: logs.ILogGroup; public readonly cloudwatchAlarms?: cloudwatch.Alarm[]; /** diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-step-function/README.md b/source/patterns/@aws-solutions-constructs/aws-s3-step-function/README.md index 8596ab919..1cbfbcc9d 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-step-function/README.md +++ b/source/patterns/@aws-solutions-constructs/aws-s3-step-function/README.md @@ -70,7 +70,7 @@ _Parameters_ | **Name** | **Type** | **Description** | |:-------------|:----------------|-----------------| |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.LogGroup`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.LogGroup.html)|Returns an instance of the LogGroup created by the construct for StateMachine| +|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| |cloudwatchAlarms?|[`cloudwatch.Alarm[]`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-cloudwatch.Alarm.html)|Returns a list of cloudwatch.Alarm created by the construct| |s3Bucket?|[`s3.Bucket`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.Bucket.html)|Returns an instance of the s3.Bucket created by the construct| |s3LoggingBucket?|[`s3.Bucket`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.Bucket.html)|Returns an instance of s3.Bucket created by the construct as the logging bucket for the primary bucket.| diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-step-function/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-s3-step-function/lib/index.ts index a99fc6e12..8ecb4eb37 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-step-function/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-s3-step-function/lib/index.ts @@ -71,7 +71,7 @@ export interface S3ToStepFunctionProps { export class S3ToStepFunction extends Construct { public readonly stateMachine: sfn.StateMachine; - public readonly stateMachineLogGroup: logs.LogGroup; + public readonly stateMachineLogGroup: logs.ILogGroup; public readonly s3Bucket?: s3.Bucket; public readonly s3LoggingBucket?: s3.Bucket; public readonly cloudwatchAlarms?: cloudwatch.Alarm[]; diff --git a/source/patterns/@aws-solutions-constructs/core/lib/step-function-defaults.ts b/source/patterns/@aws-solutions-constructs/core/lib/step-function-defaults.ts index f3c8347ad..2ce95a215 100644 --- a/source/patterns/@aws-solutions-constructs/core/lib/step-function-defaults.ts +++ b/source/patterns/@aws-solutions-constructs/core/lib/step-function-defaults.ts @@ -12,9 +12,9 @@ */ import * as sfn from '@aws-cdk/aws-stepfunctions'; -import { LogGroup } from '@aws-cdk/aws-logs'; +import { ILogGroup } from '@aws-cdk/aws-logs'; -export function DefaultStateMachineProps(_logGroup: LogGroup): sfn.StateMachineProps | any { +export function DefaultStateMachineProps(_logGroup: ILogGroup): sfn.StateMachineProps | any { const stateMachineProps: sfn.StateMachineProps | any = { logs: { diff --git a/source/patterns/@aws-solutions-constructs/core/lib/step-function-helper.ts b/source/patterns/@aws-solutions-constructs/core/lib/step-function-helper.ts index 6cc499546..cf5210208 100644 --- a/source/patterns/@aws-solutions-constructs/core/lib/step-function-helper.ts +++ b/source/patterns/@aws-solutions-constructs/core/lib/step-function-helper.ts @@ -27,36 +27,45 @@ import { buildLogGroup } from './cloudwatch-log-group-helper'; * @param stateMachineProps - user-specified properties to override the default properties. */ export function buildStateMachine(scope: cdk.Construct, stateMachineProps: sfn.StateMachineProps, - logGroupProps?: logs.LogGroupProps): [sfn.StateMachine, logs.LogGroup] { + logGroupProps?: logs.LogGroupProps): [sfn.StateMachine, logs.ILogGroup] { + + let logGroup: logs.ILogGroup; + let _smProps; + + // If they sent a logGroup in stateMachineProps + if (stateMachineProps.logs?.destination) { + logGroup = stateMachineProps.logs?.destination; + _smProps = stateMachineProps; + } else { + // Three possibilities + // 1) logGroupProps not provided - create logGroupProps with just logGroupName + // 2) logGroupProps provided with no logGroupName - override logGroupProps.logGroupName + // 3) logGroupProps provided with logGroupName - pass unaltered logGroupProps + let consolidatedLogGroupProps = logGroupProps; + + if (!consolidatedLogGroupProps) { + consolidatedLogGroupProps = {}; + } + if (!consolidatedLogGroupProps?.logGroupName) { + const logGroupPrefix = '/aws/vendedlogs/states/'; + const maxResourceNameLength = 255 - logGroupPrefix.length; + const nameParts: string[] = [ + cdk.Stack.of(scope).stackName, // Name of the stack + scope.node.id, // Construct ID + 'StateMachineLog' // Literal string for log group name portion + ]; + + const logGroupName = logGroupPrefix + generateResourceName(nameParts, maxResourceNameLength); + consolidatedLogGroupProps = overrideProps(consolidatedLogGroupProps, { logGroupName }); + } - let consolidatedLogGroupProps = logGroupProps; + // Create new Cloudwatch log group for Step function State Machine + logGroup = buildLogGroup(scope, 'StateMachineLogGroup', consolidatedLogGroupProps); - // Three possibilities - // 1) logGroupProps not provided - create logGroupProps with just logGroupName - // 2) logGroupProps provided with no logGroupName - override logGroupProps.logGroupName - // 3) logGroupProps provided with logGroupName - pass unaltered logGroupProps - if (!consolidatedLogGroupProps) { - consolidatedLogGroupProps = {}; - } - if (!consolidatedLogGroupProps?.logGroupName) { - const logGroupPrefix = '/aws/vendedlogs/states/'; - const maxResourceNameLength = 255 - logGroupPrefix.length; - const nameParts: string[] = [ - cdk.Stack.of(scope).stackName, // Name of the stack - scope.node.id, // Construct ID - 'StateMachineLog' // Literal string for log group name portion - ]; - - const logGroupName = logGroupPrefix + generateResourceName(nameParts, maxResourceNameLength); - consolidatedLogGroupProps = overrideProps(consolidatedLogGroupProps, { logGroupName }); + // Override the defaults with the user provided props + _smProps = overrideProps(smDefaults.DefaultStateMachineProps(logGroup), stateMachineProps); } - // Configure Cloudwatch log group for Step function State Machine - const logGroup = buildLogGroup(scope, 'StateMachineLogGroup', consolidatedLogGroupProps); - - // Override the defaults with the user provided props - const _smProps = overrideProps(smDefaults.DefaultStateMachineProps(logGroup), stateMachineProps); - // Override the Cloudwatch permissions to make it more fine grained const _sm = new sfn.StateMachine(scope, 'StateMachine', _smProps); const role = _sm.node.findChild('Role') as iam.Role; diff --git a/source/patterns/@aws-solutions-constructs/core/test/step-function-helper.test.ts b/source/patterns/@aws-solutions-constructs/core/test/step-function-helper.test.ts index 8d0819042..1e84347d0 100644 --- a/source/patterns/@aws-solutions-constructs/core/test/step-function-helper.test.ts +++ b/source/patterns/@aws-solutions-constructs/core/test/step-function-helper.test.ts @@ -17,7 +17,7 @@ import * as defaults from '../'; import { SynthUtils } from '@aws-cdk/assert'; import '@aws-cdk/assert/jest'; import * as sfn from '@aws-cdk/aws-stepfunctions'; -import { LogGroup } from "@aws-cdk/aws-logs"; +import { buildLogGroup } from '../lib/cloudwatch-log-group-helper'; // -------------------------------------------------------------- // Test minimal deployment with no properties @@ -49,6 +49,8 @@ test('Test deployment w/ custom properties', () => { stateMachineName: 'myStateMachine' }); // Assertion + expect(stack).toCountResources("AWS::Logs::LogGroup", 1); + expect(stack).toHaveResource("AWS::StepFunctions::StateMachine", { StateMachineName: "myStateMachine" }); @@ -63,7 +65,9 @@ test('Test deployment w/ logging enabled', () => { // Step function definition const startState = new sfn.Pass(stack, 'StartState'); // Log group - const logGroup = new LogGroup(stack, 'myLogGroup', defaults.buildLogGroup(stack)); + // const logGroup = new LogGroup(stack, 'myLogGroup', defaults.buildLogGroup(stack)); + const logGroup = buildLogGroup(stack, 'StateMachineLogGroup'); + // Build state machine defaults.buildStateMachine(stack, { definition: startState, @@ -73,13 +77,15 @@ test('Test deployment w/ logging enabled', () => { } }); // Assertion + expect(stack).toCountResources("AWS::Logs::LogGroup", 1); + expect(stack).toHaveResource("AWS::StepFunctions::StateMachine", { LoggingConfiguration: { Destinations: [{ CloudWatchLogsLogGroup: { LogGroupArn: { "Fn::GetAtt": [ - "myLogGroup46524CAB", + "StateMachineLogGroup15B91BCB", "Arn" ] } @@ -91,9 +97,9 @@ test('Test deployment w/ logging enabled', () => { }); // -------------------------------------------------------------- -// Check default Cloudwatch perissions +// Check default Cloudwatch permissions // -------------------------------------------------------------- -test('Test deployment w/ logging enabled', () => { +test('Check default Cloudwatch permissions', () => { // Stack const stack = new Stack(); // Step function definition