Skip to content

CloudFront 5xx alarm is created in the stack's region, where CloudFront metrics do not exist #481

Description

@Shimagaji

Before opening, please confirm

Which package(s) are affected?

@aws-blocks/core (the affected code is in @aws-blocks/hosting, which is not in the list)

Describe the bug

MonitoringConstruct creates the CloudFront5xxRate alarm in the stack's region. AWS/CloudFront metrics are only published in us-east-1, and CloudWatch alarms cannot watch metrics in another region (docs). For any stack outside us-east-1, the alarm never receives a datapoint.

The alarm uses treatMissingData: NOT_BREACHING, so it reports OK instead of INSUFFICIENT_DATA:

StateValue:            OK
StateUpdatedTimestamp: 2026-07-27T08:47:02Z   (= creation time, unchanged since)
StateReason:           no datapoints were received for 1 period and
                       1 missing datapoint was treated as [NonBreaching]

Related points:

  • monitoring.enabled defaults to true, so every stack outside us-east-1 gets this alarm.
  • Adding region: 'us-east-1' to the Metric is not a fix; aws-cdk-lib rejects it at synth (Cannot create an Alarm in region X based on metric in region Y). The alarm needs to live in a us-east-1 stack.
  • waf_construct.ts handles the same constraint for CloudFront-scoped WAF by throwing WafRegionError on non-us-east-1 stacks. The alarm has no equivalent check.
  • monitoring_construct.test.ts uses a us-west-2 stack and asserts the Region: 'Global' dimension. The dimension is correct, but the test does not cover which region the alarm is evaluated in, and a template assertion cannot detect that no metric will match.

Expected behavior

The alarm is created in a region where its metric exists, or synth fails when that is not possible. An alarm that is never evaluated does not report OK.

Reproduction steps

  1. Deploy a hosting-enabled app to a region other than us-east-1 with default settings.
  2. aws cloudwatch describe-alarms --region <stack-region> --alarm-name-prefix <stack>-HostingMonitoringCloudFront5xxRateStateValue: OK, StateUpdatedTimestamp equals creation time.
  3. aws cloudwatch get-metric-statistics --region <stack-region> --namespace AWS/CloudFront --metric-name 5xxErrorRate --dimensions Name=DistributionId,Value=<id> Name=Region,Value=Global ...Datapoints: []
  4. Same command with --region us-east-1 → datapoints returned.

Code snippet

// packages/hosting/src/constructs/monitoring_construct.ts
const cf5xx = new Alarm(this, 'CloudFront5xxRate', {
  metric: new Metric({
    namespace: 'AWS/CloudFront',
    metricName: '5xxErrorRate',
    dimensionsMap: {
      DistributionId: props.distribution.distributionId,
      // CloudFront metrics live in us-east-1 regardless of stack.
      Region: 'Global',
    },
    ...
  }),
  treatMissingData: TreatMissingData.NOT_BREACHING,
  ...
});

Environment

  • @aws-blocks/blocks 0.2.1 (core 0.1.11, hosting 0.1.4). Verified by code inspection that hosting 0.2.0 (released 2026-09-01) has the same alarm definition.
  • aws-cdk-lib 2.257.0, Node.js 26.7.0, stack region ap-northeast-1, static SPA + API (only this alarm is created)

Additional context

Possible fixes

  1. Create the CloudFront alarm in a us-east-1 stack (the repo already has one for Lambda@Edge, edge-lambda-stack).
  2. Use TreatMissingData.MISSING for this alarm so it reports INSUFFICIENT_DATA, and throw at synth on non-us-east-1 stacks as waf_construct.ts does.
  3. Document the limitation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions