Skip to content

Commit

Permalink
New RP Microsoft.AzureTerraform.Management - export Azure resources t…
Browse files Browse the repository at this point in the history
…o Terraform HCL (#30455)

* New RP: Microsoft.AzureTerraform (ver=2023-07-01-preview)

* prettier

* remove x-ms-discriminator-value

* readme.md: add `openapi-subtype`

* Fix LintDiff failure

* Result configuration type change from object to string

* Remove properties: `subscriptionId` and `environment`

* Change `errors` from list of string to list of `ErrorResponse`

* Add operations endpoint

* Update

* Update

* AzureTerraform RP: Sync the MS version with the private version

* Terraform: Change `exportEerraform` endpoint to LRO (#18782)

* terraform: Modify the `exportTerraform` RT to be LRO

* Update

* prettier

* spell

* CI validation

* More CI issue fixes

* typo

* Add readme.go.md

* typo

* prettier

* suppression

* Update suppression

* AzureTerrform: Remove the parallelism property (#18909)

* exportTerraform: Change resourceId -> resourceIds; Add `maskSensitive`; Change `fullConfig` defaults (#19178)

* exportTerraform: Change resourceId -> resourceIds; Add `maskSensitive`; Change `fullConfig` defaults

* rename

* rename

* rename

* Specify LRO model (#19401)

* Add up the `resourceId` in `OperationStatus` model (#19450)

* Add `uri` format (#19455)

* Add format url

* update

* TypeSpec for Microsoft.AzureTerraform (#19390)

* TypeSpec for Microsoft.AzureTerraform

* Sorted swagger file, and added typespec generated with tsp-client

* revert export.json in prep of merging

* Sorted export.json for easy diff on future typespec -> swagger

* Rerun swagger -> typespec conversion after merging latest RPSaaSMaster,
updated namespace

* tsp compile for TypeSpec -> swagger

* Refactored typescript to minimise swagger diff

* Spread ErrorResponse into OperationStatus model

* Fixed enums, use doc decorator

* Update exportTerraform path desc

* Update doc for ExportResource model

* LintDiff fix: remove unnecessary auth

* Add resourceId prop to OperationStatus model, fixed char casing so they're consistent throughout

* Made resourceId read only

* Check `Swagger BreakingChange`: minimise diff on x-ms-enum

* TypeSpec Validation fix: rename dir and add missing @doc

* Upgrade/rp tsp 0.60 (#19551) -- applying only for specification/terraform

* Revert accidental changes to cSpell.json while merging

* Added tf files used for armstrong testing

---------

Co-authored-by: magodo <wztdyl@sina.com>
  • Loading branch information
gerrytan and magodo committed Sep 20, 2024
1 parent 8d5de60 commit 46b3863
Show file tree
Hide file tree
Showing 18 changed files with 1,134 additions and 0 deletions.
7 changes: 7 additions & 0 deletions cSpell.json
Original file line number Diff line number Diff line change
Expand Up @@ -1420,6 +1420,13 @@
"sfmc's"
]
},
{
"filename": "**/specification/terraform/resource-manager/Microsoft.AzureTerraform/**/*.json",
"words": [
"azurerm",
"azapi"
]
},
{
"filename": "**/specification/deviceregistry/resource-manager/Microsoft.DeviceRegistry/**/*.json",
"words": [
Expand Down
2 changes: 2 additions & 0 deletions specification/terraform/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Override the **/terraform/** rule set at the top level to avoid relevant files getting ignored
!**/*.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "ExportTerraform",
"operationId": "ExportTerraform",
"parameters": {
"api-version": "2023-07-01-preview",
"subscriptionId": "00000000-0000-0000-0000-000000000000",
"exportParameter": {
"type": "ExportResourceGroup",
"resourceGroupName": "rg1"
}
},
"responses": {
"202": {
"headers": {
"Azure-AsyncOperation": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.AzureTerraform/operationStatus/00000000-0000-0000-0000-000000000000?api-version=2023-07-01-preview",
"Location": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.AzureTerraform/operationStatus/00000000-0000-0000-0000-000000000000?api-version=2023-07-01-preview"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"title": "Get specific operation status",
"operationId": "OperationStatuses_Get",
"parameters": {
"subscriptionId": "00000000-0000-0000-0000-000000000000",
"operationId": "00000000-0000-0000-0000-000000000000",
"api-version": "2023-07-01-preview"
},
"responses": {
"200": {
"headers": {},
"body": {
"id": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.AzureTerraform/operationStatus/00000000-0000-0000-0000-000000000000?api-version=2023-07-01-preview",
"name": "00000000-0000-0000-0000-000000000000",
"startTime": "2024-07-08T08:48:46.3160075Z",
"endTime": "2024-07-08T08:49:23.7083Z",
"status": "Succeeded",
"properties": {
"configuration": "resource \"azurerm_resource_group\" \"res-0\" {\n location = \"westeurope\"\n name = \"rg1\"\n}",
"errors": null,
"skippedResources": null
}
}
},
"202": {
"headers": {
"Azure-AsyncOperation": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.AzureTerraform/operationStatus/00000000-0000-0000-0000-000000000000?api-version=2023-07-01-preview",
"Location": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.AzureTerraform/operationStatus/00000000-0000-0000-0000-000000000000?api-version=2023-07-01-preview"
},
"body": {
"id": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.AzureTerraform/operationStatus/00000000-0000-0000-0000-000000000000?api-version=2023-07-01-preview",
"name": "00000000-0000-0000-0000-000000000000",
"startTime": "2024-07-08T08:48:46.3160075Z",
"status": "InProgress"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"title": "Get a list of operations for a resource provider",
"operationId": "Operations_List",
"parameters": {
"subscriptionId": "12345678-1234-1234-12345678abc",
"api-version": "2023-07-01-preview"
},
"responses": {
"200": {
"body": {
"value": [
{
"name": "Microsoft.AzureTerraform/operations/read",
"display": {
"provider": "Microsoft AzureTerraform",
"resource": "Azure Terraform Resource Provider",
"operation": "ListOperations",
"description": "Lists all of the available RP operations."
}
},
{
"name": "Microsoft.AzureTerraform/exportTerraform/action",
"display": {
"provider": "Microsoft AzureTerraform",
"resource": "Azure Terraform Resource Provider",
"operation": "ExportTerraform",
"description": "Exports the Terraform configuration used for the specified scope."
}
}
]
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* PLEASE DO NOT REMOVE - USED FOR CONVERTER METRICS
* Generated by package: @autorest/openapi-to-typespec
* Version: 0.9.0
* Date: 2024-08-30T14:24:13.436Z
*/
import "@typespec/rest";
import "@typespec/versioning";
import "@azure-tools/typespec-azure-core";
import "@azure-tools/typespec-azure-resource-manager";
import "./models.tsp";
import "./routes.tsp";

using TypeSpec.Rest;
using TypeSpec.Http;
using Azure.ResourceManager.Foundations;
using Azure.Core;
using Azure.ResourceManager;
using TypeSpec.Versioning;

@doc("The Azure Terraform management API provides a RESTful set of web services that used to manage your Azure Terraform resources.")
@armProviderNamespace
@service({
title: "AzureTerraformResourceProviderClient",
})
@versioned(Versions)
@armCommonTypesVersion(Azure.ResourceManager.CommonTypes.Versions.v5)
namespace Microsoft.AzureTerraform;

@doc("The available API versions.")
enum Versions {
@doc("The 2023-07-01-preview API version.")
@useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1)
@useDependency(Azure.Core.Versions.v1_0_Preview_1)
v2023_07_01_preview: "2023-07-01-preview",
}
146 changes: 146 additions & 0 deletions specification/terraform/Microsoft.AzureTerraform.Management/models.tsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import "@typespec/rest";
import "@typespec/http";
import "@azure-tools/typespec-azure-resource-manager";

using TypeSpec.Rest;
using TypeSpec.Http;
using Azure.ResourceManager;
using Azure.ResourceManager.Foundations;
using OpenAPI;

namespace Microsoft.AzureTerraform;

interface Operations extends Azure.ResourceManager.Operations {}

@doc("The parameter type")
union Type {
string,
ExportResource: "ExportResource",
ExportResourceGroup: "ExportResourceGroup",
ExportQuery: "ExportQuery",
}

@doc("The target Azure Terraform Provider")
union targetProvider {
string,

@doc("https://registry.terraform.io/providers/hashicorp/azurerm/latest")
azurerm: "azurerm",

@doc("https://registry.terraform.io/providers/Azure/azapi/latest")
azapi: "azapi",
}

@doc("The base export parameter")
@discriminator("type")
model BaseExportModel {
@doc("The parameter type")
type: Type;

@doc("The target Azure Terraform Provider")
targetProvider?: targetProvider = targetProvider.azurerm;

@doc("Whether to output all non-computed properties in the generated Terraform configuration? This probably needs manual modifications to make it valid")
fullProperties?: boolean = true;

@doc("Mask sensitive attributes in the Terraform configuration")
maskSensitive?: boolean = true;
}

@doc("Export parameter for resources queried by ARG (Azure Resource Graph)")
model ExportQuery extends BaseExportModel {
@doc("The ARG where predicate. Note that you can combine multiple conditions in one `where` predicate, e.g. `resourceGroup =~ \"my-rg\" and type =~ \"microsoft.network/virtualnetworks\"`")
query: string;

@doc("The name pattern of the Terraform resources")
namePattern?: string = "res-";

@doc("Whether to recursively list child resources of the query result")
recursive?: boolean = false;

@doc("The parameter type")
type: "ExportQuery";
}

@doc("Export parameter for individual resources.")
model ExportResource extends BaseExportModel {
@doc("The id of the resource to be exported")
resourceIds: string[];

@doc("The Terraform resource name. Only works when `resourceIds` contains only one item.")
resourceName?: string = "res-0";

@doc("The Terraform resource type. Only works when `resourceIds` contains only one item.")
resourceType?: string;

@doc("The name pattern of the Terraform resources")
namePattern?: string = "res-";

@doc("The parameter type")
type: "ExportResource";
}

@doc("Export parameter for a resource group")
model ExportResourceGroup extends BaseExportModel {
@doc("The name of the resource group to be exported")
resourceGroupName: string;

@doc("The name pattern of the Terraform resources")
namePattern?: string = "res-";

@doc("The parameter type")
type: "ExportResourceGroup";
}

@doc("The status of the LRO operation.")
model OperationStatus {
@doc("The operation status resource id.")
id?: string;

@doc("The fully qualified resource id of the resource for which the operation was performed.")
@visibility("read")
resourceId?: string;

@doc("The operation name.")
name?: string;

@doc("The start time of the operation.")
@visibility("read")
startTime?: utcDateTime;

@doc("The end time of the operation.")
@visibility("read")
endTime?: utcDateTime;

@doc("The status of the operation.")
status?: string;

@doc("The progress percentage of the operation, ranges from 0 to 100")
percentComplete?: float64;

@doc("The Terraform export result")
properties?: ExportResult;

...ErrorResponse;
}

model InProgressOperationStatus
is ArmAcceptedResponse<
"InProgress operation status",
ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader
> {
...OperationStatus;
}

@doc("The Terraform export result")
model ExportResult {
@doc("The Terraform configuration content")
configuration?: string;

@doc("A list of Azure resources which are not exported to Terraform due to there is no corresponding resources in Terraform")
skippedResources?: string[];

@doc("A list of errors derived during exporting each resource")
@extension("x-ms-identifiers", [])
errors?: ErrorDetail[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import "@azure-tools/typespec-azure-core";
import "@typespec/rest";
import "./models.tsp";
import "@azure-tools/typespec-azure-resource-manager";

using TypeSpec.Rest;
using TypeSpec.Http;
using Azure.ResourceManager;
using Azure.ResourceManager.Foundations;
using OpenAPI;

namespace Microsoft.AzureTerraform;

#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-operation" "Cannot use @armResourceOperations decorator here, the auto-generated routes do not match feature requirements"
#suppress "@azure-tools/typespec-azure-core/no-openapi" "TODO: migrate to LRO concepts DO NOT USE x-ms-long-running-operation-options"
@doc("Exports the Terraform configuration of the specified resource(s).")
@route("/subscriptions/{subscriptionId}/providers/Microsoft.AzureTerraform/exportTerraform")
@post
@tag("ExportTerraform")
@extension(
"x-ms-long-running-operation-options",
{
`final-state-via`: "azure-async-operation",
`final-state-schema`: "#/definitions/OperationStatus",
}
)
op exportTerraform(
...ApiVersionParameter,
...SubscriptionIdParameter,

@doc("The export parameter")
@body
exportParameter: BaseExportModel,
): ArmAcceptedLroResponse<
"Export request accepted.",
ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader
> | ErrorResponse;

#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator" "Cannot use @armResourceOperations decorator here, the auto-generated routes do not match feature requirements"
interface OperationStatuses {
#suppress "@azure-tools/typespec-azure-resource-manager/no-response-body" "Body of 202 is not empty: not compatible with API requirements"
@doc("Get the status of a long running azure asynchronous operation.")
@route("/subscriptions/{subscriptionId}/providers/Microsoft.AzureTerraform/operationStatuses/{operationId}")
@get
@tag("OperationStatuses")
@armResourceRead(ArmResponse<OperationStatus>)
get(
...OperationIdParameter,
...ApiVersionParameter,
...SubscriptionIdParameter,
): OperationStatus | InProgressOperationStatus | ErrorResponse;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
emit:
- "@azure-tools/typespec-autorest"
options:
"@azure-tools/typespec-autorest":
use-read-only-status-schema: true
omit-unreachable-types: true
emitter-output-dir: "{project-root}/.."
azure-resource-provider-folder: "resource-manager"
output-file: "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/export.json"
linter:
extends:
- "@azure-tools/typespec-azure-rulesets/resource-manager"
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "ExportTerraform",
"operationId": "ExportTerraform",
"parameters": {
"api-version": "2023-07-01-preview",
"subscriptionId": "00000000-0000-0000-0000-000000000000",
"exportParameter": {
"type": "ExportResourceGroup",
"resourceGroupName": "rg1"
}
},
"responses": {
"202": {
"headers": {
"Azure-AsyncOperation": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.AzureTerraform/operationStatus/00000000-0000-0000-0000-000000000000?api-version=2023-07-01-preview",
"Location": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.AzureTerraform/operationStatus/00000000-0000-0000-0000-000000000000?api-version=2023-07-01-preview"
}
}
}
}
Loading

0 comments on commit 46b3863

Please sign in to comment.