Skip to content

Add: struct-typed values via Lazy producers / provider-function arguments need the resource's own xxxToTerraform mapper #26

Description

@vincenthsh

Problem

Any value that reaches a generated resource's nested-struct property without going through plain synth-time attribute assignment — a Lazy.anyValue({ produce: ... }) producer, or the raw argument to a provider-defined function call (provider::<name>::<function>) — bypasses that struct's generated xxxToTerraform mapper entirely, so it must be pre-shaped by hand (either hand-written in the Terraform schema's own snake_case, or run through the exported xxxToTerraform function yourself). This is currently undocumented in both places a user would hit it:

  1. Lazy producers. concepts/constructs.mdx's only Lazy example (new Lazy({ produce: () => buckets }) as a TerraformOutput value) is a flat list-of-strings case that never needs struct mapping, so it doesn't demonstrate the requirement. api-reference/*/classes/lazy.mdx (all languages) is API-reference only, no usage guidance. concepts/tokens.mdx has no mention of Lazy, xxxToTerraform, or canInspect at all — the actual mechanism (canInspect() returns false for an unresolved token, so the struct mapper's early-return skips it, and the raw produce() result is substituted in later during whole-tree token resolution, never touching the mapper) isn't explained anywhere.
  2. Provider-defined functions. concepts/functions.mdx covers only the built-in Fn.* set and explicitly scopes provider-defined functions out even of the function-availability-validation section ("Provider-defined functions (provider::<name>::<function>) are out of scope"). There's no conceptual doc for provider-defined functions at all yet, so there's nowhere this gotcha could currently be documented even if someone wanted to add it.

Concrete repro

Demonstrated in cdktn-provider-features-demo (l2-kinesis-stream): assigning a plain camelCase object as one branch of a provider::cfncompat::condition_if(...) call and passing it as a struct-typed resource attribute renders with the wrong (camelCase) keys unless it's first run through the resource's own generated xxxToTerraform mapper — e.g. kinesisStreamStreamEncryptionToTerraform({ encryptionType: "KMS", keyId: "alias/aws/kinesis" }) instead of hand-writing { encryption_type: "KMS", key_id: "alias/aws/kinesis" }. The wrapper has a real ergonomic edge too: its argument is the typed KinesisStreamStreamEncryption shape, so typos/wrong types are caught by tsc, unlike a raw any-typed provider-function argument.

Ask

  • Add a Lazy example to concepts/constructs.mdx (or tokens.mdx) that produces a nested struct property (not just a flat value), showing the required xxxToTerraform(...) wrap and briefly explaining why (canInspect()/token-resolution timing).
  • Add a conceptual "Provider Functions" doc (concepts/provider-functions.mdx or similar — functions.mdx currently only covers built-in Fn.*), including the same struct-argument gotcha, since it's the identical underlying cause.
  • cdktn-provider-features-demo's l2-kinesis-stream example is a live, working repro of both patterns side by side if useful as a doc example source.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions