Skip to content

Commit 46b3863

Browse files
gerrytanmagodo
andauthored
New RP Microsoft.AzureTerraform.Management - export Azure resources to 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 <[email protected]>
1 parent 8d5de60 commit 46b3863

File tree

18 files changed

+1134
-0
lines changed

18 files changed

+1134
-0
lines changed

cSpell.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,6 +1420,13 @@
14201420
"sfmc's"
14211421
]
14221422
},
1423+
{
1424+
"filename": "**/specification/terraform/resource-manager/Microsoft.AzureTerraform/**/*.json",
1425+
"words": [
1426+
"azurerm",
1427+
"azapi"
1428+
]
1429+
},
14231430
{
14241431
"filename": "**/specification/deviceregistry/resource-manager/Microsoft.DeviceRegistry/**/*.json",
14251432
"words": [

specification/terraform/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Override the **/terraform/** rule set at the top level to avoid relevant files getting ignored
2+
!**/*.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"title": "ExportTerraform",
3+
"operationId": "ExportTerraform",
4+
"parameters": {
5+
"api-version": "2023-07-01-preview",
6+
"subscriptionId": "00000000-0000-0000-0000-000000000000",
7+
"exportParameter": {
8+
"type": "ExportResourceGroup",
9+
"resourceGroupName": "rg1"
10+
}
11+
},
12+
"responses": {
13+
"202": {
14+
"headers": {
15+
"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",
16+
"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"
17+
}
18+
}
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"title": "Get specific operation status",
3+
"operationId": "OperationStatuses_Get",
4+
"parameters": {
5+
"subscriptionId": "00000000-0000-0000-0000-000000000000",
6+
"operationId": "00000000-0000-0000-0000-000000000000",
7+
"api-version": "2023-07-01-preview"
8+
},
9+
"responses": {
10+
"200": {
11+
"headers": {},
12+
"body": {
13+
"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",
14+
"name": "00000000-0000-0000-0000-000000000000",
15+
"startTime": "2024-07-08T08:48:46.3160075Z",
16+
"endTime": "2024-07-08T08:49:23.7083Z",
17+
"status": "Succeeded",
18+
"properties": {
19+
"configuration": "resource \"azurerm_resource_group\" \"res-0\" {\n location = \"westeurope\"\n name = \"rg1\"\n}",
20+
"errors": null,
21+
"skippedResources": null
22+
}
23+
}
24+
},
25+
"202": {
26+
"headers": {
27+
"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",
28+
"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"
29+
},
30+
"body": {
31+
"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",
32+
"name": "00000000-0000-0000-0000-000000000000",
33+
"startTime": "2024-07-08T08:48:46.3160075Z",
34+
"status": "InProgress"
35+
}
36+
}
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"title": "Get a list of operations for a resource provider",
3+
"operationId": "Operations_List",
4+
"parameters": {
5+
"subscriptionId": "12345678-1234-1234-12345678abc",
6+
"api-version": "2023-07-01-preview"
7+
},
8+
"responses": {
9+
"200": {
10+
"body": {
11+
"value": [
12+
{
13+
"name": "Microsoft.AzureTerraform/operations/read",
14+
"display": {
15+
"provider": "Microsoft AzureTerraform",
16+
"resource": "Azure Terraform Resource Provider",
17+
"operation": "ListOperations",
18+
"description": "Lists all of the available RP operations."
19+
}
20+
},
21+
{
22+
"name": "Microsoft.AzureTerraform/exportTerraform/action",
23+
"display": {
24+
"provider": "Microsoft AzureTerraform",
25+
"resource": "Azure Terraform Resource Provider",
26+
"operation": "ExportTerraform",
27+
"description": "Exports the Terraform configuration used for the specified scope."
28+
}
29+
}
30+
]
31+
}
32+
}
33+
}
34+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* PLEASE DO NOT REMOVE - USED FOR CONVERTER METRICS
3+
* Generated by package: @autorest/openapi-to-typespec
4+
* Version: 0.9.0
5+
* Date: 2024-08-30T14:24:13.436Z
6+
*/
7+
import "@typespec/rest";
8+
import "@typespec/versioning";
9+
import "@azure-tools/typespec-azure-core";
10+
import "@azure-tools/typespec-azure-resource-manager";
11+
import "./models.tsp";
12+
import "./routes.tsp";
13+
14+
using TypeSpec.Rest;
15+
using TypeSpec.Http;
16+
using Azure.ResourceManager.Foundations;
17+
using Azure.Core;
18+
using Azure.ResourceManager;
19+
using TypeSpec.Versioning;
20+
21+
@doc("The Azure Terraform management API provides a RESTful set of web services that used to manage your Azure Terraform resources.")
22+
@armProviderNamespace
23+
@service({
24+
title: "AzureTerraformResourceProviderClient",
25+
})
26+
@versioned(Versions)
27+
@armCommonTypesVersion(Azure.ResourceManager.CommonTypes.Versions.v5)
28+
namespace Microsoft.AzureTerraform;
29+
30+
@doc("The available API versions.")
31+
enum Versions {
32+
@doc("The 2023-07-01-preview API version.")
33+
@useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1)
34+
@useDependency(Azure.Core.Versions.v1_0_Preview_1)
35+
v2023_07_01_preview: "2023-07-01-preview",
36+
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import "@typespec/rest";
2+
import "@typespec/http";
3+
import "@azure-tools/typespec-azure-resource-manager";
4+
5+
using TypeSpec.Rest;
6+
using TypeSpec.Http;
7+
using Azure.ResourceManager;
8+
using Azure.ResourceManager.Foundations;
9+
using OpenAPI;
10+
11+
namespace Microsoft.AzureTerraform;
12+
13+
interface Operations extends Azure.ResourceManager.Operations {}
14+
15+
@doc("The parameter type")
16+
union Type {
17+
string,
18+
ExportResource: "ExportResource",
19+
ExportResourceGroup: "ExportResourceGroup",
20+
ExportQuery: "ExportQuery",
21+
}
22+
23+
@doc("The target Azure Terraform Provider")
24+
union targetProvider {
25+
string,
26+
27+
@doc("https://registry.terraform.io/providers/hashicorp/azurerm/latest")
28+
azurerm: "azurerm",
29+
30+
@doc("https://registry.terraform.io/providers/Azure/azapi/latest")
31+
azapi: "azapi",
32+
}
33+
34+
@doc("The base export parameter")
35+
@discriminator("type")
36+
model BaseExportModel {
37+
@doc("The parameter type")
38+
type: Type;
39+
40+
@doc("The target Azure Terraform Provider")
41+
targetProvider?: targetProvider = targetProvider.azurerm;
42+
43+
@doc("Whether to output all non-computed properties in the generated Terraform configuration? This probably needs manual modifications to make it valid")
44+
fullProperties?: boolean = true;
45+
46+
@doc("Mask sensitive attributes in the Terraform configuration")
47+
maskSensitive?: boolean = true;
48+
}
49+
50+
@doc("Export parameter for resources queried by ARG (Azure Resource Graph)")
51+
model ExportQuery extends BaseExportModel {
52+
@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\"`")
53+
query: string;
54+
55+
@doc("The name pattern of the Terraform resources")
56+
namePattern?: string = "res-";
57+
58+
@doc("Whether to recursively list child resources of the query result")
59+
recursive?: boolean = false;
60+
61+
@doc("The parameter type")
62+
type: "ExportQuery";
63+
}
64+
65+
@doc("Export parameter for individual resources.")
66+
model ExportResource extends BaseExportModel {
67+
@doc("The id of the resource to be exported")
68+
resourceIds: string[];
69+
70+
@doc("The Terraform resource name. Only works when `resourceIds` contains only one item.")
71+
resourceName?: string = "res-0";
72+
73+
@doc("The Terraform resource type. Only works when `resourceIds` contains only one item.")
74+
resourceType?: string;
75+
76+
@doc("The name pattern of the Terraform resources")
77+
namePattern?: string = "res-";
78+
79+
@doc("The parameter type")
80+
type: "ExportResource";
81+
}
82+
83+
@doc("Export parameter for a resource group")
84+
model ExportResourceGroup extends BaseExportModel {
85+
@doc("The name of the resource group to be exported")
86+
resourceGroupName: string;
87+
88+
@doc("The name pattern of the Terraform resources")
89+
namePattern?: string = "res-";
90+
91+
@doc("The parameter type")
92+
type: "ExportResourceGroup";
93+
}
94+
95+
@doc("The status of the LRO operation.")
96+
model OperationStatus {
97+
@doc("The operation status resource id.")
98+
id?: string;
99+
100+
@doc("The fully qualified resource id of the resource for which the operation was performed.")
101+
@visibility("read")
102+
resourceId?: string;
103+
104+
@doc("The operation name.")
105+
name?: string;
106+
107+
@doc("The start time of the operation.")
108+
@visibility("read")
109+
startTime?: utcDateTime;
110+
111+
@doc("The end time of the operation.")
112+
@visibility("read")
113+
endTime?: utcDateTime;
114+
115+
@doc("The status of the operation.")
116+
status?: string;
117+
118+
@doc("The progress percentage of the operation, ranges from 0 to 100")
119+
percentComplete?: float64;
120+
121+
@doc("The Terraform export result")
122+
properties?: ExportResult;
123+
124+
...ErrorResponse;
125+
}
126+
127+
model InProgressOperationStatus
128+
is ArmAcceptedResponse<
129+
"InProgress operation status",
130+
ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader
131+
> {
132+
...OperationStatus;
133+
}
134+
135+
@doc("The Terraform export result")
136+
model ExportResult {
137+
@doc("The Terraform configuration content")
138+
configuration?: string;
139+
140+
@doc("A list of Azure resources which are not exported to Terraform due to there is no corresponding resources in Terraform")
141+
skippedResources?: string[];
142+
143+
@doc("A list of errors derived during exporting each resource")
144+
@extension("x-ms-identifiers", [])
145+
errors?: ErrorDetail[];
146+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import "@azure-tools/typespec-azure-core";
2+
import "@typespec/rest";
3+
import "./models.tsp";
4+
import "@azure-tools/typespec-azure-resource-manager";
5+
6+
using TypeSpec.Rest;
7+
using TypeSpec.Http;
8+
using Azure.ResourceManager;
9+
using Azure.ResourceManager.Foundations;
10+
using OpenAPI;
11+
12+
namespace Microsoft.AzureTerraform;
13+
14+
#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-operation" "Cannot use @armResourceOperations decorator here, the auto-generated routes do not match feature requirements"
15+
#suppress "@azure-tools/typespec-azure-core/no-openapi" "TODO: migrate to LRO concepts DO NOT USE x-ms-long-running-operation-options"
16+
@doc("Exports the Terraform configuration of the specified resource(s).")
17+
@route("/subscriptions/{subscriptionId}/providers/Microsoft.AzureTerraform/exportTerraform")
18+
@post
19+
@tag("ExportTerraform")
20+
@extension(
21+
"x-ms-long-running-operation-options",
22+
{
23+
`final-state-via`: "azure-async-operation",
24+
`final-state-schema`: "#/definitions/OperationStatus",
25+
}
26+
)
27+
op exportTerraform(
28+
...ApiVersionParameter,
29+
...SubscriptionIdParameter,
30+
31+
@doc("The export parameter")
32+
@body
33+
exportParameter: BaseExportModel,
34+
): ArmAcceptedLroResponse<
35+
"Export request accepted.",
36+
ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader
37+
> | ErrorResponse;
38+
39+
#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"
40+
interface OperationStatuses {
41+
#suppress "@azure-tools/typespec-azure-resource-manager/no-response-body" "Body of 202 is not empty: not compatible with API requirements"
42+
@doc("Get the status of a long running azure asynchronous operation.")
43+
@route("/subscriptions/{subscriptionId}/providers/Microsoft.AzureTerraform/operationStatuses/{operationId}")
44+
@get
45+
@tag("OperationStatuses")
46+
@armResourceRead(ArmResponse<OperationStatus>)
47+
get(
48+
...OperationIdParameter,
49+
...ApiVersionParameter,
50+
...SubscriptionIdParameter,
51+
): OperationStatus | InProgressOperationStatus | ErrorResponse;
52+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
emit:
2+
- "@azure-tools/typespec-autorest"
3+
options:
4+
"@azure-tools/typespec-autorest":
5+
use-read-only-status-schema: true
6+
omit-unreachable-types: true
7+
emitter-output-dir: "{project-root}/.."
8+
azure-resource-provider-folder: "resource-manager"
9+
output-file: "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/export.json"
10+
linter:
11+
extends:
12+
- "@azure-tools/typespec-azure-rulesets/resource-manager"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"title": "ExportTerraform",
3+
"operationId": "ExportTerraform",
4+
"parameters": {
5+
"api-version": "2023-07-01-preview",
6+
"subscriptionId": "00000000-0000-0000-0000-000000000000",
7+
"exportParameter": {
8+
"type": "ExportResourceGroup",
9+
"resourceGroupName": "rg1"
10+
}
11+
},
12+
"responses": {
13+
"202": {
14+
"headers": {
15+
"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",
16+
"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"
17+
}
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)