Update operations in Azure Api Managment with swagger link using ARM template - azure

I would like to update operation of an API with swagger link using ARM Template. When I run the below ARM Template I get the error
"error": { "code": "InvalidRequestContent", "message": "The request
content was invalid and could not be deserialized: 'Could not find
member 'dependsOn' on object of type 'DeploymentPropertiesDefinition'.
Path 'properties.dependsOn', line 1, position 734.'."
https://learn.microsoft.com/en-us/azure/templates/microsoft.apimanagement/2018-06-01-preview/service/apis
{
"$schema":
"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"ApimServiceName": {
"type": "string"
},
"swaggerjson": {"type": "string"}
},
"variables": {
},
"resources": [
{
"type": "Microsoft.ApiManagement/service/apis",
"name": "[concat(parameters('ApimServiceName'), '/animalAPI4')]",
"apiVersion": "2018-02-01-preview",
"scale": null,
"properties": {
"displayName": "HTTP animal API",
"apiRevision": "1",
"description": "API Management facade for a very handy and free online HTTP toolsds",
"serviceUrl": "https://animailhttpbin.org",
"path": "animals4",
"contentFormat": "swagger-link-json",
"contentValue": "[parameters('swaggerjson')]",
"apiVersionSet": {
"id": "[concat(resourceId('Microsoft.ApiManagement/service', parameters('ApimServiceName')), '/api-version-sets/versionset-animal-api4')]"
},
"protocols": [
"https"
],
"authenticationSettings": null,
"subscriptionKeyParameterNames": null,
"apiVersion": "v1"
},
"dependsOn": [
]
}
]
}

Figured it out the issue was with the linked template from where I was calling the bracket around properties also include dependsOn. fixed the bracket issue

Related

Get resolved ARM template after failed deployment

Is it possible to get the ARM template as it was during runtime in the Azure Portal with the variables and parameters resolved?
Example below:
AzureDeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"type": "string",
"defaultValue": "dev",
},
"storageSKU": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_RAGRS",
"Standard_ZRS",
"Premium_LRS",
"Premium_ZRS",
"Standard_GZRS",
"Standard_RAGZRS"
]
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
}
},
"variables": {
"storageAccountName": "[concat('companyname',parameters('environment'),'sa01'))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"name": "[variables('storageName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('storageSKU')]"
},
"kind": "StorageV2",
"properties": {
"supportsHttpsTrafficOnly": true
}
}
]
}
AzureDeploy.parameters.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"value": "dev"
}
}
}
If this deployment was to fail on something such as the name or the SKU, would I be able to access the portal or somehow see how these values were resolved when the script was ran?
The deployment happens in a CD pipeline in AzureDevops and I have control of the variable groups etc. so I know what is being passed in but not how it resolves. In a more complex template, I have an error claiming an Id is not set on a Logic App API connection but I cannot tell if the error is due to the variable I am using in the concat function or if the value is genuinely incorrect (resolving okay according to data passed in).
If anyone is familiar with troubleshooting these through the deployments blade in Azure then you may have some tips on how to see a more detailed view.
Thanks,
Edit:
The code below triggers Intellisense in Visual Studio 2019 but has been confirmed working during deployment. No warnings in VS Code as per comments. Majority of code omitted for brevity.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"type": "string",
"defaultValue": "dev"
},
"increment": {
"type": "string",
"defaultValue": "01"
},
"keyvaultName": {
"type": "string",
"defaultValue": "randomKeyVaultName",
"metadata": {
"description": "Keyvault Name for deployment"
}
}
},
"variables": {
"uniqueKeyVaultName": "[parameters('keyvaultName')]"
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults/secrets",
"apiVersion": "2016-10-01",
"name": "[concat(variables('uniqueKeyVaultName'), '/407045A0-1B78-47B5-9090-59C0AE9A96F6')]",
"location": "northeurope",
"dependsOn": [
"[resourceId('Microsoft.Resources/deployments', 'cosmosdb_linkedtemplate')]"
],
"properties": {
"contentType": "Graph",
"value": "[concat('{''D'': ''DatabaseName'', ''U'': ''https://randomcosmosdb-',parameters('environment'),'-cdb-',parameters('increment'),'.documents.azure.com'', ''C'': ''CollectionName'', ''K'': ''',reference('cosmosdb_linkedtemplate').outputs.accountKey.value,'''}')]",
"attributes": {
"enabled": true
}
}
}
],
"outputs": {}
}
If you want to see the evaluated template there are a few things you can do to get it without deploying:
1) call the /validate api: https://learn.microsoft.com/en-us/rest/api/resources/deployments/validate -- but you need to use an older apiVersion at the moment (e.g. 2017-05-01)... the response will contain the fully evaluated template. If you have an older version of PowerShell or the CLI, you can see the response from the rest API by using the -debug switch. But keep in mind, the more recent versions of PS/CLI will use a newer apiVersion and those don't return the full template (at this time).
2) The /whatif api will also return evaluated JSON but there's a bit more to wade through if all you're after is the evaluated template: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-deploy-what-if
Tha help?

How can I add an azure function to an API Management using ARM template

I'm using this ARM template to add an external Azure function (already defined in other template) to my API management but I get a validation error (resource is not defined in template). Is there any solution to automate mapping azure function with an API management?
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {...},
"resources": [
{
"apiVersion": "2017-03-01",
"name": "[parameters('apiManagementServiceName')]",
"type": "Microsoft.ApiManagement/service",
"location": "[parameters('location')]",
"tags": {},
"sku": {
"name": "[parameters('sku')]",
"capacity": "[parameters('skuCount')]"
},
"properties": {
"publisherEmail": "[parameters('publisherEmail')]",
"publisherName": "[parameters('publisherName')]"
}
},
{
"type": "Microsoft.ApiManagement/service/apis",
"apiVersion": "2018-06-01-preview",
"name": "[concat(parameters('apiManagementServiceName'), '/', parameters('indexerApp'))]",
"dependsOn": [
"[resourceId('Microsoft.ApiManagement/service', parameters('apiManagementServiceName'))]",
"[resourceId(resourceGroup().name, 'Microsoft.Web/sites', parameters('indexerApp'))]"
],
"properties": {
"displayName": "[parameters('indexerApp')]",
"apiRevision": "1",
"description": "Import from \"[parameters('indexerApp')]\" Function App",
"path": "[parameters('indexerApp')]",
"protocols": [
"https"
]
}
}
]
}
The resource that links directly to a Logic App, Function or other internal Azure resource is a backends (note plural):
{
"name": "string",
"type": "Microsoft.ApiManagement/service/backends",
"apiVersion": "2019-01-01",
"properties": {
"title": "string",
"description": "string",
"resourceId": "string",
"properties": {
"serviceFabricCluster": {
"clientCertificatethumbprint": "string",
"maxPartitionResolutionRetries": "integer",
"managementEndpoints": [
"string"
],
"serverCertificateThumbprints": [
"string"
],
"serverX509Names": [
{
"name": "string",
"issuerCertificateThumbprint": "string"
}
]
}
},
"credentials": {
"certificate": [
"string"
],
"query": {},
"header": {},
"authorization": {
"scheme": "string",
"parameter": "string"
}
},
"proxy": {
"url": "string",
"username": "string",
"password": "string"
},
"tls": {
"validateCertificateChain": "boolean",
"validateCertificateName": "boolean"
},
"url": "string",
"protocol": "string"
}
}
I believe that if you specify the resourceId property, the Azure infrastructure automatically wires up the other properties to your Function (or Logic App). The format of the "id" is not obvious, it expects a Management URI, the format of which is mentioned in this documentation
You then link this created backends to an operation using the operation's policy - this is a pain to express in ARM templates, but it should contain a policy expression:
<set-backend-service backend-id=\"[name of your backend]\"/>
An example of how these are linked together can be found at this linked sample. It features Service Fabric but it should be generally applicable to Functions as well.

Template deployment to Azure API management with swagger fails with 'path' must not be empty

I am trying to create an API and operations in azure API management using the swagger import feature, using a template derived from the doumentation at https://learn.microsoft.com/en-us/azure/templates/microsoft.apimanagement/2018-01-01/service/apis
Every time I deploy my API using my Azure Resource manager template to Azure API management I get the error 'path' must not be empty. What am I doing wrong? Path is definitely not empty!
For this example you can just use any valid swagger file contents such as at https://petstore.swagger.io/v2/swagger.json
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"apim_name": {
"type": "string"
},
"api_name": {
"type": "string"
},
"swagger_json": {
"type": "string"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.ApiManagement/service/apis",
"name": "[concat(parameters('apim_name'), '/' ,parameters('api_name'))]",
"apiVersion": "2018-06-01-preview",
"properties": {
"displayName": "Pet Store",
"description": "Cool api def",
"serviceUrl": "https://petstore.swagger.io/v2",
"path": "petstore",
"protocols": [
"https"
],
"authenticationSettings": {
"oAuth2": null,
"openid": null,
"subscriptionKeyRequired": true
},
"subscriptionKeyParameterNames": {
"header": "Ocp-Apim-Subscription-Key",
"query": "subscription-key"
},
"contentValue": "[parameters('swagger_json')]",
"contentFormat": "swagger-json"
}
}
]
}
It seems the API management resource manager APIs are fussy about parameters when using the swagger import feature and the docs and error messages are a little lacking.
The secret is that the swagger file definition replaces most of the properties you would normally pass for an API in the template so you need a much reduced template, as below.
Hope this helps someone else!
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"apim_name": {
"type": "string"
},
"api_name": {
"type": "string"
},
"swagger_json": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.ApiManagement/service/apis",
"name": "[concat(parameters('apim_name'), '/' ,parameters('api_name'))]",
"apiVersion": "2018-06-01-preview",
"properties": {
"path": "petstore",
"contentValue": "[parameters('swagger_json')]",
"contentFormat": "swagger-json"
}
}
]
}

Set Access key of service bus in Arm Template

I have trying to set up the access keys to an azure service bus in an azure resource manager template. No matter what I do the template ignores the keys and sets some random ones instead without giving any errors. I have the following parameters file:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environmentName": { "value": "Integration" },
"primaryKey": {
"value": "<myKey1>"
},
"secondaryKey": {
"value": "<myKey2>"
}
}
}
where myKey are substitued the real value of the keys. I also have the following template (part of it below):
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environmentName": {
"type": "string"
},
"primaryKey": {
"type": "string"
},
"secondaryKey": {
"type": "string"
}
},
"variables": {
"ServiceBus_ReadWriteKey": "[concat(parameters('environmentName'), '/ReadWrite')]",
"servicebus_namespace": "[parameters('environmentName')]",
"servicebus_topic_name": "[concat(parameters('environmentName'), '/products')]",
This is the resource that creates the access policy and should set it's keys:
{
"type": "Microsoft.ServiceBus/namespaces/AuthorizationRules",
"name": "[variables('ServiceBus_ReadWriteKey')]",
"apiVersion": "2015-08-01",
"scale": null,
"properties": {
"keyName": "ReadWrite",
"claimType": "SharedAccessKey",
"claimValue": "None",
"primaryKey": "[parameters('primaryKey')]",
"secondaryKey": "[parameters('secondaryKey')]",
"rights": [
"Listen",
"Send"
],
"revision": -1
},
"dependsOn": [
"[resourceId('Microsoft.ServiceBus/namespaces', variables('servicebus_namespace'))]"
]
},
The access policy is created, always with a random key, never the one I specified. How do I set this programmatically and what is wrong with the code above?
You are using a different api version as the sample you are using:
sample api version 2014-09-01
your api version 2015-08-01
try to change the api version to see if that causes the issue

Azure API Management ARM template: skuproperties cannot be null

I'm trying to provision the following API Management via ARM, with the following template (note specifically the apiVersion date of 2016-07-07). This results in the error:
Invalid parameter: Value cannot be null.\r\nParameter name: skuproperties
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"apimSettings": {
"type": "object",
"defaultValue": {
"sku": "Developer",
"skuCount": "1",
"publisherName": "",
"publisherEmail": ""
}
}
},
"variables": {
"apiManagementServiceName": "[concat('apim', uniqueString(resourceGroup().id))]"
},
"resources": [{
"apiVersion": "2016-07-07",
"name": "[variables('apiManagementServiceName')]",
"type": "Microsoft.ApiManagement/service",
"location": "[resourceGroup().location]",
"properties": {
"sku": {
"name": "[parameters('apimSettings').sku]",
"capacity": "[parameters('apimSettings').skuCount]"
},
"publisherEmail": "[parameters('apimSettings').publisherEmail]",
"publisherName": "[parameters('apimSettings').publisherName]"
}
}],
"outputs": {
"apimUri" : {
"type": "object",
"value": "[reference(variables('apiManagementServiceName'))]"
}
}
}
The schema for that version of API Management doesn't show 'skuProperties'. Note, the deployment works if I use the old version 2014-02-14. I also noted that the deployment template schema refers to the newer API Management schema.
Clearly it wants "skuproperties" but how would I know what to provide there?
this is how you use it:
{
"type": "Microsoft.ApiManagement/service",
"sku": {
"name": "Developer",
"capacity": 1
},
"name": "[parameters('name')]",
"apiVersion": "2016-10-10",
"location": "[parameters('location')]",
"properties": {
"publisherEmail": "[parameters('adminEmail')]",
"publisherName": "[parameters('orgName')]"
}
}
This is the description of the API Management API model. As you can see it uses 2016-10-10 and the object similar to what I've described. That's why its working that way.

Resources