Repository: cdklabs/cdk-monitoring-constructs (language: python)

Issue:
[ec2] add filter of instance IDs
As a customer:

> I would just prefer a property under .monitorEC2instances that would allow me to specify instance ID's or something along those lines. I didn't deploy the instances via an ASG, so it seems like an all or nothing approach using this construct.


Discussion / hints:
If ASG is undefined, all instances are monitored and the metrics are created as a metric search expression. I think we need a different approach for a list of IDs - we do not want to use search expression, but iterate through the IDs, and create one metric for each instance separately, then combine them in a widget.

Fix patch:
diff --git a/API.md b/API.md
index c2350104..8666fdbb 100644
--- a/API.md
+++ b/API.md
@@ -12739,6 +12739,51 @@ public readonly addUnhealthyTaskCountAlarm: {[ key: string ]: UnhealthyTaskCount
 
 ---
 
+### EC2MetricFactoryProps <a name="EC2MetricFactoryProps" id="cdk-monitoring-constructs.EC2MetricFactoryProps"></a>
+
+#### Initializer <a name="Initializer" id="cdk-monitoring-constructs.EC2MetricFactoryProps.Initializer"></a>
+
+```typescript
+import { EC2MetricFactoryProps } from 'cdk-monitoring-constructs'
+
+const eC2MetricFactoryProps: EC2MetricFactoryProps = { ... }
+```
+
+#### Properties <a name="Properties" id="Properties"></a>
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| <code><a href="#cdk-monitoring-constructs.EC2MetricFactoryProps.property.autoScalingGroup">autoScalingGroup</a></code> | <code>aws-cdk-lib.aws_autoscaling.IAutoScalingGroup</code> | Auto-Scaling Group to monitor. |
+| <code><a href="#cdk-monitoring-constructs.EC2MetricFactoryProps.property.instanceIds">instanceIds</a></code> | <code>string[]</code> | Selected IDs of EC2 instances to monitor. |
+
+---
+
+##### `autoScalingGroup`<sup>Optional</sup> <a name="autoScalingGroup" id="cdk-monitoring-constructs.EC2MetricFactoryProps.property.autoScalingGroup"></a>
+
+```typescript
+public readonly autoScalingGroup: IAutoScalingGroup;
+```
+
+- *Type:* aws-cdk-lib.aws_autoscaling.IAutoScalingGroup
+- *Default:* no Auto-Scaling Group filter
+
+Auto-Scaling Group to monitor.
+
+---
+
+##### `instanceIds`<sup>Optional</sup> <a name="instanceIds" id="cdk-monitoring-constructs.EC2MetricFactoryProps.property.instanceIds"></a>
+
+```typescript
+public readonly instanceIds: string[];
+```
+
+- *Type:* string[]
+- *Default:* no instance filter
+
+Selected IDs of EC2 instances to monitor.
+
+---
+
 ### EC2MonitoringOptions <a name="EC2MonitoringOptions" id="cdk-monitoring-constructs.EC2MonitoringOptions"></a>
 
 #### Initializer <a name="Initializer" id="cdk-monitoring-constructs.EC2MonitoringOptions.Initializer"></a>
@@ -12753,6 +12798,8 @@ const eC2MonitoringOptions: EC2MonitoringOptions = { ... }
 
 | **Name** | **Type** | **Description** |
 | --- | --- | --- |
+| <code><a href="#cdk-monitoring-constructs.EC2MonitoringOptions.property.autoScalingGroup">autoScalingGroup</a></code> | <code>aws-cdk-lib.aws_autoscaling.IAutoScalingGroup</code> | Auto-Scaling Group to monitor. |
+| <code><a href="#cdk-monitoring-constructs.EC2MonitoringOptions.property.instanceIds">instanceIds</a></code> | <code>string[]</code> | Selected IDs of EC2 instances to monitor. |
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringOptions.property.alarmFriendlyName">alarmFriendlyName</a></code> | <code>string</code> | Plain name, used in naming alarms. |
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringOptions.property.humanReadableName">humanReadableName</a></code> | <code>string</code> | Human-readable name is a freeform string, used as a caption or description. |
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringOptions.property.localAlarmNamePrefixOverride">localAlarmNamePrefixOverride</a></code> | <code>string</code> | If this is defined, the local alarm name prefix used in naming alarms for the construct will be set to this value. |
@@ -12760,7 +12807,32 @@ const eC2MonitoringOptions: EC2MonitoringOptions = { ... }
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringOptions.property.addToDetailDashboard">addToDetailDashboard</a></code> | <code>boolean</code> | Flag indicating if the widgets should be added to detailed dashboard. |
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringOptions.property.addToSummaryDashboard">addToSummaryDashboard</a></code> | <code>boolean</code> | Flag indicating if the widgets should be added to summary dashboard. |
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringOptions.property.useCreatedAlarms">useCreatedAlarms</a></code> | <code><a href="#cdk-monitoring-constructs.IAlarmConsumer">IAlarmConsumer</a></code> | Calls provided function to process all alarms created. |
-| <code><a href="#cdk-monitoring-constructs.EC2MonitoringOptions.property.autoScalingGroup">autoScalingGroup</a></code> | <code>aws-cdk-lib.aws_autoscaling.IAutoScalingGroup</code> | *No description.* |
+
+---
+
+##### `autoScalingGroup`<sup>Optional</sup> <a name="autoScalingGroup" id="cdk-monitoring-constructs.EC2MonitoringOptions.property.autoScalingGroup"></a>
+
+```typescript
+public readonly autoScalingGroup: IAutoScalingGroup;
+```
+
+- *Type:* aws-cdk-lib.aws_autoscaling.IAutoScalingGroup
+- *Default:* no Auto-Scaling Group filter
+
+Auto-Scaling Group to monitor.
+
+---
+
+##### `instanceIds`<sup>Optional</sup> <a name="instanceIds" id="cdk-monitoring-constructs.EC2MonitoringOptions.property.instanceIds"></a>
+
+```typescript
+public readonly instanceIds: string[];
+```
+
+- *Type:* string[]
+- *Default:* no instance filter
+
+Selected IDs of EC2 instances to monitor.
 
 ---
 
@@ -12862,16 +12934,6 @@ Calls provided function to process all alarms created.
 
 ---
 
-##### `autoScalingGroup`<sup>Optional</sup> <a name="autoScalingGroup" id="cdk-monitoring-constructs.EC2MonitoringOptions.property.autoScalingGroup"></a>
-
-```typescript
-public readonly autoScalingGroup: IAutoScalingGroup;
-```
-
-- *Type:* aws-cdk-lib.aws_autoscaling.IAutoScalingGroup
-
----
-
 ### EC2MonitoringProps <a name="EC2MonitoringProps" id="cdk-monitoring-constructs.EC2MonitoringProps"></a>
 
 #### Initializer <a name="Initializer" id="cdk-monitoring-constructs.EC2MonitoringProps.Initializer"></a>
@@ -12886,6 +12948,8 @@ const eC2MonitoringProps: EC2MonitoringProps = { ... }
 
 | **Name** | **Type** | **Description** |
 | --- | --- | --- |
+| <code><a href="#cdk-monitoring-constructs.EC2MonitoringProps.property.autoScalingGroup">autoScalingGroup</a></code> | <code>aws-cdk-lib.aws_autoscaling.IAutoScalingGroup</code> | Auto-Scaling Group to monitor. |
+| <code><a href="#cdk-monitoring-constructs.EC2MonitoringProps.property.instanceIds">instanceIds</a></code> | <code>string[]</code> | Selected IDs of EC2 instances to monitor. |
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringProps.property.alarmFriendlyName">alarmFriendlyName</a></code> | <code>string</code> | Plain name, used in naming alarms. |
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringProps.property.humanReadableName">humanReadableName</a></code> | <code>string</code> | Human-readable name is a freeform string, used as a caption or description. |
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringProps.property.localAlarmNamePrefixOverride">localAlarmNamePrefixOverride</a></code> | <code>string</code> | If this is defined, the local alarm name prefix used in naming alarms for the construct will be set to this value. |
@@ -12893,7 +12957,32 @@ const eC2MonitoringProps: EC2MonitoringProps = { ... }
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringProps.property.addToDetailDashboard">addToDetailDashboard</a></code> | <code>boolean</code> | Flag indicating if the widgets should be added to detailed dashboard. |
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringProps.property.addToSummaryDashboard">addToSummaryDashboard</a></code> | <code>boolean</code> | Flag indicating if the widgets should be added to summary dashboard. |
 | <code><a href="#cdk-monitoring-constructs.EC2MonitoringProps.property.useCreatedAlarms">useCreatedAlarms</a></code> | <code><a href="#cdk-monitoring-constructs.IAlarmConsumer">IAlarmConsumer</a></code> | Calls provided function to process all alarms created. |
-| <code><a href="#cdk-monitoring-constructs.EC2MonitoringProps.property.autoScalingGroup">autoScalingGroup</a></code> | <code>aws-cdk-lib.aws_autoscaling.IAutoScalingGroup</code> | *No description.* |
+
+---
+
+##### `autoScalingGroup`<sup>Optional</sup> <a name="autoScalingGroup" id="cdk-monitoring-constructs.EC2MonitoringProps.property.autoScalingGroup"></a>
+
+```typescript
+public readonly autoScalingGroup: IAutoScalingGroup;
+```
+
+- *Type:* aws-cdk-lib.aws_autoscaling.IAutoScalingGroup
+- *Default:* no Auto-Scaling Group filter
+
+Auto-Scaling Group to monitor.
+
+---
+
+##### `instanceIds`<sup>Optional</sup> <a name="instanceIds" id="cdk-monitoring-constructs.EC2MonitoringProps.property.instanceIds"></a>
+
+```typescript
+public readonly instanceIds: string[];
+```
+
+- *Type:* string[]
+- *Default:* no instance filter
+
+Selected IDs of EC2 instances to monitor.
 
 ---
 
@@ -12995,16 +13084,6 @@ Calls provided function to process all alarms created.
 
 ---
 
-##### `autoScalingGroup`<sup>Optional</sup> <a name="autoScalingGroup" id="cdk-monitoring-constructs.EC2MonitoringProps.property.autoScalingGroup"></a>
-
-```typescript
-public readonly autoScalingGroup: IAutoScalingGroup;
-```
-
-- *Type:* aws-cdk-lib.aws_autoscaling.IAutoScalingGroup
-
----
-
 ### Ec2NetworkLoadBalancerMonitoringProps <a name="Ec2NetworkLoadBalancerMonitoringProps" id="cdk-monitoring-constructs.Ec2NetworkLoadBalancerMonitoringProps"></a>
 
 Monitoring props for EC2 service with network load balancer and plain service.
@@ -38549,13 +38628,13 @@ Returns widgets to be placed on the main dashboard.
 ```typescript
 import { EC2MetricFactory } from 'cdk-monitoring-constructs'
 
-new EC2MetricFactory(metricFactory: MetricFactory, autoScalingGroup?: IAutoScalingGroup)
+new EC2MetricFactory(metricFactory: MetricFactory, props: EC2MetricFactoryProps)
 ```
 
 | **Name** | **Type** | **Description** |
 | --- | --- | --- |
 | <code><a href="#cdk-monitoring-constructs.EC2MetricFactory.Initializer.parameter.metricFactory">metricFactory</a></code> | <code><a href="#cdk-monitoring-constructs.MetricFactory">MetricFactory</a></code> | *No description.* |
-| <code><a href="#cdk-monitoring-constructs.EC2MetricFactory.Initializer.parameter.autoScalingGroup">autoScalingGroup</a></code> | <code>aws-cdk-lib.aws_autoscaling.IAutoScalingGroup</code> | *No description.* |
+| <code><a href="#cdk-monitoring-constructs.EC2MetricFactory.Initializer.parameter.props">props</a></code> | <code><a href="#cdk-monitoring-constructs.EC2MetricFactoryProps">EC2MetricFactoryProps</a></code> | *No description.* |
 
 ---
 
@@ -38565,9 +38644,9 @@ new EC2MetricFactory(metricFactory: MetricFactory, autoScalingGroup?: IAutoScali
 
 ---
 
-##### `autoScalingGroup`<sup>Optional</sup> <a name="autoScalingGroup" id="cdk-monitoring-constructs.EC2MetricFactory.Initializer.parameter.autoScalingGroup"></a>
+##### `props`<sup>Required</sup> <a name="props" id="cdk-monitoring-constructs.EC2MetricFactory.Initializer.parameter.props"></a>
 
-- *Type:* aws-cdk-lib.aws_autoscaling.IAutoScalingGroup
+- *Type:* <a href="#cdk-monitoring-constructs.EC2MetricFactoryProps">EC2MetricFactoryProps</a>
 
 ---
 
@@ -38588,7 +38667,7 @@ new EC2MetricFactory(metricFactory: MetricFactory, autoScalingGroup?: IAutoScali
 ##### `metricAverageCpuUtilisationPercent` <a name="metricAverageCpuUtilisationPercent" id="cdk-monitoring-constructs.EC2MetricFactory.metricAverageCpuUtilisationPercent"></a>
 
 ```typescript
-public metricAverageCpuUtilisationPercent(): IMetric
+public metricAverageCpuUtilisationPercent(): IMetric[]
 ```
 
 The percentage of allocated EC2 compute units that are currently in use on the instance.
@@ -38600,7 +38679,7 @@ CloudWatch when the instance is not allocated a full processor core.
 ##### `metricAverageDiskReadBytes` <a name="metricAverageDiskReadBytes" id="cdk-monitoring-constructs.EC2MetricFactory.metricAverageDiskReadBytes"></a>
 
 ```typescript
-public metricAverageDiskReadBytes(): IMetric
+public metricAverageDiskReadBytes(): IMetric[]
 ```
 
 Bytes read from all instance store volumes available to the instance.
@@ -38611,7 +38690,7 @@ This can be used to determine the speed of the application.
 ##### `metricAverageDiskReadOps` <a name="metricAverageDiskReadOps" id="cdk-monitoring-constructs.EC2MetricFactory.metricAverageDiskReadOps"></a>
 
 ```typescript
-public metricAverageDiskReadOps(): IMetric
+public metricAverageDiskReadOps(): IMetric[]
 ```
 
 Completed read operations from all instance store volumes available to the instance in a specified period of time.
@@ -38619,7 +38698,7 @@ Completed read operations from all instance store volumes available to the insta
 ##### `metricAverageDiskWriteBytes` <a name="metricAverageDiskWriteBytes" id="cdk-monitoring-constructs.EC2MetricFactory.metricAverageDiskWriteBytes"></a>
 
 ```typescript
-public metricAverageDiskWriteBytes(): IMetric
+public metricAverageDiskWriteBytes(): IMetric[]
 ```
 
 Bytes written to all instance store volumes available to the instance.
@@ -38630,7 +38709,7 @@ This can be used to determine the speed of the application.
 ##### `metricAverageDiskWriteOps` <a name="metricAverageDiskWriteOps" id="cdk-monitoring-constructs.EC2MetricFactory.metricAverageDiskWriteOps"></a>
 
 ```typescript
-public metricAverageDiskWriteOps(): IMetric
+public metricAverageDiskWriteOps(): IMetric[]
 ```
 
 Completed write operations to all instance store volumes available to the instance in a specified period of time.
@@ -38638,7 +38717,7 @@ Completed write operations to all instance store volumes available to the instan
 ##### `metricAverageNetworkInRateBytes` <a name="metricAverageNetworkInRateBytes" id="cdk-monitoring-constructs.EC2MetricFactory.metricAverageNetworkInRateBytes"></a>
 
 ```typescript
-public metricAverageNetworkInRateBytes(): IMetric
+public metricAverageNetworkInRateBytes(): IMetric[]
 ```
 
 The number of bytes received on all network interfaces by the instance.
@@ -38648,7 +38727,7 @@ This metric identifies the volume of incoming network traffic to a single instan
 ##### `metricAverageNetworkOutRateBytes` <a name="metricAverageNetworkOutRateBytes" id="cdk-monitoring-constructs.EC2MetricFactory.metricAverageNetworkOutRateBytes"></a>
 
 ```typescript
-public metricAverageNetworkOutRateBytes(): IMetric
+public metricAverageNetworkOutRateBytes(): IMetric[]
 ```
 
 The number of bytes sent out on all network interfaces by the instance.
@@ -48104,6 +48183,43 @@ Returns all widgets.
 These should go to the detailed service dashboard.
 
 
+### IEC2MetricFactoryStrategy <a name="IEC2MetricFactoryStrategy" id="cdk-monitoring-constructs.IEC2MetricFactoryStrategy"></a>
+
+- *Implemented By:* <a href="#cdk-monitoring-constructs.IEC2MetricFactoryStrategy">IEC2MetricFactoryStrategy</a>
+
+#### Methods <a name="Methods" id="Methods"></a>
+
+| **Name** | **Description** |
+| --- | --- |
+| <code><a href="#cdk-monitoring-constructs.IEC2MetricFactoryStrategy.createMetrics">createMetrics</a></code> | *No description.* |
+
+---
+
+##### `createMetrics` <a name="createMetrics" id="cdk-monitoring-constructs.IEC2MetricFactoryStrategy.createMetrics"></a>
+
+```typescript
+public createMetrics(metricFactory: MetricFactory, metricName: string, statistic: MetricStatistic): IMetric[]
+```
+
+###### `metricFactory`<sup>Required</sup> <a name="metricFactory" id="cdk-monitoring-constructs.IEC2MetricFactoryStrategy.createMetrics.parameter.metricFactory"></a>
+
+- *Type:* <a href="#cdk-monitoring-constructs.MetricFactory">MetricFactory</a>
+
+---
+
+###### `metricName`<sup>Required</sup> <a name="metricName" id="cdk-monitoring-constructs.IEC2MetricFactoryStrategy.createMetrics.parameter.metricName"></a>
+
+- *Type:* string
+
+---
+
+###### `statistic`<sup>Required</sup> <a name="statistic" id="cdk-monitoring-constructs.IEC2MetricFactoryStrategy.createMetrics.parameter.statistic"></a>
+
+- *Type:* <a href="#cdk-monitoring-constructs.MetricStatistic">MetricStatistic</a>
+
+---
+
+
 ### ILoadBalancerMetricFactory <a name="ILoadBalancerMetricFactory" id="cdk-monitoring-constructs.ILoadBalancerMetricFactory"></a>
 
 - *Implemented By:* <a href="#cdk-monitoring-constructs.ApplicationLoadBalancerMetricFactory">ApplicationLoadBalancerMetricFactory</a>, <a href="#cdk-monitoring-constructs.NetworkLoadBalancerMetricFactory">NetworkLoadBalancerMetricFactory</a>, <a href="#cdk-monitoring-constructs.ILoadBalancerMetricFactory">ILoadBalancerMetricFactory</a>
diff --git a/lib/monitoring/aws-ec2/EC2MetricFactory.ts b/lib/monitoring/aws-ec2/EC2MetricFactory.ts
index c92c0e4a..27a0cbbd 100644
--- a/lib/monitoring/aws-ec2/EC2MetricFactory.ts
+++ b/lib/monitoring/aws-ec2/EC2MetricFactory.ts
@@ -1,22 +1,150 @@
 import { IAutoScalingGroup } from "aws-cdk-lib/aws-autoscaling";
-import { DimensionsMap } from "aws-cdk-lib/aws-cloudwatch";
+import { DimensionsMap, IMetric } from "aws-cdk-lib/aws-cloudwatch";
 
 import { MetricFactory, MetricStatistic } from "../../common";
 
 const EC2Namespace = "AWS/EC2";
 
-export class EC2MetricFactory {
-  protected readonly metricFactory: MetricFactory;
-  protected readonly autoScalingGroup?: IAutoScalingGroup;
+export interface IEC2MetricFactoryStrategy {
+  createMetrics(
+    metricFactory: MetricFactory,
+    metricName: string,
+    statistic: MetricStatistic
+  ): IMetric[];
+}
+
+/**
+ * Creates a single metric for the whole ASG.
+ */
+class AutoScalingGroupStrategy implements IEC2MetricFactoryStrategy {
+  protected autoScalingGroup: IAutoScalingGroup;
+
+  constructor(autoScalingGroup: IAutoScalingGroup) {
+    this.autoScalingGroup = autoScalingGroup;
+  }
 
-  constructor(
+  createMetrics(
     metricFactory: MetricFactory,
-    autoScalingGroup?: IAutoScalingGroup
+    metricName: string,
+    statistic: MetricStatistic
   ) {
-    this.metricFactory = metricFactory;
+    return [
+      metricFactory.createMetric(
+        metricName,
+        statistic,
+        undefined,
+        resolveDimensions(this.autoScalingGroup, undefined),
+        undefined,
+        EC2Namespace
+      ),
+    ];
+  }
+}
+
+/**
+ * Creates multiple metrics (one for each instance) with an optional ASG filter.
+ */
+class SelectedInstancesStrategy implements IEC2MetricFactoryStrategy {
+  protected instanceIds: string[];
+  protected autoScalingGroup?: IAutoScalingGroup;
+
+  constructor(instanceIds: string[], autoScalingGroup?: IAutoScalingGroup) {
+    this.instanceIds = instanceIds;
     this.autoScalingGroup = autoScalingGroup;
   }
 
+  createMetrics(
+    metricFactory: MetricFactory,
+    metricName: string,
+    statistic: MetricStatistic
+  ) {
+    return this.instanceIds.map((instanceId) => {
+      return metricFactory.createMetric(
+        metricName,
+        statistic,
+        `${metricName} (${instanceId})`,
+        resolveDimensions(this.autoScalingGroup, instanceId),
+        undefined,
+        EC2Namespace
+      );
+    });
+  }
+}
+
+/**
+ * Creates a single metric search expression for all instances.
+ */
+class AllInstancesStrategy implements IEC2MetricFactoryStrategy {
+  createMetrics(
+    metricFactory: MetricFactory,
+    metricName: string,
+    statistic: MetricStatistic
+  ) {
+    return [
+      metricFactory.createMetricSearch(
+        `MetricName="${metricName}"`,
+        { InstanceId: undefined as unknown as string },
+        statistic,
+        EC2Namespace
+      ),
+    ];
+  }
+}
+
+function resolveDimensions(
+  autoScalingGroup?: IAutoScalingGroup,
+  instanceId?: string
+): DimensionsMap {
+  const dimensions: DimensionsMap = {};
+  if (autoScalingGroup) {
+    dimensions.AutoScalingGroupName = autoScalingGroup.autoScalingGroupName;
+  }
+  if (instanceId) {
+    dimensions.InstanceId = instanceId;
+  }
+  return dimensions;
+}
+
+function resolveStrategy(
+  props: EC2MetricFactoryProps
+): IEC2MetricFactoryStrategy {
+  if (props.instanceIds) {
+    // instance filter + optional ASG
+    return new SelectedInstancesStrategy(
+      props.instanceIds,
+      props.autoScalingGroup
+    );
+  } else if (props.autoScalingGroup) {
+    // ASG only
+    return new AutoScalingGroupStrategy(props.autoScalingGroup);
+  } else {
+    // all instances
+    return new AllInstancesStrategy();
+  }
+}
+
+export interface EC2MetricFactoryProps {
+  /**
+   * Auto-Scaling Group to monitor.
+   * @default no Auto-Scaling Group filter
+   */
+  readonly autoScalingGroup?: IAutoScalingGroup;
+  /**
+   * Selected IDs of EC2 instances to monitor.
+   * @default no instance filter
+   */
+  readonly instanceIds?: string[];
+}
+
+export class EC2MetricFactory {
+  protected readonly metricFactory: MetricFactory;
+  protected readonly strategy: IEC2MetricFactoryStrategy;
+
+  constructor(metricFactory: MetricFactory, props: EC2MetricFactoryProps) {
+    this.metricFactory = metricFactory;
+    this.strategy = resolveStrategy(props);
+  }
+
   /**
    * The percentage of allocated EC2 compute units that are currently in use on the instance.
    * This metric identifies the processing power required to run an application on a selected instance.
@@ -24,7 +152,7 @@ export class EC2MetricFactory {
    * CloudWatch when the instance is not allocated a full processor core.
    */
   metricAverageCpuUtilisationPercent() {
-    return this.createMetric("CPUUtilization", MetricStatistic.AVERAGE);
+    return this.createMetrics("CPUUtilization", MetricStatistic.AVERAGE);
   }
 
   /**
@@ -33,7 +161,7 @@ export class EC2MetricFactory {
    * This can be used to determine the speed of the application.
    */
   metricAverageDiskReadBytes() {
-    return this.createMetric("DiskReadBytes", MetricStatistic.AVERAGE);
+    return this.createMetrics("DiskReadBytes", MetricStatistic.AVERAGE);
   }
 
   /**
@@ -42,21 +170,21 @@ export class EC2MetricFactory {
    * This can be used to determine the speed of the application.
    */
   metricAverageDiskWriteBytes() {
-    return this.createMetric("DiskWriteBytes", MetricStatistic.AVERAGE);
+    return this.createMetrics("DiskWriteBytes", MetricStatistic.AVERAGE);
   }
 
   /**
    * Completed read operations from all instance store volumes available to the instance in a specified period of time.
    */
   metricAverageDiskReadOps() {
-    return this.createMetric("DiskReadOps", MetricStatistic.AVERAGE);
+    return this.createMetrics("DiskReadOps", MetricStatistic.AVERAGE);
   }
 
   /**
    * Completed write operations to all instance store volumes available to the instance in a specified period of time.
    */
   metricAverageDiskWriteOps() {
-    return this.createMetric("DiskWriteOps", MetricStatistic.AVERAGE);
+    return this.createMetrics("DiskWriteOps", MetricStatistic.AVERAGE);
   }
 
   /**
@@ -64,7 +192,7 @@ export class EC2MetricFactory {
    * This metric identifies the volume of incoming network traffic to a single instance.
    */
   metricAverageNetworkInRateBytes() {
-    return this.createMetric("NetworkIn", MetricStatistic.AVERAGE);
+    return this.createMetrics("NetworkIn", MetricStatistic.AVERAGE);
   }
 
   /**
@@ -72,44 +200,14 @@ export class EC2MetricFactory {
    * This metric identifies the volume of outgoing network traffic from a single instance.
    */
   metricAverageNetworkOutRateBytes() {
-    return this.createMetric("NetworkOut", MetricStatistic.AVERAGE);
+    return this.createMetrics("NetworkOut", MetricStatistic.AVERAGE);
   }
 
-  private createMetric(metricName: string, statistic: MetricStatistic) {
-    if (this.autoScalingGroup) {
-      return this.metricForAutoScalingGroup(metricName, statistic);
-    }
-    return this.metricForAllInstances(metricName, statistic);
-  }
-
-  private metricForAutoScalingGroup(
-    metricName: string,
-    statistic: MetricStatistic
-  ) {
-    const dimensionsMap: DimensionsMap = {};
-    if (this.autoScalingGroup) {
-      dimensionsMap.AutoScalingGroupName =
-        this.autoScalingGroup.autoScalingGroupName;
-    }
-    return this.metricFactory.createMetric(
+  private createMetrics(metricName: string, statistic: MetricStatistic) {
+    return this.strategy.createMetrics(
+      this.metricFactory,
       metricName,
-      statistic,
-      undefined,
-      dimensionsMap,
-      undefined,
-      EC2Namespace
-    );
-  }
-
-  private metricForAllInstances(
-    metricName: string,
-    statistic: MetricStatistic
-  ) {
-    return this.metricFactory.createMetricSearch(
-      `MetricName="${metricName}"`,
-      { InstanceId: undefined as unknown as string },
-      statistic,
-      EC2Namespace
+      statistic
     );
   }
 }
diff --git a/lib/monitoring/aws-ec2/EC2Monitoring.ts b/lib/monitoring/aws-ec2/EC2Monitoring.ts
index d8a806ac..124a35a5 100644
--- a/lib/monitoring/aws-ec2/EC2Monitoring.ts
+++ b/lib/monitoring/aws-ec2/EC2Monitoring.ts
@@ -1,4 +1,3 @@
-import { IAutoScalingGroup } from "aws-cdk-lib/aws-autoscaling";
 import { GraphWidget, IMetric, IWidget } from "aws-cdk-lib/aws-cloudwatch";
 
 import {
@@ -17,11 +16,11 @@ import {
   MonitoringHeaderWidget,
   MonitoringNamingStrategy,
 } from "../../dashboard";
-import { EC2MetricFactory } from "./EC2MetricFactory";
+import { EC2MetricFactory, EC2MetricFactoryProps } from "./EC2MetricFactory";
 
-export interface EC2MonitoringOptions extends BaseMonitoringProps {
-  readonly autoScalingGroup?: IAutoScalingGroup;
-}
+export interface EC2MonitoringOptions
+  extends EC2MetricFactoryProps,
+    BaseMonitoringProps {}
 
 export interface EC2MonitoringProps extends EC2MonitoringOptions {}
 
@@ -29,13 +28,13 @@ export class EC2Monitoring extends Monitoring {
   protected readonly family: string;
   protected readonly title: string;
 
-  protected readonly cpuUtilisationMetric: IMetric;
-  protected readonly diskReadBytesMetric: IMetric;
-  protected readonly diskWriteBytesMetric: IMetric;
-  protected readonly diskReadOpsMetric: IMetric;
-  protected readonly diskWriteOpsMetric: IMetric;
-  protected readonly networkInMetric: IMetric;
-  protected readonly networkOutMetric: IMetric;
+  protected readonly cpuUtilisationMetrics: IMetric[];
+  protected readonly diskReadBytesMetrics: IMetric[];
+  protected readonly diskWriteBytesMetrics: IMetric[];
+  protected readonly diskReadOpsMetrics: IMetric[];
+  protected readonly diskWriteOpsMetrics: IMetric[];
+  protected readonly networkInMetrics: IMetric[];
+  protected readonly networkOutMetrics: IMetric[];
 
   constructor(scope: MonitoringScope, props: EC2MonitoringProps) {
     super(scope, props);
@@ -52,16 +51,16 @@ export class EC2Monitoring extends Monitoring {
 
     const metricFactory = new EC2MetricFactory(
       scope.createMetricFactory(),
-      props.autoScalingGroup
+      props
     );
-    this.cpuUtilisationMetric =
+    this.cpuUtilisationMetrics =
       metricFactory.metricAverageCpuUtilisationPercent();
-    this.diskReadBytesMetric = metricFactory.metricAverageDiskReadBytes();
-    this.diskWriteBytesMetric = metricFactory.metricAverageDiskWriteBytes();
-    this.diskReadOpsMetric = metricFactory.metricAverageDiskReadOps();
-    this.diskWriteOpsMetric = metricFactory.metricAverageDiskWriteOps();
-    this.networkInMetric = metricFactory.metricAverageNetworkInRateBytes();
-    this.networkOutMetric = metricFactory.metricAverageNetworkOutRateBytes();
+    this.diskReadBytesMetrics = metricFactory.metricAverageDiskReadBytes();
+    this.diskWriteBytesMetrics = metricFactory.metricAverageDiskWriteBytes();
+    this.diskReadOpsMetrics = metricFactory.metricAverageDiskReadOps();
+    this.diskWriteOpsMetrics = metricFactory.metricAverageDiskWriteOps();
+    this.networkInMetrics = metricFactory.metricAverageNetworkInRateBytes();
+    this.networkOutMetrics = metricFactory.metricAverageNetworkOutRateBytes();
   }
 
   summaryWidgets(): IWidget[] {
@@ -104,7 +103,7 @@ export class EC2Monitoring extends Monitoring {
       width,
       height,
       title: "CPU Utilization",
-      left: [this.cpuUtilisationMetric],
+      left: [...this.cpuUtilisationMetrics],
       leftYAxis: PercentageAxisFromZeroToHundred,
     });
   }
@@ -114,7 +113,7 @@ export class EC2Monitoring extends Monitoring {
       width,
       height,
       title: "Disk - Bytes",
-      left: [this.diskReadBytesMetric, this.diskWriteBytesMetric],
+      left: [...this.diskReadBytesMetrics, ...this.diskWriteBytesMetrics],
       leftYAxis: SizeAxisBytesFromZero,
     });
   }
@@ -124,7 +123,7 @@ export class EC2Monitoring extends Monitoring {
       width,
       height,
       title: "Disk - OPS",
-      left: [this.diskReadOpsMetric, this.diskWriteOpsMetric],
+      left: [...this.diskReadOpsMetrics, ...this.diskWriteOpsMetrics],
       leftYAxis: CountAxisFromZero,
     });
   }
@@ -134,7 +133,7 @@ export class EC2Monitoring extends Monitoring {
       width,
       height,
       title: "Network",
-      left: [this.networkInMetric, this.networkOutMetric],
+      left: [...this.networkInMetrics, ...this.networkOutMetrics],
       leftYAxis: SizeAxisBytesFromZero,
     });
   }


Test patch:
diff --git a/test/monitoring/aws-ec2/EC2Monitoring.test.ts b/test/monitoring/aws-ec2/EC2Monitoring.test.ts
index 1eec2a61..be160ddf 100644
--- a/test/monitoring/aws-ec2/EC2Monitoring.test.ts
+++ b/test/monitoring/aws-ec2/EC2Monitoring.test.ts
@@ -3,6 +3,7 @@ import { Template } from "aws-cdk-lib/assertions";
 import { AutoScalingGroup } from "aws-cdk-lib/aws-autoscaling";
 
 import { EC2Monitoring } from "../../../lib";
+import { addMonitoringDashboardsToStack } from "../../utils/SnapshotUtil";
 import { TestMonitoringScope } from "../TestMonitoringScope";
 
 test("snapshot test: all instances, no alarms", () => {
@@ -10,10 +11,11 @@ test("snapshot test: all instances, no alarms", () => {
 
   const scope = new TestMonitoringScope(stack, "Scope");
 
-  new EC2Monitoring(scope, {
+  const monitoring = new EC2Monitoring(scope, {
     alarmFriendlyName: "EC2",
   });
 
+  addMonitoringDashboardsToStack(stack, monitoring);
   expect(Template.fromStack(stack)).toMatchSnapshot();
 });
 
@@ -22,7 +24,7 @@ test("snapshot test: ASG, no alarms", () => {
 
   const scope = new TestMonitoringScope(stack, "Scope");
 
-  new EC2Monitoring(scope, {
+  const monitoring = new EC2Monitoring(scope, {
     alarmFriendlyName: "EC2",
     autoScalingGroup: AutoScalingGroup.fromAutoScalingGroupName(
       stack,
@@ -31,5 +33,39 @@ test("snapshot test: ASG, no alarms", () => {
     ),
   });
 
+  addMonitoringDashboardsToStack(stack, monitoring);
+  expect(Template.fromStack(stack)).toMatchSnapshot();
+});
+
+test("snapshot test: instance filter, no alarms", () => {
+  const stack = new Stack();
+
+  const scope = new TestMonitoringScope(stack, "Scope");
+
+  const monitoring = new EC2Monitoring(scope, {
+    alarmFriendlyName: "EC2",
+    instanceIds: ["instance1", "instance2"],
+  });
+
+  addMonitoringDashboardsToStack(stack, monitoring);
+  expect(Template.fromStack(stack)).toMatchSnapshot();
+});
+
+test("snapshot test: instance filter + ASG, no alarms", () => {
+  const stack = new Stack();
+
+  const scope = new TestMonitoringScope(stack, "Scope");
+
+  const monitoring = new EC2Monitoring(scope, {
+    alarmFriendlyName: "EC2",
+    instanceIds: ["instance1", "instance2"],
+    autoScalingGroup: AutoScalingGroup.fromAutoScalingGroupName(
+      stack,
+      "DummyASG",
+      "DummyASG"
+    ),
+  });
+
+  addMonitoringDashboardsToStack(stack, monitoring);
   expect(Template.fromStack(stack)).toMatchSnapshot();
 });
diff --git a/test/monitoring/aws-ec2/__snapshots__/EC2Monitoring.test.ts.snap b/test/monitoring/aws-ec2/__snapshots__/EC2Monitoring.test.ts.snap
index 9dc916fc..5e3159f3 100644
--- a/test/monitoring/aws-ec2/__snapshots__/EC2Monitoring.test.ts.snap
+++ b/test/monitoring/aws-ec2/__snapshots__/EC2Monitoring.test.ts.snap
@@ -9,6 +9,68 @@ Object {
       "Type": "AWS::SSM::Parameter::Value<String>",
     },
   },
+  "Resources": Object {
+    "Alarm7103F465": Object {
+      "Properties": Object {
+        "DashboardBody": "{\\"widgets\\":[]}",
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+    "Resource": Object {
+      "Properties": Object {
+        "DashboardBody": Object {
+          "Fn::Join": Array [
+            "",
+            Array [
+              "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### EC2 Auto Scaling Group **DummyASG**\\"}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"CPU Utilization\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"CPUUtilization\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"max\\":100,\\"label\\":\\"%\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":6,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - OPS\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"DiskReadOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"],[\\"AWS/EC2\\",\\"DiskWriteOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Count\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - Bytes\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"DiskReadBytes\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"],[\\"AWS/EC2\\",\\"DiskWriteBytes\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Network\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"NetworkIn\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"],[\\"AWS/EC2\\",\\"NetworkOut\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}}]}",
+            ],
+          ],
+        },
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+    "Summary68521F81": Object {
+      "Properties": Object {
+        "DashboardBody": Object {
+          "Fn::Join": Array [
+            "",
+            Array [
+              "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### EC2 Auto Scaling Group **DummyASG**\\"}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"CPU Utilization\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"CPUUtilization\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"max\\":100,\\"label\\":\\"%\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":8,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - OPS\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"DiskReadOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"],[\\"AWS/EC2\\",\\"DiskWriteOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Count\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Network\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"NetworkIn\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"],[\\"AWS/EC2\\",\\"NetworkOut\\",\\"AutoScalingGroupName\\",\\"DummyASG\\"]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}}]}",
+            ],
+          ],
+        },
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+  },
   "Rules": Object {
     "CheckBootstrapVersion": Object {
       "Assertions": Array [
@@ -48,6 +110,270 @@ Object {
       "Type": "AWS::SSM::Parameter::Value<String>",
     },
   },
+  "Resources": Object {
+    "Alarm7103F465": Object {
+      "Properties": Object {
+        "DashboardBody": "{\\"widgets\\":[]}",
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+    "Resource": Object {
+      "Properties": Object {
+        "DashboardBody": Object {
+          "Fn::Join": Array [
+            "",
+            Array [
+              "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### EC2 **All Instances**\\"}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"CPU Utilization\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"CPUUtilization\\\\\\"', 'Average', 300)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"max\\":100,\\"label\\":\\"%\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":6,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - OPS\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"DiskReadOps\\\\\\"', 'Average', 300)\\"}],[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"DiskWriteOps\\\\\\"', 'Average', 300)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Count\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - Bytes\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"DiskReadBytes\\\\\\"', 'Average', 300)\\"}],[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"DiskWriteBytes\\\\\\"', 'Average', 300)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Network\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"NetworkIn\\\\\\"', 'Average', 300)\\"}],[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"NetworkOut\\\\\\"', 'Average', 300)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}}]}",
+            ],
+          ],
+        },
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+    "Summary68521F81": Object {
+      "Properties": Object {
+        "DashboardBody": Object {
+          "Fn::Join": Array [
+            "",
+            Array [
+              "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### EC2 **All Instances**\\"}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"CPU Utilization\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"CPUUtilization\\\\\\"', 'Average', 300)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"max\\":100,\\"label\\":\\"%\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":8,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - OPS\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"DiskReadOps\\\\\\"', 'Average', 300)\\"}],[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"DiskWriteOps\\\\\\"', 'Average', 300)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Count\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Network\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"NetworkIn\\\\\\"', 'Average', 300)\\"}],[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/EC2,InstanceId}  MetricName=\\\\\\"NetworkOut\\\\\\"', 'Average', 300)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}}]}",
+            ],
+          ],
+        },
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+  },
+  "Rules": Object {
+    "CheckBootstrapVersion": Object {
+      "Assertions": Array [
+        Object {
+          "Assert": Object {
+            "Fn::Not": Array [
+              Object {
+                "Fn::Contains": Array [
+                  Array [
+                    "1",
+                    "2",
+                    "3",
+                    "4",
+                    "5",
+                  ],
+                  Object {
+                    "Ref": "BootstrapVersion",
+                  },
+                ],
+              },
+            ],
+          },
+          "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.",
+        },
+      ],
+    },
+  },
+}
+`;
+
+exports[`snapshot test: instance filter + ASG, no alarms 1`] = `
+Object {
+  "Parameters": Object {
+    "BootstrapVersion": Object {
+      "Default": "/cdk-bootstrap/hnb659fds/version",
+      "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]",
+      "Type": "AWS::SSM::Parameter::Value<String>",
+    },
+  },
+  "Resources": Object {
+    "Alarm7103F465": Object {
+      "Properties": Object {
+        "DashboardBody": "{\\"widgets\\":[]}",
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+    "Resource": Object {
+      "Properties": Object {
+        "DashboardBody": Object {
+          "Fn::Join": Array [
+            "",
+            Array [
+              "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### EC2 Auto Scaling Group **DummyASG**\\"}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"CPU Utilization\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"CPUUtilization\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"CPUUtilization (instance1)\\"}],[\\"AWS/EC2\\",\\"CPUUtilization\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"CPUUtilization (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"max\\":100,\\"label\\":\\"%\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":6,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - OPS\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"DiskReadOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskReadOps (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskReadOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskReadOps (instance2)\\"}],[\\"AWS/EC2\\",\\"DiskWriteOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskWriteOps (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskWriteOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskWriteOps (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Count\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - Bytes\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"DiskReadBytes\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskReadBytes (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskReadBytes\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskReadBytes (instance2)\\"}],[\\"AWS/EC2\\",\\"DiskWriteBytes\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskWriteBytes (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskWriteBytes\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskWriteBytes (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Network\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"NetworkIn\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"NetworkIn (instance1)\\"}],[\\"AWS/EC2\\",\\"NetworkIn\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"NetworkIn (instance2)\\"}],[\\"AWS/EC2\\",\\"NetworkOut\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"NetworkOut (instance1)\\"}],[\\"AWS/EC2\\",\\"NetworkOut\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"NetworkOut (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}}]}",
+            ],
+          ],
+        },
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+    "Summary68521F81": Object {
+      "Properties": Object {
+        "DashboardBody": Object {
+          "Fn::Join": Array [
+            "",
+            Array [
+              "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### EC2 Auto Scaling Group **DummyASG**\\"}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"CPU Utilization\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"CPUUtilization\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"CPUUtilization (instance1)\\"}],[\\"AWS/EC2\\",\\"CPUUtilization\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"CPUUtilization (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"max\\":100,\\"label\\":\\"%\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":8,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - OPS\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"DiskReadOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskReadOps (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskReadOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskReadOps (instance2)\\"}],[\\"AWS/EC2\\",\\"DiskWriteOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskWriteOps (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskWriteOps\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskWriteOps (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Count\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Network\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"NetworkIn\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"NetworkIn (instance1)\\"}],[\\"AWS/EC2\\",\\"NetworkIn\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"NetworkIn (instance2)\\"}],[\\"AWS/EC2\\",\\"NetworkOut\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"NetworkOut (instance1)\\"}],[\\"AWS/EC2\\",\\"NetworkOut\\",\\"AutoScalingGroupName\\",\\"DummyASG\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"NetworkOut (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}}]}",
+            ],
+          ],
+        },
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+  },
+  "Rules": Object {
+    "CheckBootstrapVersion": Object {
+      "Assertions": Array [
+        Object {
+          "Assert": Object {
+            "Fn::Not": Array [
+              Object {
+                "Fn::Contains": Array [
+                  Array [
+                    "1",
+                    "2",
+                    "3",
+                    "4",
+                    "5",
+                  ],
+                  Object {
+                    "Ref": "BootstrapVersion",
+                  },
+                ],
+              },
+            ],
+          },
+          "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.",
+        },
+      ],
+    },
+  },
+}
+`;
+
+exports[`snapshot test: instance filter, no alarms 1`] = `
+Object {
+  "Parameters": Object {
+    "BootstrapVersion": Object {
+      "Default": "/cdk-bootstrap/hnb659fds/version",
+      "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]",
+      "Type": "AWS::SSM::Parameter::Value<String>",
+    },
+  },
+  "Resources": Object {
+    "Alarm7103F465": Object {
+      "Properties": Object {
+        "DashboardBody": "{\\"widgets\\":[]}",
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+    "Resource": Object {
+      "Properties": Object {
+        "DashboardBody": Object {
+          "Fn::Join": Array [
+            "",
+            Array [
+              "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### EC2 **All Instances**\\"}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"CPU Utilization\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"CPUUtilization\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"CPUUtilization (instance1)\\"}],[\\"AWS/EC2\\",\\"CPUUtilization\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"CPUUtilization (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"max\\":100,\\"label\\":\\"%\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":6,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - OPS\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"DiskReadOps\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskReadOps (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskReadOps\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskReadOps (instance2)\\"}],[\\"AWS/EC2\\",\\"DiskWriteOps\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskWriteOps (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskWriteOps\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskWriteOps (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Count\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - Bytes\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"DiskReadBytes\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskReadBytes (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskReadBytes\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskReadBytes (instance2)\\"}],[\\"AWS/EC2\\",\\"DiskWriteBytes\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskWriteBytes (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskWriteBytes\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskWriteBytes (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Network\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"NetworkIn\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"NetworkIn (instance1)\\"}],[\\"AWS/EC2\\",\\"NetworkIn\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"NetworkIn (instance2)\\"}],[\\"AWS/EC2\\",\\"NetworkOut\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"NetworkOut (instance1)\\"}],[\\"AWS/EC2\\",\\"NetworkOut\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"NetworkOut (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}}]}",
+            ],
+          ],
+        },
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+    "Summary68521F81": Object {
+      "Properties": Object {
+        "DashboardBody": Object {
+          "Fn::Join": Array [
+            "",
+            Array [
+              "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### EC2 **All Instances**\\"}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"CPU Utilization\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"CPUUtilization\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"CPUUtilization (instance1)\\"}],[\\"AWS/EC2\\",\\"CPUUtilization\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"CPUUtilization (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"max\\":100,\\"label\\":\\"%\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":8,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Disk - OPS\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"DiskReadOps\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskReadOps (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskReadOps\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskReadOps (instance2)\\"}],[\\"AWS/EC2\\",\\"DiskWriteOps\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"DiskWriteOps (instance1)\\"}],[\\"AWS/EC2\\",\\"DiskWriteOps\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"DiskWriteOps (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Count\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Network\\",\\"region\\":\\"",
+              Object {
+                "Ref": "AWS::Region",
+              },
+              "\\",\\"metrics\\":[[\\"AWS/EC2\\",\\"NetworkIn\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"NetworkIn (instance1)\\"}],[\\"AWS/EC2\\",\\"NetworkIn\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"NetworkIn (instance2)\\"}],[\\"AWS/EC2\\",\\"NetworkOut\\",\\"InstanceId\\",\\"instance1\\",{\\"label\\":\\"NetworkOut (instance1)\\"}],[\\"AWS/EC2\\",\\"NetworkOut\\",\\"InstanceId\\",\\"instance2\\",{\\"label\\":\\"NetworkOut (instance2)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"bytes\\",\\"showUnits\\":false}}}}]}",
+            ],
+          ],
+        },
+      },
+      "Type": "AWS::CloudWatch::Dashboard",
+    },
+  },
   "Rules": Object {
     "CheckBootstrapVersion": Object {
       "Assertions": Array [