Skip to content

Add comprehensive project layout best practices#17006

Merged
CamSoper merged 7 commits intomasterfrom
joeduffy/fix-issue-11766-project-layout
Jan 30, 2026
Merged

Add comprehensive project layout best practices#17006
CamSoper merged 7 commits intomasterfrom
joeduffy/fix-issue-11766-project-layout

Conversation

@joeduffy
Copy link
Copy Markdown
Member

Expands the "Organizing your project code" section with practical guidance:

  • Common project structures (flat, by layer, by service)
  • When to use each approach
  • Pulumi-specific tips for config helpers and naming conventions
  • How to organize application code alongside infrastructure
  • When to split into separate projects

This gives users concrete examples rather than just abstract concepts.

Fixes #11766

Expands the "Organizing your project code" section with practical guidance:
- Common project structures (flat, by layer, by service)
- When to use each approach
- Pulumi-specific tips for config helpers and naming conventions
- How to organize application code alongside infrastructure
- When to split into separate projects

This gives users concrete examples rather than just abstract concepts.

Fixes #11766

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Jan 12, 2026

Documentation Review

This PR significantly expands the "Organizing your project code" section with practical, actionable guidance. The content is well-structured and provides valuable real-world examples. However, there are a few issues to address:


Issues Found

1. Typographical inconsistency (line 331)

The text uses "Typescript" but should be "TypeScript" (capital S) for consistency with the official TypeScript branding and the rest of the documentation.

Organize your code in a way that makes it easy to understand and maintain. One way to do this in TypeScript is to break out your code into separate files, and then import them into your main file. In this example, the entrypoint for our Pulumi program is `index.ts`, but we use the `utils.ts` file for supporting functions.

2. Consider adding a trailing newline verification

While I cannot confirm from the diff whether the file ends with a newline (as required by AGENTS.md), please verify that the file ends with a proper trailing newline character.


Strengths

  • Clear structure: The hierarchical organization (flat → by layer → by service) provides an effective learning progression
  • Practical examples: The directory tree diagrams and code snippets give concrete guidance
  • Good decision guidance: "When to use" sections help readers choose appropriate patterns
  • Pulumi-specific tips: The configuration helpers and naming conventions sections add real value
  • Appropriate cross-references: The stack references link is well-placed

Style Compliance

✅ Headings follow sentence case (H2+)
✅ No directional language ("above," "below")
✅ Consistent terminology
✅ Clear, concise paragraphs
✅ Code examples are realistic and follow best practices
✅ Internal links use proper Markdown syntax


Overall, this is a strong enhancement that addresses issue #11766 effectively. Once the TypeScript capitalization is corrected, this will be ready to merge.

Mention me (@claude) if you'd like me to review any updates or have questions!

@pulumi-bot
Copy link
Copy Markdown
Collaborator

Copy link
Copy Markdown
Contributor

@cnunciato cnunciato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things we might want to tweak here, but this extra detail definitely helps!

Comment thread content/docs/iac/guides/basics/organizing-projects-stacks/_index.md Outdated
Comment on lines +376 to +379
// Validate config at program start
if (!["dev", "staging", "prod"].includes(environment)) {
throw new Error(`Unknown environment: ${environment}`);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this (hard-coding "allowed" stack names) a common pattern? I haven't seen it much myself — but if it's something we think is a best practice, or that we see in the wild, I'd be okay with it. Otherwise, might suggest we nix, or replace with something more common (reading another file, from ENV, from an async service, etc.).

This particular example would also benefit slightly from a usage example. (It'd be simple, but complete the picture a bit better.) Happy to add one if you like!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkodroff is this something we ever see in the wild?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just not a good practice IMO. The environment name is usually synonymous with the stack name, and to me, by virtue of a stack being initialized, it's valid, not something we need to validate after the fact.

Comment thread content/docs/iac/guides/basics/organizing-projects-stacks/_index.md Outdated
Comment thread content/docs/iac/guides/basics/organizing-projects-stacks/_index.md Outdated
export function name(resourceName: string): string {
return `${project}-${stack}-${resourceName}`;
}
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one could also benefit from a usage example (again, simple, but would make the usefulness clearer IMO).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is needed at all with latest and greatest autonaming.

Comment thread content/docs/iac/guides/basics/organizing-projects-stacks/_index.md
Comment thread content/docs/iac/guides/basics/organizing-projects-stacks/_index.md Outdated
Comment thread content/docs/iac/guides/basics/organizing-projects-stacks/_index.md Outdated
…ex.md

Co-authored-by: Christian Nunciato <c@nunciato.org>
…ex.md

Co-authored-by: Christian Nunciato <c@nunciato.org>
…ex.md

Co-authored-by: Christian Nunciato <c@nunciato.org>
…ex.md

Co-authored-by: Christian Nunciato <c@nunciato.org>
…ex.md

Co-authored-by: Christian Nunciato <c@nunciato.org>
@pulumi-bot
Copy link
Copy Markdown
Collaborator

@pulumi-bot
Copy link
Copy Markdown
Collaborator

@pulumi-bot
Copy link
Copy Markdown
Collaborator

@pulumi-bot
Copy link
Copy Markdown
Collaborator

@pulumi-bot
Copy link
Copy Markdown
Collaborator

Copy link
Copy Markdown
Member

@jkodroff jkodroff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is such foundational guidance, I think we need to go over this with a fine-toothed comb and make sure there's consensus. I'm not quite at the "Request Changes" level since this probably makes things better, but I think we would do better to vet this a little more before shipping.


#### Organized by resource layer

For medium-sized projects, organize files by infrastructure layer:
Copy link
Copy Markdown
Member

@jkodroff jkodroff Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree on this. I would keep all resources in the entrypoint file, except for (local) components, which nearly always go in a separate file. If there's a local library or maybe structured config classes, those would also each go in a separate file.

If you have that many resources that you need to split among that many files, you should probably have separate programs, e.g the classic Networking -> K8s Cluster -> Workloads pattern of codebases.

├── Pulumi.dev.yaml
├── Pulumi.prod.yaml
├── index.ts # Main entrypoint
└── config.ts # Config helpers and constants
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually not necessary IMO.

├── Pulumi.yaml
├── Pulumi.dev.yaml
├── Pulumi.prod.yaml
├── index.ts # Main entrypoint
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without giving an outline of what the entrypoint file contains, this example risks confusing more than it clarifies.

}
```

**Application code alongside infrastructure:** If your Pulumi project also contains application code (such as Lambda function code or Docker build contexts), consider organizing it into clearly labeled directories:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example is the most useful yet, but it's specific to a serverless app IMO.

We should also show a containerized version, which for me would do something like:

README.md
Makefile # or whatever - orchestrates building the app code, deploying to a container registry, and then calling Pulumi to deploy
app/
  (app code here)
infra/
  (Pulumi code here)

@CamSoper CamSoper self-assigned this Jan 29, 2026
Based on review feedback from jkodroff and cnunciato:

- Remove environment validation example (conflicts with stack-based environments)
- Remove resource naming conventions helper (modern autonaming makes this unnecessary)
- Revise file organization guidance to emphasize keeping resources in entrypoint
- Add guidance to split into multiple projects if complexity grows
- Soften config.ts guidance from prescriptive to optional
- Add containerized application example with Makefile pattern
- Convert bold headers to proper subheadings for better structure

These changes make the guidance more conservative and aligned with current best practices.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@CamSoper
Copy link
Copy Markdown
Contributor

@jkodroff I've addressed your feedback from the review:

  1. Removed environment validation example - Agreed this isn't a best practice and conflicts with stack-based environments
  2. Removed naming conventions helper - Modern autonaming makes this unnecessary
  3. Revised file organization guidance - Now emphasizes keeping resources in entrypoint, with separate files primarily for components/libraries. Added guidance to split into multiple projects if complexity grows
  4. Softened config.ts guidance - Changed from prescriptive to optional
  5. Enhanced service/feature example - Added context about what entrypoint contains
  6. Added containerized example - Included the Makefile pattern you suggested alongside the serverless example
  7. Fixed formatting - Changed bold headers to proper subheadings per @cnunciato's feedback

The revised guidance is more conservative and aligned with current best practices. A few questions:

  • Is there more work you'd like to see on this before it ships?
  • Do you think this content is valuable to merge now, or should we backburner it for more team discussion?

@pulumi-bot
Copy link
Copy Markdown
Collaborator

@CamSoper CamSoper merged commit 63750aa into master Jan 30, 2026
12 checks passed
@CamSoper CamSoper deleted the joeduffy/fix-issue-11766-project-layout branch January 30, 2026 19:29
tehsis pushed a commit that referenced this pull request Feb 9, 2026
* Add comprehensive project layout best practices

Expands the "Organizing your project code" section with practical guidance:
- Common project structures (flat, by layer, by service)
- When to use each approach
- Pulumi-specific tips for config helpers and naming conventions
- How to organize application code alongside infrastructure
- When to split into separate projects

This gives users concrete examples rather than just abstract concepts.

Fixes #11766

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Update content/docs/iac/guides/basics/organizing-projects-stacks/_index.md

Co-authored-by: Christian Nunciato <c@nunciato.org>

* Update content/docs/iac/guides/basics/organizing-projects-stacks/_index.md

Co-authored-by: Christian Nunciato <c@nunciato.org>

* Update content/docs/iac/guides/basics/organizing-projects-stacks/_index.md

Co-authored-by: Christian Nunciato <c@nunciato.org>

* Update content/docs/iac/guides/basics/organizing-projects-stacks/_index.md

Co-authored-by: Christian Nunciato <c@nunciato.org>

* Update content/docs/iac/guides/basics/organizing-projects-stacks/_index.md

Co-authored-by: Christian Nunciato <c@nunciato.org>

* Address PR feedback on project organization guidance

Based on review feedback from jkodroff and cnunciato:

- Remove environment validation example (conflicts with stack-based environments)
- Remove resource naming conventions helper (modern autonaming makes this unnecessary)
- Revise file organization guidance to emphasize keeping resources in entrypoint
- Add guidance to split into multiple projects if complexity grows
- Soften config.ts guidance from prescriptive to optional
- Add containerized application example with Makefile pattern
- Convert bold headers to proper subheadings for better structure

These changes make the guidance more conservative and aligned with current best practices.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Cam Soper <csoper@pulumi.com>
Co-authored-by: Christian Nunciato <c@nunciato.org>
Co-authored-by: Cam <cam.soper@outlook.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Document recommended project layout structures

6 participants