Repository: awslabs/aws-ddk (language: python)

Issue:
(core) Airflow (MWWA) data pipeline stage
**Is your feature request related to a problem? Please describe.**
DDK Airflow integration

**Describe the solution you'd like**
I'd like to be able to kickoff MWWA DAG's in DDK DataPipelines. A stage should kickoff the DAG and wait for it to complete.

**Describe alternatives you've considered**
N/A
**Additional context**
N/A

*P.S. Please Don't attach files. Add code snippets directly in the message body instead.*


Discussion / hints:
Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 7 days it will automatically be closed.
I would like to bump this up as we have a feature request for a customer to add this as a data pipeline stage

Fix patch:
diff --git a/API.md b/API.md
index a493c65c..fcf42337 100644
--- a/API.md
+++ b/API.md
@@ -4262,6 +4262,245 @@ public readonly pluginFile: BucketDeployment;
 ---
 
 
+### MWAATriggerDagsStage <a name="MWAATriggerDagsStage" id="aws-ddk-core.MWAATriggerDagsStage"></a>
+
+Stage that contains a step function that runs a Managed Apache Airflow (MWAA) dag or set of dags .
+
+#### Initializers <a name="Initializers" id="aws-ddk-core.MWAATriggerDagsStage.Initializer"></a>
+
+```typescript
+import { MWAATriggerDagsStage } from 'aws-ddk-core'
+
+new MWAATriggerDagsStage(scope: Construct, id: string, props: MWAATriggerDagsStageProps)
+```
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.Initializer.parameter.scope">scope</a></code> | <code>constructs.Construct</code> | Scope within which this construct is defined. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.Initializer.parameter.id">id</a></code> | <code>string</code> | Identifier of the stage. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.Initializer.parameter.props">props</a></code> | <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps">MWAATriggerDagsStageProps</a></code> | Properties for the stage. |
+
+---
+
+##### `scope`<sup>Required</sup> <a name="scope" id="aws-ddk-core.MWAATriggerDagsStage.Initializer.parameter.scope"></a>
+
+- *Type:* constructs.Construct
+
+Scope within which this construct is defined.
+
+---
+
+##### `id`<sup>Required</sup> <a name="id" id="aws-ddk-core.MWAATriggerDagsStage.Initializer.parameter.id"></a>
+
+- *Type:* string
+
+Identifier of the stage.
+
+---
+
+##### `props`<sup>Required</sup> <a name="props" id="aws-ddk-core.MWAATriggerDagsStage.Initializer.parameter.props"></a>
+
+- *Type:* <a href="#aws-ddk-core.MWAATriggerDagsStageProps">MWAATriggerDagsStageProps</a>
+
+Properties for the stage.
+
+---
+
+#### Methods <a name="Methods" id="Methods"></a>
+
+| **Name** | **Description** |
+| --- | --- |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.toString">toString</a></code> | Returns a string representation of this construct. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.addAlarm">addAlarm</a></code> | Add a CloudWatch alarm for the DataStage. |
+
+---
+
+##### `toString` <a name="toString" id="aws-ddk-core.MWAATriggerDagsStage.toString"></a>
+
+```typescript
+public toString(): string
+```
+
+Returns a string representation of this construct.
+
+##### `addAlarm` <a name="addAlarm" id="aws-ddk-core.MWAATriggerDagsStage.addAlarm"></a>
+
+```typescript
+public addAlarm(id: string, props: AlarmProps): DataStage
+```
+
+Add a CloudWatch alarm for the DataStage.
+
+###### `id`<sup>Required</sup> <a name="id" id="aws-ddk-core.MWAATriggerDagsStage.addAlarm.parameter.id"></a>
+
+- *Type:* string
+
+Identifier of the CloudWatch Alarm.
+
+---
+
+###### `props`<sup>Required</sup> <a name="props" id="aws-ddk-core.MWAATriggerDagsStage.addAlarm.parameter.props"></a>
+
+- *Type:* <a href="#aws-ddk-core.AlarmProps">AlarmProps</a>
+
+Properties for the alarm.
+
+---
+
+#### Static Functions <a name="Static Functions" id="Static Functions"></a>
+
+| **Name** | **Description** |
+| --- | --- |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.isConstruct">isConstruct</a></code> | Checks if `x` is a construct. |
+
+---
+
+##### ~~`isConstruct`~~ <a name="isConstruct" id="aws-ddk-core.MWAATriggerDagsStage.isConstruct"></a>
+
+```typescript
+import { MWAATriggerDagsStage } from 'aws-ddk-core'
+
+MWAATriggerDagsStage.isConstruct(x: any)
+```
+
+Checks if `x` is a construct.
+
+###### `x`<sup>Required</sup> <a name="x" id="aws-ddk-core.MWAATriggerDagsStage.isConstruct.parameter.x"></a>
+
+- *Type:* any
+
+Any object.
+
+---
+
+#### Properties <a name="Properties" id="Properties"></a>
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.property.node">node</a></code> | <code>constructs.Node</code> | The tree node. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.property.description">description</a></code> | <code>string</code> | Description of the stage. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.property.eventPattern">eventPattern</a></code> | <code>aws-cdk-lib.aws_events.EventPattern</code> | Output event pattern of the stage. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.property.name">name</a></code> | <code>string</code> | Name of the stage. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.property.targets">targets</a></code> | <code>aws-cdk-lib.aws_events.IRuleTarget[]</code> | Input targets for the stage. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.property.alarmsEnabled">alarmsEnabled</a></code> | <code>boolean</code> | Flag indicating whether the alarms are enabled for this stage. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.property.cloudwatchAlarms">cloudwatchAlarms</a></code> | <code>aws-cdk-lib.aws_cloudwatch.Alarm[]</code> | List of CloudWatch Alarms linked to the stage. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.property.stateMachine">stateMachine</a></code> | <code>aws-cdk-lib.aws_stepfunctions.StateMachine</code> | State machine. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStage.property.mwaaEnvironmentName">mwaaEnvironmentName</a></code> | <code>string</code> | *No description.* |
+
+---
+
+##### `node`<sup>Required</sup> <a name="node" id="aws-ddk-core.MWAATriggerDagsStage.property.node"></a>
+
+```typescript
+public readonly node: Node;
+```
+
+- *Type:* constructs.Node
+
+The tree node.
+
+---
+
+##### `description`<sup>Optional</sup> <a name="description" id="aws-ddk-core.MWAATriggerDagsStage.property.description"></a>
+
+```typescript
+public readonly description: string;
+```
+
+- *Type:* string
+
+Description of the stage.
+
+---
+
+##### `eventPattern`<sup>Optional</sup> <a name="eventPattern" id="aws-ddk-core.MWAATriggerDagsStage.property.eventPattern"></a>
+
+```typescript
+public readonly eventPattern: EventPattern;
+```
+
+- *Type:* aws-cdk-lib.aws_events.EventPattern
+
+Output event pattern of the stage.
+
+Event pattern describes the structure of output event(s) produced by this stage.
+Event Rules use event patterns to select events and route them to targets.
+
+---
+
+##### `name`<sup>Optional</sup> <a name="name" id="aws-ddk-core.MWAATriggerDagsStage.property.name"></a>
+
+```typescript
+public readonly name: string;
+```
+
+- *Type:* string
+
+Name of the stage.
+
+---
+
+##### `targets`<sup>Optional</sup> <a name="targets" id="aws-ddk-core.MWAATriggerDagsStage.property.targets"></a>
+
+```typescript
+public readonly targets: IRuleTarget[];
+```
+
+- *Type:* aws-cdk-lib.aws_events.IRuleTarget[]
+
+Input targets for the stage.
+
+Targets are used by Event Rules to describe what should be invoked when a rule matches an event.
+
+---
+
+##### `alarmsEnabled`<sup>Required</sup> <a name="alarmsEnabled" id="aws-ddk-core.MWAATriggerDagsStage.property.alarmsEnabled"></a>
+
+```typescript
+public readonly alarmsEnabled: boolean;
+```
+
+- *Type:* boolean
+
+Flag indicating whether the alarms are enabled for this stage.
+
+---
+
+##### `cloudwatchAlarms`<sup>Required</sup> <a name="cloudwatchAlarms" id="aws-ddk-core.MWAATriggerDagsStage.property.cloudwatchAlarms"></a>
+
+```typescript
+public readonly cloudwatchAlarms: Alarm[];
+```
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.Alarm[]
+
+List of CloudWatch Alarms linked to the stage.
+
+---
+
+##### `stateMachine`<sup>Required</sup> <a name="stateMachine" id="aws-ddk-core.MWAATriggerDagsStage.property.stateMachine"></a>
+
+```typescript
+public readonly stateMachine: StateMachine;
+```
+
+- *Type:* aws-cdk-lib.aws_stepfunctions.StateMachine
+
+State machine.
+
+---
+
+##### `mwaaEnvironmentName`<sup>Required</sup> <a name="mwaaEnvironmentName" id="aws-ddk-core.MWAATriggerDagsStage.property.mwaaEnvironmentName"></a>
+
+```typescript
+public readonly mwaaEnvironmentName: string;
+```
+
+- *Type:* string
+
+---
+
+
 ### RedshiftDataApiStage <a name="RedshiftDataApiStage" id="aws-ddk-core.RedshiftDataApiStage"></a>
 
 Stage that contains a step function that executes Redshift Data API statements.
@@ -9739,6 +9978,224 @@ Log level for WorkerLogs.
 
 ---
 
+### MWAALambdasResult <a name="MWAALambdasResult" id="aws-ddk-core.MWAALambdasResult"></a>
+
+#### Initializer <a name="Initializer" id="aws-ddk-core.MWAALambdasResult.Initializer"></a>
+
+```typescript
+import { MWAALambdasResult } from 'aws-ddk-core'
+
+const mWAALambdasResult: MWAALambdasResult = { ... }
+```
+
+#### Properties <a name="Properties" id="Properties"></a>
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| <code><a href="#aws-ddk-core.MWAALambdasResult.property.statusLambda">statusLambda</a></code> | <code>aws-cdk-lib.aws_lambda.Function</code> | *No description.* |
+| <code><a href="#aws-ddk-core.MWAALambdasResult.property.triggerLambda">triggerLambda</a></code> | <code>aws-cdk-lib.aws_lambda.Function</code> | *No description.* |
+
+---
+
+##### `statusLambda`<sup>Required</sup> <a name="statusLambda" id="aws-ddk-core.MWAALambdasResult.property.statusLambda"></a>
+
+```typescript
+public readonly statusLambda: Function;
+```
+
+- *Type:* aws-cdk-lib.aws_lambda.Function
+
+---
+
+##### `triggerLambda`<sup>Required</sup> <a name="triggerLambda" id="aws-ddk-core.MWAALambdasResult.property.triggerLambda"></a>
+
+```typescript
+public readonly triggerLambda: Function;
+```
+
+- *Type:* aws-cdk-lib.aws_lambda.Function
+
+---
+
+### MWAATriggerDagsStageProps <a name="MWAATriggerDagsStageProps" id="aws-ddk-core.MWAATriggerDagsStageProps"></a>
+
+Properties of the MWAA Trigger Dags stage.
+
+#### Initializer <a name="Initializer" id="aws-ddk-core.MWAATriggerDagsStageProps.Initializer"></a>
+
+```typescript
+import { MWAATriggerDagsStageProps } from 'aws-ddk-core'
+
+const mWAATriggerDagsStageProps: MWAATriggerDagsStageProps = { ... }
+```
+
+#### Properties <a name="Properties" id="Properties"></a>
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.description">description</a></code> | <code>string</code> | Description of the stage. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.name">name</a></code> | <code>string</code> | Name of the stage. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.additionalRolePolicyStatements">additionalRolePolicyStatements</a></code> | <code>aws-cdk-lib.aws_iam.PolicyStatement[]</code> | Additional IAM policy statements to add to the state machine role. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.alarmsEnabled">alarmsEnabled</a></code> | <code>boolean</code> | Enable/Disable all alarms in the stage. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.stateMachineFailedExecutionsAlarmEvaluationPeriods">stateMachineFailedExecutionsAlarmEvaluationPeriods</a></code> | <code>number</code> | The number of periods over which data is compared to the specified threshold. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.stateMachineFailedExecutionsAlarmThreshold">stateMachineFailedExecutionsAlarmThreshold</a></code> | <code>number</code> | The number of failed state machine executions before triggering CW alarm. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.stateMachineInput">stateMachineInput</a></code> | <code>{[ key: string ]: any}</code> | Input of the state machine. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.stateMachineName">stateMachineName</a></code> | <code>string</code> | Name of the state machine. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.mwaaEnvironmentName">mwaaEnvironmentName</a></code> | <code>string</code> | Name of airflow environment. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.dagPath">dagPath</a></code> | <code>string</code> | Path to array of dag id's to check. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.dags">dags</a></code> | <code>string[]</code> | Name of dag(s) to trigger. |
+| <code><a href="#aws-ddk-core.MWAATriggerDagsStageProps.property.statusCheckPeriod">statusCheckPeriod</a></code> | <code>aws-cdk-lib.Duration</code> | Time to wait between execution status checks. |
+
+---
+
+##### `description`<sup>Optional</sup> <a name="description" id="aws-ddk-core.MWAATriggerDagsStageProps.property.description"></a>
+
+```typescript
+public readonly description: string;
+```
+
+- *Type:* string
+
+Description of the stage.
+
+---
+
+##### `name`<sup>Optional</sup> <a name="name" id="aws-ddk-core.MWAATriggerDagsStageProps.property.name"></a>
+
+```typescript
+public readonly name: string;
+```
+
+- *Type:* string
+
+Name of the stage.
+
+---
+
+##### `additionalRolePolicyStatements`<sup>Optional</sup> <a name="additionalRolePolicyStatements" id="aws-ddk-core.MWAATriggerDagsStageProps.property.additionalRolePolicyStatements"></a>
+
+```typescript
+public readonly additionalRolePolicyStatements: PolicyStatement[];
+```
+
+- *Type:* aws-cdk-lib.aws_iam.PolicyStatement[]
+
+Additional IAM policy statements to add to the state machine role.
+
+---
+
+##### `alarmsEnabled`<sup>Optional</sup> <a name="alarmsEnabled" id="aws-ddk-core.MWAATriggerDagsStageProps.property.alarmsEnabled"></a>
+
+```typescript
+public readonly alarmsEnabled: boolean;
+```
+
+- *Type:* boolean
+- *Default:* true
+
+Enable/Disable all alarms in the stage.
+
+---
+
+##### `stateMachineFailedExecutionsAlarmEvaluationPeriods`<sup>Optional</sup> <a name="stateMachineFailedExecutionsAlarmEvaluationPeriods" id="aws-ddk-core.MWAATriggerDagsStageProps.property.stateMachineFailedExecutionsAlarmEvaluationPeriods"></a>
+
+```typescript
+public readonly stateMachineFailedExecutionsAlarmEvaluationPeriods: number;
+```
+
+- *Type:* number
+- *Default:* 1
+
+The number of periods over which data is compared to the specified threshold.
+
+---
+
+##### `stateMachineFailedExecutionsAlarmThreshold`<sup>Optional</sup> <a name="stateMachineFailedExecutionsAlarmThreshold" id="aws-ddk-core.MWAATriggerDagsStageProps.property.stateMachineFailedExecutionsAlarmThreshold"></a>
+
+```typescript
+public readonly stateMachineFailedExecutionsAlarmThreshold: number;
+```
+
+- *Type:* number
+- *Default:* 1
+
+The number of failed state machine executions before triggering CW alarm.
+
+---
+
+##### `stateMachineInput`<sup>Optional</sup> <a name="stateMachineInput" id="aws-ddk-core.MWAATriggerDagsStageProps.property.stateMachineInput"></a>
+
+```typescript
+public readonly stateMachineInput: {[ key: string ]: any};
+```
+
+- *Type:* {[ key: string ]: any}
+
+Input of the state machine.
+
+---
+
+##### `stateMachineName`<sup>Optional</sup> <a name="stateMachineName" id="aws-ddk-core.MWAATriggerDagsStageProps.property.stateMachineName"></a>
+
+```typescript
+public readonly stateMachineName: string;
+```
+
+- *Type:* string
+
+Name of the state machine.
+
+---
+
+##### `mwaaEnvironmentName`<sup>Required</sup> <a name="mwaaEnvironmentName" id="aws-ddk-core.MWAATriggerDagsStageProps.property.mwaaEnvironmentName"></a>
+
+```typescript
+public readonly mwaaEnvironmentName: string;
+```
+
+- *Type:* string
+
+Name of airflow environment.
+
+---
+
+##### `dagPath`<sup>Optional</sup> <a name="dagPath" id="aws-ddk-core.MWAATriggerDagsStageProps.property.dagPath"></a>
+
+```typescript
+public readonly dagPath: string;
+```
+
+- *Type:* string
+
+Path to array of dag id's to check.
+
+---
+
+##### `dags`<sup>Optional</sup> <a name="dags" id="aws-ddk-core.MWAATriggerDagsStageProps.property.dags"></a>
+
+```typescript
+public readonly dags: string[];
+```
+
+- *Type:* string[]
+
+Name of dag(s) to trigger.
+
+---
+
+##### `statusCheckPeriod`<sup>Optional</sup> <a name="statusCheckPeriod" id="aws-ddk-core.MWAATriggerDagsStageProps.property.statusCheckPeriod"></a>
+
+```typescript
+public readonly statusCheckPeriod: Duration;
+```
+
+- *Type:* aws-cdk-lib.Duration
+- *Default:* aws_cdk.Duration.seconds(15)
+
+Time to wait between execution status checks.
+
+---
+
 ### PermissionsBoundaryProps <a name="PermissionsBoundaryProps" id="aws-ddk-core.PermissionsBoundaryProps"></a>
 
 #### Initializer <a name="Initializer" id="aws-ddk-core.PermissionsBoundaryProps.Initializer"></a>
diff --git a/package-lock.json b/package-lock.json
index 1c744e96..85ab4651 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -38,12 +38,12 @@
         "jest": "^27",
         "jest-junit": "^15",
         "jsii": "1.x",
-        "jsii-diff": "^1.83.0",
+        "jsii-diff": "^1.84.0",
         "jsii-docgen": "^7.2.9",
-        "jsii-pacmak": "^1.83.0",
+        "jsii-pacmak": "^1.84.0",
         "npm-check-updates": "^16",
         "prettier": "^2.8.8",
-        "projen": "^0.71.94",
+        "projen": "^0.71.103",
         "standard-version": "^9",
         "ts-jest": "^27",
         "typescript": "^4.9.5"
@@ -1245,28 +1245,28 @@
       "dev": true
     },
     "node_modules/@jsii/check-node": {
-      "version": "1.83.0",
-      "resolved": "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.83.0.tgz",
-      "integrity": "sha512-6UqMGNZs22wpOYxlT5JgoJyF1K/vkj+ZY57zrBp3WYN6rPQt7iZ0Y8CnLGZ3kwwzhatIrzbhng+8jPXFSVrNyw==",
+      "version": "1.84.0",
+      "resolved": "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.84.0.tgz",
+      "integrity": "sha512-gLa+N1WKksCjTXaK8VMjTbEXf58QlrDOovoTOEzhGNgTFyAUX8woIRAUmk+X70ssDzBvgh3E98mIsDKoWOp6zA==",
       "dev": true,
       "dependencies": {
         "chalk": "^4.1.2",
         "semver": "^7.5.1"
       },
       "engines": {
-        "node": ">= 14.6.0"
+        "node": ">= 14.17.0"
       }
     },
     "node_modules/@jsii/spec": {
-      "version": "1.83.0",
-      "resolved": "https://registry.npmjs.org/@jsii/spec/-/spec-1.83.0.tgz",
-      "integrity": "sha512-lhTW4ShZe7B2CnUFHyxHM+wWhSNK9UIzZTZV5C6Lx7vCpCtXGzP63ziPnpSQ0B0AD1ZS5o3GaYDAPieelkf2Ow==",
+      "version": "1.84.0",
+      "resolved": "https://registry.npmjs.org/@jsii/spec/-/spec-1.84.0.tgz",
+      "integrity": "sha512-P2PCE4jlmuTh5Oj7Be2jdn5qyzIWHX4rcyYspddc0DLZAuLB/LRQYytrxgfdy4+NroGhrPeKPBoF9MwJ5CzfXA==",
       "dev": true,
       "dependencies": {
         "ajv": "^8.12.0"
       },
       "engines": {
-        "node": ">= 14.6.0"
+        "node": ">= 14.17.0"
       }
     },
     "node_modules/@jsii/spec/node_modules/ajv": {
@@ -2714,8 +2714,6 @@
     },
     "node_modules/aws-cdk-lib/node_modules/semver": {
       "version": "7.3.8",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
-      "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
       "dev": true,
       "inBundle": true,
       "license": "ISC",
@@ -3466,9 +3464,9 @@
       }
     },
     "node_modules/codemaker": {
-      "version": "1.83.0",
-      "resolved": "https://registry.npmjs.org/codemaker/-/codemaker-1.83.0.tgz",
-      "integrity": "sha512-KyGpWygoeUhPY0FlLb8mp6k6sccg+sRHmgNcl5L54Lg5ppqufQL1DIPmDqymMRHqeCGxrnB/bZWeKJhtsjDAKQ==",
+      "version": "1.84.0",
+      "resolved": "https://registry.npmjs.org/codemaker/-/codemaker-1.84.0.tgz",
+      "integrity": "sha512-sOUH3y2q2DEO+gDiBCCoGgkDs8aMY0LTMH0FmHbKpqReZwWDAmWJ0Voc4Thp4Mn380bPku9/ncqyY1a3MZnfEQ==",
       "dev": true,
       "dependencies": {
         "camelcase": "^6.3.0",
@@ -3476,7 +3474,7 @@
         "fs-extra": "^10.1.0"
       },
       "engines": {
-        "node": ">= 14.6.0"
+        "node": ">= 14.17.0"
       }
     },
     "node_modules/codemaker/node_modules/camelcase": {
@@ -7578,13 +7576,13 @@
       }
     },
     "node_modules/jsii": {
-      "version": "1.83.0",
-      "resolved": "https://registry.npmjs.org/jsii/-/jsii-1.83.0.tgz",
-      "integrity": "sha512-LxWncwj1lEJN0IIFksrNSh4ksTUbMKLLS6UC01JKxOiyVvxuXTc0skl3XYCVLjJvd1S20oBSalFD2evxMFUaqQ==",
+      "version": "1.84.0",
+      "resolved": "https://registry.npmjs.org/jsii/-/jsii-1.84.0.tgz",
+      "integrity": "sha512-vtrw3fRrr5Do4LDNxAVXHgtHDyxHvohyzAfBwxcMEYzZ51gJX52wsdlaGE1p0dPe1V9uCAbNQTDKbAMgVJkg0Q==",
       "dev": true,
       "dependencies": {
-        "@jsii/check-node": "1.83.0",
-        "@jsii/spec": "^1.83.0",
+        "@jsii/check-node": "1.84.0",
+        "@jsii/spec": "^1.84.0",
         "case": "^1.6.3",
         "chalk": "^4",
         "fast-deep-equal": "^3.1.3",
@@ -7601,19 +7599,19 @@
         "jsii": "bin/jsii"
       },
       "engines": {
-        "node": ">= 14.6.0"
+        "node": ">= 14.17.0"
       }
     },
     "node_modules/jsii-diff": {
-      "version": "1.83.0",
-      "resolved": "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.83.0.tgz",
-      "integrity": "sha512-IY3OBIBFNjrsE/4wO9eyt+emmz15LL1dYJaNUk1IfM3ROzodpbuNV/nwQ76THpGfaN+E436NWyM56JU5oP3pBA==",
+      "version": "1.84.0",
+      "resolved": "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.84.0.tgz",
+      "integrity": "sha512-MDw8GNkBtBxlTqMcgUANV/q4h5offJ/KN9gyU5BYK/eXsKs7xa5vBmihOgQWvqx8cnszrTMNhvpnvMSNxcPRzw==",
       "dev": true,
       "dependencies": {
-        "@jsii/check-node": "1.83.0",
-        "@jsii/spec": "^1.83.0",
+        "@jsii/check-node": "1.84.0",
+        "@jsii/spec": "^1.84.0",
         "fs-extra": "^10.1.0",
-        "jsii-reflect": "^1.83.0",
+        "jsii-reflect": "^1.84.0",
         "log4js": "^6.9.1",
         "yargs": "^16.2.0"
       },
@@ -7621,7 +7619,7 @@
         "jsii-diff": "bin/jsii-diff"
       },
       "engines": {
-        "node": ">= 14.6.0"
+        "node": ">= 14.17.0"
       }
     },
     "node_modules/jsii-docgen": {
@@ -7648,20 +7646,20 @@
       }
     },
     "node_modules/jsii-pacmak": {
-      "version": "1.83.0",
-      "resolved": "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.83.0.tgz",
-      "integrity": "sha512-eVSX86tUx6/55O73Bc/NrcOkIWNH3YdyS+WdQdIPKgoOVfTWqbnUOY5rYoyUUcCOrO2wLtgVeP8u1bJkoD3U5w==",
+      "version": "1.84.0",
+      "resolved": "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.84.0.tgz",
+      "integrity": "sha512-+EGfpQDPSyDNPWclcOes6dUhwDsn5dG0bBgVb3hpRWZ0uDe7wLCVwGxh7fphx2XtNvTwdNfspTSBLBMqscOYmg==",
       "dev": true,
       "dependencies": {
-        "@jsii/check-node": "1.83.0",
-        "@jsii/spec": "^1.83.0",
+        "@jsii/check-node": "1.84.0",
+        "@jsii/spec": "^1.84.0",
         "clone": "^2.1.2",
-        "codemaker": "^1.83.0",
+        "codemaker": "^1.84.0",
         "commonmark": "^0.30.0",
         "escape-string-regexp": "^4.0.0",
         "fs-extra": "^10.1.0",
-        "jsii-reflect": "^1.83.0",
-        "jsii-rosetta": "^1.83.0",
+        "jsii-reflect": "^1.84.0",
+        "jsii-rosetta": "^1.84.0",
         "semver": "^7.5.1",
         "spdx-license-list": "^6.6.0",
         "xmlbuilder": "^15.1.1",
@@ -7671,41 +7669,41 @@
         "jsii-pacmak": "bin/jsii-pacmak"
       },
       "engines": {
-        "node": ">= 14.6.0"
+        "node": ">= 14.17.0"
       }
     },
     "node_modules/jsii-reflect": {
-      "version": "1.83.0",
-      "resolved": "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.83.0.tgz",
-      "integrity": "sha512-cR3QxpoUp8w9CwCP8dtkff8PZfQMT1gbciUObs0Mr6E2bEyH33QpOmllkIHMspZqtBiz46pWrIkAe5IqJnadtg==",
+      "version": "1.84.0",
+      "resolved": "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.84.0.tgz",
+      "integrity": "sha512-Iuh0GAxsQscK1re9sWEQHG0wKswnr7ha4EZ8j47Sigo8yBIZNp01P+V0kbZ55bDjiT66Sqqu3jaDJdYzR/5o4w==",
       "dev": true,
       "dependencies": {
-        "@jsii/check-node": "1.83.0",
-        "@jsii/spec": "^1.83.0",
+        "@jsii/check-node": "1.84.0",
+        "@jsii/spec": "^1.84.0",
         "chalk": "^4",
         "fs-extra": "^10.1.0",
-        "oo-ascii-tree": "^1.83.0",
+        "oo-ascii-tree": "^1.84.0",
         "yargs": "^16.2.0"
       },
       "bin": {
         "jsii-tree": "bin/jsii-tree"
       },
       "engines": {
-        "node": ">= 14.6.0"
+        "node": ">= 14.17.0"
       }
     },
     "node_modules/jsii-rosetta": {
-      "version": "1.83.0",
-      "resolved": "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.83.0.tgz",
-      "integrity": "sha512-9yMTijjLoINcrhzA+r96zAPAEvVNXRqKei5SOP+ScmGKhPZ1/fYb7Z3+Unr3VWkWgUtVaiqUZTxAvVUAQHo/Pg==",
+      "version": "1.84.0",
+      "resolved": "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.84.0.tgz",
+      "integrity": "sha512-VrXmc6utiNs3eNTKxVky0LTxoQrsh5GuEGyfj9ihwCkojYBJ3w80PdkMQEeRpWGdaCLEocjpy1X67xgZ4ZbPlg==",
       "dev": true,
       "dependencies": {
-        "@jsii/check-node": "1.83.0",
-        "@jsii/spec": "1.83.0",
+        "@jsii/check-node": "1.84.0",
+        "@jsii/spec": "1.84.0",
         "@xmldom/xmldom": "^0.8.8",
         "commonmark": "^0.30.0",
         "fast-glob": "^3.2.12",
-        "jsii": "1.83.0",
+        "jsii": "1.84.0",
         "semver": "^7.5.1",
         "semver-intersect": "^1.4.0",
         "stream-json": "^1.8.0",
@@ -7717,7 +7715,7 @@
         "jsii-rosetta": "bin/jsii-rosetta"
       },
       "engines": {
-        "node": ">= 14.6.0"
+        "node": ">= 14.17.0"
       }
     },
     "node_modules/jsii-rosetta/node_modules/typescript": {
@@ -9450,12 +9448,12 @@
       }
     },
     "node_modules/oo-ascii-tree": {
-      "version": "1.83.0",
-      "resolved": "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.83.0.tgz",
-      "integrity": "sha512-Fib3Py1moaeRkIRCZyKmqHvuWGf1x3SXE5vjFc5L13EMgycO6edNgkLFa/0zSy+oZHzkNneLY3Ozt7UZFy0k6g==",
+      "version": "1.84.0",
+      "resolved": "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.84.0.tgz",
+      "integrity": "sha512-8bvsAKFAQ7HwU3lAEDwsKYDkTqsDTsRTkr3J0gvH1U805d2no9rUNYptWzg3oYku5h5mr9Bko+BIh1pjSD8qrg==",
       "dev": true,
       "engines": {
-        "node": ">= 14.6.0"
+        "node": ">= 14.17.0"
       }
     },
     "node_modules/open": {
@@ -9916,9 +9914,9 @@
       }
     },
     "node_modules/projen": {
-      "version": "0.71.94",
-      "resolved": "https://registry.npmjs.org/projen/-/projen-0.71.94.tgz",
-      "integrity": "sha512-zedd04Y1DDdqWVcgJ+RSBjE5ubkPjUm0Ln9ER0BnWRtdq/zUfhPeBNMRB7HtpgZFmWSmW4jKrySv/OwNtceLzA==",
+      "version": "0.71.103",
+      "resolved": "https://registry.npmjs.org/projen/-/projen-0.71.103.tgz",
+      "integrity": "sha512-zhfMkwyLQ0US4GlO1FB1gnwy8WicBDZbIX0pAZklc6duz9TviXsdfzAI1lG4Cu/fmJcXnXcvv4AjeaFm2b+LTA==",
       "bundleDependencies": [
         "@iarna/toml",
         "case",
@@ -9944,7 +9942,7 @@
         "fast-json-patch": "^3.1.1",
         "glob": "^8",
         "ini": "^2.0.0",
-        "semver": "^7.5.1",
+        "semver": "^7.5.2",
         "shx": "^0.3.4",
         "xmlbuilder2": "^3.1.1",
         "yaml": "^2.2.2",
@@ -10510,9 +10508,9 @@
       }
     },
     "node_modules/projen/node_modules/semver": {
-      "version": "7.5.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
-      "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+      "version": "7.5.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz",
+      "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==",
       "dev": true,
       "inBundle": true,
       "license": "ISC",
diff --git a/src/stages/index.ts b/src/stages/index.ts
index 74eb152e..3ed13f9d 100644
--- a/src/stages/index.ts
+++ b/src/stages/index.ts
@@ -3,6 +3,7 @@ export * from "./athena-sql";
 export * from "./databrew-transform";
 export * from "./glue-transform";
 export * from "./kinesis-s3";
+export * from "./mwaa-trigger-dags";
 export * from "./redshift-data-api";
 export * from "./s3-event";
 export * from "./sns-lambda";
diff --git a/src/stages/mwaa-trigger-dags.ts b/src/stages/mwaa-trigger-dags.ts
new file mode 100644
index 00000000..d26cb152
--- /dev/null
+++ b/src/stages/mwaa-trigger-dags.ts
@@ -0,0 +1,250 @@
+import * as cdk from "aws-cdk-lib";
+import * as events from "aws-cdk-lib/aws-events";
+import * as iam from "aws-cdk-lib/aws-iam";
+import * as lambda from "aws-cdk-lib/aws-lambda";
+import * as sfn from "aws-cdk-lib/aws-stepfunctions";
+import * as tasks from "aws-cdk-lib/aws-stepfunctions-tasks";
+import { Construct } from "constructs";
+import { StateMachineStage, StateMachineStageProps } from "../pipelines/stage";
+
+/**
+ * Properties of the MWAA Trigger Dags stage.
+ */
+export interface MWAATriggerDagsStageProps extends StateMachineStageProps {
+  /**
+   * Name of airflow environment.
+   */
+  readonly mwaaEnvironmentName: string;
+  /**
+   * Name of dag(s) to trigger.
+   */
+  readonly dags?: string[];
+  /**
+   * Path to array of dag id's to check.
+   */
+  readonly dagPath?: string;
+  /**
+   * Time to wait between execution status checks.
+   * @default aws_cdk.Duration.seconds(15)
+   */
+  readonly statusCheckPeriod?: cdk.Duration;
+}
+
+export interface MWAALambdasResult {
+  readonly triggerLambda: lambda.Function;
+  readonly statusLambda: lambda.Function;
+}
+
+/**
+ * Stage that contains a step function that runs a Managed Apache Airflow (MWAA) dag or set of dags .
+ */
+export class MWAATriggerDagsStage extends StateMachineStage {
+  readonly targets?: events.IRuleTarget[];
+  readonly eventPattern?: events.EventPattern;
+  readonly stateMachine: sfn.StateMachine;
+  readonly mwaaEnvironmentName: string;
+
+  /**
+   * Constructs MWAATriggerDagsStage.
+   * @param scope Scope within which this construct is defined.
+   * @param id Identifier of the stage.
+   * @param props Properties for the stage.
+   */
+  constructor(scope: Construct, id: string, props: MWAATriggerDagsStageProps) {
+    super(scope, id, props);
+
+    this.mwaaEnvironmentName = props.mwaaEnvironmentName;
+    if (props.dags && props.dagPath) {
+      throw TypeError("For this stage provide one of 'dags' or 'dagPath' parameter, not both");
+    }
+    const dagIds = props.dagPath ? sfn.JsonPath.stringAt(props.dagPath) : props.dags;
+    if (!dagIds) {
+      throw TypeError("For this stage one of 'dags' or 'dagPath' parameter is required");
+    }
+    const lambdas = this.buildLambdas();
+
+    const definition = new sfn.Parallel(this, "Parallel States");
+    const waitTask = new sfn.Wait(this, "Wait Before Checking Status", {
+      time: sfn.WaitTime.duration(props.statusCheckPeriod ?? cdk.Duration.seconds(15)),
+    });
+    definition.branch(
+      new tasks.LambdaInvoke(this, "Trigger Dag", {
+        lambdaFunction: lambdas.triggerLambda,
+        payload: sfn.TaskInput.fromObject({ dag_ids: dagIds }),
+        resultPath: sfn.JsonPath.DISCARD,
+      })
+        .next(waitTask)
+        .next(
+          new tasks.LambdaInvoke(this, "Get Dag Execution Status", {
+            lambdaFunction: lambdas.statusLambda,
+            payload: sfn.TaskInput.fromObject({ dag_ids: dagIds }),
+            resultPath: "$.result",
+          }).next(
+            new sfn.Choice(this, `Check Execution Status`)
+              .when(sfn.Condition.stringEquals("$.result.Payload", "success"), new sfn.Succeed(this, "Success"))
+              .when(
+                sfn.Condition.stringEquals("$.result.Payload", "failed"),
+                new sfn.Fail(this, "Failure", { error: "DagExecutionFailed" }),
+              )
+              .otherwise(waitTask),
+          ),
+        ),
+    );
+
+    ({
+      eventPattern: this.eventPattern,
+      targets: this.targets,
+      stateMachine: this.stateMachine,
+    } = this.createStateMachine(definition, props));
+  }
+
+  private buildLambdas(): MWAALambdasResult {
+    const lambdaRole = new iam.Role(this, `MWAA Stage Lambda Role`, {
+      assumedBy: new iam.ServicePrincipal("lambda.amazonaws.com"),
+      description: "lambda role to trigger airflow dag execution",
+    });
+
+    // Enable the functions to get flow execution records
+    lambdaRole.addToPolicy(
+      new iam.PolicyStatement({
+        effect: iam.Effect.ALLOW,
+        actions: ["airflow:CreateCliToken"],
+        resources: ["*"],
+      }),
+    );
+
+    const triggerLambda = new lambda.Function(this, "Trigger Dag Lambda", {
+      code: lambda.Code.fromInline(`
+# Copyright 2023 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.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import boto3
+import http.client
+import base64
+import ast
+from datetime import datetime 
+import json
+
+execution_date = datetime.today().strftime('%Y-%m-%d')
+mwaa_env_name = "${this.mwaaEnvironmentName}"
+
+client = boto3.client('mwaa')
+
+def run_api_call(conn, payload, headers):
+    print(f"running command: {payload}")
+    conn.request("POST", "/aws_mwaa/cli", payload, headers)
+    res = conn.getresponse()
+    data = res.read()
+    dict_str = data.decode("UTF-8")
+    mydata = ast.literal_eval(dict_str)
+    return base64.b64decode(mydata['stdout'])
+    
+def lambda_handler(event, context):
+    # get web token
+    mwaa_cli_token = client.create_cli_token(
+        Name=mwaa_env_name
+    )
+    
+    conn = http.client.HTTPSConnection(mwaa_cli_token['WebServerHostname'])
+    headers = {
+      'Authorization': 'Bearer ' + mwaa_cli_token['CliToken'],
+      'Content-Type': 'text/plain'
+    }
+
+    for dag_id in event['dag_ids']:
+      run_api_call(conn, f"dags trigger {dag_id}", headers)
+        `),
+      handler: "index.lambda_handler",
+      role: lambdaRole,
+      runtime: lambda.Runtime.PYTHON_3_9,
+      memorySize: 256,
+      timeout: cdk.Duration.seconds(60),
+    });
+
+    const statusLambda = new lambda.Function(this, "Check Dag Status Lambda", {
+      code: lambda.Code.fromInline(`
+# Copyright 2023 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.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import boto3
+import http.client
+import base64
+import ast
+from datetime import datetime 
+import json
+
+execution_date = datetime.today().strftime('%Y-%m-%d')
+mwaa_env_name = "${this.mwaaEnvironmentName}"
+
+client = boto3.client('mwaa')
+
+def run_api_call(conn, payload, headers):
+    print(f"running command: {payload}")
+    conn.request("POST", "/aws_mwaa/cli", payload, headers)
+    res = conn.getresponse()
+    data = res.read()
+    dict_str = data.decode("UTF-8")
+    mydata = ast.literal_eval(dict_str)
+    return base64.b64decode(mydata['stdout'])
+    
+def lambda_handler(event, context):
+    # get web token
+    mwaa_cli_token = client.create_cli_token(
+        Name=mwaa_env_name
+    )
+  
+    conn = http.client.HTTPSConnection(mwaa_cli_token['WebServerHostname'])
+    headers = {
+      'Authorization': 'Bearer ' + mwaa_cli_token['CliToken'],
+      'Content-Type': 'text/plain'
+    }
+
+    dag_results = []
+    for dag_id in event['dag_ids']:
+      results = json.loads(run_api_call(conn, f"dags list-runs -d {dag_id} -o json -s {execution_date}", headers))
+      for result in results:
+          dag_results.append(result['state'])
+          break
+    
+    if "running" in dag_results:
+        return "running"
+    elif "failed" in dag_results:
+        return "failed"
+    else:
+        return "success"
+        `),
+      handler: "index.lambda_handler",
+      role: lambdaRole,
+      runtime: lambda.Runtime.PYTHON_3_9,
+      memorySize: 256,
+      timeout: cdk.Duration.seconds(60),
+    });
+
+    return {
+      triggerLambda,
+      statusLambda,
+    };
+  }
+}


Test patch:
diff --git a/integ/integ.mwaa-trigger.test.ts b/integ/integ.mwaa-trigger.test.ts
new file mode 100644
index 00000000..de7be314
--- /dev/null
+++ b/integ/integ.mwaa-trigger.test.ts
@@ -0,0 +1,40 @@
+import * as integration from "@aws-cdk/integ-tests-alpha";
+import * as cdk from "aws-cdk-lib";
+import { Construct } from "constructs";
+import { RequireApproval } from "aws-cdk-lib/cloud-assembly-schema";
+
+import { MWAATriggerDagsStage } from "../src";
+
+
+class MWAATriggerDagsStageTestStack extends cdk.Stack {
+  constructor(scope: Construct, id: string, props: cdk.StackProps) {
+    super(scope, id, props);
+
+    new MWAATriggerDagsStage(this, "MWAA Trigger Stage", {
+      mwaaEnvironmentName: "dummy",
+      dags: ["foo", "bar"]
+    });
+  }
+}
+
+const app = new cdk.App();
+new integration.IntegTest(app, "MWAA Trigger Dags Stage Integration Tests", {
+    testCases: [
+      new MWAATriggerDagsStageTestStack(app, "MWAATriggerDagsTest", {}),
+    ],
+    diffAssets: true,
+    stackUpdateWorkflow: true,
+    cdkCommandOptions: {
+      deploy: {
+        args: {
+          requireApproval: RequireApproval.NEVER,
+          json: true,
+        },
+      },
+      destroy: {
+        args: {
+          force: true,
+        },
+      },
+    },
+});
diff --git a/test/mwaa-trigger-dags-stage.test.ts b/test/mwaa-trigger-dags-stage.test.ts
new file mode 100644
index 00000000..ecc6d0c9
--- /dev/null
+++ b/test/mwaa-trigger-dags-stage.test.ts
@@ -0,0 +1,70 @@
+import * as cdk from "aws-cdk-lib";
+import { Match, Template } from "aws-cdk-lib/assertions";
+
+import { MWAATriggerDagsStage } from "../src";
+
+test("MWAA Trigger Dags Stage Basic", () => {
+  const stack = new cdk.Stack();
+  new MWAATriggerDagsStage(stack, "MWAA Stage", { mwaaEnvironmentName: "dummyenv", dags: ["dummy"] });
+  const template = Template.fromStack(stack);
+  template.hasResourceProperties("AWS::StepFunctions::StateMachine", {
+    DefinitionString: {
+      "Fn::Join": [
+        "",
+        Match.arrayWith([Match.stringLikeRegexp("Trigger Dag"), Match.stringLikeRegexp("Get Dag Execution Status")]),
+      ],
+    },
+  });
+});
+
+test("MWAA Trigger Dags Stage More Options", () => {
+  const stack = new cdk.Stack();
+  new MWAATriggerDagsStage(stack, "MWAA Stage", {
+    mwaaEnvironmentName: "dummyenv",
+    dags: ["foo", "bar"],
+    statusCheckPeriod: cdk.Duration.minutes(1),
+  });
+  const template = Template.fromStack(stack);
+  template.hasResourceProperties("AWS::StepFunctions::StateMachine", {
+    DefinitionString: {
+      "Fn::Join": [
+        "",
+        Match.arrayWith([Match.stringLikeRegexp("Trigger Dag"), Match.stringLikeRegexp("Get Dag Execution Status")]),
+      ],
+    },
+  });
+});
+
+test("MWAA Trigger Dags Path", () => {
+  const stack = new cdk.Stack();
+  new MWAATriggerDagsStage(stack, "MWAA Stage", {
+    mwaaEnvironmentName: "dummyenv",
+    dagPath: "$.dag_ids",
+  });
+  const template = Template.fromStack(stack);
+  template.hasResourceProperties("AWS::StepFunctions::StateMachine", {
+    DefinitionString: {
+      "Fn::Join": ["", Match.arrayWith([Match.stringLikeRegexp(".*dag_ids")])],
+    },
+  });
+});
+
+test("MWAATriggerDags missing dags property", () => {
+  const stack = new cdk.Stack();
+  expect(() => {
+    new MWAATriggerDagsStage(stack, "Stage", {
+      mwaaEnvironmentName: "dummyenv",
+    });
+  }).toThrowError("For this stage one of 'dags' or 'dagPath' parameter is required");
+});
+
+test("MWAATriggerDags duplicate dags properties", () => {
+  const stack = new cdk.Stack();
+  expect(() => {
+    new MWAATriggerDagsStage(stack, "Stage", {
+      mwaaEnvironmentName: "dummyenv",
+      dags: ["foo"],
+      dagPath: "$.dags",
+    });
+  }).toThrowError("For this stage provide one of 'dags' or 'dagPath' parameter, not both");
+});