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

Issue:
feat: Add region and account parameters as optional global defaults
This lets me create cross-account and cross-region monitoring. Currently only the current account is supported.

My PR adds these parameters at the *global level* because I didn't want to go through every resource and add these extra parameters. This creates a limitation where an instance of `MonitoringFacade` would refer only to those specific region/accounts.

This is good enough for me though, so please advise if it's not desired.

---

_By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license_


Discussion / hints:

Fix patch:
diff --git a/API.md b/API.md
index e94eae51..b0e7bc47 100644
--- a/API.md
+++ b/API.md
@@ -55062,7 +55062,7 @@ if undefined, uses the global default
 ##### `createMetricAnomalyDetection` <a name="createMetricAnomalyDetection" id="cdk-monitoring-constructs.MetricFactory.createMetricAnomalyDetection"></a>
 
 ```typescript
-public createMetricAnomalyDetection(metric: IMetric, stdev: number, label: string, color?: string, expressionId?: string, period?: Duration): Metric | MathExpression
+public createMetricAnomalyDetection(metric: IMetric, stdev: number, label: string, color?: string, expressionId?: string, period?: Duration, region?: string, account?: string): Metric | MathExpression
 ```
 
 Factory method that creates anomaly detection on a metric.
@@ -55127,10 +55127,30 @@ if undefined, uses the global default
 
 ---
 
+###### `region`<sup>Optional</sup> <a name="region" id="cdk-monitoring-constructs.MetricFactory.createMetricAnomalyDetection.parameter.region"></a>
+
+- *Type:* string
+
+specify a custom region;
+
+if undefined, uses the global default
+
+---
+
+###### `account`<sup>Optional</sup> <a name="account" id="cdk-monitoring-constructs.MetricFactory.createMetricAnomalyDetection.parameter.account"></a>
+
+- *Type:* string
+
+specify a custom account;
+
+if undefined, uses the global default
+
+---
+
 ##### `createMetricMath` <a name="createMetricMath" id="cdk-monitoring-constructs.MetricFactory.createMetricMath"></a>
 
 ```typescript
-public createMetricMath(expression: string, usingMetrics: {[ key: string ]: IMetric}, label: string, color?: string, period?: Duration): Metric | MathExpression
+public createMetricMath(expression: string, usingMetrics: {[ key: string ]: IMetric}, label: string, color?: string, period?: Duration, region?: string, account?: string): Metric | MathExpression
 ```
 
 Factory method that creates a metric math expression.
@@ -55181,10 +55201,30 @@ if undefined, uses the global default
 
 ---
 
+###### `region`<sup>Optional</sup> <a name="region" id="cdk-monitoring-constructs.MetricFactory.createMetricMath.parameter.region"></a>
+
+- *Type:* string
+
+specify a custom region;
+
+if undefined, uses the global default
+
+---
+
+###### `account`<sup>Optional</sup> <a name="account" id="cdk-monitoring-constructs.MetricFactory.createMetricMath.parameter.account"></a>
+
+- *Type:* string
+
+specify a custom account;
+
+if undefined, uses the global default
+
+---
+
 ##### `createMetricSearch` <a name="createMetricSearch" id="cdk-monitoring-constructs.MetricFactory.createMetricSearch"></a>
 
 ```typescript
-public createMetricSearch(query: string, dimensionsMap: {[ key: string ]: string}, statistic: MetricStatistic, namespace?: string, label?: string, period?: Duration): IMetric
+public createMetricSearch(query: string, dimensionsMap: {[ key: string ]: string}, statistic: MetricStatistic, namespace?: string, label?: string, period?: Duration, region?: string, account?: string): IMetric
 ```
 
 Factory method that creates a metric search query.
@@ -55249,6 +55289,26 @@ if undefined, uses the global default
 
 ---
 
+###### `region`<sup>Optional</sup> <a name="region" id="cdk-monitoring-constructs.MetricFactory.createMetricSearch.parameter.region"></a>
+
+- *Type:* string
+
+specify a custom region;
+
+if undefined, uses the global default
+
+---
+
+###### `account`<sup>Optional</sup> <a name="account" id="cdk-monitoring-constructs.MetricFactory.createMetricSearch.parameter.account"></a>
+
+- *Type:* string
+
+specify a custom account;
+
+if undefined, uses the global default
+
+---
+
 ##### `divideMetric` <a name="divideMetric" id="cdk-monitoring-constructs.MetricFactory.divideMetric"></a>
 
 ```typescript
@@ -64708,7 +64768,7 @@ new XaxrMathExpression(props: XaxrMathExpressionProps)
 
 ---
 
-##### `toMetricConfig` <a name="toMetricConfig" id="cdk-monitoring-constructs.XaxrMathExpression.toMetricConfig"></a>
+##### ~~`toMetricConfig`~~ <a name="toMetricConfig" id="cdk-monitoring-constructs.XaxrMathExpression.toMetricConfig"></a>
 
 ```typescript
 public toMetricConfig(): MetricConfig
@@ -64716,7 +64776,7 @@ public toMetricConfig(): MetricConfig
 
 Inspect the details of the metric object.
 
-##### `with` <a name="with" id="cdk-monitoring-constructs.XaxrMathExpression.with"></a>
+##### ~~`with`~~ <a name="with" id="cdk-monitoring-constructs.XaxrMathExpression.with"></a>
 
 ```typescript
 public with(options: MathExpressionOptions): IMetric
diff --git a/lib/common/metric/MetricFactory.ts b/lib/common/metric/MetricFactory.ts
index 89b82018..115b3b2e 100644
--- a/lib/common/metric/MetricFactory.ts
+++ b/lib/common/metric/MetricFactory.ts
@@ -108,13 +108,17 @@ export class MetricFactory {
    * @param label metric label (required, as there is no reasonable default)
    * @param color metric color; if undefined, uses a CloudWatch provided color (preferred)
    * @param period specify a custom period; if undefined, uses the global default
+   * @param region specify a custom region; if undefined, uses the global default
+   * @param account specify a custom account; if undefined, uses the global default
    */
   createMetricMath(
     expression: string,
     usingMetrics: Record<string, IMetric>,
     label: string,
     color?: string,
-    period?: Duration
+    period?: Duration,
+    region?: string,
+    account?: string
   ): MetricWithAlarmSupport {
     return new MathExpression({
       label,
@@ -122,6 +126,8 @@ export class MetricFactory {
       expression,
       usingMetrics,
       period: period ?? this.globalDefaults.period ?? DefaultMetricPeriod,
+      searchRegion: region ?? this.globalDefaults.region,
+      searchAccount: account ?? this.globalDefaults.account,
     });
   }
 
@@ -136,6 +142,8 @@ export class MetricFactory {
    * @param namespace specify a custom namespace; if undefined, uses the global default
    * @param label specify custom label for search metrics; default is " " as it cannot be empty string
    * @param period specify a custom period; if undefined, uses the global default
+   * @param region specify a custom region; if undefined, uses the global default
+   * @param account specify a custom account; if undefined, uses the global default
    */
   createMetricSearch(
     query: string,
@@ -143,7 +151,9 @@ export class MetricFactory {
     statistic: MetricStatistic,
     namespace?: string,
     label?: string,
-    period?: Duration
+    period?: Duration,
+    region?: string,
+    account?: string
   ): IMetric {
     const finalPeriod =
       period ?? this.globalDefaults.period ?? DefaultMetricPeriod;
@@ -169,6 +179,8 @@ export class MetricFactory {
       // cannot be an empty string and undefined is no good either
       label: label ?? " ",
       period: finalPeriod,
+      searchRegion: region ?? this.globalDefaults.region,
+      searchAccount: account ?? this.globalDefaults.account,
     });
   }
 
@@ -185,6 +197,8 @@ export class MetricFactory {
    * @param color metric color; if undefined, uses a CloudWatch provided color (preferred)
    * @param expressionId expression ID of the metric; uses `m1` if undefined
    * @param period specify a custom period; if undefined, uses the global default
+   * @param region specify a custom region; if undefined, uses the global default
+   * @param account specify a custom account; if undefined, uses the global default
    */
   createMetricAnomalyDetection(
     metric: IMetric,
@@ -192,7 +206,9 @@ export class MetricFactory {
     label: string,
     color?: string,
     expressionId?: string,
-    period?: Duration
+    period?: Duration,
+    region?: string,
+    account?: string
   ): MetricWithAlarmSupport {
     const finalExpressionId = expressionId ?? "m1";
     const usingMetrics: Record<string, IMetric> = {};
@@ -203,6 +219,8 @@ export class MetricFactory {
       usingMetrics,
       expression: `ANOMALY_DETECTION_BAND(${finalExpressionId},${stdev})`,
       period: period ?? this.globalDefaults.period ?? DefaultMetricPeriod,
+      searchRegion: region ?? this.globalDefaults.region,
+      searchAccount: account ?? this.globalDefaults.account,
     });
   }
 
diff --git a/lib/common/metric/XaxrMathExpression.ts b/lib/common/metric/XaxrMathExpression.ts
index 50bb6f2f..e31af201 100644
--- a/lib/common/metric/XaxrMathExpression.ts
+++ b/lib/common/metric/XaxrMathExpression.ts
@@ -28,9 +28,12 @@ export interface XaxrMathExpressionProps extends MathExpressionProps {
   readonly region?: string;
 }
 
+// TODO: remove this as a breaking change
 /**
  * Custom wrapper class for MathExpression that supports account and region specification.
  * @see https://github.com/aws/aws-cdk/issues/9039
+ *
+ * @deprecated Use MathExpression from aws-cdk-lib/aws-cloudwatch instead.
  */
 export class XaxrMathExpression implements IMetric {
   private props: XaxrMathExpressionProps;
@@ -41,22 +44,22 @@ export class XaxrMathExpression implements IMetric {
     this.mathExpression = new MathExpression(props);
   }
 
+  /**
+   * @deprecated Use MathExpression from aws-cdk-lib/aws-cloudwatch instead.
+   */
   with(options: MathExpressionOptions): IMetric {
-    return new XaxrMathExpression({
+    return new MathExpression({
       ...this.props,
       ...options,
+      searchAccount: this.props.account,
+      searchRegion: this.props.region,
     });
   }
 
+  /**
+   * @deprecated Use MathExpression from aws-cdk-lib/aws-cloudwatch instead.
+   */
   toMetricConfig(): MetricConfig {
-    const defaultMetricConfig = this.mathExpression.toMetricConfig();
-    return {
-      ...defaultMetricConfig,
-      renderingProperties: {
-        ...defaultMetricConfig.renderingProperties,
-        accountId: this.props.account,
-        region: this.props.region,
-      },
-    };
+    return this.mathExpression.toMetricConfig();
   }
 }
diff --git a/lib/monitoring/aws-billing/BillingMetricFactory.ts b/lib/monitoring/aws-billing/BillingMetricFactory.ts
index 853695af..d61be780 100644
--- a/lib/monitoring/aws-billing/BillingMetricFactory.ts
+++ b/lib/monitoring/aws-billing/BillingMetricFactory.ts
@@ -1,11 +1,7 @@
 import { Duration } from "aws-cdk-lib";
-import { IMetric, Metric } from "aws-cdk-lib/aws-cloudwatch";
+import { IMetric, MathExpression, Metric } from "aws-cdk-lib/aws-cloudwatch";
 
-import {
-  MetricStatistic,
-  MetricWithAlarmSupport,
-  XaxrMathExpression,
-} from "../../common";
+import { MetricStatistic, MetricWithAlarmSupport } from "../../common";
 
 export const BillingRegion = "us-east-1";
 export const BillingCurrency = "USD";
@@ -17,20 +13,17 @@ const DefaultServiceLimit = 10;
 
 export class BillingMetricFactory {
   metricSearchTopCostByServiceInUsd(): IMetric {
-    // standard MathExpression class does not support region
-    // TODO: revisit after migration to CDK 1.126.0
-
-    const search = new XaxrMathExpression({
+    const search = new MathExpression({
       period: BillingPeriod,
-      region: BillingRegion,
+      searchRegion: BillingRegion,
       expression: `SEARCH('{${BillingNamespace},Currency,ServiceName} MetricName="${BillingMetric}"', 'Maximum', ${BillingPeriod.toSeconds()})`,
       usingMetrics: {},
       label: " ",
     });
 
-    return new XaxrMathExpression({
+    return new MathExpression({
       period: BillingPeriod,
-      region: BillingRegion,
+      searchRegion: BillingRegion,
       expression: `SORT(search, MAX, DESC, ${DefaultServiceLimit})`,
       usingMetrics: { search },
       label: " ",
diff --git a/lib/monitoring/aws-cloudfront/CloudFrontDistributionMetricFactory.ts b/lib/monitoring/aws-cloudfront/CloudFrontDistributionMetricFactory.ts
index c7ad2833..28ae1a3c 100644
--- a/lib/monitoring/aws-cloudfront/CloudFrontDistributionMetricFactory.ts
+++ b/lib/monitoring/aws-cloudfront/CloudFrontDistributionMetricFactory.ts
@@ -60,16 +60,16 @@ export class CloudFrontDistributionMetricFactory {
   }
 
   metricRequestCount() {
-    return this.metricFactory
-      .createMetric(
-        "Requests",
-        MetricStatistic.SUM,
-        "Uploaded",
-        this.dimensionsMap,
-        undefined,
-        CloudFrontNamespace
-      )
-      .with({ region: CloudFrontDefaultMetricRegion });
+    return this.metricFactory.createMetric(
+      "Requests",
+      MetricStatistic.SUM,
+      "Uploaded",
+      this.dimensionsMap,
+      undefined,
+      CloudFrontNamespace,
+      undefined,
+      CloudFrontDefaultMetricRegion
+    );
   }
 
   metricRequestRate() {
@@ -96,29 +96,29 @@ export class CloudFrontDistributionMetricFactory {
   }
 
   metricTotalBytesUploaded() {
-    return this.metricFactory
-      .createMetric(
-        "BytesUploaded",
-        MetricStatistic.SUM,
-        "Uploaded",
-        this.dimensionsMap,
-        undefined,
-        CloudFrontNamespace
-      )
-      .with({ region: CloudFrontDefaultMetricRegion });
+    return this.metricFactory.createMetric(
+      "BytesUploaded",
+      MetricStatistic.SUM,
+      "Uploaded",
+      this.dimensionsMap,
+      undefined,
+      CloudFrontNamespace,
+      undefined,
+      CloudFrontDefaultMetricRegion
+    );
   }
 
   metricTotalBytesDownloaded() {
-    return this.metricFactory
-      .createMetric(
-        "BytesDownloaded",
-        MetricStatistic.SUM,
-        "Downloaded",
-        this.dimensionsMap,
-        undefined,
-        CloudFrontNamespace
-      )
-      .with({ region: CloudFrontDefaultMetricRegion });
+    return this.metricFactory.createMetric(
+      "BytesDownloaded",
+      MetricStatistic.SUM,
+      "Downloaded",
+      this.dimensionsMap,
+      undefined,
+      CloudFrontNamespace,
+      undefined,
+      CloudFrontDefaultMetricRegion
+    );
   }
 
   /**
@@ -127,54 +127,54 @@ export class CloudFrontDistributionMetricFactory {
    * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/viewing-cloudfront-metrics.html#monitoring-console.distributions-additional
    */
   metricCacheHitRateAverageInPercent() {
-    return this.metricFactory
-      .createMetric(
-        "CacheHitRate",
-        MetricStatistic.AVERAGE,
-        "Hit Rate",
-        this.dimensionsMap,
-        undefined,
-        CloudFrontNamespace
-      )
-      .with({ region: CloudFrontDefaultMetricRegion });
+    return this.metricFactory.createMetric(
+      "CacheHitRate",
+      MetricStatistic.AVERAGE,
+      "Hit Rate",
+      this.dimensionsMap,
+      undefined,
+      CloudFrontNamespace,
+      undefined,
+      CloudFrontDefaultMetricRegion
+    );
   }
 
   metric4xxErrorRateAverage() {
-    return this.metricFactory
-      .createMetric(
-        "4xxErrorRate",
-        MetricStatistic.AVERAGE,
-        "4XX",
-        this.dimensionsMap,
-        undefined,
-        CloudFrontNamespace
-      )
-      .with({ region: CloudFrontDefaultMetricRegion });
+    return this.metricFactory.createMetric(
+      "4xxErrorRate",
+      MetricStatistic.AVERAGE,
+      "4XX",
+      this.dimensionsMap,
+      undefined,
+      CloudFrontNamespace,
+      undefined,
+      CloudFrontDefaultMetricRegion
+    );
   }
 
   metric5xxErrorRateAverage() {
-    return this.metricFactory
-      .createMetric(
-        "5xxErrorRate",
-        MetricStatistic.AVERAGE,
-        "5XX",
-        this.dimensionsMap,
-        undefined,
-        CloudFrontNamespace
-      )
-      .with({ region: CloudFrontDefaultMetricRegion });
+    return this.metricFactory.createMetric(
+      "5xxErrorRate",
+      MetricStatistic.AVERAGE,
+      "5XX",
+      this.dimensionsMap,
+      undefined,
+      CloudFrontNamespace,
+      undefined,
+      CloudFrontDefaultMetricRegion
+    );
   }
 
   metricTotalErrorRateAverage() {
-    return this.metricFactory
-      .createMetric(
-        "TotalErrorRate",
-        MetricStatistic.AVERAGE,
-        "Total",
-        this.dimensionsMap,
-        undefined,
-        CloudFrontNamespace
-      )
-      .with({ region: CloudFrontDefaultMetricRegion });
+    return this.metricFactory.createMetric(
+      "TotalErrorRate",
+      MetricStatistic.AVERAGE,
+      "Total",
+      this.dimensionsMap,
+      undefined,
+      CloudFrontNamespace,
+      undefined,
+      CloudFrontDefaultMetricRegion
+    );
   }
 }


Test patch:
diff --git a/test/common/metric/MetricFactory.test.ts b/test/common/metric/MetricFactory.test.ts
index 891d5d9b..ea68f313 100644
--- a/test/common/metric/MetricFactory.test.ts
+++ b/test/common/metric/MetricFactory.test.ts
@@ -21,7 +21,7 @@ test("createMetric without global namespace throws an error", () => {
   ).toThrowError();
 });
 
-test("snapshot test: global defaults", () => {
+describe("snapshot test: global defaults", () => {
   function testMetric(props: MetricFactoryDefaults) {
     const metricFactory = new MetricFactory({
       globalDefaults: {
@@ -29,30 +29,69 @@ test("snapshot test: global defaults", () => {
         ...props,
       },
     });
+
     const metric = metricFactory.createMetric(
       "DummyMetricName",
       MetricStatistic.P90
     );
-    expect(metric).toMatchSnapshot();
+    const metricMath = metricFactory.createMetricMath(
+      "DummyExpression",
+      {},
+      "label"
+    );
+    const metricSearch = metricFactory.createMetricSearch(
+      "DummyQuery",
+      {},
+      MetricStatistic.P90
+    );
+    const metricAnomalyDetection = metricFactory.createMetricAnomalyDetection(
+      new Metric({
+        metricName: "DummyMetric1",
+        namespace: "DummyNamespace",
+      }),
+      2,
+      "label"
+    );
+
+    expect({
+      metric,
+      metricMath,
+      metricSearch,
+      metricAnomalyDetection,
+    }).toMatchSnapshot();
   }
 
-  testMetric({
-    namespace: "SomeNamespace",
+  test("with namespace", () => {
+    testMetric({
+      namespace: "CustomTestNamespace",
+    });
   });
-  testMetric({
-    period: Duration.minutes(15),
+
+  test("with period", () => {
+    testMetric({
+      period: Duration.minutes(15),
+    });
   });
-  testMetric({
-    region: "us-west-2",
+
+  test("with region", () => {
+    testMetric({
+      region: "us-west-2",
+    });
   });
-  testMetric({
-    account: "123456789",
+
+  test("with account", () => {
+    testMetric({
+      account: "123456789",
+    });
   });
-  testMetric({
-    namespace: "SomeNamespace",
-    period: Duration.minutes(15),
-    region: "us-west-2",
-    account: "123456789",
+
+  test("with multiple props", () => {
+    testMetric({
+      namespace: "CustomTestNamespace",
+      period: Duration.minutes(15),
+      region: "us-west-2",
+      account: "123456789",
+    });
   });
 });
 
diff --git a/test/common/metric/__snapshots__/MetricFactory.test.ts.snap b/test/common/metric/__snapshots__/MetricFactory.test.ts.snap
index bb8c8071..306aa897 100644
--- a/test/common/metric/__snapshots__/MetricFactory.test.ts.snap
+++ b/test/common/metric/__snapshots__/MetricFactory.test.ts.snap
@@ -399,118 +399,503 @@ MathExpression {
 }
 `;
 
-exports[`snapshot test: global defaults 1`] = `
-Metric {
-  "account": undefined,
-  "color": undefined,
-  "dimensions": undefined,
-  "label": undefined,
-  "metricName": "DummyMetricName",
-  "namespace": "SomeNamespace",
-  "period": Duration {
-    "amount": 5,
-    "unit": TimeUnit {
-      "inMillis": 60000,
-      "isoLabel": "M",
-      "label": "minutes",
+exports[`snapshot test: global defaults with account 1`] = `
+Object {
+  "metric": Metric {
+    "account": "123456789",
+    "color": undefined,
+    "dimensions": undefined,
+    "label": undefined,
+    "metricName": "DummyMetricName",
+    "namespace": "DummyNamespace",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
     },
+    "region": undefined,
+    "statistic": "p90",
+    "unit": undefined,
+    "warnings": undefined,
+  },
+  "metricAnomalyDetection": AnomalyDetectionMathExpression {
+    "color": undefined,
+    "expression": "ANOMALY_DETECTION_BAND(m1,2)",
+    "label": "label",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": "123456789",
+    "searchRegion": undefined,
+    "usingMetrics": Object {
+      "m1": Metric {
+        "account": undefined,
+        "color": undefined,
+        "dimensions": undefined,
+        "label": undefined,
+        "metricName": "DummyMetric1",
+        "namespace": "DummyNamespace",
+        "period": Duration {
+          "amount": 5,
+          "unit": TimeUnit {
+            "inMillis": 60000,
+            "isoLabel": "M",
+            "label": "minutes",
+          },
+        },
+        "region": undefined,
+        "statistic": "Average",
+        "unit": undefined,
+        "warnings": undefined,
+      },
+    },
+  },
+  "metricMath": MathExpression {
+    "color": undefined,
+    "expression": "DummyExpression",
+    "label": "label",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": "123456789",
+    "searchRegion": undefined,
+    "usingMetrics": Object {},
+    "warnings": Array [
+      "Math expression 'DummyExpression' references unknown identifiers: ummyExpression. Please add them to the 'usingMetrics' map.",
+    ],
+  },
+  "metricSearch": MathExpression {
+    "color": undefined,
+    "expression": "SEARCH('{DummyNamespace}  DummyQuery', 'p90', 300)",
+    "label": " ",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": "123456789",
+    "searchRegion": undefined,
+    "usingMetrics": Object {},
+    "warnings": Array [
+      "Math expression 'SEARCH('{DummyNamespace}  DummyQuery', 'p90', 300)' references unknown identifiers: ummyNamespace, ummyQuery, p90. Please add them to the 'usingMetrics' map.",
+    ],
   },
-  "region": undefined,
-  "statistic": "p90",
-  "unit": undefined,
-  "warnings": undefined,
 }
 `;
 
-exports[`snapshot test: global defaults 2`] = `
-Metric {
-  "account": undefined,
-  "color": undefined,
-  "dimensions": undefined,
-  "label": undefined,
-  "metricName": "DummyMetricName",
-  "namespace": "DummyNamespace",
-  "period": Duration {
-    "amount": 15,
-    "unit": TimeUnit {
-      "inMillis": 60000,
-      "isoLabel": "M",
-      "label": "minutes",
+exports[`snapshot test: global defaults with multiple props 1`] = `
+Object {
+  "metric": Metric {
+    "account": "123456789",
+    "color": undefined,
+    "dimensions": undefined,
+    "label": undefined,
+    "metricName": "DummyMetricName",
+    "namespace": "CustomTestNamespace",
+    "period": Duration {
+      "amount": 15,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
     },
+    "region": "us-west-2",
+    "statistic": "p90",
+    "unit": undefined,
+    "warnings": undefined,
+  },
+  "metricAnomalyDetection": AnomalyDetectionMathExpression {
+    "color": undefined,
+    "expression": "ANOMALY_DETECTION_BAND(m1,2)",
+    "label": "label",
+    "period": Duration {
+      "amount": 15,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": "123456789",
+    "searchRegion": "us-west-2",
+    "usingMetrics": Object {
+      "m1": Metric {
+        "account": undefined,
+        "color": undefined,
+        "dimensions": undefined,
+        "label": undefined,
+        "metricName": "DummyMetric1",
+        "namespace": "DummyNamespace",
+        "period": Duration {
+          "amount": 15,
+          "unit": TimeUnit {
+            "inMillis": 60000,
+            "isoLabel": "M",
+            "label": "minutes",
+          },
+        },
+        "region": undefined,
+        "statistic": "Average",
+        "unit": undefined,
+        "warnings": undefined,
+      },
+    },
+  },
+  "metricMath": MathExpression {
+    "color": undefined,
+    "expression": "DummyExpression",
+    "label": "label",
+    "period": Duration {
+      "amount": 15,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": "123456789",
+    "searchRegion": "us-west-2",
+    "usingMetrics": Object {},
+    "warnings": Array [
+      "Math expression 'DummyExpression' references unknown identifiers: ummyExpression. Please add them to the 'usingMetrics' map.",
+    ],
+  },
+  "metricSearch": MathExpression {
+    "color": undefined,
+    "expression": "SEARCH('{CustomTestNamespace}  DummyQuery', 'p90', 900)",
+    "label": " ",
+    "period": Duration {
+      "amount": 15,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": "123456789",
+    "searchRegion": "us-west-2",
+    "usingMetrics": Object {},
+    "warnings": Array [
+      "Math expression 'SEARCH('{CustomTestNamespace}  DummyQuery', 'p90', 900)' references unknown identifiers: ustomTestNamespace, ummyQuery, p90. Please add them to the 'usingMetrics' map.",
+    ],
   },
-  "region": undefined,
-  "statistic": "p90",
-  "unit": undefined,
-  "warnings": undefined,
 }
 `;
 
-exports[`snapshot test: global defaults 3`] = `
-Metric {
-  "account": undefined,
-  "color": undefined,
-  "dimensions": undefined,
-  "label": undefined,
-  "metricName": "DummyMetricName",
-  "namespace": "DummyNamespace",
-  "period": Duration {
-    "amount": 5,
-    "unit": TimeUnit {
-      "inMillis": 60000,
-      "isoLabel": "M",
-      "label": "minutes",
+exports[`snapshot test: global defaults with namespace 1`] = `
+Object {
+  "metric": Metric {
+    "account": undefined,
+    "color": undefined,
+    "dimensions": undefined,
+    "label": undefined,
+    "metricName": "DummyMetricName",
+    "namespace": "CustomTestNamespace",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
     },
+    "region": undefined,
+    "statistic": "p90",
+    "unit": undefined,
+    "warnings": undefined,
+  },
+  "metricAnomalyDetection": AnomalyDetectionMathExpression {
+    "color": undefined,
+    "expression": "ANOMALY_DETECTION_BAND(m1,2)",
+    "label": "label",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": undefined,
+    "searchRegion": undefined,
+    "usingMetrics": Object {
+      "m1": Metric {
+        "account": undefined,
+        "color": undefined,
+        "dimensions": undefined,
+        "label": undefined,
+        "metricName": "DummyMetric1",
+        "namespace": "DummyNamespace",
+        "period": Duration {
+          "amount": 5,
+          "unit": TimeUnit {
+            "inMillis": 60000,
+            "isoLabel": "M",
+            "label": "minutes",
+          },
+        },
+        "region": undefined,
+        "statistic": "Average",
+        "unit": undefined,
+        "warnings": undefined,
+      },
+    },
+  },
+  "metricMath": MathExpression {
+    "color": undefined,
+    "expression": "DummyExpression",
+    "label": "label",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": undefined,
+    "searchRegion": undefined,
+    "usingMetrics": Object {},
+    "warnings": Array [
+      "Math expression 'DummyExpression' references unknown identifiers: ummyExpression. Please add them to the 'usingMetrics' map.",
+    ],
+  },
+  "metricSearch": MathExpression {
+    "color": undefined,
+    "expression": "SEARCH('{CustomTestNamespace}  DummyQuery', 'p90', 300)",
+    "label": " ",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": undefined,
+    "searchRegion": undefined,
+    "usingMetrics": Object {},
+    "warnings": Array [
+      "Math expression 'SEARCH('{CustomTestNamespace}  DummyQuery', 'p90', 300)' references unknown identifiers: ustomTestNamespace, ummyQuery, p90. Please add them to the 'usingMetrics' map.",
+    ],
   },
-  "region": "us-west-2",
-  "statistic": "p90",
-  "unit": undefined,
-  "warnings": undefined,
 }
 `;
 
-exports[`snapshot test: global defaults 4`] = `
-Metric {
-  "account": "123456789",
-  "color": undefined,
-  "dimensions": undefined,
-  "label": undefined,
-  "metricName": "DummyMetricName",
-  "namespace": "DummyNamespace",
-  "period": Duration {
-    "amount": 5,
-    "unit": TimeUnit {
-      "inMillis": 60000,
-      "isoLabel": "M",
-      "label": "minutes",
+exports[`snapshot test: global defaults with period 1`] = `
+Object {
+  "metric": Metric {
+    "account": undefined,
+    "color": undefined,
+    "dimensions": undefined,
+    "label": undefined,
+    "metricName": "DummyMetricName",
+    "namespace": "DummyNamespace",
+    "period": Duration {
+      "amount": 15,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
     },
+    "region": undefined,
+    "statistic": "p90",
+    "unit": undefined,
+    "warnings": undefined,
+  },
+  "metricAnomalyDetection": AnomalyDetectionMathExpression {
+    "color": undefined,
+    "expression": "ANOMALY_DETECTION_BAND(m1,2)",
+    "label": "label",
+    "period": Duration {
+      "amount": 15,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": undefined,
+    "searchRegion": undefined,
+    "usingMetrics": Object {
+      "m1": Metric {
+        "account": undefined,
+        "color": undefined,
+        "dimensions": undefined,
+        "label": undefined,
+        "metricName": "DummyMetric1",
+        "namespace": "DummyNamespace",
+        "period": Duration {
+          "amount": 15,
+          "unit": TimeUnit {
+            "inMillis": 60000,
+            "isoLabel": "M",
+            "label": "minutes",
+          },
+        },
+        "region": undefined,
+        "statistic": "Average",
+        "unit": undefined,
+        "warnings": undefined,
+      },
+    },
+  },
+  "metricMath": MathExpression {
+    "color": undefined,
+    "expression": "DummyExpression",
+    "label": "label",
+    "period": Duration {
+      "amount": 15,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": undefined,
+    "searchRegion": undefined,
+    "usingMetrics": Object {},
+    "warnings": Array [
+      "Math expression 'DummyExpression' references unknown identifiers: ummyExpression. Please add them to the 'usingMetrics' map.",
+    ],
+  },
+  "metricSearch": MathExpression {
+    "color": undefined,
+    "expression": "SEARCH('{DummyNamespace}  DummyQuery', 'p90', 900)",
+    "label": " ",
+    "period": Duration {
+      "amount": 15,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": undefined,
+    "searchRegion": undefined,
+    "usingMetrics": Object {},
+    "warnings": Array [
+      "Math expression 'SEARCH('{DummyNamespace}  DummyQuery', 'p90', 900)' references unknown identifiers: ummyNamespace, ummyQuery, p90. Please add them to the 'usingMetrics' map.",
+    ],
   },
-  "region": undefined,
-  "statistic": "p90",
-  "unit": undefined,
-  "warnings": undefined,
 }
 `;
 
-exports[`snapshot test: global defaults 5`] = `
-Metric {
-  "account": "123456789",
-  "color": undefined,
-  "dimensions": undefined,
-  "label": undefined,
-  "metricName": "DummyMetricName",
-  "namespace": "SomeNamespace",
-  "period": Duration {
-    "amount": 15,
-    "unit": TimeUnit {
-      "inMillis": 60000,
-      "isoLabel": "M",
-      "label": "minutes",
+exports[`snapshot test: global defaults with region 1`] = `
+Object {
+  "metric": Metric {
+    "account": undefined,
+    "color": undefined,
+    "dimensions": undefined,
+    "label": undefined,
+    "metricName": "DummyMetricName",
+    "namespace": "DummyNamespace",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
     },
+    "region": "us-west-2",
+    "statistic": "p90",
+    "unit": undefined,
+    "warnings": undefined,
+  },
+  "metricAnomalyDetection": AnomalyDetectionMathExpression {
+    "color": undefined,
+    "expression": "ANOMALY_DETECTION_BAND(m1,2)",
+    "label": "label",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": undefined,
+    "searchRegion": "us-west-2",
+    "usingMetrics": Object {
+      "m1": Metric {
+        "account": undefined,
+        "color": undefined,
+        "dimensions": undefined,
+        "label": undefined,
+        "metricName": "DummyMetric1",
+        "namespace": "DummyNamespace",
+        "period": Duration {
+          "amount": 5,
+          "unit": TimeUnit {
+            "inMillis": 60000,
+            "isoLabel": "M",
+            "label": "minutes",
+          },
+        },
+        "region": undefined,
+        "statistic": "Average",
+        "unit": undefined,
+        "warnings": undefined,
+      },
+    },
+  },
+  "metricMath": MathExpression {
+    "color": undefined,
+    "expression": "DummyExpression",
+    "label": "label",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": undefined,
+    "searchRegion": "us-west-2",
+    "usingMetrics": Object {},
+    "warnings": Array [
+      "Math expression 'DummyExpression' references unknown identifiers: ummyExpression. Please add them to the 'usingMetrics' map.",
+    ],
+  },
+  "metricSearch": MathExpression {
+    "color": undefined,
+    "expression": "SEARCH('{DummyNamespace}  DummyQuery', 'p90', 300)",
+    "label": " ",
+    "period": Duration {
+      "amount": 5,
+      "unit": TimeUnit {
+        "inMillis": 60000,
+        "isoLabel": "M",
+        "label": "minutes",
+      },
+    },
+    "searchAccount": undefined,
+    "searchRegion": "us-west-2",
+    "usingMetrics": Object {},
+    "warnings": Array [
+      "Math expression 'SEARCH('{DummyNamespace}  DummyQuery', 'p90', 300)' references unknown identifiers: ummyNamespace, ummyQuery, p90. Please add them to the 'usingMetrics' map.",
+    ],
   },
-  "region": "us-west-2",
-  "statistic": "p90",
-  "unit": undefined,
-  "warnings": undefined,
 }
 `;
 
diff --git a/test/facade/__snapshots__/MonitoringAspect.test.ts.snap b/test/facade/__snapshots__/MonitoringAspect.test.ts.snap
index 0269b70f..8acfb1d6 100644
--- a/test/facade/__snapshots__/MonitoringAspect.test.ts.snap
+++ b/test/facade/__snapshots__/MonitoringAspect.test.ts.snap
@@ -1554,7 +1554,7 @@ Object {
     },
     "DashboardFactoryDashboard3E20AD6E": Object {
       "Properties": Object {
-        "DashboardBody": "{\\"start\\":\\"-PT8H\\",\\"periodOverride\\":\\"inherit\\",\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### AWS Account Billing **Billing**\\"}},{\\"type\\":\\"metric\\",\\"width\\":18,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"bar\\",\\"title\\":\\"Most Expensive Services (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"region\\":\\"us-east-1\\",\\"expression\\":\\"SORT(search, MAX, DESC, 10)\\",\\"period\\":86400}],[{\\"label\\":\\" \\",\\"region\\":\\"us-east-1\\",\\"expression\\":\\"SEARCH('{AWS/Billing,Currency,ServiceName} MetricName=\\\\\\"EstimatedCharges\\\\\\"', 'Maximum', 86400)\\",\\"period\\":86400,\\"visible\\":false,\\"id\\":\\"search\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"USD\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"singleValue\\",\\"title\\":\\"Total Cost (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[\\"AWS/Billing\\",\\"EstimatedCharges\\",\\"Currency\\",\\"USD\\",{\\"label\\":\\"Estimated Charges\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400,\\"stat\\":\\"Maximum\\"}]],\\"setPeriodToTimeRange\\":false,\\"singleValueFullPrecision\\":false}}]}",
+        "DashboardBody": "{\\"start\\":\\"-PT8H\\",\\"periodOverride\\":\\"inherit\\",\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### AWS Account Billing **Billing**\\"}},{\\"type\\":\\"metric\\",\\"width\\":18,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"bar\\",\\"title\\":\\"Most Expensive Services (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"expression\\":\\"SORT(search, MAX, DESC, 10)\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400}],[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/Billing,Currency,ServiceName} MetricName=\\\\\\"EstimatedCharges\\\\\\"', 'Maximum', 86400)\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400,\\"visible\\":false,\\"id\\":\\"search\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"USD\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"singleValue\\",\\"title\\":\\"Total Cost (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[\\"AWS/Billing\\",\\"EstimatedCharges\\",\\"Currency\\",\\"USD\\",{\\"label\\":\\"Estimated Charges\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400,\\"stat\\":\\"Maximum\\"}]],\\"setPeriodToTimeRange\\":false,\\"singleValueFullPrecision\\":false}}]}",
         "DashboardName": "DummyDashboard",
       },
       "Type": "AWS::CloudWatch::Dashboard",
diff --git a/test/monitoring/aws-billing/__snapshots__/BillingMonitoring.test.ts.snap b/test/monitoring/aws-billing/__snapshots__/BillingMonitoring.test.ts.snap
index f45fa1eb..4e1e1da6 100644
--- a/test/monitoring/aws-billing/__snapshots__/BillingMonitoring.test.ts.snap
+++ b/test/monitoring/aws-billing/__snapshots__/BillingMonitoring.test.ts.snap
@@ -18,7 +18,7 @@ Object {
     },
     "Resource": Object {
       "Properties": Object {
-        "DashboardBody": "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### AWS Account Billing **Billing**\\"}},{\\"type\\":\\"metric\\",\\"width\\":18,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"bar\\",\\"title\\":\\"Most Expensive Services (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"region\\":\\"us-east-1\\",\\"expression\\":\\"SORT(search, MAX, DESC, 10)\\",\\"period\\":86400}],[{\\"label\\":\\" \\",\\"region\\":\\"us-east-1\\",\\"expression\\":\\"SEARCH('{AWS/Billing,Currency,ServiceName} MetricName=\\\\\\"EstimatedCharges\\\\\\"', 'Maximum', 86400)\\",\\"period\\":86400,\\"visible\\":false,\\"id\\":\\"search\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"USD\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"singleValue\\",\\"title\\":\\"Total Cost (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[\\"AWS/Billing\\",\\"EstimatedCharges\\",\\"Currency\\",\\"USD\\",{\\"label\\":\\"Estimated Charges\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400,\\"stat\\":\\"Maximum\\"}]],\\"setPeriodToTimeRange\\":false,\\"singleValueFullPrecision\\":false}}]}",
+        "DashboardBody": "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### AWS Account Billing **Billing**\\"}},{\\"type\\":\\"metric\\",\\"width\\":18,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"bar\\",\\"title\\":\\"Most Expensive Services (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"expression\\":\\"SORT(search, MAX, DESC, 10)\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400}],[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/Billing,Currency,ServiceName} MetricName=\\\\\\"EstimatedCharges\\\\\\"', 'Maximum', 86400)\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400,\\"visible\\":false,\\"id\\":\\"search\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"USD\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"singleValue\\",\\"title\\":\\"Total Cost (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[\\"AWS/Billing\\",\\"EstimatedCharges\\",\\"Currency\\",\\"USD\\",{\\"label\\":\\"Estimated Charges\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400,\\"stat\\":\\"Maximum\\"}]],\\"setPeriodToTimeRange\\":false,\\"singleValueFullPrecision\\":false}}]}",
       },
       "Type": "AWS::CloudWatch::Dashboard",
     },
@@ -95,7 +95,7 @@ Object {
     },
     "Resource": Object {
       "Properties": Object {
-        "DashboardBody": "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### AWS Account Billing **Billing**\\"}},{\\"type\\":\\"metric\\",\\"width\\":18,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"bar\\",\\"title\\":\\"Most Expensive Services (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"region\\":\\"us-east-1\\",\\"expression\\":\\"SORT(search, MAX, DESC, 10)\\",\\"period\\":86400}],[{\\"label\\":\\" \\",\\"region\\":\\"us-east-1\\",\\"expression\\":\\"SEARCH('{AWS/Billing,Currency,ServiceName} MetricName=\\\\\\"EstimatedCharges\\\\\\"', 'Maximum', 86400)\\",\\"period\\":86400,\\"visible\\":false,\\"id\\":\\"search\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"USD\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"singleValue\\",\\"title\\":\\"Total Cost (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[\\"AWS/Billing\\",\\"EstimatedCharges\\",\\"Currency\\",\\"USD\\",{\\"label\\":\\"Estimated Charges\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400,\\"stat\\":\\"Maximum\\"}]],\\"setPeriodToTimeRange\\":false,\\"singleValueFullPrecision\\":false}}]}",
+        "DashboardBody": "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### AWS Account Billing **Billing**\\"}},{\\"type\\":\\"metric\\",\\"width\\":18,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"bar\\",\\"title\\":\\"Most Expensive Services (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[{\\"label\\":\\" \\",\\"expression\\":\\"SORT(search, MAX, DESC, 10)\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400}],[{\\"label\\":\\" \\",\\"expression\\":\\"SEARCH('{AWS/Billing,Currency,ServiceName} MetricName=\\\\\\"EstimatedCharges\\\\\\"', 'Maximum', 86400)\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400,\\"visible\\":false,\\"id\\":\\"search\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"USD\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"singleValue\\",\\"title\\":\\"Total Cost (USD)\\",\\"region\\":\\"us-east-1\\",\\"metrics\\":[[\\"AWS/Billing\\",\\"EstimatedCharges\\",\\"Currency\\",\\"USD\\",{\\"label\\":\\"Estimated Charges\\",\\"region\\":\\"us-east-1\\",\\"period\\":86400,\\"stat\\":\\"Maximum\\"}]],\\"setPeriodToTimeRange\\":false,\\"singleValueFullPrecision\\":false}}]}",
       },
       "Type": "AWS::CloudWatch::Dashboard",
     },