pulumi-arm-to-pulumi
Convert or migrate Azure ARM (Azure Resource Manager) templates, Bicep templates, or code to Pulumi, including importing existing Azure resources. This skill MUST be loaded whenever a user requests migration, conversion, or import of ARM templates, Bicep templates, ARM code, Bicep code, or Azure resources to Pulumi.
What this skill does
## IMPORTANT: PLAN ADJUSTMENT REQUIRED
**If you have already generated a migration plan before loading this skill, you MUST:**
1. Review your existing plan against the workflows and requirements in this skill
2. Identify any gaps, missing steps, or incorrect assumptions
3. Update and revise your plan to align with this skill's guidance
4. Communicate the adjusted plan to the user before proceeding
## CRITICAL SUCCESS REQUIREMENTS
The migration output MUST meet all of the following:
1. **Complete Resource Coverage**
- Every ARM template resource MUST:
- Be represented in the Pulumi program **OR**
- Be explicitly justified in the final report.
2. **Successful Deployment**
- The produced Pulumi program must be structurally valid and capable of a successful `pulumi preview` (assuming proper config).
3. **Zero-Diff Import Validation** (if importing existing resources)
- After import, `pulumi preview` must show:
- NO updates
- NO replaces
- NO creates
- NO deletes
- Any diffs must be resolved using the Preview Resolution Workflow. See [arm-import.md](arm-import.md).
4. **Final Migration Report**
- Always output a formal migration report suitable for a Pull Request.
- Include:
- ARM → Pulumi resource mapping
- Provider decisions (azure-native vs azure)
- Behavioral differences
- Missing or manually required steps
- Validation instructions
## WHEN INFORMATION IS MISSING
If a user-provided ARM template is incomplete, ambiguous, or missing artifacts, ask **targeted questions** before generating Pulumi code.
If there is ambiguity on how to handle a specific resource property on import, ask **targeted questions** before altering Pulumi code.
## MIGRATION WORKFLOW
Follow this workflow **exactly** and in this order:
### 1. INFORMATION GATHERING
#### 1.1 Verify Azure Credentials
Running Azure CLI commands (e.g., `az resource list`, `az resource show`). Requires initial login using ESC and `az login`
- If the user has already provided an ESC environment, use it.
- If no ESC environment is specified, **ask the user which ESC environment to use** before proceeding with Azure CLI commands.
**Setting up Azure CLI using ESC:**
- ESC environments can provide Azure credentials through environment variables or Azure CLI configuration
- Login to Azure using ESC to provide credentials, e.g: `pulumi env run {org}/{project}/{environment} -- bash -c 'az login --service-principal -u "$ARM_CLIENT_ID" --tenant "$ARM_TENANT_ID" --federated-token "$ARM_OIDC_TOKEN"'`. ESC is not required after establishing the session
- Verify credentials are working: `az account show`
- Confirm subscription: `az account list --query "[].{Name:name, SubscriptionId:id, IsDefault:isDefault}" -o table`
**For detailed ESC information:** Load the `pulumi-esc` skill by calling the tool "Skill" with name = "pulumi-esc"
#### 1.2 Analyze ARM Template Structure
ARM templates do not have the concept of "stacks" like CloudFormation. Read the ARM template JSON file directly:
```bash
# View template structure
cat template.json | jq '.resources[] | {type: .type, name: .name}'
# View parameters
cat template.json | jq '.parameters'
# View variables
cat template.json | jq '.variables'
```
Extract:
- Resource types and names
- Parameters and their default values
- Variables and expressions
- Dependencies (dependsOn arrays)
- Nested templates or linked templates
- Copy loops (iteration constructs)
- Conditional deployments (condition property)
**Documentation:** [ARM Template Structure](https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/syntax)
#### 1.3 Build Resource Inventory (if importing existing resources)
If the ARM template has already been deployed and you're importing existing resources:
```bash
# List all resources in a resource group
az resource list \
--resource-group <resource-group-name> \
--output json
# Get specific resource details
az resource show \
--ids <resource-id> \
--output json
# Query specific properties using JMESPath
az resource show \
--ids <resource-id> \
--query "{name:name, location:location, properties:properties}" \
--output json
```
**Documentation:** [Azure CLI Documentation](https://learn.microsoft.com/en-us/cli/azure/)
### 2. CODE CONVERSION (ARM → PULUMI)
**IMPORTANT:** ARM to Pulumi conversion requires manual translation. There is **NO** automated conversion tool for ARM templates. You are responsible for the complete conversion.
#### Key Conversion Principles
1. **Provider Strategy**:
- **Default**: Use `@pulumi/azure-native` for full Azure Resource Manager API coverage
- **Fallback**: Use `@pulumi/azure` (classic provider) when azure-native doesn't support specific features or when you need simplified abstractions
**Documentation:**
- [Azure Native Provider](https://www.pulumi.com/registry/packages/azure-native/)
- [Azure Classic Provider](https://www.pulumi.com/registry/packages/azure/)
2. **Language Support**:
- **TypeScript/JavaScript**: Most common, excellent IDE support
- **Python**: Great for data teams and ML workflows
- **C#**: Natural fit for .NET teams
- **Go**: High performance, strong typing
- **Java**: Enterprise Java teams
- **YAML**: Simple declarative approach
- Choose based on user preference or existing codebase
3. **Complete Coverage**:
- Convert ALL resources in the ARM template
- Preserve all conditionals, loops, and dependencies
- Maintain parameter and variable logic
**Follow conversion patterns in [arm-conversion-patterns.md](arm-conversion-patterns.md).**
[arm-conversion-patterns.md](arm-conversion-patterns.md) provides:
- Parameters, variables, and outputs mapping
- Copy loops, conditionals, and dependsOn translation
- Nested templates → ComponentResource
- Azure Classic provider examples (VNet, App Service)
- TypeScript output handling and common pitfalls
### 3. RESOURCE IMPORT (EXISTING RESOURCES) - OPTIONAL
After conversion, you can optionally import existing resources to be managed by Pulumi. If the user does not request this, suggest it as a follow-up step to conversion.
**CRITICAL**: When the user requests importing existing Azure resources into Pulumi, see [arm-import.md](arm-import.md) for detailed import procedures and zero-diff validation workflows.
[arm-import.md](arm-import.md) provides:
- Inline import ID patterns and examples
- Azure Resource ID format conventions
- Child resource handling (e.g., WebAppApplicationSettings)
- **Preview Resolution Workflow** for achieving zero-diff after import
- Step-by-step debugging for property conflicts
#### Key Import Principles
1. **Inline Import Approach**:
- Use `import` resource option with Azure Resource IDs
- No separate import tool (unlike `pulumi-cdk-importer`)
2. **Azure Resource IDs**:
- Follow predictable pattern: `/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}`
- Can be generated by convention or queried via Azure CLI
3. **Zero-Diff Validation**:
- Run `pulumi preview` after import
- Resolve all diffs using Preview Resolution Workflow
- Goal: NO updates, replaces, creates, or deletes
### 4. PULUMI CONFIGURATION
Set up stack configuration matching ARM template parameters:
```bash
# Set Azure region
pulumi config set azure-native:location eastus --stack dev
# Set application parameters
pulumi config set storageAccountName mystorageaccount --stack dev
# Set secret parameters
pulumi config set --secret adminPassword MyS3cr3tP@ssw0rd --stack dev
```
### 5. VALIDATION
After achieving zero diff in preview (if importing), validate the migration:
1. **Review all exports:**
```bash
pulumi stack output
```
2. **Verify resource relationships:**
```bash
pulumi stack graph
```
3. **Test application functionality** (if applicable)
4. **Document any manual steps**Related in Ads & Marketing
ads
IncludedMulti-platform paid advertising audit and optimization skill. Analyzes Google, Meta, YouTube, LinkedIn, TikTok, Microsoft, and Apple Ads. 250+ checks with scoring, parallel agents, industry templates, and AI creative generation.
banana
IncludedAI image generation Creative Director powered by Google Gemini Nano Banana models. Use this skill for ANY request involving image creation, editing, visual asset production, or creative direction. Triggers on: generate an image, create a photo, edit this picture, design a logo, make a banner, visual for my anything, and all /banana commands. Handles text-to-image, image editing, multi-turn creative sessions, batch workflows, and brand presets.
rpg-migration-analyzer
IncludedAnalyzes legacy RPG (Report Program Generator) programs from AS/400 and IBM i systems for migration to modern Java applications. Extracts business logic from RPG III/IV/ILE source code, identifies data structures (D-specs), file operations (F-specs), program dependencies (CALLB/CALLP), and converts RPG constructs to Java equivalents. Generates migration reports, complexity estimates, and Java implementation strategies with POJO classes, JPA entities, and service methods. Use when modernizing AS/400 or IBM i legacy systems, analyzing RPG source files (.rpg, .rpgle, .RPGLE), converting RPG to Java, mapping data specifications to Java classes, planning legacy system migration, or when user mentions RPG analysis, Report Program Generator, RPG III/IV/ILE, AS/400 modernization, IBM i migration, packed decimal conversion, or mainframe application rewrite.
brand-library-architect
IncludedBuild a complete brand library for a product — visual asset render pipeline, brand documentation set (BRAND, COPY, MANIFESTO, BIOS, FAQ, GLOSSARY, TONE, PRICING), open-source convention files (README, CONTRIBUTING, SECURITY, CODE_OF_CONDUCT), and a self-contained press kit. This skill should be used when the user asks to "build a brand library / brand kit / press kit / brand assets" for a product, "set up a brand library workflow," "create a positioning manifesto plus visual identity," or any combination of brand documentation + visual asset pipeline. Apply phase-by-phase or run end-to-end. Templates are product-agnostic and use {{TOKEN}} placeholders the skill prompts the user to fill.
writing-tech-post
IncludedAuthors engineering blog posts end-to-end: launch deep-dives, incident postmortems, architecture migrations, performance case studies, tutorials, AI/agent system writeups, security disclosures, and research-to-product translations. Picks the correct archetype, plans the abstraction ladder, enforces an evidence cadence (diagrams, benchmarks, profiles, traces, code, ablations), tunes voice against publisher house styles (Datadog, Vercel, GitHub, AWS, Meta, Cloudflare, Jane Street), and runs a pre-publish gate for narrative momentum and disclosure ethics. Use when drafting a new engineering post, restructuring a draft that feels flat, deciding which evidence form belongs where, validating that depth and product context are balanced, or preparing a postmortem, migration, or performance narrative for external publication. Do not use for API reference documentation, README authoring, marketing copy, release notes, generic SEO content, ghost-written executive thought leadership, or non-engineering long-form essays.
blog-google
IncludedGoogle API integration for blog performance: PageSpeed Insights, CrUX Core Web Vitals with 25-week history, Search Console performance, URL Inspection, Indexing API, GA4 organic traffic, NLP entity analysis for E-E-A-T, YouTube video search for embedding, and Google Ads Keyword Planner. Progressive feature availability based on credential tier (API key, OAuth/service account, GA4, Ads). Shares config with claude-seo at ~/.config/claude-seo/google-api.json. Use when user says "google data", "page speed", "core web vitals", "search console", "indexation", "GA4", "keyword research", "nlp entities", "blog performance", "youtube search", "google api setup".