Pulumi Migrate From Discovered Stack
PulumiOfficialPublished by Pulumi
- Skill
- Workflow
- Cloud and DevOps
- Apache-2.0
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured, state-first workflow for migrating existing CloudFormation or ARM stacks into Pulumi. It relies on the Pulumi Cloud Discovery feature to identify and map cloud resources, ensuring a zero-diff transition from existing infrastructure to Pulumi management. The process emphasizes iterative importing, validation via preview, and optional structural refactoring to ensure the resulting code is maintainable and idiomatic.
What it does
- Fetches and categorizes resources from discovered CloudFormation or ARM stacks.
- Automates the generation of import files for Pulumi resources.
- Manages the import process with code generation to ensure state and code parity.
- Provides a mechanism to annotate migration progress and handle mapping exceptions.
- Supports optional refactoring to improve code structure and maintainability.
- Generates a comprehensive migration report for pull request documentation.
When to use it
- When you have a stack already identified by Pulumi Cloud's Discovery feature.
- When you need to bring existing cloud resources under Pulumi management.
- When you require a zero-diff migration path from CloudFormation or ARM.
- When you need to track migration progress directly within the Pulumi Cloud UI.
Advantages
- Ensures exact parity between cloud state and Pulumi code via zero-diff validation.
- Leverages existing cloud discovery data to reduce manual mapping effort.
- Provides clear visibility into migration status through the Pulumi Cloud API.
- Supports iterative batch importing for large or complex stacks.
- Allows for structural refactoring to align with best practices before finalizing.
Usage examples
- “I have a discovered CloudFormation stack in my Pulumi Cloud dashboard. How do I start migrating it?”
- The agent will initiate Phase 0, gathering the necessary project, stack, and credential details to begin the triage and import process.
- “I've imported some resources but some are showing as NotFound. What should I do?”
- The agent will guide you through Phase 5, helping you determine if the resource is deleted, requires a mapping override, or needs a manual annotation.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/pulumi/pulumi-migrate-from-discovered-stack/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip pulumi-migrate-from-discovered-stack.zip -d .agents/skills
Documentation by Pulumi
Scope: this skill only applies to stacks Pulumi Cloud's Discovery feature has already scanned and exposed through the discovered-stacks API (GET .../discovered-stacks/{projectName}/{stackName}/resources, see below). It is not for migrating an arbitrary CloudFormation/ARM template or account that Discovery hasn't scanned yet — if no discovered stack exists for the source, this skill has nothing to read and does not apply.
Do not load
cloudformation-to-pulumiorpulumi-arm-to-pulumialongside this skill. Those two skills prescribe a template-first workflow (mechanical translation → import) and mandateaws-nativefor AWS. This skill is cloud-state-first (import from discovered state → optional refactor against the template later) and defaults toawsclassic /azure-native. The useful reference material from those two skills has been curated intocloudformation.mdandarm.mdin this folder.
Plan adjustment
If you already generated a migration plan before loading this skill, review it against the workflow below and update it — the phases here supersede any earlier plan. Communicate the adjusted plan to the user before proceeding.
Success criteria
A migration is complete when:
Complete resource coverage — every discovered resource is imported OR has an annotation explaining why not.
Zero-diff —
pulumi previewshows no changes. This proves the code matches the cloud state exactly.Progress tracked via the API — use
compareToand migration annotations so progress is visible in Pulumi Cloud, not just in agent memory.PR as the output — a pull request with the migrated code and a migration report.
THE DISCOVERED-STACKS API
Fetching resources
GET /api/preview/insights/{orgName}/discovered-stacks/{projectName}/{stackName}/resources?compareTo={targetProject}/{targetStack}Always include compareTo if the target Pulumi stack exists (it may already have state from a previous migration attempt). Returns a list of DiscoveredResourceInfo objects. The JSON paths below are exact — verify before consuming:
name— top-level: logical name (CF Logical ID / ARM resource name). Use this as the Pulumi resource name.originType— top-level: native cloud type (e.g.AWS::S3::Bucket,Microsoft.Storage/storageAccounts)providerType— top-level: mapped Pulumi type token (e.g.aws:s3/bucket:Bucket).nullif unmapped.resource.inputs.providerId— physical cloud ID forpulumi import.resource.urn— the URN to use asresourceUrnin annotation requests (copy verbatim).migrationStatus— top-level: one of the statuses below.annotation— top-level: user/agent annotation if one exists (see Annotations below).
The resource.inputs object also carries raw cloud-provider data:
For CloudFormation — resource.inputs.cloudFormation:
physicalResourceId— the original CF physical IDresourceType— the CF type (e.g.AWS::IAM::Role)resourceStatus— e.g.CREATE_COMPLETE,DELETE_COMPLETEdriftStatus—NOT_CHECKED,IN_SYNC,DRIFTED
For CDK-synthesized CF stacks, inputs.cdkPath is also present — see cloudformation.md §5 for how to use it.
For ARM — resource.inputs.arm. ARM resources are grouped by resource group, not by
deployment, so a resource with no deployment currently backing it (its deployment history
aged out of Azure's retention window, or it was created outside any tracked deployment) is
still returned — just as a placeholder, with resource.inputs.deploymentName empty and a
different arm shape:
Deployment-backed (
resource.inputs.deploymentNamenon-empty) —armis a deployment-operation object:properties.targetResource.id/.resourceType/.resourceName,properties.provisioningState(e.g.Succeeded).Placeholder (
resource.inputs.deploymentNameempty) —armis the raw Azure generic-resource object instead: top-levelid,name,type,location,tags. Noproperties.targetResource— don't look for it.
Either way, prefer the top-level resource.inputs.providerId for the import ID (see
above) rather than reaching into arm — it's already normalized across both shapes.
Migration statuses
Statuses are PascalCase. First match wins:
Migrated— the resource was found in thecompareToPulumi stack. Already under Pulumi management; skip.Ready—providerTypeandproviderIdare set and the scanner confirmed the resource exists. Import withpulumi import <providerType> <name> <providerId> --generate-code --out <file>.ts(NEVER without--generate-code --out— see Phase 4).NotFound—providerTypeandproviderIdare set, but the scanner could not confirm the resource's current state. May be deleted, mapping may be imperfect, or scanner hit a gap. Verify before importing.NotApplicable— container or wrapper types (AWS::CloudFormation::Stack,Microsoft.Resources/deployments,Microsoft.Resources/resourceGroups,pulumi:providers:*) are not individually migratable. Skip silently.NoMatch—providerTypeisnull. No mapping found. Common examples:CF Custom Resources (e.g.
Custom::VpcRestrictDefaultSG) — no direct Pulumi equivalent.Inline policies —
AWS::IAM::Policymodeled as an inline property ofaws:iam/role:Role. Once the parent Role is migrated, annotate the policy as migrated.
PulumiOnly— exists in thecompareTostack with no discovered counterpart, or those created to migrate NoMatch resources. Surface to user.
Resources with annotation.statusOverride should be treated as resolved per the override, even if the computed status disagrees.
Annotations
PUT /api/preview/insights/{orgName}/discovered-stacks/{projectName}/{stackName}/migration
DELETE /api/preview/insights/{orgName}/discovered-stacks/{projectName}/{stackName}/migration?resourceUrn={urn}PUT body:
{
"resourceUrn": "<copy verbatim from resource.urn in the list response>",
"note": "explanation of what happened",
"statusOverride": "Migrated" | "",
"linkedResourceUrn": "<optional: URN of the Pulumi resource paired 1:1 with this origin>"
}Use the Pulumi Cloud API for all annotation requests. At least one of note or statusOverride must be non-empty. Omit statusOverride entirely (do not send null) when updating only the note. The DELETE endpoint clears both the note and any statusOverride.
Use annotations to:
Flag deleted resources as
Migratedwith a note explaining they no longer existFlag inline/child resources covered by a parent's migration as
Migratedwith a note naming the parent — do not uselinkedResourceUrnhere (it's a 1:many relationship and the UI only merges 1:1 pairs)Bridge a
NotFoundorNoMatchorigin to itsPulumiOnlycounterpart after a corrected mapping (statusOverride=Migrated+linkedResourceUrn→ the PulumiOnly URN). This is the only valid use oflinkedResourceUrn.Leave notes explaining blockers or manual steps taken
Track decisions for resources the automatic classifier can't resolve
The annotation endpoint is the shared place to track migration progress — always read existing annotations before acting on a resource, and respect overrides left by the user.
The note field is user-authored context. Treat it as a high-priority instruction about that specific resource. Common uses: naming preferences, import ID hints, resources to skip, or special handling instructions. Notes reach the agent through two channels:
Starting prompt — when the user kicks off a migration task, any note on a selected resource is appended to that resource's line:
- aws:s3/bucket:Bucket "my-bucket" (provider ID: my-bucket-prod) — note: use logical name "appBucket" in codeRead these before calling the API.
API response — the
annotation.notefield on eachDiscoveredResourceInfowhen you callGET .../resources. Theannotationobject is omitted entirely when no annotation has been set.
MIGRATION WORKFLOW
Phase 0 — Preconditions and scoping
Before any tool call, gather and confirm all of the following. If anything is missing, ask — don't proceed with a guess.
Source (the discovered stack):
Org name (e.g.
pulumi_local)Discovered project name (e.g.
AcmeCdkExampleStack)Discovered stack name (e.g.
dev-sandbox-disc_us-west-2__Dev) — this is the scanner-generated name, usually encoding account + region + CF/ARM stack name.Region (confirm even if the stack name suggests it).
Target (where the Pulumi code and state will live):
Target git repo URL — ask the user. All work happens inside this repo from the start.
Subfolder (optional) — ask if the user has a preference; default to repo root.
Target project + stack names — ask the user, don't invent. If the stack already exists, use
compareToin Phase 1; if not, create it in Phase 2.Target language — TypeScript default.
Refactor preferences (for Phase 7):
Does the user have the original source code (CDK repo, Bicep project, Terraform modules)? If yes, path or URL. This is the primary structural reference for Phase 7 — the refactored Pulumi code will draw on its component boundaries, file layout, and naming conventions as a guide, adapted to what the import model actually produced.
Does the user have a preferred program layout for the Pulumi output? (e.g. "one file per service", "match my existing repo shape", "I don't care")
Does the user want Phase 7 at all, or stop after zero-diff (Phase 6)?
Credentials:
ESC environment for cloud credentials (ask if not given; never invent). ESC is preferred — see
cloudformation.md §1orarm.md §1.
Don't start Phase 1 until all of the above are confirmed. Summarize the plan back to the user and wait for approval.
Phase 1 — Resource fetch and triage
Start here every time, even when resuming an existing migration. The API + any existing annotations are the source of truth for what's been done so far. If the target repo already has Pulumi code, read it — it tells you the conventions, existing resources, and how far a previous attempt got.
Fetch discovered resources:
GET .../discovered-stacks/{projectName}/{stackName}/resources.Target stack exists (resumed migration): append
?compareTo=<targetProject>/<targetStack>.Target stack does not exist (greenfield): omit
compareTo— the API returns 404 if the target stack isn't found. After Phase 2 creates the stack, subsequent calls can include it.
Save the response to disk —
./.migration/resources-baseline.json.Run triage:
python3 <skill-base-dir>/scripts/triage.py .migration/resources-baseline.json— prints status counts (accounting for annotation overrides) and a per-resource table.Present the plan to the user:
"Found N resources. A already Migrated, M Ready, K NotFound, J NoMatch, L non-migratable containers. I'll import Ready first, then verify NotFound, then triage NoMatch with you. Sound good?"
Get confirmation before writing any code.
Phase 2 — Target repo and Pulumi stack setup
Clone the target git repo (from Phase 0) and work inside it for all subsequent phases. If the repo already has code, read it to understand existing conventions and resources before adding new ones.
If the target stack already exists (Phase 0 check), select it. Otherwise:
Create the Pulumi project:
pulumi new <language> --name <project> --stack <org>/<project>/<stack> --yes.
Set provider config:
pulumi config set aws:region <r>(orazure-native:location).Link the ESC environment if provided.
No empty pulumi up needed.
Concrete commands for project + stack setup, region config, and provider install:
cloudformation.md §2orarm.md §2.
Phase 3 — Build the import file
Generate the import file: python3 <skill-base-dir>/scripts/build_import.py .migration/resources-baseline.json .migration/import.json. This filters Ready/NotFound resources (excluding already-annotated ones) and maps API fields to the Pulumi import format (type ← providerType, name ← name, id ← resource.inputs.providerId).
Phase 4 — Import
Using the import.json from Phase 3.
Always use --generate-code --out — without it, resources land in state with no code, breaking pulumi preview.
pulumi import --file import.json --generate-code --out batch.<ext>
# then: append generated code into the main program file and delete the batch filePer-batch loop: import → preview → commit → annotate. Aim for ~20 resources per batch. For CDK stacks, batch by cdkPath top-level group; otherwise batch by resource type prefix.
Import the batch.
pulumi preview— zero diff required. Fix any diffs before moving on.Commit the program changes to a branch.
Annotate each imported resource —
PUT .../migrationwith note and nostatusOverride. Annotations survive context resets and are visible in the UI.
?compareTo is a live progress signal — pulumi import writes state immediately, so migrationStatus flips to Migrated after each import. Do not run pulumi up (see Phase 6).
Reserve statusOverride for cases where the computed status will be wrong:
statusOverride=Migrated(withlinkedResourceUrn) — resource covered by another (inline IAM policy → parent Role, IGW attachment → IGW, etc.).statusOverride=Migrated(with a note, nolinkedResourceUrn) — resource is deleted, dangling, or has no Pulumi equivalent. Flag it resolved so it drops out of the outstanding work.
Phase 5 — NotFound and NoMatch triage
Default strategy: try first, annotate second. For both NotFound and corrected-mapping cases, attempting pulumi import is the fastest way to learn what's actually wrong. The error messages are precise and actionable.
NotFound (providerType set, state unconfirmed):
Common outcomes:
Resource is deleted.
pulumi importreturnsPreview failed: resource '<id>' does not exist. AnnotatestatusOverride=Migratedwith the literal error in the note. Don't retry. In practice, a substantial share of NotFound resources turn out to be deleted rather than a mapping error.Wrong
providerTypemapping. Import fails with a type-validation error or schema mismatch. Several CF types have multiple valid Pulumi mappings (VPC gateway attachment / VPN vs IGW; S3 vs s3control; RDS instance vs cluster instance; SES v2 vs v1; etc.) — our scanner picks a primary that doesn't always match your resource. Look up theoriginTypeincloudformation.md §7, overrideproviderTypein the import file, retry. Then handle the fingerprint side-effect (next bullet).Wrong-mapping side-effect: PulumiOnly appears. When the agent imports with a corrected
providerType, fingerprint matching against the discovered resource fails. The discovered resource staysNotFound(orNoMatch) and a newPulumiOnlyentry appears. Annotate the original origin row asstatusOverride=MigratedwithlinkedResourceUrnpointing to the PulumiOnly URN. This bridges them in the UI and keeps the bookkeeping clean.Resource is alive and mapping is correct. Import succeeds. Status flips to
Migratedautomatically.
NoMatch (providerType is null):
Common patterns:
Inline IAM policies.
AWS::IAM::Policywhose name matches a migrated Role's prefix is an inline policy already captured asinlinePolicieson the Role's import. AnnotatestatusOverride=Migratedwith note:"inline policy of <RoleName>".AWS::SecretsManager::SecretTargetAttachment has no direct Pulumi mapping. The link between secret and target (RDS cluster, etc.) is implicit via the cluster's credentials config. Annotate
statusOverride=Migratedwith a note explaining the implicit link.CDK Custom Resources (
Custom::*). Typically a Lambda handler doing the actual work. Checkcloudformation.md §5for known handler → Pulumi replacement mappings. Don't annotateMigratedwithout confirming with the user — surface what the handler does and let them decide.Other NoMatch types. Look up the
originTypein the cloud provider docs (CF resource type reference or ARM resource type reference) to understand what the resource is, then search the Pulumi registry for a matching provider type. If the mapping is ambiguous, surface to the user and ask.
Pre-existing PulumiOnly entries. Beyond the corrected-mapping artifacts above, PulumiOnly also covers resources already in the target stack that aren't part of this migration. Leave those as-is — no annotation needed.
For cloud-specific lookup commands (verifying resources exist, finding import IDs, querying the cloud), provider-choice rules (
awsclassic vsaws-native,azure-nativevsazure), the Preview Resolution Workflow, and known import quirks, seecloudformation.md §3–§6orarm.md §3–§6.
Phase 6 — Reconciliation & PR
Run
pulumi preview— confirm there are NO changes. Any diff means the generated code doesn't match the imported state. Diffs come in three shapes:Removed (
-) — a field the cloud has but your code doesn't set. Add it to the code with the real cloud value. Don'tignoreChanges.Added (
+) — a field your code sets that the provider didn't return. If computed/read-only →ignoreChanges. If a provider default re-statement → remove from code.Changed (
~) — value mismatch. Query the cloud, determine the correct value, update code. Never silence withignoreChanges.
Expect 2–5 preview rounds for complex resources. Never run
pulumi upto resolve diffs — that modifies the cloud, not the code. Seecloudformation.md §6orarm.md §6for cloud-specific diff patterns.Do one final
GET resources?compareTo=...and verify the expected distribution (this reflects the current backend state —migrationStatusis already up-to-date since everypulumi importwrites state):Migrated— all imported resourcesPulumiOnly— Pulumi-only resources, including any corrected-mapping imports linked via annotationNoMatchremaining — every one should have an annotationNotApplicable(containers) — silently skipped
Proceed to Phase 7 (refactor offer) before opening the PR.
The migration is functionally complete when preview is clean and the API triage shows no unresolved resources. Do not run pulumi up. The imported state is already synced to Pulumi Cloud via pulumi import; there's nothing for pulumi up to do that serves the migration.
Phase 7 — Refactor and maintainability review (before the PR)
Zero-diff is achieved, but the imported code is "flat" — hardcoded values, no cross-resource references, all resources at the top level. Before opening the PR, offer the user a readability refactor.
7a — Offer and orient
If Phase 0 didn't capture explicit refactor preferences, or the user hasn't explicitly declined, ask now:
"Preview is clean and all resources are accounted for. Before I open the PR, I'd like to refactor the code for maintainability — replacing any hardcoding with cross-resource references, extracting config parameters, and grouping related resources. (If you gave me a source repo, I'll use it as the structural blueprint, matching the intended file layout and component names.) Want me to go ahead?"
If they decline, skip to Phase 8.
7b — Implement the refactor
Read refactor.md for strategies, invariants, and template-reading references. Key priorities in order:
Take structural cues from the source repo first — if the user provided a source repo, read it now (clone or use the local path from Phase 0). Use its file layout, component/module boundaries, and naming conventions as a guide. Where a group of resources maps naturally to a class, module, or subdirectory in the source and that grouping still feels natural for the imported Pulumi program, mirror that structure; otherwise avoid forcing artificial groupings just to match the source mechanically.
Replace literal ARN/ID references with cross-resource output references.
Extract config parameters (region, account ID, environment tag).
Consolidate into
ComponentResourceclasses where the source repo or CDK paths suggest a natural grouping.Split into files only last — and only when a natural isle warrants it.
Run pulumi preview after every non-trivial change. Zero-diff must hold throughout. If preview shows a diff, revert that single change before trying anything else — see refactor.md § The invariant for recovery steps.
7c — User walkthrough and maintainability sign-off
After the refactor, present the result to the user before opening the PR:
Show a summary of what changed: files created/renamed, components introduced, literals replaced, config keys added.
Walk through the top-level
index.ts(or equivalent) line by line if it's under ~80 lines; otherwise describe the module breakdown.Highlight any judgment calls (e.g. "I grouped the IAM resources into
iam.tsto match thelib/iam/directory in your source repo — let me know if you'd prefer a different name").Ask explicitly: "Does this structure match how you'd expect to maintain this code?" Wait for the user's answer. If they request changes, make them (always preview after) and repeat the walkthrough until they're satisfied.
Only proceed to Phase 8 once the user confirms the structure is acceptable.
Phase 8 — PR and migration report
Produce the migration report (see below) and open the PR. The PR includes whatever state the code is in — raw imported code (if the user skipped Phase 7) or the refactored version (if they opted in).
MIGRATION REPORT FORMAT
Include in the PR description:
Overview — source discovered stack → target Pulumi stack, region, language.
Triage summary — counts by status at start and end.
Resource mapping table — name, origin type, provider type, status, notes.
Gaps — unmapped resources and why, with annotations.
Progress URL — link to the discovered-stacks comparison endpoint for ongoing tracking.
Next steps — pending user decisions, optional refactoring.
Files
- ATTRIBUTION.mdAdded by AutoGineer906 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SKILL.md23.1 KiB
- agents/openai.yaml318 B
- arm.md12.4 KiB
- cloudformation.md12.6 KiB
- refactor.md8.4 KiB
- scripts/build_import.pyScript2.9 KiB
- scripts/triage.pyScript2.4 KiB
- use_cases.yaml770 B
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Python
Security
What our scanner noticed· Low risk
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Pulumi
- Publisher
- Pulumi (Official)
- Source
- pulumi/agent-skills · migration/skills/pulumi-migrate-from-discovered-stack · commit 82f222a
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Pulumi or Pulumi.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download pulumi-migrate-from-discovered-stack.zip