Infrastructure-as-code migration rarely fails because teams cannot translate syntax. It fails because nobody can confidently answer a simpler question first: what infrastructure do we actually have, who owns it, and is it still aligned with production reality?
That is why Pulumi’s recent announcement of Discovered Stacks matters. The feature is positioned as one place for viewing infrastructure, and Pulumi has also published specific guidance for migrating CloudFormation to Pulumi using Discovered Stacks. For developers, platform engineers, and CTOs, the key takeaway is clear: CloudFormation-to-Pulumi migration is becoming an inventory problem before it is a rewrite problem.
Context: IaC modernization is not just code conversion

CloudFormation has been the default AWS-native infrastructure-as-code tool for many organizations. It is widely used, deeply integrated with AWS, and often embedded in years of deployment processes, account structures, templates, nested stacks, service catalogs, and hand-built operational practices.
Pulumi offers a different model: define infrastructure using general-purpose programming languages such as TypeScript, Python, Go, C#, Java, and YAML. For engineering teams that want stronger abstractions, reusable components, automated testing, and closer alignment between application and infrastructure development, Pulumi can be attractive.
But a migration from CloudFormation to Pulumi is not just a matter of converting JSON or YAML into TypeScript or Python. Most long-lived cloud environments include:
- CloudFormation stacks created by different teams at different times
- Manually created infrastructure outside any IaC system
- Resources imported into CloudFormation after the fact
- Drift between declared templates and deployed infrastructure
- Deprecated environments nobody wants to touch
- Shared resources with unclear ownership
- Compliance-sensitive resources that cannot be recreated casually
In other words, the hard part is not only writing the new Pulumi program. The hard part is deciding what should be represented, where it belongs, who owns it, and how to move safely without disrupting production.
What Pulumi announced
Pulumi announced Discovered Stacks for Pulumi Cloud in its blog post, Discovered Stacks: One Place for All Your Infrastructure. Pulumi positions the capability as a way to view infrastructure in one place, including resources that may not yet be managed by Pulumi programs.
Pulumi also published migration guidance in Migrate CloudFormation to Pulumi with Discovered Stacks. That article connects discovery directly to CloudFormation migration, showing how teams can use discovered infrastructure as a starting point for organizing and migrating resources into Pulumi-managed stacks.
The important pattern is not simply that a new feature exists. The pattern is that modern IaC migration tooling is moving upstream. Instead of beginning with a blank repository and asking teams to rewrite everything, the process starts by surfacing the actual infrastructure footprint.
That shift reflects the operational reality many organizations face. Before you modernize infrastructure code, you need a reliable infrastructure inventory.
Why inventory comes before rewrite
1. Cloud environments are rarely as clean as the repo suggests
Many organizations treat the IaC repository as the source of truth. In a healthy environment, that should be true. In a long-lived environment, it often is not.
Production systems accumulate exceptions. An urgent incident leads to a manual security group update. A data team creates a bucket for a one-off workflow. A networking change is tested manually and never backfilled into templates. A CloudFormation stack is updated out-of-band. Over time, the gap between intended state and actual state grows.
If a team begins a Pulumi migration by translating only the templates in Git, it may miss unmanaged or drifted resources that production depends on. That creates risk. The new IaC system looks clean, but the environment remains partially unmanaged.
Inventory helps expose the real migration surface area.
2. Ownership is a modernization dependency
IaC migrations frequently uncover an uncomfortable truth: some infrastructure has no clear owner. That may include old load balancers, IAM roles, DNS records, S3 buckets, VPC peering connections, Lambda functions, databases, or queues.
This is not just an organizational inconvenience. Ownership determines who can approve changes, who understands runtime impact, who pays for the resource, and who is accountable for security posture.
A CloudFormation-to-Pulumi migration is a chance to reestablish ownership boundaries. Rather than creating Pulumi stacks that mirror historical accidents, teams can group resources around maintainable domains: application, platform service, network foundation, data system, shared security layer, or environment.
The code migration should follow the ownership model, not the other way around.
3. Drift changes the migration plan
Drift is one of the biggest sources of migration surprise. A CloudFormation template may say one thing while the live infrastructure says another. If the migration imports or recreates based only on templates, it can accidentally overwrite changes that were made directly in the cloud provider.
This is why discovery is so valuable. It gives teams a chance to compare declared infrastructure, actual infrastructure, and desired future state. Some drift should be eliminated. Some drift may represent intentional emergency fixes that should be codified. Some drift may reveal abandoned resources that should be retired.
A rewrite treats drift as an obstacle. A modernization program treats drift as information.
Rethinking stacks as maintainable units
One of the most important design decisions in Pulumi migration is how to define stacks. A common mistake is to map every CloudFormation stack directly to a Pulumi stack. That may be appropriate in some cases, but it can also preserve old coupling and make the new system harder to operate.
A better approach is to use inventory data to decide stack boundaries deliberately.
Group by lifecycle
Resources that change together usually belong together. For example, an application service, its container infrastructure, its task roles, and its service-specific alarms may fit naturally into one stack. A shared VPC, central DNS zone, or organization-wide security baseline may have a different lifecycle and should likely be managed separately.
Lifecycle-based grouping reduces accidental blast radius. It also makes CI/CD easier because each stack can have a clear deployment cadence.
Group by ownership
If two teams must approve changes independently, their resources probably should not be tightly coupled in the same stack. Inventory makes these ownership seams visible.
For CTOs and engineering leaders, this is where IaC migration intersects with operating model design. The stack structure should reflect how teams actually build, run, and support systems.
Group by risk
Some resources are low-risk to refactor. Others, such as production databases, IAM trust policies, networking foundations, and DNS records, require extra care. Migration plans should separate high-risk resources from fast-moving application infrastructure.
A practical pattern is to start with read-only discovery, then import low-risk resources, then handle critical shared resources with dedicated migration runbooks and review gates.
Practical implications for engineering teams
Start with a discovery sprint
Before writing much Pulumi code, run a focused discovery sprint. The goal is to answer four questions:
- What infrastructure exists across accounts, regions, and environments?
- Which resources are managed by CloudFormation, Pulumi, another IaC tool, or nothing at all?
- Who owns each major resource group?
- Where is there drift, duplication, or obvious technical debt?
Pulumi’s Discovered Stacks can support this inventory-first workflow by giving teams a centralized view of infrastructure before everything is fully converted into Pulumi programs.
Build a migration map, not just a backlog
A list of CloudFormation templates to convert is not enough. Teams need a migration map that links resources to target stacks, owners, dependencies, risk levels, and migration method.
For each resource group, document whether the plan is to:
- Import it into Pulumi as-is
- Refactor it into a new component abstraction
- Leave it temporarily under CloudFormation
- Retire it as unused infrastructure
- Replace it during a larger platform upgrade
This prevents the migration from becoming a mechanical rewrite that carries forward every historical decision.
Use migration as a debt reduction opportunity
IaC modernization is a rare moment when teams have permission to inspect infrastructure assumptions. Use it to reduce operational debt.
Look for unused IAM roles, overly broad policies, untagged resources, old security groups, unsupported runtime versions, duplicated networking patterns, and inconsistent naming conventions. Not every issue should block migration, but each should be captured and prioritized.
At Vibgrate, we often see modernization succeed when teams separate inventory, migration, and remediation into related but distinct workstreams. Trying to fix everything during the rewrite can stall the program. Ignoring debt entirely means missing much of the value.
Avoid the big-bang rewrite
A big-bang IaC migration is tempting because it promises a clean cutover. In practice, it increases risk. Infrastructure has too many dependencies, and production systems rarely tolerate sweeping ownership changes well.
An incremental approach is safer:
- Discover infrastructure and classify resources.
- Define target stack boundaries.
- Import or migrate one domain at a time.
- Validate state and drift after each step.
- Decommission old CloudFormation stacks only when ownership is clear.
- Add policy, testing, and CI/CD controls as the Pulumi footprint grows.
This approach lets teams modernize while continuing to ship software.
What CTOs should watch
For engineering leaders, the CloudFormation-to-Pulumi conversation should not be framed only as tooling preference. It is a governance, maintainability, and delivery conversation.
The most important metrics are not lines of YAML converted or number of Pulumi programs created. Better signals include:
- Percentage of infrastructure with clear ownership
- Percentage of resources managed through IaC
- Number of unmanaged production resources
- Drift detected and resolved over time
- Deployment frequency for infrastructure changes
- Lead time for safe environment provisioning
- Reduction in duplicated infrastructure patterns
These metrics connect IaC migration to business outcomes: faster delivery, lower operational risk, better compliance posture, and easier platform evolution.
Conclusion: discovery is the new starting line
Pulumi’s Discovered Stacks announcement and CloudFormation migration guidance highlight a broader modernization principle: teams cannot safely rewrite what they have not inventoried. Before choosing abstractions, languages, or component libraries, organizations need to understand the infrastructure they already run.
For developers and platform teams, that means treating discovery, ownership mapping, and drift analysis as first-class migration work. For CTOs, it means funding IaC modernization as an incremental reliability and maintainability program, not a one-time translation project.
CloudFormation-to-Pulumi migration can absolutely be a path toward more expressive, testable, and maintainable infrastructure code. But the winning teams will start with inventory, group resources into sensible stacks, reduce unmanaged infrastructure, and modernize one safe step at a time.
