[Onboard] Support MCP Tools for Azure Terraform#2382
[Onboard] Support MCP Tools for Azure Terraform#2382liuwuliuyun wants to merge 5 commits intomainfrom
Conversation
1851c93 to
2027c44
Compare
…, and conftest tools Add 10 new MCP tools for Terraform workflows on Azure: - AzureRM and AzAPI provider documentation retrieval - Azure Verified Modules (AVM) listing, versions, and documentation - Azure Export for Terraform (aztfexport) resource, resource group, and query export - Conftest policy validation for workspace files and plan files Includes comprehensive unit tests, consolidated tool definitions, CODEOWNERS, changelog entry, README updates, e2e test prompts, and telemetry tagging. Closes #2215
2027c44 to
e4b41f5
Compare
|
AOT Analysis: |
|
Spelling Check: |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a new Azure Terraform area to the Azure MCP Server, providing tools for AzureRM/AzAPI documentation lookup, Azure Verified Modules (AVM) discovery, aztfexport command generation, and conftest policy validation.
Changes:
- Introduces a new
Azure.Mcp.Tools.AzureTerraformtool project (commands, services, models, options) and registers it in the server. - Adds unit tests for new command/service behaviors and adds the new test project to the solution.
- Updates server docs/metadata (commands list, e2e prompts, consolidated tools, README), CODEOWNERS, spelling dictionary, and changelog.
Reviewed changes
Copilot reviewed 80 out of 80 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/Conftest/ConftestWorkspaceValidationCommandTests.cs | Adds command tests for conftest workspace validation tool |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/Conftest/ConftestServiceTests.cs | Adds unit tests for conftest command generation and install help |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/Conftest/ConftestPlanValidationCommandTests.cs | Adds command tests for conftest plan validation tool |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AzureRMDocsServiceParsingTests.cs | Adds parsing tests for AzureRM markdown extraction helpers |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AzureRMDocsGetCommandTests.cs | Adds command tests for AzureRM docs tool |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/Azure.Mcp.Tools.AzureTerraform.UnitTests.csproj | Introduces new unit test project and dependencies |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AztfexportServiceTests.cs | Adds tests for aztfexport command generation and install help |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AztfexportResourceGroupCommandTests.cs | Adds command tests for aztfexport resource-group tool |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AztfexportResourceCommandTests.cs | Adds command tests for aztfexport resource tool |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AztfexportQueryCommandTests.cs | Adds command tests for aztfexport query tool |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AzApiDocsServiceFormatTests.cs | Adds tests for AzAPI HCL formatting output |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AzAPIDocsGetCommandTests.cs | Adds command tests for AzAPI docs tool |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AvmVersionListCommandTests.cs | Adds command tests for AVM version listing tool |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AvmModuleListCommandTests.cs | Adds command tests for AVM module listing tool |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AvmDocumentationGetCommandTests.cs | Adds command tests for AVM documentation retrieval tool |
| tools/Azure.Mcp.Tools.AzureTerraform/tests/Azure.Mcp.Tools.AzureTerraform.UnitTests/AvmDocsServiceParsingTests.cs | Adds parsing tests for AVM CSV and repo URL mapping |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/IConftestService.cs | Adds interface for conftest availability check and command generation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/IAzureRMDocsService.cs | Adds interface for AzureRM docs retrieval |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/IAztfexportService.cs | Adds interface for aztfexport availability check and command generation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/IAzApiExamplesService.cs | Adds interface for AzAPI terraform example retrieval |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/IAzAPIDocsService.cs | Adds interface for AzAPI docs/schema retrieval |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/IAvmDocsService.cs | Adds interface for AVM listing/version/docs retrieval |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/ConftestService.cs | Implements conftest command generation, install help, and policy args |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/AzureRMDocsService.cs | Implements AzureRM markdown fetch + parsing (summary/args/attrs/examples/notes) |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/AztfexportService.cs | Implements aztfexport command generation and install help |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/AzApiExamplesService.cs | Implements fetching AzAPI Terraform samples from template-reference-generator |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/AzAPIDocsService.cs | Implements schema formatting for AzAPI resources using Bicep schema generator |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/AvmJsonContext.cs | Adds source-gen JSON context for GitHub release deserialization |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Services/AvmDocsService.cs | Implements AVM module CSV parsing, caching, GitHub releases/README retrieval |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Options/Conftest/ConftestWorkspaceValidationOptions.cs | Adds option model for conftest workspace command |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Options/Conftest/ConftestPlanValidationOptions.cs | Adds option model for conftest plan command |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Options/AzureTerraformOptionDefinitions.cs | Defines System.CommandLine options for all AzureTerraform tools |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Options/AzureRMDocsOptions.cs | Adds options model for AzureRM docs command |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Options/AztfexportResourceOptions.cs | Adds options model for aztfexport resource command |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Options/AztfexportResourceGroupOptions.cs | Adds options model for aztfexport resource-group command |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Options/AztfexportQueryOptions.cs | Adds options model for aztfexport query command |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Options/AzAPIDocsOptions.cs | Adds options model for AzAPI docs command |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Options/AvmVersionOptions.cs | Adds options model for AVM versions command |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Options/AvmModuleListOptions.cs | Adds options model for AVM list command |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Options/AvmDocumentationOptions.cs | Adds options model for AVM get-docs command |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/InstallationMethod.cs | Adds model for install methods in tool responses |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/InstallationHelp.cs | Adds model for install help in tool responses |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/GitHubRelease.cs | Adds GitHub release DTO for AVM versions |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/ConftestCommandResult.cs | Adds response model for conftest command generation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/AzureTerraformTelemetryTags.cs | Adds telemetry tag constants for the AzureTerraform area |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/AzureRMDocsResult.cs | Adds response model for AzureRM docs tool |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/AztfexportCommandResult.cs | Adds response model for aztfexport command generation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/AzAPIExample.cs | Adds model for AzAPI sample snippets |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/AzAPIDocsResult.cs | Adds response model for AzAPI docs/schema tool |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/AvmVersionListResult.cs | Adds response model for AVM versions tool |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/AvmVersion.cs | Adds AVM version DTO |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/AvmModuleListResult.cs | Adds response model for AVM list tool |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/AvmModule.cs | Adds AVM module DTO |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/AvmDocumentationResult.cs | Adds response model for AVM get-docs tool |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/AttributeDetail.cs | Adds model for parsed AzureRM attributes |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Models/ArgumentDetail.cs | Adds model for parsed AzureRM arguments (incl. block args) |
| tools/Azure.Mcp.Tools.AzureTerraform/src/GlobalUsings.cs | Adds global usings for System.CommandLine + MCP core option helpers |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/Conftest/ConftestWorkspaceValidationCommand.cs | Adds conftest workspace command implementation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/Conftest/ConftestPlanValidationCommand.cs | Adds conftest plan command implementation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzureTerraformJsonContext.cs | Adds source-gen JSON context for tool responses |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzureRMDocsGetCommand.cs | Adds AzureRM docs command implementation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportResourceGroupCommand.cs | Adds aztfexport resource-group command implementation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportResourceCommand.cs | Adds aztfexport resource command implementation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AztfexportQueryCommand.cs | Adds aztfexport query command implementation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AzAPIDocsGetCommand.cs | Adds AzAPI docs/schema command implementation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmVersionListCommand.cs | Adds AVM versions command implementation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmModuleListCommand.cs | Adds AVM module list command implementation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Commands/AvmDocumentationGetCommand.cs | Adds AVM documentation retrieval command implementation |
| tools/Azure.Mcp.Tools.AzureTerraform/src/AzureTerraformSetup.cs | Registers AzureTerraform services/commands and defines command groups |
| tools/Azure.Mcp.Tools.AzureTerraform/src/Azure.Mcp.Tools.AzureTerraform.csproj | Introduces the new AzureTerraform tool project and dependencies |
| tools/Azure.Mcp.Tools.AzureTerraform/src/AssemblyInfo.cs | Exposes internals to unit tests/live tests |
| servers/Azure.Mcp.Server/src/Resources/consolidated-tools.json | Adds two aggregated tool entries mapping to AzureTerraform tools |
| servers/Azure.Mcp.Server/src/Program.cs | Registers AzureTerraform area with the server |
| servers/Azure.Mcp.Server/docs/e2eTestPrompts.md | Adds e2e prompts for AzureTerraform tools |
| servers/Azure.Mcp.Server/docs/azmcp-commands.md | Documents new AzureTerraform CLI commands |
| servers/Azure.Mcp.Server/changelog-entries/1774593854839.yaml | Adds changelog entry for AzureTerraform toolset |
| servers/Azure.Mcp.Server/README.md | Adds AzureTerraform example prompts + service area list entry |
| Microsoft.Mcp.slnx | Adds AzureTerraform projects to the solution |
| .vscode/cspell.json | Adds Terraform-related terms to spelling dictionary |
| .github/CODEOWNERS | Adds code owners for AzureTerraform tool directory |
Comments suppressed due to low confidence (4)
tools/Azure.Mcp.Tools.AzureTerraform/src/Services/AvmDocsService.cs:1
Lockis not available on most target frameworks in current .NET LTS releases; this will fail to compile unless the repo targets a framework that includesSystem.Threading.Lock. Replace this with a standardobject(used with thelockstatement) or another widely-available sync primitive (e.g.,SemaphoreSlim) to keep the caching thread-safe and buildable.
tools/Azure.Mcp.Tools.AzureTerraform/src/Services/ConftestService.cs:1- The
policySet switchis case-sensitive, but later checks treatpolicySetcase-insensitively (e.g.,avmsecseverity filter). This means inputs likeAVMSECwill silently select./policyinstead of./policy/avmsec. NormalizepolicySet(e.g.,ToLowerInvariant()) before the switch or use a case-insensitive comparison approach for selectingpolicyPath.
tools/Azure.Mcp.Tools.AzureTerraform/src/Services/AzAPIDocsService.cs:1 - Stripping a trailing
sto compute the Terraform label can produce incorrect labels for types like.../status(becomesstatu) or other nouns where naive singularization is wrong. Since the label is arbitrary, prefer leavinglastPartunchanged (or using a safer normalization, e.g.,ToLowerInvariant()+ replace invalid characters) to avoid generating surprising/incorrect labels.
tools/Azure.Mcp.Tools.AzureTerraform/src/Services/AzAPIDocsService.cs:1 - This method returns text that is later embedded inside quoted HCL strings. If
prop.Descriptionorprop.Modifierscontains double quotes, backslashes, or newlines, the generated HCL will become invalid. Escape these values for HCL-string safety (at minimum:\\,\", and line breaks) before interpolation.
jongio
left a comment
There was a problem hiding this comment.
Solid new toolset. A few issues to address - 3 bugs in service logic and some structural items.
| internal static void AddPolicyArgs(List<string> args, string policySet, string? severityFilter, string? customPolicies) | ||
| { | ||
| var policyPath = policySet switch | ||
| { |
There was a problem hiding this comment.
Bug: this switch is case-sensitive, but the severity check below uses StringComparison.OrdinalIgnoreCase. If someone passes AVMSEC or Avmsec, the switch falls through to the default ./policy path while the severity filter still triggers - producing an invalid -p .conftest_severity_X.rego arg alongside the wrong policy path.
Fix: normalize before the switch:
policySet = policySet.ToLowerInvariant();Or use if/else with StringComparison.OrdinalIgnoreCase instead of a switch.
There was a problem hiding this comment.
Added policySet.ToLowerInvariant() before the switch to fix case-sensitivity bug, and lowered the switch cases to match
| string[] resourceParts = resourceTypeName.Split('/'); | ||
| string lastPart = resourceParts[^1]; | ||
| string label = lastPart.EndsWith('s') ? lastPart[..^1] : lastPart; | ||
|
|
There was a problem hiding this comment.
This strips a trailing s to singularize the label, but it breaks on resource types that end in s without being plural: status becomes statu, address becomes addres, etc.
Since this label is arbitrary (it's just the HCL resource name), consider using lastPart.ToLowerInvariant() as-is, or at minimum add a guard for common false positives.
There was a problem hiding this comment.
Good catch, I peplaced naive singularization (strip trailing 's') with lastPart.ToLowerInvariant() to avoid mangling resource types like status/address
| else | ||
| { | ||
| sb.AppendLine($" {prop.Name} = \"{FormatPropertyDescription(prop)}\""); | ||
| } |
There was a problem hiding this comment.
Property descriptions are interpolated into HCL-quoted strings without escaping. If prop.Description or prop.Modifiers contains double quotes, backslashes, or newlines, the generated HCL will be invalid.
Add an escape helper:
static string EscapeHcl(string value) =>
value.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n");Applies to FormatPropertyDescription, FormatPropertyDescriptionWithRequired, and inline interpolations in FormatObjectProperties.
There was a problem hiding this comment.
Added EscapeHcl() helper and applied it to FormatPropertyDescriptionWithRequired, FormatObjectProperties inline descriptions to prevent invalid HCL from quotes/backslashes/newlines in descriptions
| @@ -0,0 +1,651 @@ | |||
| // Copyright (c) Microsoft Corporation. | |||
There was a problem hiding this comment.
This file is 651 lines - exceeds the repo 500-line convention. The markdown parsing logic (ExtractArguments, ExtractBlockDefinitions, ExtractAttributes, ExtractExamples, ExtractNotes, and the regex patterns) could move to a separate AzureRMDocsParser static class.
There was a problem hiding this comment.
Extracted all parsing methods and regex patterns into a new AzureRMDocsParser.cs static class (service was 651 lines, now ~130 lines + ~430 line parser)
| { | ||
| return null; | ||
| } | ||
| } |
There was a problem hiding this comment.
RemarksJson, TerraformSampleEntry, and AzApiExamplesJsonContext are defined here alongside AzApiExamplesService. Per repo convention, each class should be in its own file. Consider moving the DTOs to Models/ and the JSON context to its own file.
There was a problem hiding this comment.
Moved RemarksJson, TerraformSampleEntry DTOs to Models/ and AzApiExamplesJsonContext to its own file
| ConfigureGitHubHeaders(client); | ||
|
|
||
| var response = await client.GetAsync(new Uri(apiUrl), cancellationToken).ConfigureAwait(false); | ||
| response.EnsureSuccessStatusCode(); |
There was a problem hiding this comment.
GitHub API calls here (releases endpoint) don't handle rate limiting. A 403 with X-RateLimit-Remaining: 0 will throw a generic HttpRequestException with no hint about what went wrong. Consider catching 403 responses and checking the rate limit headers to provide an actionable error message.
There was a problem hiding this comment.
Added CheckForRateLimit() helper that detects 403 + X-RateLimit-Remaining: 0 and throws an actionable error with reset time
| } | ||
|
|
||
| if (includeRoleAssignment) | ||
| { |
There was a problem hiding this comment.
Nit: the --parallelism option description says "max: 50" but there's no runtime validation. A user passing parallelism=1000 would get that value passed straight to aztfexport. Consider clamping: Math.Clamp(parallelism, 1, 50).
There was a problem hiding this comment.
AztfexportService.cs - Added Math.Clamp(parallelism, 1, 50) in all three command generation methods
|
Hi @jongio , thanks for the review comments, beside changes replied, I also updated AzApiDocsServiceFormatTests.cs assertion updated to match new ToLowerInvariant() label behavior. |
… parsing - Moved markdown parsing logic from AzureRMDocsService to a new AzureRMDocsParser class for better separation of concerns. - Introduced RemarksJson and TerraformSampleEntry models for structured data handling. - Updated AzApiExamplesService to utilize new models and parsing methods. - Added clamping for parallelism in AztfexportService methods to ensure valid input. - Refactored ConftestService to handle policy set names in a case-insensitive manner. - Adjusted unit tests to reflect changes in method calls and expected outputs.
|
The build failure is caused by a repo-wide NuGet vulnerability issue, not by changes in this PR. Root cause: This affects every project in the solution (Storage, SignalR, ServiceFabric, ServiceBus, Redis, Quota, Pricing, Speech, etc.) and will block all PRs until the package is updated or the warning is suppressed on |
What does this PR do?
Adds a new Azure Terraform toolset to the Azure MCP Server with 10 tools across 5 functional areas:
azureterraform_azurerm_get) — Retrieve AzureRM provider documentation for Terraform resourcesazureterraform_azapi_get) — Retrieve AzAPI provider documentation for Azure resources by resource type and API versionazureterraform_avm_list,azureterraform_avm_versions,azureterraform_avm_get) — List, query versions, and retrieve documentation for Azure Verified Modulesazureterraform_aztfexport_resource,azureterraform_aztfexport_resourcegroup,azureterraform_aztfexport_query) — Generate aztfexport commands to export Azure resources to Terraform configurationazureterraform_conftest_workspace,azureterraform_conftest_plan) — Generate conftest commands to validate Terraform configurations against Azure policiesThese tools are bundled in a single PR because they form a cohesive toolset for Terraform workflows on Azure, sharing common models, services, and infrastructure. Splitting them would create artificial boundaries within tightly coupled code.
Azure Terraform documentation:
GitHub issue number?
#2215
Pre-merge Checklist
servers/Azure.Mcp.Server/README.mdand/orservers/Fabric.Mcp.Server/README.mddocumentationREADME.mdchanges running the script./eng/scripts/Process-PackageReadMe.ps1. See Package READMEToolDescriptionEvaluatorand obtained a score of0.4or more and a top 3 ranking for all related test promptsconsolidated-tools.jsonbreaking-changelabelservers/Azure.Mcp.Server/docs/azmcp-commands.md./eng/scripts/Update-AzCommandsMetadata.ps1to update tool metadata inazmcp-commands.md(required for CI)servers/Azure.Mcp.Server/docs/e2eTestPrompts.mdcrypto mining, spam, data exfiltration, etc.)/azp run mcp - pullrequest - liveto run Live Test Pipeline