Aztfexport
Skill bg-szy/TOP-SKILLS/skills/claude-code-skills/aztfexport
Use when exporting existing Azure resources to Terraform using aztfexport. Triggers on aztfexport, Azure import to Terraform, export Azure resource, bring Azure under Terraform management, reverse-engineer Azure infrastructure, bootstrap IaC from live Azure resources. Covers resource, resource-group, and query modes.From its SKILL.md
npx -y skills add bg-szy/TOP-SKILLS --skill aztfexportAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.1 KB, ~1.4k tokens by cl100k_base, as published. Nobody here has run it
aztfexport — Export Azure Resources to Terraform
Overview
aztfexport is a Microsoft tool that exports existing Azure resources into Terraform HCL + state. It reverse-engineers live Azure infrastructure into Terraform configurations. Use this for Azure-only workflows or Terraform versions before 1.14's native terraform query.
When to Use
- Export a single Azure resource to Terraform →
aztfexport resource - Export an entire resource group →
aztfexport resource-group - Export resources matching an Azure Resource Graph query →
aztfexport query - Bootstrapping IaC from existing Azure infrastructure
Use terraform-search-import skill instead when: Terraform >= 1.14 with terraform query + bulk import (multi-cloud, not Azure-specific).
Prerequisites
- aztfexport installed:
brew install aztfexport(macOS) or see GitHub releases - Azure CLI authenticated:
az login+ correct subscription selected - Architecture check (critical on macOS):
If mismatch (e.g., x86_64 binary on arm64 Mac), reinstall the correct architecture version.file $(which aztfexport) # Check binary arch uname -m # Check system arch
Workflow
Step 1: Discover the Resource ID
Use Azure CLI to find the resource ID. See references/RESOURCE-DISCOVERY.md for patterns by resource type.
Generic fallback:
az resource list --query "[?name=='RESOURCE_NAME']" -o table
Step 2: Validate aztfexport Binary
file $(which aztfexport)
uname -m
aztfexport --version
Architecture mismatch causes cryptic failures. Always verify before first use on a new machine.
Step 3: Run aztfexport
Single resource:
aztfexport resource \
--non-interactive \
--plain-ui \
-o ./terraform-export \
"/subscriptions/SUB_ID/resourceGroups/RG/providers/TYPE/NAME"
Resource group:
aztfexport resource-group \
--non-interactive \
--plain-ui \
-o ./terraform-export \
RESOURCE_GROUP_NAME
Azure Resource Graph query:
aztfexport query \
--non-interactive \
--plain-ui \
-o ./terraform-export \
"resources | where name == 'MY_RESOURCE'"
Step 4: Review Generated Files
ls ./terraform-export/
# Expect: main.tf, provider.tf, terraform.tfstate, import.tf (sometimes)
main.tf— generated HCL withres-0style resource namesprovider.tf— AzureRM provider configurationterraform.tfstate— imported state file- Consider renaming
res-0to descriptive names (update both HCL and state)
Step 5: Verify
cd ./terraform-export
terraform init
terraform plan
A clean plan (no changes) confirms successful export. Minor diffs may appear for computed attributes — review and suppress with lifecycle { ignore_changes } if appropriate.
Critical Flags
| Flag | Purpose | When Required |
|---|---|---|
--non-interactive | Skip interactive prompts | Always in CI/headless/Claude |
--plain-ui | Disable TUI (terminal UI) | Always pair with --non-interactive — without it, fails when no /dev/tty |
-o <dir> | Output directory | Always (must be empty or non-existent) |
--append | Append to existing Terraform dir | When adding to existing config (but see gotcha below) |
--overwrite | Overwrite existing files | When re-exporting to same directory |
--hcl-only | Generate HCL without importing state | When you only need the code |
Gotchas & Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
Binary crashes silently or exec format error | Architecture mismatch (x86 on ARM Mac) | Run file $(which aztfexport) + uname -m, reinstall correct arch |
--non-interactive alone fails | No /dev/tty in headless environments | Always pair with --plain-ui |
| "directory is not empty" error | Output dir has files | Use -o <fresh-dir> or --overwrite |
--append fails on non-empty dir without state | aztfexport expects existing Terraform state | Use -o to a fresh subdirectory instead |
| Can't find Azure resource ID | Resource type unknown or wrong API | Try multiple az commands — see RESOURCE-DISCOVERY.md |
res-0 style names in output | Default aztfexport naming | Rename post-export in both HCL and state |
terraform plan shows diffs after export | Computed/server-side attributes | Review diffs — use ignore_changes for benign ones |
Example: Export an Activity Log Alert
# Step 1: Find the resource ID
az monitor activity-log alert list -g myResourceGroup \
--query "[?name=='my-alert'].id" -o tsv
# Step 2: Export
aztfexport resource \
--non-interactive \
--plain-ui \
-o ./alert-export \
"/subscriptions/xxxx/resourceGroups/myRG/providers/Microsoft.Insights/activityLogAlerts/my-alert"
# Step 3: Verify
cd ./alert-export
terraform init
terraform plan
Gotchas
- Architecture mismatch between the aztfexport binary and the AzureRM provider's CGO bindings — Apple Silicon needs ARM64 build, x86 binary on M-series silently degrades.
- Resource-name regex defaults exclude special chars — resources with
.in the name (FQDNs, etc.) are skipped silently. - Generated
importblocks (Terraform 1.5+) vsstate importcommands — aztfexport now writes blocks; older workflows expecting state-import calls break. --include-role-assignmentis OFF by default — RBAC is left out of state, which is usually exactly what you don't want.- Provider version pinning: aztfexport pins to specific AzureRM versions in its imports; mismatched provider in your target stack causes spurious plan diffs.
- Non-interactive (
-n) skips name customization — auto-generated TF names likeazurerm_storage_account_001end up in your code permanently if not reviewed.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.