fix: skip auto-named defaults that trigger upstream ConflictsWith - #3457
Conversation
The dynamic bridge runs `SetAutonaming` against every resource exposed by a wrapped provider, which attaches an `AutoName` default to any property literally called `name`. During Check, `defaults.ApplyDefaultInfoValues` fires that default whenever the user omits `name`, populating it with a generated `<urn-name>-<random>` value before the inputs are forwarded to the upstream provider's `ValidateResourceConfig`. For providers like `aws_cloudwatch_log_group` that expose `name` and `name_prefix` as `Optional + Computed + ConflictsWith: each other`, the injected `name` collides with the user-supplied `name_prefix` and the SDKv2 server returns two "Conflicting configuration arguments" diagnostics. The protocol-level schema does not surface `ConflictsWith`, so the bridge cannot know about the conflict ahead of time. Detect this case after the first `ValidateResourceConfig` call: if a ConflictsWith diagnostic points at an attribute the bridge auto-named, strip the auto-default from the inputs and re-validate once. The cleaned inputs are also returned from Check so the property does not leak into state — the upstream SDK will compute the final `name` from `name_prefix` during plan/apply, matching tofu's behaviour.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3457 +/- ##
==========================================
+ Coverage 69.82% 69.85% +0.03%
==========================================
Files 347 348 +1
Lines 38011 38083 +72
==========================================
+ Hits 26541 26603 +62
+ Misses 9661 9660 -1
- Partials 1809 1820 +11 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Add TestConflictsWithBothUserSpecified to verify that the auto-defaulted-conflict-stripper does not swallow the upstream ConflictsWith diagnostics when the user explicitly sets both `name` and `name_prefix`. The bridge must still report both SDKv2 "Conflicting configuration arguments" failures so the user can correct their program.
There was a problem hiding this comment.
No actionable issues found.
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
proxy.golang.org
To allow these domains, add them to the
network.allowedlist in your workflow frontmatter:
network:
allowed:
- defaults
- "proxy.golang.org"See Network Configuration for more information.
Reviewed by Internal Trusted PR Reviewer
To install this agentic workflow, run
gh aw add pulumi-labs/gh-aw-internal/.github/workflows/gh-aw-pr-review.md@8a92f53fac170563f7727cacab2dbedb5d5b9e29
| continue | ||
| } | ||
| pk := resource.PropertyKey(tfbridge.TerraformToPulumiNameV2(tfKey, schemaMap, schemaInfos)) | ||
| if _, inUser := inputs[pk]; inUser { |
There was a problem hiding this comment.
This doesn't matter for dynamically bridged providers, as they don't have preCheck callbacks, but on regular bridged providers shouldn't we use the checked inputs?
Fixes the bug introduced in #3457 as pointed out by @guineveresaenger: we no longer drop insertions added by `PreCheckCallback`.
|
This PR has been shipped in release v3.131.0. |
Summary
The dynamic bridge runs
SetAutonamingagainst every wrapped provider, which attaches anAutoNamedefault to any property literally calledname. DuringCheck,defaults.ApplyDefaultInfoValuesfires that default whenever the user omitsname, populating it with a generated value before forwarding to the upstream provider'sValidateResourceConfig.For providers like
aws_cloudwatch_log_groupwhosenameandname_prefixareOptional + Computed + ConflictsWith: each other, the injectednamecollides with the user-suppliedname_prefixand SDKv2 returns two "Conflicting configuration arguments" diagnostics. The protocol-level schema doesn't surfaceConflictsWith, so the bridge can't anticipate the conflict.This change detects the case after the first
ValidateResourceConfigcall: if aConflictsWithdiagnostic targets an attribute the bridge auto-named, strip the auto-default from the inputs and re-validate once. The cleaned inputs are also returned fromCheckso the property doesn't leak into state — the upstream SDK will compute the finalnamefromname_prefixduring plan/apply, matching tofu's behavior.Fixes #1095
Test plan
TestConflictsWithNamePrefixOnlyindynamic/conflicting_test.goreproduces the failure and now passes (check + create subtests).pkg/pf/tfbridgeunit tests still pass.