private addStepFunction()

in source/lib/compliant-framework-stack.ts [590:699]


  private addStepFunction() {

    const alertSubscriptionCmk = new kms.Key(this, 'alertSubscriptionCmk', {
      enableKeyRotation: true
    })
    const alertSubscriptionCmkAlias = new kms.Alias(this, 'alertSubscriptionCmkAlias', {
      aliasName: 'alias/compliant-framework/notification-email/topic/cmk',
      targetKey: alertSubscriptionCmk
    })

    const alertSubscription = new subscriptions.EmailSubscription(
      this.frameworkNotificationEmail.valueAsString);
    const alertTopic = new sns.Topic(this, 'alertTopic', {
      displayName: 'Compliant Framework Info',
      masterKey: alertSubscriptionCmkAlias
    });
    alertTopic.addSubscription(alertSubscription);

    //
    // Base Tasks
    //
    const startTask = new sfn.Pass(this, 'Begin State Function', {})
    const failTask = new sfn.Fail(this, 'Failed')

    // Notify Success Task
    const notifySuccessTask = this.addStepFunctionNotifySuccess(alertTopic, alertSubscriptionCmk)

    // Notify Failure Task
    const notifyFailureTask = this.addStepFunctionNotifyFailure(alertTopic, alertSubscriptionCmk)
      .next(failTask);


    // Verify SNS Subscriptions Task
    const verifySnsSubscriptionTask = this.addStepFunctionVerifySnsSubscription(alertTopic)
      .addRetry({
        maxAttempts: 5,
        interval: cdk.Duration.seconds(30),
      }).addCatch(notifyFailureTask)

    // Verify GovCloud API Keys Task
    const verifyGovCloudApiKeysTask = this.addStepFunctionVerifyGovCloudApiKeys()
      .addCatch(notifyFailureTask)

    // Initialize Organization Task
    const initializeOrganizationTask = this.addStepFunctionInitializeOrganization()
      .addCatch(notifyFailureTask)

    // Create Accounts Task
    const createAccountsTask = this.addStepFunctionCreateAccounts()
      .addCatch(notifyFailureTask)

    // Invite Accounts Task
    const inviteAccountsTask = this.addStepFunctionInviteAccounts()
      .addRetry({
        maxAttempts: 5,
        interval: cdk.Duration.seconds(30),
      }).addCatch(notifyFailureTask);


    // Deploy Framework (into GovCloud)
    const codebuildTask = this.addStepFunctionDeployFramework()
      .addCatch(notifyFailureTask);

    //
    // State Machine
    //
    const stateMachineLogGroup = new logs.LogGroup(this, 'stateMachineLogGroup', {
      removalPolicy: cdk.RemovalPolicy.DESTROY
    });

    const definition = startTask
      .next(verifySnsSubscriptionTask)
      .next(verifyGovCloudApiKeysTask)
      .next(initializeOrganizationTask)
      .next(createAccountsTask)
      .next(inviteAccountsTask)
      .next(codebuildTask)
      .next(notifySuccessTask);

    const stateMachine = new sfn.StateMachine(this, 'stateMachine', {
      definition,
      stateMachineName: 'CompliantFramework',
      logs: {
        destination: stateMachineLogGroup,
        level: sfn.LogLevel.ALL,
      }
    });

    const cfnStateMachineDefPolicy = stateMachine.role?.node.tryFindChild('DefaultPolicy')?.node.findChild('Resource') as iam.CfnPolicy;
    cfnStateMachineDefPolicy.cfnOptions.metadata = {
      cfn_nag: {
        rules_to_suppress: [
          {
            id: 'W12',
            reason: `State machine permission actions require use of * resource`
          },
          {
            id: 'W76',
            reason: `SPCM for IAM policy document is higher than 25`
          }
        ]
      }
    };

    //
    // Kick off the State Machine
    //
    this.executeStateMachine(stateMachine.stateMachineArn)

  }