0.0.5 • Published 7 months ago

stack-workflow v0.0.5

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

Stack Workflow Construct

Overview

This AWS Solutions Construct implements a state machine (AWS Step Functions) to manage the execution flow of multiple stacks (AWS CloudFormation).

Here is a minimal deployable pattern definition:

Typescript

import { Construct } from 'constructs';
import { Stack, StackProps } from 'aws-cdk-lib';
import { CSDCStackWorkflow } from 'stack-workflow';

new CSDCStackWorkflow(this, 'test-stack-workflow');

Deployment

Preparations

  • Make sure you have an AWS account
  • Configure credential of aws cli
  • Install Node.js LTS version 18.17.0 or later
  • Install Docker Engine
  • Install the dependencies of the solution by executing the command yarn install --check-files && npx projen
  • Initialize the CDK toolkit stack into AWS environment (only for deploying via AWS CDK for the first time), and run npx cdk bootstrap

Deploy the construct

cdk deploy --app='./lib/integ.default.js' --require-approval never

Test

yarn test

Getting Started

After creating the Stack, you can see the following output: | Key | Value | Description | | ---- | ---- | ---- | | WorkflowStateMachineArn | arn:aws:states:ap-southeast-1:*:stateMachine:<workflow-state-machine-name> | Workflow State Machine Arn | | ActionStateMachineArn | arn:aws:states:ap-southeast-1:*:stateMachine:<action-state-machine-name> | Action State Machine Arn | | CallbackBucketName | stack-workflow-callback-xxx | Callback Bucket Name |

Access the AWS Step Functions console, select the workflow state machine, click the Start Execution button, and enter the following JSON data to complete the tasks.

Task1: Run stack

Target: Use stack to create/update/delete a DynamoDB table in ap-southeast-1 region.

Execution input:

{
  "Type": "Stack",
  "Data": {
    "Input": {
      "Region": "ap-southeast-1",
      "TemplateURL": "https://s3-us-west-1.amazonaws.com/cloudformation-templates-us-west-1/DynamoDBSI.template",
      "Action": "Create",
      "Parameters": [
        {
          "ParameterKey": "ReadCapacityUnits",
          "ParameterValue": "5"
        },
        {
          "ParameterKey": "WriteCapacityUnits",
          "ParameterValue": "10"
        }
      ],
      "StackName": "Stack-test1"
    }
  },
  "End": true
}

Tips:

You only need to modify Data.Input.Action to complete other stack operations: Update, Delete.

Task2: Run stacks concurrently

Target: Concurrently executing two stacks in ap-southeast-1 region, one for creating DynamoDB table and one for creating SQS queue with a specific name.

Execution input:

{
  "Type": "Parallel",
  "End": true,
  "Branches": [
    {
      "States": {
        "Stack-test21": {
          "Type": "Stack",
          "Data": {
            "Input": {
              "Region": "ap-southeast-1",
              "TemplateURL": "https://s3-us-west-1.amazonaws.com/cloudformation-templates-us-west-1/DynamoDBSI.template",
              "Action": "Create",
              "Parameters": [
                {
                  "ParameterKey": "ReadCapacityUnits",
                  "ParameterValue": "5"
                },
                {
                  "ParameterKey": "WriteCapacityUnits",
                  "ParameterValue": "10"
                }
              ],
              "StackName": "Stack-test21"
            }
          },
          "End": true
        }
      },
      "StartAt": "Stack-test21"
    },
    {
      "States": {
        "Stack-test22": {
          "Type": "Stack",
          "Data": {
            "Input": {
              "Region": "ap-southeast-1",
              "TemplateURL": "https://s3-us-west-2.amazonaws.com/cloudformation-templates-us-west-2/SQSWithQueueName.template",
              "Action": "Create",
              "Parameters": [
                {
                  "ParameterKey": "QueueName",
                  "ParameterValue": "test22"
                }
              ],
              "StackName": "Stack-test22"
            }
          },
          "End": true
        }
      },
      "StartAt": "Stack-test22"
    }
  ]
}

Task3: Run stacks serially

Target: Serially executing two stacks in ap-southeast-1 region. First, create a DynamoDB table, and after the first stack is completed, create SQS queue with a specific name.

Execution input:

{
  "Type": "Parallel",
  "End": true,
  "Branches": [
    {
      "States": {
        "Stack-test31": {
          "Type": "Stack",
          "Data": {
            "Input": {
              "Region": "ap-southeast-1",
              "TemplateURL": "https://s3-us-west-1.amazonaws.com/cloudformation-templates-us-west-1/DynamoDBSI.template",
              "Action": "Create",
              "Parameters": [
                {
                  "ParameterKey": "ReadCapacityUnits",
                  "ParameterValue": "5"
                },
                {
                  "ParameterKey": "WriteCapacityUnits",
                  "ParameterValue": "10"
                }
              ],
              "StackName": "Stack-test31"
            }
          },
          "Next": "Stack-test32"
        },
        "Stack-test32": {
          "Type": "Stack",
          "Data": {
            "Input": {
              "Region": "ap-southeast-1",
              "TemplateURL": "https://s3-us-west-2.amazonaws.com/cloudformation-templates-us-west-2/SQSWithQueueName.template",
              "Action": "Create",
              "Parameters": [
                {
                  "ParameterKey": "QueueName",
                  "ParameterValue": "test32"
                }
              ],
              "StackName": "Stack-test32"
            }
          },
          "End": true
        }
      },
      "StartAt": "Stack-test31"
    }
  ]
}

Task4: Run stacks with input/output dependency

Target: Serially executing two stacks in ap-southeast-1 region. First, create a DynamoDB table, and after the first stack is completed, create SQS queue with a specific name that is first stack output(first stack output DynamoDB table name as second stack input queue name).

Execution input:

{
  "Type": "Parallel",
  "End": true,
  "Branches": [
    {
      "States": {
        "Stack-test41": {
          "Type": "Stack",
          "Data": {
            "Input": {
              "Region": "ap-southeast-1",
              "TemplateURL": "https://s3-us-west-1.amazonaws.com/cloudformation-templates-us-west-1/DynamoDBSI.template",
              "Action": "Create",
              "Parameters": [
                {
                  "ParameterKey": "ReadCapacityUnits",
                  "ParameterValue": "5"
                },
                {
                  "ParameterKey": "WriteCapacityUnits",
                  "ParameterValue": "10"
                }
              ],
              "StackName": "Stack-test41"
            }
          },
          "Next": "Stack-test42"
        },
        "Stack-test42": {
          "Type": "Stack",
          "Data": {
            "Input": {
              "Region": "ap-southeast-1",
              "TemplateURL": "https://s3-us-west-2.amazonaws.com/cloudformation-templates-us-west-2/SQSWithQueueName.template",
              "Action": "Create",
              "Parameters": [
                {
                  "ParameterKey": "QueueName.#",
                  "ParameterValue": "#.Stack-test41.TableName"
                },
              ],
              "StackName": "Stack-test42"
            }
          },
          "End": true
        }
      },
      "StartAt": "Stack-test41"
    }
  ]
}

Tips:

Of course, you can also use JsonPath to obtain values from Outputs, and such parameters can achieve the same effect:

{
  "ParameterKey": "QueueName.$",
  "ParameterValue": "$.Stack-test41.Outputs[0].OutputValue"
}

Architecture

Architecture Diagram

Default settings

Out of the box implementation of the Construct without any override will set the following defaults:

AWS Step Functions

  • Workflow state machine timeout is 2 hours, stack action state machine timeout is 1 hour
  • Specifies Amazon X-Ray tracing is enabled for state machine

AWS Lambda

  • The runtime environment: NODEJS_18_X
  • The system architectures compatible with this lambda function: X86_64
  • The function execution time (15 seconds) after which Lambda terminates the function

AWS CloudFormation

  • Create stack with DisableRollback:true
  • Disable termination protection on the specified stack
  • Explicitly acknowledge that stack template contains certain capabilities(CAPABILITY_IAM, CAPABILITY_NAMED_IAM, CAPABILITY_AUTO_EXPAND) in order for CloudFormation to create the stack

Amazon S3 Bucket

  • Configure Access logging for S3 Bucket
  • Enable server-side encryption for S3 Bucket using AWS managed KMS Key
  • Enforce encryption of data in transit
  • Turn on the versioning for S3 Bucket
  • Don't allow public access for S3 Bucket
  • Retain the S3 Bucket when deleting the CloudFormation stack
  • Applies Lifecycle rule to move noncurrent object versions to Glacier storage after 90 days

License

This project is licensed under the Apache-2.0 License.

Acknowledgements

This project utilizes projen.