diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index fdee533ff..01e5c580b 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -20,7 +20,7 @@ "name": "azure-cloud-development", "source": "azure-cloud-development", "description": "Comprehensive Azure cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications.", - "version": "1.0.0" + "version": "1.0.1" }, { "name": "cast-imaging", diff --git a/agents/terraform-azure-implement.agent.md b/agents/terraform-azure-implement.agent.md index dc11366e0..da6d6f50b 100644 --- a/agents/terraform-azure-implement.agent.md +++ b/agents/terraform-azure-implement.agent.md @@ -1,7 +1,7 @@ --- description: "Act as an Azure Terraform Infrastructure as Code coding specialist that creates and reviews Terraform for Azure resources." name: "Azure Terraform IaC Implementation Specialist" -tools: ["edit/editFiles", "search", "runCommands", "fetch", "todos", "azureterraformbestpractices", "documentation", "get_bestpractices", "microsoft-docs"] +tools: [execute/getTerminalOutput, execute/awaitTerminal, execute/runInTerminal, read/problems, read/readFile, read/terminalSelection, read/terminalLastCommand, agent, edit/createDirectory, edit/createFile, edit/editFiles, search, web/fetch, 'azure-mcp/*', todo] --- # Azure Terraform Infrastructure as Code Implementation Specialist diff --git a/docs/README.plugins.md b/docs/README.plugins.md index 6d01ba49a..64160150c 100644 --- a/docs/README.plugins.md +++ b/docs/README.plugins.md @@ -21,7 +21,7 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-plugins) for guidelines on how t | Name | Description | Items | Tags | | ---- | ----------- | ----- | ---- | | [awesome-copilot](../plugins/awesome-copilot/README.md) | Meta prompts that help you discover and generate curated GitHub Copilot agents, instructions, prompts, and skills. | 5 items | github-copilot, discovery, meta, prompt-engineering, agents | -| [azure-cloud-development](../plugins/azure-cloud-development/README.md) | Comprehensive Azure cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications. | 9 items | azure, cloud, infrastructure, bicep, terraform, serverless, architecture, devops | +| [azure-cloud-development](../plugins/azure-cloud-development/README.md) | Comprehensive Azure cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications. | 10 items | azure, cloud, infrastructure, bicep, terraform, serverless, architecture, devops | | [cast-imaging](../plugins/cast-imaging/README.md) | A comprehensive collection of specialized agents for software analysis, impact assessment, structural quality advisories, and architectural review using CAST Imaging. | 3 items | cast-imaging, software-analysis, architecture, quality, impact-analysis, devops | | [clojure-interactive-programming](../plugins/clojure-interactive-programming/README.md) | Tools for REPL-first Clojure workflows featuring Clojure instructions, the interactive programming chat mode and supporting guidance. | 2 items | clojure, repl, interactive-programming | | [context-engineering](../plugins/context-engineering/README.md) | Tools and techniques for maximizing GitHub Copilot effectiveness through better context management. Includes guidelines for structuring code, an agent for planning multi-file changes, and prompts for context-aware development. | 4 items | context, productivity, refactoring, best-practices, architecture | diff --git a/docs/README.skills.md b/docs/README.skills.md index e3fa113e8..f386d7bae 100644 --- a/docs/README.skills.md +++ b/docs/README.skills.md @@ -121,6 +121,7 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-skills) for guidelines on how to | [github-issues](../skills/github-issues/SKILL.md) | Create, update, and manage GitHub issues using MCP tools. Use this skill when users want to create bug reports, feature requests, or task issues, update existing issues, add labels/assignees/milestones, or manage issue workflows. Triggers on requests like "create an issue", "file a bug", "request a feature", "update issue X", or any GitHub issue management task. | `references/templates.md` | | [go-mcp-server-generator](../skills/go-mcp-server-generator/SKILL.md) | Generate a complete Go MCP server project with proper structure, dependencies, and implementation using the official github.com/modelcontextprotocol/go-sdk. | None | | [image-manipulation-image-magick](../skills/image-manipulation-image-magick/SKILL.md) | Process and manipulate images using ImageMagick. Supports resizing, format conversion, batch processing, and retrieving image metadata. Use when working with images, creating thumbnails, resizing wallpapers, or performing batch image operations. | None | +| [import-infrastructure-as-code](../skills/import-infrastructure-as-code/SKILL.md) | Import existing Azure resources into Terraform using Azure CLI discovery and Azure Verified Modules (AVM). Use when asked to reverse-engineer live Azure infrastructure, generate Infrastructure as Code from existing subscriptions/resource groups/resource IDs, map dependencies, derive exact import addresses from downloaded module source, prevent configuration drift, and produce AVM-based Terraform files ready for validation and planning across any Azure resource type. | None | | [java-add-graalvm-native-image-support](../skills/java-add-graalvm-native-image-support/SKILL.md) | GraalVM Native Image expert that adds native image support to Java applications, builds the project, analyzes build errors, applies fixes, and iterates until successful compilation using Oracle best practices. | None | | [java-docs](../skills/java-docs/SKILL.md) | Ensure that Java types are documented with Javadoc comments and follow best practices for documentation. | None | | [java-junit](../skills/java-junit/SKILL.md) | Get best practices for JUnit 5 unit testing, including data-driven tests | None | diff --git a/plugins/azure-cloud-development/.github/plugin/plugin.json b/plugins/azure-cloud-development/.github/plugin/plugin.json index 4a17f2c7a..83b772134 100644 --- a/plugins/azure-cloud-development/.github/plugin/plugin.json +++ b/plugins/azure-cloud-development/.github/plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "azure-cloud-development", "description": "Comprehensive Azure cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications.", - "version": "1.0.0", + "version": "1.0.1", "author": { "name": "Awesome Copilot Community" }, @@ -28,6 +28,7 @@ ], "skills": [ "./skills/azure-resource-health-diagnose/", - "./skills/az-cost-optimize/" + "./skills/az-cost-optimize/", + "./skills/import-infrastructure-as-code/" ] } diff --git a/skills/import-infrastructure-as-code/SKILL.md b/skills/import-infrastructure-as-code/SKILL.md new file mode 100644 index 000000000..dde2f2efa --- /dev/null +++ b/skills/import-infrastructure-as-code/SKILL.md @@ -0,0 +1,367 @@ +--- +name: import-infrastructure-as-code +description: 'Import existing Azure resources into Terraform using Azure CLI discovery and Azure Verified Modules (AVM). Use when asked to reverse-engineer live Azure infrastructure, generate Infrastructure as Code from existing subscriptions/resource groups/resource IDs, map dependencies, derive exact import addresses from downloaded module source, prevent configuration drift, and produce AVM-based Terraform files ready for validation and planning across any Azure resource type.' +--- + +# Import Infrastructure as Code (Azure -> Terraform with AVM) + +Convert existing Azure infrastructure into maintainable Terraform code using discovery data and Azure Verified Modules. + +## When to Use This Skill + +Use this skill when the user asks to: + +- Import existing Azure resources into Terraform +- Generate IaC from live Azure environments +- Handle any Azure resource type supported by AVM (and document justified non-AVM fallbacks) +- Recreate infrastructure from a subscription or resource group +- Map dependencies between discovered Azure resources +- Use AVM modules instead of handwritten `azurerm_*` resources + +## Prerequisites + +- Azure CLI installed and authenticated (`az login`) +- Access to the target subscription or resource group +- Terraform CLI installed +- Network access to Terraform Registry and AVM index sources + +## Inputs + +| Parameter | Required | Default | Description | +|---|---|---|---| +| `subscription-id` | No | Active CLI context | Azure subscription used for subscription-scope discovery and context setting | +| `resource-group-name` | No | None | Azure resource group used for resource-group-scope discovery | +| `resource-id` | No | None | One or more Azure ARM resource IDs used for specific-resource-scope discovery | + +At least one of `subscription-id`, `resource-group-name`, or `resource-id` is required. + +## Step-by-Step Workflows + +### 1) Collect Required Scope (Mandatory) + +Request one of these scopes before running discovery commands: + +- Subscription scope: `` +- Resource group scope: `` +- Specific resources scope: one or more `` values + +Scope handling rules: + +- Treat Azure ARM resource IDs (for example `/subscriptions/.../providers/...`) as cloud resource identifiers, not local file system paths. +- Use resource IDs only with Azure CLI `--ids` arguments (for example `az resource show --ids `). +- Never pass resource IDs to file-reading commands (`cat`, `ls`, `read_file`, glob searches) unless the user explicitly says they are local file paths. +- If the user already provided one valid scope, do not ask for additional scope inputs unless required by a failing command. +- Do not ask follow-up questions that can be answered from already-provided scope values. + +If scope is missing, ask for it explicitly and stop. + +### 2) Authenticate and Set Context + +Run only the commands required for the selected scope. + +For subscription scope: + +```bash +az login +az account set --subscription +az account show --query "{subscriptionId:id, name:name, tenantId:tenantId}" -o json +``` + +Expected output: JSON object with `subscriptionId`, `name`, and `tenantId`. + +For resource group or specific resource scope, `az login` is still required but `az account set` is optional if the active context is already correct. + +When using specific resource scope, prefer direct `--ids`-based commands first and avoid extra discovery prompts for subscription or resource group unless needed for a concrete command. + +### 3) Run Discovery Commands + +Discover resources using the selected scopes. Ensure to fetch all necessary information for accurate Terraform generation. + +```bash +# Subscription scope +az resource list --subscription -o json + +# Resource group scope +az resource list --resource-group -o json + +# Specific resource scope +az resource show --ids ... -o json +``` + +Expected output: JSON object or array containing Azure resource metadata (`id`, `type`, `name`, `location`, `tags`, `properties`). + +### 4) Resolve Dependencies Before Code Generation + +Parse exported JSON and map: + +- Parent-child relationships (for example: NIC -> Subnet -> VNet) +- Cross-resource references in `properties` +- Ordering for Terraform creation + +IMPORTANT: Generate the following documentation and save it to a docs folder in the root of the project. +- `exported-resources.json` with all discovered resources and their metadata, including dependencies and references. +- `EXPORTED-ARCHITECTURE.MD` file with a human-readable architecture overview based on the discovered resources and their relationships. + +### 5) Select Azure Verified Modules (Required) + +Use the latest AVM version for each resource type. + +### Terraform Registry + +- Search for "avm" + resource name +- Filter by "Partner" tag to find official AVM modules +- Example: Search "avm storage account" → filter by Partner + +### Official AVM Index + +> **Note:** The following links always point to the latest version of the CSV files on the main branch. As intended, this means the files may change over time. If you require a point-in-time version, consider using a specific release tag in the URL. + +- **Terraform Resource Modules**: `https://raw.githubusercontent.com/Azure/Azure-Verified-Modules/refs/heads/main/docs/static/module-indexes/TerraformResourceModules.csv` +- **Terraform Pattern Modules**: `https://raw.githubusercontent.com/Azure/Azure-Verified-Modules/refs/heads/main/docs/static/module-indexes/TerraformPatternModules.csv` +- **Terraform Utility Modules**: `https://raw.githubusercontent.com/Azure/Azure-Verified-Modules/refs/heads/main/docs/static/module-indexes/TerraformUtilityModules.csv` + +### Individual Module information + +Use the `web` tool or another suitable MCP method to get module information if not available locally in the `.terraform` folder. + +Use AVM sources: + +- Registry: `https://registry.terraform.io/modules/Azure//azurerm/latest` +- GitHub: `https://github.com/Azure/terraform-azurerm-avm-res--` + +Prefer AVM modules over handwritten `azurerm_*` resources when an AVM module exists. + +When fetching module information from GitHub repositories, the README.md file in the root of the repository typically contains all detailed information about the module, for example: https://raw.githubusercontent.com/Azure/terraform-azurerm-avm-res--/refs/heads/main/README.md + +### 5a) Read the Module README Before Writing Any Code (Mandatory) + +**This step is not optional.** Before writing a single line of HCL for a module, fetch and +read the full README for that module. Do not rely on knowledge of the raw `azurerm` provider +or prior experience with other AVM modules. + +For each selected AVM module, fetch its README: + +```text +https://raw.githubusercontent.com/Azure/terraform-azurerm-avm-res--/refs/heads/main/README.md +``` + +Or if the module is already downloaded after `terraform init`: + +```bash +cat .terraform/modules//README.md +``` + +From the README, extract and record **before writing code**: + +1. **Required Inputs** — every input the module requires. Any child resource listed here + (NICs, extensions, subnets, public IPs) is managed **inside** the module. Do **not** + create standalone module blocks for those resources. +2. **Optional Inputs** — the exact Terraform variable names and their declared `type`. + Do not assume they match the raw `azurerm` provider argument names or block shapes. +3. **Usage examples** — check what resource group identifier is used (`parent_id` vs + `resource_group_name`), how child resources are expressed (inline map vs separate module), + and what syntax each input expects. + +#### Apply module rules as patterns, not assumptions + +Use the lessons below as examples of the *type* of mismatch that often causes imports to fail. +Do not assume these exact names apply to every AVM module. Always verify each selected module's +README and `variables.tf`. + +**`avm-res-compute-virtualmachine` (any version)** + +- `network_interfaces` is a **Required Input**. NICs are owned by the VM module. Never + create standalone `avm-res-network-networkinterface` modules alongside a VM module — + define every NIC inline under `network_interfaces`. +- TrustedLaunch is expressed through the top-level booleans `secure_boot_enabled = true` + and `vtpm_enabled = true`. The `security_type` argument exists only under `os_disk` for + Confidential VM disk encryption and must not be used for TrustedLaunch. +- `boot_diagnostics` is a `bool`, not an object. Use `boot_diagnostics = true`; use the + separate `boot_diagnostics_storage_account_uri` variable if a storage URI is needed. +- Extensions are managed inside the module via the `extensions` map. Do not create + standalone extension resources. + +**`avm-res-network-virtualnetwork` (any version)** + +- This module is backed by the AzAPI provider, not `azurerm`. Use `parent_id` (the full + resource group resource ID string) to specify the resource group, not `resource_group_name`. +- Every example in the README shows `parent_id`; none show `resource_group_name`. + +Generalized takeaway for all AVM modules: + +- Determine child resource ownership from **Required Inputs** before creating sibling modules. +- Determine accepted variable names and types from **Optional Inputs** and `variables.tf`. +- Determine identifier style and input shape from README usage examples. +- Do not infer argument names from raw `azurerm_*` resources. + +### 6) Generate Terraform Files + +### Before Writing Import Blocks — Inspect Module Source (Mandatory) + +After `terraform init` downloads the modules, inspect each module's source files to determine +the exact Terraform resource addresses before writing any `import {}` blocks. Never write +import addresses from memory. + +#### Step A — Identify the provider and resource label + +```bash +grep "^resource" .terraform/modules//main*.tf +``` + +This reveals whether the module uses `azurerm_*` or `azapi_resource` labels. For example, +`avm-res-network-virtualnetwork` exposes `azapi_resource "vnet"`, not +`azurerm_virtual_network "this"`. + +#### Step B — Identify child modules and nested paths + +```bash +grep "^module" .terraform/modules//main*.tf +``` + +If child resources are managed in a sub-module (subnets, extensions, etc.), the import +address must include every intermediate module label: + +```text +module..module.[""]..