What happened?
The Import docs for IAM resources are wrong for pulumi-gcp — roughly 425 of its ~1438 resources with an Import section still emit a literal terraform import ... command, and the large majority of those are the IAM "triad" resources (*IamBinding / *IamMember / *IamPolicy). See pulumi/pulumi-gcp#1473, where the residual after the earlier import-rewriting work was traced to this repo.
The root cause is parseImportCode in pkg/tfgen/docs.go:
var importCodePattern = regexp.MustCompile(
`^\s*(?:[%$]\s+)?(?:pulumi|terraform) import[\\\s]+([^.]+)[.]([^\s]+)[\\\s]+([^\s]+)\s*$`)
The ID capture group is ([^\s]+)\s*$ — a single whitespace-free token. IAM import IDs are space-delimited, quoted identifiers (resource + role + member), so the pattern never matches and rewriteImportLines leaves the upstream terraform import line verbatim.
This produces three distinct defects on a single rendered page. From gcp:accesscontextmanager/accessPolicyIamBinding (live today, gcp v9.34.0):
IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g.
$ terraform import google_access_context_manager_access_policy_iam_member.editor "accessPolicies/{{access_policy}} roles/accesscontextmanager.policyAdmin user:jane@example.com"
IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g.
$ terraform import google_access_context_manager_access_policy_iam_binding.editor "accessPolicies/{{access_policy}} roles/accesscontextmanager.policyAdmin"
IAM policy imports use the identifier of the resource in question, e.g.
$ pulumi import gcp:accesscontextmanager/accessPolicyIamBinding:AccessPolicyIamBinding editor accessPolicies/{{access_policy}}
- Unrewritten
terraform import lines. The two space-delimited examples keep the Terraform CLI, the upstream google_* resource name, and no Pulumi token. A user following these docs runs the wrong binary.
- The one line that does rewrite gets the wrong token. Upstream ships one shared doc page for all three triad members, so the IamPolicy example is the only one whose ID is a single token — and the rewriter stamps it with whatever page it is currently generating. On the Binding page above, the policy example is labeled
...accessPolicyIamBinding:AccessPolicyIamBinding. The same happens on storage/bucketIAMMember, where the policy example renders as pulumi import gcp:storage/bucketIAMMember:BucketIAMMember editor b/{{bucket}}. So the only pulumi import line on the page is an incorrect command.
- Some pages lose the Import body entirely. On
gcp:projects/iAMMember the whole Import section collapses to two -> notes — one of which itself contains a bare terraform import google_project_iam_binding.my_project "{{your-project-id}} roles/{{role_id}} condition-title" in prose. Every actual import instruction is gone; the page gives no pulumi import guidance at all.
Expected behavior
parseImportCode / rewriteImportLines should handle space-delimited import IDs, so that
$ terraform import google_storage_bucket_iam_member.editor "b/{{bucket}} roles/storage.objectViewer user:jane@example.com"
becomes
$ pulumi import gcp:storage/bucketIAMMember:BucketIAMMember editor "b/{{bucket}} roles/storage.objectViewer user:jane@example.com"
Suggested scope:
- Extend the ID capture to accept a quoted, whitespace-containing ID (
"..." / '...'), keeping the quotes in the emitted pulumi import command. This alone fixes the bulk of the ~425 gcp resources.
- Decide what to do with triad pages where the upstream example refers to a sibling resource (
_iam_policy example on the IamBinding page). Substituting the current page's token, as happens today, is actively wrong. Options: map the upstream google_*_iam_{member,binding,policy} name to the corresponding Pulumi token instead of the page's own token, or drop examples that don't correspond to the resource being generated.
- Handle inline-code
terraform import mentions in prose (outside fences) — that's what leaks on projects/iAMMember.
- Investigate why the
projects/iAMMember Import body is elided entirely; that's a separate failure from the leak and leaves the resource undocumented for import.
Reproduction
- Upstream source:
website/docs/r/google_project_iam.html.markdown and the *_iam.html.markdown pages generally.
make tfgen in pulumi/pulumi-gcp emits parseImports "gcp:<...>" should not render the string 'terraform' in its emitted markdown. for each affected resource.
- Grep the generated
provider/cmd/pulumi-resource-gcp/schema.json for terraform import — ~425 resources, ~800 lines, concentrated in *IamBinding / *IamMember / *IamPolicy.
This is not gcp-specific — any bridged provider whose upstream docs use quoted, space-delimited import IDs hits it (aws, azure, and others with IAM-style composite IDs). <- Not sure why Claude thinks this. Homie better verify this against an actual Registry page to prove it.
Related
What happened?
The Import docs for IAM resources are wrong for
pulumi-gcp— roughly 425 of its ~1438 resources with an Import section still emit a literalterraform import ...command, and the large majority of those are the IAM "triad" resources (*IamBinding/*IamMember/*IamPolicy). See pulumi/pulumi-gcp#1473, where the residual after the earlier import-rewriting work was traced to this repo.The root cause is
parseImportCodeinpkg/tfgen/docs.go:The ID capture group is
([^\s]+)\s*$— a single whitespace-free token. IAM import IDs are space-delimited, quoted identifiers (resource + role + member), so the pattern never matches andrewriteImportLinesleaves the upstreamterraform importline verbatim.This produces three distinct defects on a single rendered page. From
gcp:accesscontextmanager/accessPolicyIamBinding(live today, gcp v9.34.0):terraform importlines. The two space-delimited examples keep the Terraform CLI, the upstreamgoogle_*resource name, and no Pulumi token. A user following these docs runs the wrong binary....accessPolicyIamBinding:AccessPolicyIamBinding. The same happens onstorage/bucketIAMMember, where the policy example renders aspulumi import gcp:storage/bucketIAMMember:BucketIAMMember editor b/{{bucket}}. So the onlypulumi importline on the page is an incorrect command.gcp:projects/iAMMemberthe whole Import section collapses to two->notes — one of which itself contains a bareterraform import google_project_iam_binding.my_project "{{your-project-id}} roles/{{role_id}} condition-title"in prose. Every actual import instruction is gone; the page gives nopulumi importguidance at all.Expected behavior
parseImportCode/rewriteImportLinesshould handle space-delimited import IDs, so thatbecomes
Suggested scope:
"..."/'...'), keeping the quotes in the emittedpulumi importcommand. This alone fixes the bulk of the ~425 gcp resources._iam_policyexample on theIamBindingpage). Substituting the current page's token, as happens today, is actively wrong. Options: map the upstreamgoogle_*_iam_{member,binding,policy}name to the corresponding Pulumi token instead of the page's own token, or drop examples that don't correspond to the resource being generated.terraform importmentions in prose (outside fences) — that's what leaks onprojects/iAMMember.projects/iAMMemberImport body is elided entirely; that's a separate failure from the leak and leaves the resource undocumented for import.Reproduction
website/docs/r/google_project_iam.html.markdownand the*_iam.html.markdownpages generally.make tfgeninpulumi/pulumi-gcpemitsparseImports "gcp:<...>" should not render the string 'terraform' in its emitted markdown.for each affected resource.provider/cmd/pulumi-resource-gcp/schema.jsonforterraform import— ~425 resources, ~800 lines, concentrated in*IamBinding/*IamMember/*IamPolicy.This is not gcp-specific — any bridged provider whose upstream docs use quoted, space-delimited import IDs hits it (aws, azure, and others with IAM-style composite IDs). <- Not sure why Claude thinks this. Homie better verify this against an actual Registry page to prove it.
Related
terraformwithpulumiglobally #2251 — broader "replaceterraformwithpulumiglobally".