mcpField
A
aztfexport

aztfexport

github.com/julianobarbosaCloud & DevOps1455 installsUpdated 2d ago
Repository

About aztfexport

aztfexport is a skill for turning existing Azure resources into Terraform configuration and state. It helps users bootstrap infrastructure as code through single-resource, resource-group, or Azure Resource Graph exports, with guidance on verification and troubleshooting.

Key features

  1. 01Export a single Azure resource
  2. 02Export an entire resource group
  3. 03Export by Azure Resource Graph query
  4. 04Generate Terraform configuration and state
  5. 05Guidance for validation and troubleshooting

Use cases

  1. 01Import Azure resources into Terraform
  2. 02Create IaC for a resource group
  3. 03Select and export resources by query
  4. 04Review exports and run terraform plan

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/julianobarbosa/claude-code-skills --skill aztfexport

After installing, type/aztfexportin Claude Code to confirm it loaded.

Bundled filesreferences/RESOURCE-DISCOVERY.md

Details

From the project README

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

  1. aztfexport installed: brew install aztfexport (macOS) or see GitHub releases
  2. Azure CLI authenticated: az login + correct subscription selected
  3. Architecture check (critical on macOS):
    file $(which aztfexport)  # Check binary arch
    uname -m                  # Check system arch
    
    If mismatch (e.g., x86_64 binary on arm64 Mac), reinstall the correct architecture version.

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 with res-0 style resource names
  • provider.tf — AzureRM provider configuration
  • terraform.tfstate — imported state file
  • Consider renaming res-0 to 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

FlagPurposeWhen Required
--non-interactiveSkip interactive promptsAlways in CI/headless/Claude
--plain-uiDisable TUI (terminal UI)Always pair with --non-interactive — without it, fails when no /dev/tty
-o <dir>Output directoryAlways (must be empty or non-existent)
--appendAppend to existing Terraform dirWhen adding to existing config (but see gotcha below)
--overwriteOverwrite existing filesWhen re-exporting to same directory
--hcl-onlyGenerate HCL without importing stateWhen you only need the code

Gotchas & Troubleshooting

ProblemCauseSolution
Binary crashes silently or exec format errorArchitecture mismatch (x86 on ARM Mac)Run file $(which aztfexport) + uname -m, reinstall correct arch
--non-interactive alone failsNo /dev/tty in headless environmentsAlways pair with --plain-ui
"directory is not empty" errorOutput dir has filesUse -o <fresh-dir> or --overwrite
--append fails on non-empty dir without stateaztfexport expects existing Terraform stateUse -o to a fresh subdirectory instead
Can't find Azure resource IDResource type unknown or wrong APITry multiple az commands — see RESOURCE-DISCOVERY.md
res-0 style names in outputDefault aztfexport namingRename post-export in both HCL and state
terraform plan shows diffs after exportComputed/server-side attributesReview 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 import blocks (Terraform 1.5+) vs state import commands — aztfexport now writes blocks; older workflows expecting state-import calls break.
  • --include-role-assignment is 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 like azurerm_storage_account_001 end up in your code permanently if not reviewed.

Comments

Markdown supported