Skip to content

fix(toolkit-lib): drift numResourcesUnchecked ignores UNKNOWN-status resources - #1837

Open
Adityaj0 wants to merge 1 commit into
aws:mainfrom
Adityaj0:fix/drift-numresourcesunchecked-includes-unknown-status
Open

fix(toolkit-lib): drift numResourcesUnchecked ignores UNKNOWN-status resources#1837
Adityaj0 wants to merge 1 commit into
aws:mainfrom
Adityaj0:fix/drift-numresourcesunchecked-includes-unknown-status

Conversation

@Adityaj0

Copy link
Copy Markdown
Contributor

fixes #1836

Reason for this change

`DriftFormatter.formatStackDrift()` (`packages/@aws-cdk/toolkit-lib/lib/api/drift/drift-formatter.ts`) computed:

numResourcesUnchecked: this.allStackResources.size - this.resourceDriftResults.length,

This only counts resources CloudFormation returned no drift record for at all. But the printed "Unchecked Resources" text section (`formatStackDriftChanges`, a few lines below) uses different, more complete logic — it also treats a resource as unchecked if it has a drift record whose status is `UNKNOWN`:

const uncheckedResources = Array.from(this.allStackResources.keys()).filter((logicalId) => {
  const drift = drifts.find((d) => d.LogicalResourceId === logicalId);
  return !drift || drift.StackResourceDriftStatus === StackResourceDriftStatus.UNKNOWN;
});

`UNKNOWN` is a real, common CloudFormation status (missing permissions, resource type without full drift-detection support, throttling — there's already error-handling elsewhere in this codebase specifically for it).

Net effect: a resource with an `UNKNOWN`-status drift record is listed under "Unchecked Resources" in the detailed output, but doesn't count toward `numResourcesUnchecked`. That field feeds `Toolkit.driftAll`'s final summary line in `toolkit.ts`:

const totalUnchecked = Object.values(allDriftResults).reduce((total, current) => total + (current.numResourcesUnchecked ?? 0), 0);
await driftSpan.end(\`\n  Number of resources with drift: \${totalDrifts}\${totalUnchecked ? \` (\${totalUnchecked} unchecked)\` : ''}\`);

...so if the only unchecked resources have `UNKNOWN` status (rather than being entirely missing from the results), `totalUnchecked` is 0 and the `(N unchecked)` suffix is silently dropped — even though the detailed output right above it explicitly lists an unchecked resource. Self-contradictory CLI output that can give false confidence everything was verified.

Description of changes

Extracts the unchecked-resource computation into a single `getUncheckedResources()` private helper, used by both:

  • the numeric `numResourcesUnchecked` field (both branches of `formatStackDrift`), and
  • the printed "Unchecked Resources" list (`formatStackDriftChanges`, previously duplicating the same filter inline)

so the count and the list are computed from one source of truth and can't diverge again.

Description of how you validated changes

Added assertions to the two existing tests that already construct `UNKNOWN`-status fixtures (`'formatting with UNKNOWN drift status'` and `'formatting with only UNKNOWN drift status'` in `test/api/drift/drift.test.ts`) — they exercised the `unchecked` text output but never checked `numResourcesUnchecked`. Verified both new assertions fail on the pre-fix code (expected 1 / 2, got 0 in both cases) and pass with the fix.

Ran the full `test/api/drift/` and `test/actions/drift.test.ts` suites — 27 passed, no regressions. `eslint --fix` clean.

Checklist

  • Unit tests added/updated
  • Integration tests added/updated (not applicable — pure output-formatting bug in a helper class, fully covered by unit tests)
  • No manual edits to generated files

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

…resources

DriftFormatter.formatStackDrift() computed numResourcesUnchecked as
`allStackResources.size - resourceDriftResults.length` - only counting
resources CloudFormation returned no drift record for at all. The actual
"Unchecked Resources" text section (formatStackDriftChanges) also treats a
resource with an UNKNOWN-status drift record as unchecked, which is a real,
common status (missing permissions, unsupported resource type, throttling).

This meant a resource could be printed under "Unchecked Resources" while
numResourcesUnchecked - and therefore the CLI's final summary line, which
sums this field and only appends "(N unchecked)" when it's truthy - showed
0, silently dropping the warning and contradicting the detailed output.

Extracts the unchecked-resource computation into a single
getUncheckedResources() helper used by both the numeric count and the
printed list, so they can't diverge again.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(toolkit-lib): cdk drift's numResourcesUnchecked count contradicts the printed 'Unchecked Resources' list

1 participant