Closed brynjarte closed 1 year ago
Same problem here, I have also tried to hack the schema into the state file and it does not recognise it. I am going to have to remove it from the Terraform template as an idiomatic resource and deploy it as ARM.
It seems to me the problem is not necessarilly in attaching the schema but more in creating it. When looking at a schema created through the portal (first schema) and through terraform (second schema) they look quite different.
{
"value": [
{
"id": "/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.ApiManagement/xxx/apis/xxx /schemas/602c03040b253a192c4b8ac9",
"type": "Microsoft.ApiManagement/service/apis/schemas",
"name": "602c03040b253a192c4b8ac9",
"properties": {
"contentType": "application/vnd.oai.openapi.components+json",
"document": {
"components": {
"schemas": {
"post-component-request-1": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"duration": {
"type": "integer"
},
"owner": {},
"statusID": {
"type": "integer"
}
}
}
}
}
}
}
},
{
"id": "/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.ApiManagement/service/xxx/apis/xxx /schemas/post-features-request-1",
"type": "Microsoft.ApiManagement/service/apis/schemas",
"name": "post-features-request-1",
"properties": {
"contentType": "application/vnd.oai.openapi.components+json",
"document": {
"value": "{\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"name\": {\r\n \"type\": \"string\"\r\n },\r\n \"description\": {\r\n \"type\": \"string\"\r\n },\r\n \"duration\": {\r\n \"type\": \"integer\"\r\n },\r\n \"owner\": {},\r\n \"statusID\": {\r\n \"type\": \"integer\"\r\n }\r\n }\r\n}"
}
}
}
],
"count": 2
}
Looking at the api to create apim schemas it offers two different body options properties.document.definitions
(for Swagger and OpenAPI schemas) and properties.document.value
(for everything else). The schema created through the portal is written into properties.document.definitions
and uses application/vnd.oai.openapi.components+json
as the content-type. The schema created through terraform is written into properties.document.value
and uses the content-type that is specified in the template. At least using the portal or terraform it doesn't seem possible to use a schema that is written into properties.document.value
.
It seems like the solution would be to write the definition to properties.document.definitions
if the content-type is set to application/vnd.ms-azure-apim.swagger.definitions+json
or application/vnd.oai.openapi.components+json
(or give the option to choose manually).
When attaching a schema to an opertion, it seems to not only be necessary to set the schma_id but also the type_name. Only when setting both properties to the schemaID the schema is correctly displayed in the apim dev portal.
To work around the terraform limitation in creating schemas i am now invoking the REST API directly using a local-exec provisioner. It has it's limitations, especially when deleting or updating schemas, since the dependecies to the operations using the schemas are not correctly resolved. But for the time being this was the best solution i could come up with.
resource "null_resource" "api_schema" {
for_each = fileset(local.api_schemas_folder, "*")
triggers = {
rgname = azurerm_resource_group.function.name
apimgmtname = azurerm_api_management.marble.name
apiname = azurerm_api_management_api.marble-dev-fctn.name
schema = file("${local.api_schemas_folder}/${each.key}")
}
provisioner "local-exec" {
command = <<-EOT
$ErrorActionPreference = "Stop"
az login --service-principal -u $env:ARM_CLIENT_ID -p="$env:ARM_CLIENT_SECRET" -t $env:ARM_TENANT_ID
$token = az account get-access-token --resource 'https://management.core.windows.net/' | ConvertFrom-Json
$Uri = "https://management.azure.com/subscriptions/$($env:ARM_SUBSCRIPTION_ID)/resourceGroups/${self.triggers.rgname}/providers/Microsoft.ApiManagement/service/${self.triggers.apimgmtname}/apis/${self.triggers.apiname}/schemas/${split(".", each.key)[0]}?api-version=2019-12-01"
$Body = '{
"properties": {
"contentType": "application/vnd.oai.openapi.components+json",
"document": {
"components": {
"schemas": {
"${split(".", each.value)[0]}": ${self.triggers.schema}
}
}
}
}
}'
Invoke-RestMethod -Method Put `
-Uri $Uri `
-Body $Body `
-ContentType "application/json" `
-Authentication OAuth -Token (ConvertTo-SecureString $token.accessToken -AsPlainText -Force)
EOT
interpreter = ["pwsh", "-Command"]
}
provisioner "local-exec" {
when = destroy
command = <<-EOT
$ErrorActionPreference = "Stop"
az login --service-principal -u $env:ARM_CLIENT_ID -p="$env:ARM_CLIENT_SECRET" -t $env:ARM_TENANT_ID
$token = az account get-access-token --resource 'https://management.core.windows.net/' | ConvertFrom-Json
$Uri = "https://management.azure.com/subscriptions/$($env:ARM_SUBSCRIPTION_ID)/resourceGroups/${self.triggers.rgname}/providers/Microsoft.ApiManagement/service/${self.triggers.apimgmtname}/apis/${self.triggers.apiname}/schemas/${split(".", each.key)[0]}?api-version=2019-12-01"
Invoke-RestMethod -Method Delete `
-Uri $Uri `
-Headers @{
"If-match" = "*"
} `
-Authentication OAuth -Token (ConvertTo-SecureString $token.accessToken -AsPlainText -Force)
EOT
interpreter = ["pwsh", "-Command"]
}
}
@tim-mrbl is this still relevant? Initial issue is logged against a very old provider version. If this issue still persist, would you mind opening a new one against a current version of terraform and provider? Thank you.
This is still relevant with
Terraform v1.0.4
on windows_amd64
+ provider registry.terraform.io/hashicorp/azurerm v2.72.0
However, your comment lead me to investigate this once again and looking at the provider source i think i know which changes would be necessary:
In case the contentType is application/vnd.ms-azure-apim.swagger.definitions+json
or application/vnd.oai.openapi.components+json
object
definitions
instead of valueThe source for this it the api documentation.
In addition to that I found that the import function has this differentiation, but it does not seem to work, the definitions are not imported. This has to be investigated further.
I think i will give fixing this myself a try. I have, however, never worked on a terraform provider (or Go for that matter) so we will see how far i come, but maybe i can provide a solution to this in the next couple of days.
@tim-mrbl awesome! Feel free to join our slack for any questions or discussion and let me know if I can help. Looking forward to your first PR!
I got it to work locally, it would need some polishing before i can publish ist.
While working on it i found something that i think is a problem with the underlying api. I opened a Stackoverflow question in the hope that someone has an idea whats going on there: https://stackoverflow.com/questions/68881245/openapi-type-schemas-are-written-to-the-swagger-type-field
It looks like #18394 may help. I'll have a look asap.
I am going to close this as it was opened for v1.x
(and last was an issue with v2.x
) which are no longer actively maintained and it seems the pr #18394 might have resolved this.
If this is still an issue with v3.x
of the provider please do let us know by opening a new issue, thanks!
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Community Note
Terraform (and AzureRM Provider) Version
Terraform v0.11.13
Affected Resource(s)
azurerm_api_management_api_schema
azurerm_api_management_api_operation
Terraform Configuration Files
Expected Behavior
By applying this the operation "post_new_profile" should have the schema attached to the operation.
Actual Behavior
The schema is not attached, and you will have to go into the operation and representation and add the schema manually.