Skip to content

Commit 3083925

Browse files
seo: add FAQ sections to Language Essentials series to earn FAQPage schema (#21064)
Adds a 'Frequently asked questions' section (3 Q&A pairs each) to the 6 leaf pages under content/docs/iac/guides/basics/language-essentials/: variables, conditionals, loops, functions, classes, packages-and-dependencies. These pages already auto-qualify for supplemental FAQPage schema (type: docs, no frontmatter flag needed) but none of their existing headings were question-phrased, so the collector never found anything to emit. Rather than rephrasing the existing declarative H2s (out of scope per STYLE-GUIDE.md, which restricts trailing '?' headings to a named 'Frequently asked questions' exception), each page gets a dedicated FAQ section with clean, answer-first Q&A prose placed immediately before Next steps, mirroring the established pattern already used across content/docs/iac/comparisons/*.md. Verified with an isolated Hugo harness (schema/graph-builder.html + dependencies + real content copied verbatim, per the pulumi_docs_hugo_schema_harness playbook): all 6 rendered pages emit a FAQPage entity with 3 Question/acceptedAnswer pairs each, and no leaked markdown (no stray '#', code fences, pipes, or list markers) in any answer text. _index.md is intentionally untouched: it's a Hugo section bundle (.IsPage is false), which never qualifies for FAQPage schema regardless of content. HowTo schema is also out of scope here; it's gated to .Type == 'blog' in graph-builder.html and structurally cannot apply to a docs page. Co-authored-by: workprentice <257153108+workprentice@users.noreply.github.com>
1 parent 88a52b4 commit 3083925

6 files changed

Lines changed: 84 additions & 0 deletions

File tree

content/docs/iac/guides/basics/language-essentials/classes.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,20 @@ for the decision itself, and
327327
for the full walkthrough, including packaging it for other languages to
328328
consume.
329329

330+
## Frequently asked questions
331+
332+
### Do I need to know object-oriented programming to use Pulumi?
333+
334+
No. Classes are entirely optional in Pulumi, and most day-to-day infrastructure code is plain functions and resource declarations. You only reach for a class when you want to package resources into a reusable, named component that other code can create and reference as a unit.
335+
336+
### What is a ComponentResource?
337+
338+
A `ComponentResource` is a resource that groups a set of child resources under one logical parent and exposes their combined outputs through a single interface, using `registerOutputs` (`RegisterOutputs` in C#). Consumers of the [component](/docs/iac/concepts/components/) interact with that simple interface instead of wiring up each child resource themselves.
339+
340+
### Can I use a component written in another language?
341+
342+
Yes, if it's packaged as a source-based package. Consumers run `pulumi package add` against its Git URL, and Pulumi generates an SDK in whichever language they're using, YAML included. A plain npm- or PyPI-style native language package, by contrast, only works in the language it was published for.
343+
330344
## Next steps
331345

332346
Continue to

content/docs/iac/guides/basics/language-essentials/conditionals.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,20 @@ in an `if` statement; see
263263
[working with outputs](/docs/iac/concepts/inputs-outputs/apply/) for how that
264264
works.
265265

266+
## Frequently asked questions
267+
268+
### How do I make a resource conditional in Pulumi?
269+
270+
Wrap the resource declaration in a plain `if` statement in your programming language. There's no special conditional-resource construct to learn: the same branching you already use for any other decision in your code decides whether Pulumi sees the resource declaration at all, using ordinary values like [stack configuration](/docs/iac/concepts/config/).
271+
272+
### What replaces `count = 0` in Pulumi?
273+
274+
Nothing special is needed; an ordinary `if` statement takes its place. Because you're working with a real language rather than a declarative block, references to a conditionally created resource stay single values instead of becoming zero-or-one-element lists the way Terraform's `count` produces, which keeps the rest of your program simpler.
275+
276+
### Can I branch on a resource output?
277+
278+
No, not directly. A resource [output](/docs/iac/concepts/inputs-outputs/) isn't known while your program runs, so an `if` can only branch on values known at that time, such as the stack name, configuration, or plain inputs. If a decision genuinely depends on a value produced by another resource, make it inside an [`apply`](/docs/iac/concepts/inputs-outputs/apply/) callback instead of at the top level of your program.
279+
266280
## Next steps
267281

268282
Continue to [loops and iteration](/docs/iac/guides/basics/language-essentials/loops/)

content/docs/iac/guides/basics/language-essentials/functions.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,20 @@ does, that's the signal to move to a class-based
278278
[component](/docs/iac/guides/basics/language-essentials/classes/)
279279
instead.
280280

281+
## Frequently asked questions
282+
283+
### When should I use a function instead of a component?
284+
285+
Reach for a plain function when you just want to group or parameterize a handful of resource declarations, and reach for a [component](/docs/iac/concepts/components/) once that group needs its own identity, combined outputs, or the ability to be referenced elsewhere in the program as a single unit. A function is the lighter-weight option; a component is the one that behaves like a resource itself.
286+
287+
### Are Pulumi functions the same as Terraform modules?
288+
289+
Not quite. The closest analogue to a Terraform module is a Pulumi component resource, which gets its own name, state entry, and combined outputs. A plain function in your programming language is a lighter-weight grouping mechanism with no state identity of its own; it just runs code and returns values.
290+
291+
### Can I pass a resource output into a function?
292+
293+
Yes. Accept it as an ordinary function parameter and pass it straight through to whatever resource properties need it. You don't need to unwrap an [output](/docs/iac/concepts/inputs-outputs/) before handing it to a function; Pulumi resolves it later, once its value is known.
294+
281295
## Next steps
282296

283297
Continue to

content/docs/iac/guides/basics/language-essentials/loops.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,20 @@ See [working with outputs](/docs/iac/concepts/inputs-outputs/apply/) and
339339
[combining outputs](/docs/iac/concepts/inputs-outputs/all/) for the full
340340
picture in every language.
341341

342+
## Frequently asked questions
343+
344+
### How do I replace `for_each` when I move from Terraform to Pulumi?
345+
346+
With a normal loop or comprehension over a list or map in your programming language. There's no separate meta-argument to learn: you iterate over the same data structure you'd use anywhere else in your code, and each iteration declares one resource.
347+
348+
### How do I keep resource names stable when I create resources in a loop?
349+
350+
Build each resource's logical name from a stable key drawn from your data, such as an item's identifier, rather than from the loop's iteration order or index. Pulumi tracks resources by their [logical name](/docs/iac/concepts/resources/names/), so changing that name causes Pulumi to replace the resource, and a name derived from iteration order shifts whenever the underlying list is reordered or resized.
351+
352+
### Can I loop over a resource output?
353+
354+
Not directly, since an [output](/docs/iac/concepts/inputs-outputs/) isn't a concrete value while your program runs. Call [`.apply()`](/docs/iac/concepts/inputs-outputs/apply/) on a single output, or [`pulumi.all([...])`](/docs/iac/concepts/inputs-outputs/all/) to combine several, and do the iteration inside the callback once the values are resolved.
355+
342356
## Next steps
343357

344358
Continue to [functions](/docs/iac/guides/basics/language-essentials/functions/) to

content/docs/iac/guides/basics/language-essentials/packages-and-dependencies.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@ your organization and shouldn't be public, Pulumi Cloud supports private
6464
packages, so you get the same install-and-import experience internally
6565
without publishing anything externally.
6666

67+
## Frequently asked questions
68+
69+
### Do I still need to run `pulumi plugin install`?
70+
71+
Usually not. The Pulumi CLI installs any missing provider plugins automatically the first time you run `pulumi preview` or `pulumi up` in a project. Manual installation is for cases like pre-fetching plugins in CI, working offline, or pinning a specific plugin version ahead of time; it isn't a step you need in ordinary day-to-day development.
72+
73+
### How do I add a Pulumi provider to my project?
74+
75+
Through your language's own package manager: `npm install @pulumi/aws` in TypeScript, `pip install pulumi-aws` in Python, a Go module dependency, `Pulumi.Aws` through NuGet, or `com.pulumi.aws` through Maven. You can also run `pulumi package add` to generate a local SDK directly from a plugin or schema, which is the same mechanism source-based component packages use.
76+
77+
### How do I share a component privately with my organization?
78+
79+
Publish it to the Pulumi Private Registry with `pulumi package publish` against a tagged Git repository. Teammates can then discover the package in the registry and generate an SDK for it in whichever language they're using, the same way they would consume any first-party provider.
80+
6781
## Next steps
6882

6983
Revisit the [series overview](/docs/iac/guides/basics/language-essentials/) or apply

content/docs/iac/guides/basics/language-essentials/variables.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,20 @@ works, and each language's interpolation helper, such as `pulumi.interpolate`
321321
in TypeScript or `pulumi.Output.format()` in Python, for building strings out
322322
of them.
323323

324+
## Frequently asked questions
325+
326+
### What replaces Terraform locals and variables in Pulumi?
327+
328+
An ordinary variable in your programming language plays the role Terraform's `locals` and `variable` blocks play. Per-stack inputs that used to live in a `variable` block instead come from [stack configuration](/docs/iac/concepts/config/), which you read at the top of your program and assign to a regular variable.
329+
330+
### Why doesn't string interpolation work on a resource output?
331+
332+
Because an output value isn't known while your program runs; it only resolves once the resource is created or updated. Standard string interpolation needs a value in hand immediately, so each language SDK provides an [output](/docs/iac/concepts/inputs-outputs/)-aware helper instead: `pulumi.interpolate` in TypeScript, `Output.format()` in Python and Java, `pulumi.Sprintf()` in Go, and `Output.Format()` in C#.
333+
334+
### Do I have to declare a type for every variable?
335+
336+
No. Type inference handles most cases, so you can assign a value and let the compiler work out its type. Declaring a type explicitly still pays off for public function signatures and component inputs, where it gives you IDE completion and catches mismatches at compile time rather than at deployment time.
337+
324338
## Next steps
325339

326340
Continue to [conditionals](/docs/iac/guides/basics/language-essentials/conditionals/)

0 commit comments

Comments
 (0)