11// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22// SPDX-License-Identifier: Apache-2.0
33import { readdirSync } from 'fs' ;
4- import { StackProps , Stack , App , CfnParameter , CfnCondition , Fn , CfnResource } from 'aws-cdk-lib' ;
4+ import { StackProps , Stack , App , CfnResource } from 'aws-cdk-lib' ;
55import { Runtime } from 'aws-cdk-lib/aws-lambda' ;
66import AdminAccountParam from './admin-account-param' ;
77import { RedshiftAuditLogging } from './member/redshift-audit-logging' ;
@@ -11,6 +11,7 @@ import { MemberBucketEncryption } from './member/bucket-encryption';
1111import { MemberVersion } from './member/version' ;
1212import { SerializedNestedStackFactory } from './cdk-helper/nested-stack' ;
1313import { WaitProvider } from './wait-provider' ;
14+ import { MemberPlaybook } from './member-playbook' ;
1415
1516export interface SolutionProps extends StackProps {
1617 solutionId : string ;
@@ -27,7 +28,7 @@ export class MemberStack extends Stack {
2728
2829 const adminAccountParam = new AdminAccountParam ( this , 'AdminAccountParameter' ) ;
2930
30- new RedshiftAuditLogging ( this , 'RedshiftAuditLogging' , { solutionId : props . solutionId } ) ;
31+ const redShiftLogging = new RedshiftAuditLogging ( this , 'RedshiftAuditLogging' , { solutionId : props . solutionId } ) ;
3132
3233 new MemberRemediationKey ( this , 'MemberKey' , { solutionId : props . solutionId } ) ;
3334
@@ -60,40 +61,40 @@ export class MemberStack extends Stack {
6061 this . nestedStacks . push ( nestedStackNoRoles as Stack ) ;
6162
6263 const playbookDirectory = `${ __dirname } /../playbooks` ;
63- const ignore = [ '.DS_Store' , 'common' , '.pytest_cache' , 'NEWPLAYBOOK' , '.coverage' ] ;
64- const illegalChars = / [ \\ . _ ] / g;
64+ const ignore = [ '.DS_Store' , 'common' , '.pytest_cache' , 'NEWPLAYBOOK' , '.coverage' , 'SC' ] ;
6565 const listOfPlaybooks : string [ ] = [ ] ;
6666 const items = readdirSync ( playbookDirectory ) ;
6767 items . forEach ( ( file ) => {
6868 if ( ! ignore . includes ( file ) ) {
69- const templateFile = `${ file } MemberStack.template` ;
70-
71- const parmname = file . replace ( illegalChars , '' ) ;
72- const memberStackOption = new CfnParameter ( this , `LoadMemberStack${ parmname } ` , {
73- type : 'String' ,
74- description : `Load Playbook member stack for ${ file } ?` ,
75- default : 'yes' ,
76- allowedValues : [ 'yes' , 'no' ] ,
77- } ) ;
78- memberStackOption . overrideLogicalId ( `Load${ parmname } MemberStack` ) ;
79- listOfPlaybooks . push ( memberStackOption . logicalId ) ;
80-
81- const nestedStack = nestedStackFactory . addNestedStack ( `PlaybookMemberStack${ file } ` , {
82- templateRelativePath : `playbooks/${ templateFile } ` ,
69+ const playbook = new MemberPlaybook ( this , {
70+ name : file ,
71+ defaultState : 'no' ,
72+ nestedStackFactory,
8373 parameters : {
8474 SecHubAdminAccount : adminAccountParam . value ,
8575 WaitProviderServiceToken : waitProvider . serviceToken ,
8676 } ,
87- condition : new CfnCondition ( this , `load${ file } Cond` , {
88- expression : Fn . conditionEquals ( memberStackOption , 'yes' ) ,
89- } ) ,
9077 } ) ;
91- const cfnResource = nestedStack . nestedStackResource as CfnResource ;
92- cfnResource . overrideLogicalId ( `PlaybookMemberStack ${ file } ` ) ;
93- this . nestedStacks . push ( nestedStack as Stack ) ;
78+
79+ listOfPlaybooks . push ( playbook . parameterName ) ;
80+ this . nestedStacks . push ( playbook . playbookStack ) ;
9481 }
9582 } ) ;
9683
84+ const scPlaybook = new MemberPlaybook ( this , {
85+ name : 'SC' ,
86+ defaultState : 'yes' ,
87+ description :
88+ 'If the consolidated control findings feature is turned on in Security Hub, only enable the Security Control (SC) playbook. If the feature is not turned on, enable the playbooks for the security standards that are enabled in Security Hub. Enabling additional playbooks can result in reaching the quota for EventBridge Rules.' ,
89+ nestedStackFactory,
90+ parameters : {
91+ SecHubAdminAccount : adminAccountParam . value ,
92+ WaitProviderServiceToken : waitProvider . serviceToken ,
93+ } ,
94+ } ) ;
95+
96+ this . nestedStacks . push ( scPlaybook . playbookStack ) ;
97+
9798 /********************
9899 ** Metadata
99100 ********************/
@@ -105,9 +106,17 @@ export class MemberStack extends Stack {
105106 Parameters : [ memberLogGroup . paramId ] ,
106107 } ,
107108 {
108- Label : { default : 'Playbooks' } ,
109+ Label : { default : 'Consolidated control finding Playbook' } ,
110+ Parameters : [ scPlaybook . parameterName ] ,
111+ } ,
112+ {
113+ Label : { default : 'Security Standard Playbooks' } ,
109114 Parameters : listOfPlaybooks ,
110115 } ,
116+ {
117+ Label : { default : 'Configuration' } ,
118+ Parameters : [ redShiftLogging . paramId , adminAccountParam . paramId ] ,
119+ } ,
111120 ] ,
112121 ParameterLabels : {
113122 [ memberLogGroup . paramId ] : {
0 commit comments