Discovered Stacks
Discovered Stacks bring the infrastructure you manage outside of Pulumi IaC into the same stack model it uses. When Discovery scans your cloud accounts, it recognizes AWS CloudFormation stacks and Azure Resource Manager (ARM) deployments and represents each one as a discovered stack in Pulumi Cloud, preserving the grouping the source tool already gave them.
A discovered stack looks and navigates like any other Pulumi stack: it appears on the Stacks page, lists its resources, and shows per-resource detail. Every resource also carries a migration status, so a discovered stack doubles as a live, auditable record of how far along you are in migrating it to Pulumi IaC.
Sources
Discovered stacks are created automatically. Whenever a scanned account contains resources managed by a supported external IaC provider, Discovery groups those resources into discovered stacks with no additional setup. To build them, Discovery reads the source provider’s own API — the AWS CloudFormation API, or the Azure Resource Manager API — to list the stacks or deployments and their resources, then maps each resource to its matching Pulumi IaC provider type:
- AWS CloudFormation: each CloudFormation stack becomes a discovered stack. For CDK applications, the synthesized CloudFormation stacks are discovered.
- Azure Resource Manager: each ARM or Bicep deployment becomes a discovered stack, preserving deployment-level grouping.
To set up scanning, see Create and manage cloud accounts.
Naming
Discovered stacks are named automatically, so the same source stack found in different accounts, regions, or resource groups produces distinct, recognizable names. Each name has two parts: the project is inferred from the source stack (its name with any autogenerated suffix stripped), and the stack combines the cloud account name with the scope the source was found in — the AWS region or Azure resource group — plus that suffix. This mirrors Pulumi’s own project-and-stack model: one source template deployed across multiple accounts or regions becomes multiple stacks under a single project.
- CloudFormation: a
payments-api-<suffix>stack scanned inus-east-1under theprodcloud account becomes projectpayments-api, stackprod-us-east-1-<suffix>. - Azure Resource Manager: the resource group is attached to the stack name, so the same deployment in a
payments-rgresource group becomes projectpayments-api, stackprod-payments-rg-<suffix>.
Discovered stacks in the console
On the Stacks page, turn on Show Discovered Stacks to list discovered stacks alongside your Pulumi IaC stacks. They support the same filtering, sorting, and navigation, and are marked with a chip that identifies them as discovered.
Because a discovered stack’s resources come from an external source, each resource carries two type identifiers:
- Pulumi type: how the resource is represented in Pulumi’s model, such as
aws:s3/bucket:Bucket. - Origin type: the type in the source system, such as
AWS::S3::Bucketfor CloudFormation orMicrosoft.Storage/storageAccountsfor ARM.
The resource list shows both columns, and the resource detail page shows Origin Properties — the properties as reported by the source — alongside the properties in Pulumi’s model.
Migration statuses
Every resource in a discovered stack carries a migration status that shows where it stands on the path to being managed by Pulumi IaC. Statuses are computed automatically by Pulumi Cloud.
On a discovered stack’s Migration tab, you select a target Pulumi stack to compare against — the stack you’re migrating the resources into. The console lines the discovered resources up against that target stack side by side and computes each resource’s status from the comparison, so you can see at a glance what is already Migrated, what is still Ready to import, and what exists on only one side. Until you select a target, the statuses describe the discovered resources on their own (Ready, Not found, No exact match, Not applicable); selecting one turns on the comparison statuses (Migrated and Existing).
| Status | Meaning | Recommended next step |
|---|---|---|
| Ready | The resource maps to a Pulumi type, and Discovery confirmed it exists in the cloud. | Import it. This is the bulk of a typical migration. |
| Not found | The resource maps to a Pulumi type, but Discovery could not confirm its current state. It may have been deleted, or it may be a type Discovery doesn’t verify or doesn’t have access to — many Not found resources are actually live and import cleanly. | Verify the resource still exists, then import it or mark it resolved. |
| No exact match | No Pulumi type mapping was found. Common examples are CloudFormation custom resources and inline IAM policies that Pulumi models as part of their parent resource. | Review it. |
| Not applicable | The resource is a container or wrapper construct, such as AWS::CloudFormation::Stack or Microsoft.Resources/deployments, with no cloud resource of its own to migrate. | None. |
| Migrated | The resource was found in the target Pulumi stack and is under Pulumi IaC management. | None. |
| Existing | The resource is in the target Pulumi stack but has no discovered counterpart — a resource added to Pulumi IaC separately, or the imported form of a Not found or No exact match resource. | None. |
Resolving resources
To fully keep track of a migration, you can record how you handled resources that were not automatically ready to migrate. Mark a resource as resolved to note that it’s taken care of: it stays visible in the list but drops out of the outstanding work, and the decision persists for everyone looking at the stack.
Resolve a resource when it has nothing left to import on its own — deleted, an inline definition covered by its parent’s migration, or with no Pulumi equivalent you need — or when you have migrated it in a way the console can’t detect automatically. When you mark a resource resolved, you can:
- Add a comment explaining the decision, so the reasoning is there for whoever looks next — for example, “deleted; nothing to migrate” or “covered by its parent role.”
- Link the target-stack resource you migrated it into. For non-direct migrations — a resource imported under a corrected type, or one whose Pulumi form doesn’t line up one-to-one with the source — the console can’t pair the two automatically; linking them records the migration explicitly and keeps source and target connected. See Link an imported resource to its origin for a worked example.
Together with the computed statuses, this keeps the record complete: every resource is either migrated or deliberately resolved — never quietly forgotten.