Skip to content

cloudwatch: Explicitly set region and accountId fields are removed from metrics when they match the stack #28731

Closed
ryichk/todolist
#19
@TrevorBurnham

Description

Describe the bug

In my dashboard created from the CDK, I noticed that the region property was missing from metrics when that metric matched the stack. For example, for a stack in us-east-1, the metrics would look like this:

[
  {
    "label": "My metric [us-west-2]",
    "region": "us-west-2",
    "period": 60,
    "stat": "Maximum"
  },
  {
    "label": "My metric [us-east-1]",
    "period": 60,
    "stat": "Maximum"
  },
  // ...
]

This broke some region-based filtering logic in my UI application.

Expected Behavior

I expected the region field to exist for all of my metrics, since I was setting it explicitly:

new Metric({
  label: `My metric [${region}]`,
  region: region,
  period: 60,
  stat: 'Maximum'
})

Current Behavior

During serialization, the region and accountId fields are removed if they match the corresponding region and account values on the stack.

Reproduction Steps

You can confirm the behavior by adding this unit test to cross-environment.test.ts:

test('metric with explicit account and region will render as-is in stack with same region and account', () => {
  // GIVEN
  const graph = new GraphWidget({
    left: [
      a.with({ account: '1234', region: 'us-north-5' }),
    ],
  });

  // THEN
  // Assertion fails. It would pass if the stack had different region and account values.
  graphMetricsAre(new Stack(undefined, undefined, { env: { region: 'us-north-5', account: '1234' } }), graph, [
    ['Test', 'ACount', { accountId: '1234', region: 'us-north-5' }],
  ]);
});

Possible Solution

The problem arises from these two lines in the metricGraphJson function:

if (stat.account) { options.accountId = accountIfDifferentFromStack(stat.account); }
if (stat.region) { options.region = regionIfDifferentFromStack(stat.region); }

I'm not sure, but I think the intent here is to prevent the region and account from being included in the output if they were set implicitly by the attachTo function. As that function's description says:

If the metric is subsequently used in a Dashboard or Alarm in a different Stack defined in a different account or region, the appropriate 'region' and 'account' fields will be added to it.

I'm not sure why it's so important to prevent the region and account fields from being included when they match the stack, but if it is, you could have attachTo attach a placeholder that metricGraphJson can process appropriately (e.g. "${ifDifferentFromStack(us-east-1)}") rather than attaching a value that's indistinguishable from one that's been explicitly set.

Additional Information/Context

No response

CDK CLI Version

2.121.1

Framework Version

No response

Node.js Version

18.15.0

OS

macOS 13.6.3

Language

TypeScript

Language Version

No response

Other information

Possibly related to #18951?

Metadata

Assignees

No one assigned

    Labels

    @aws-cdk/aws-cloudwatchRelated to Amazon CloudWatchbugThis issue is a bug.effort/mediumMedium work item – several days of effortp2

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions