How to check if name already exists? Azure Ressource Manager Template - json

is it possible to check, in an ARM Template, if the name for my Virtual Machine already exists?
I am developing a Solution Template for the Azure Marketplace. Maybe it is possible to set a paramter in the UiDefinition uniqe?
The goal is to reproduce this green Hook

A couple notes...
VM Names only need to be unique within a resourceGroup, not within the subscription
Solution Templates must be deployed to empty resourceGroups, so collisions with existing resources aren't possible
For solution templates the preference is that you simply name the VMs for the user, rather than asking - use something that is appropriate for the workload (e.g. jumpbox) - not all solutions do this but we're trying to improve that experience
Given that it's not likely we'll ever build a control that checks for naming collisions on resources without globally unique constraints.
That help?

This looks impossible, according to the documentation.
There are no validation scenarious.

I assume that you should be using the Microsoft.Common.TextBox UI element in your createUiDefinition.json.
I have tried to reproduce a green check by creating a simple createUiDefinition.json as below with a Microsoft.Common.TextBox UI element as shown below.
{
"$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json",
"handler": "Microsoft.Compute.MultiVm",
"version": "0.1.2-preview",
"parameters": {
"basics": [
{
"name": "textBoxA",
"type": "Microsoft.Common.TextBox",
"label": "VM Name",
"defaultValue": "",
"toolTip": "Please enter a VM name",
"constraints": {
"required": true
},
"visible": true
}
],
"steps": [],
"outputs": {}
}
}
I am able to reproduce the green check beside the VM Name textbox as shown below:
However, this green check DOES NOT imply the VM Name is Available.
This is because based on my testing, even if I use an existing VM Name in the same subscription, it is still showing the green check.
Based on the official documented constraints that are supported by the Microsoft.Common.TextBox UI element, it DOES NOT VALIDATE Name Availability.
Hope this helps!

While bmoore's point is correct that it's unlikely you would ever need this for a VM (nor is there an API for it), there are other compute resources that do have global naming requirements.
As of 2022 this concept is possible now with the use of the ArmApiControl UI element. It allows you to call ARM apis as part of validation in the createUiDefinition.json. Here is an example using the check name API for an Azure App service.
{
"$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
"handler": "Microsoft.Azure.CreateUIDef",
"version": "0.1.2-preview",
"parameters": {
"basics": [
{}
],
"steps": [
{
"name": "domain",
"label": "Domain Names",
"elements": [
{
"name": "domainInfo",
"type": "Microsoft.Common.InfoBox",
"visible": true,
"options": {
"icon": "Info",
"text": "Pick the domain name that you want to use for your app."
}
},
{
"name": "appServiceAvailabilityApi",
"type": "Microsoft.Solutions.ArmApiControl",
"request": {
"method": "POST",
"path": "[concat(subscription().id, '/providers/Microsoft.Web/checknameavailability?api-version=2021-02-01')]",
"body": "[parse(concat('{\"name\":\"', concat('', steps('domain').domainName), '\", \"type\": \"Microsoft.Web/sites\"}'))]"
}
},
{
"name": "domainName",
"type": "Microsoft.Common.TextBox",
"label": "Domain Name Word",
"toolTip": "The name of your app service",
"placeholder": "yourcompanyname",
"constraints": {
"validations": [
{
"regex": "^[a-zA-Z0-9]{4,30}$",
"message": "Alphanumeric, between 4 and 30 characters."
},
{
"isValid": "[not(equals(steps('domain').appServiceAvailabilityApi.nameAvailable, false))]",
"message": "[concat('Error with the url: ', steps('domain').domainName, '. Reason: ', steps('domain').appServiceAvailabilityApi.reason)]"
},
{
"isValid": "[greater(length(steps('domain').domainName), 4)]",
"message": "The unique domain suffix should be longer than 4 characters."
},
{
"isValid": "[less(length(steps('domain').domainName), 30)]",
"message": "The unique domain suffix should be shorter than 30 characters."
}
]
}
},
{
"name": "section1",
"type": "Microsoft.Common.Section",
"label": "URLs to be created:",
"elements": [
{
"name": "domainExamplePortal",
"type": "Microsoft.Common.TextBlock",
"visible": true,
"options": {
"text": "[concat('https://', steps('domain').domainName, '.azurewebsites.net - The main app service URL')]"
}
}
],
"visible": true
}
]
}
],
"outputs": {
"desiredDomainName": "[steps('domain').domainName]"
}
}
}
You can copy the above code and test it in the createUiDefinition.json sandbox azure provides.

Related

ARM template for Data Factory connector in Logic Apps with Managed Identity

I have a Logic App that uses the Azure Data Factory action "Create a pipeline run" that works perfectly.
This is how the Logic App looks like
The authentication method to Azure Data Factory that I use is "System assigned" managed identity.
After creating and testing the Logic App, I now want to create an ARM template to save it in the code repository for deployment, however I'm struggling to get the authentication part of the ARM template to work. I'm not sure how the syntax should be and I don't find anything in the Microsoft documentation.
In the Logic App resource I have added:
"identity": {
"type": "SystemAssigned"
}
This is how the connections part of the Logic app resource looks like:
"$connections": {
"value": {
"azuredatafactory": {
"connectionId": "[parameters('connections_azuredatafactory_externalid')]",
"connectionName": "[parameters('connections_azuredatafactory_name')]",
"connectionProperties": {
"authentication": {
"type": "ManagedServiceIdentity"
}
},
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/francecentral/managedApis/azuredatafactory')]"
}
}
}
And this is how the connector resource look like (I think I'm missing something here (?)):
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[parameters('connections_azuredatafactory_name')]",
"location": "francecentral",
"kind": "V1",
"properties": {
"displayName": "[parameters('connections_azuredatafactory_displayname')]",
"alternativeParameterValues": {},
"parameterValueSet": {
"name": "managedIdentityAuth",
"values": {}
},
"statuses": [
{
"status": "Ready"
}
],
"api": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/francecentral/managedApis/azuredatafactory')]"
}
}
}
The error message I get when trying to deploy this through Visual studio 2022 is:
Template deployment returned the following errors:
Resource Microsoft.Logic/workflows 'logic-d365-dwh-01-ip-dev-rxlse' failed with message '{
"error": {
"code": "WorkflowManagedIdentityConfigurationInvalid",
"message": "The workflow connection parameter 'azuredatafactory' is not valid. The API connection 'azuredatafactory' is not configured to support managed identity."
}
}'
Anyone who knows what the problem could be?
1)I have created azure logic App with 3 actions (http request, create ADF pipeline, response).
Here is the reference image:
2)Then to connect to ADF used system assigned managed identity & I have given access for logic App to create pipeline in ADF.
Here is the reference image:
Then I have tested in portal & it is succussed
Then I have exported ARM Template & downloaded.
Then in visual studio I have created new project of type Azure resource group then I have edited logicapp.json & logic app parameters file based on template.
Then I have deployed it and it is succussed.
ARM template code which I have used for reference:
{
"$schema": "[https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#"](https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#%22 "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#%22"),
"contentVersion": "1.0.0.0",
"parameters": {
"workflows_so1LP_name": {
"defaultValue": "so1LP",
"type": "String"
},
"connections_azuredatafactory_1_externalid": {
"defaultValue": "/subscriptions/<subscription-id>/resourceGroups/so1/providers/Microsoft.Web/connections/azuredatafactory-1",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2017-07-01",
"name": "[parameters('workflows_so1LP_name')]",
"location": "centralus",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"state": "Enabled",
"definition": {
"$schema": "[https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#"](https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#%22 "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#%22"),
"contentVersion": "1.0.0.0",
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"type": "Request",
"kind": "Http",
"inputs": {}
}
},
"actions": {
"Create_a_pipeline_run": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azuredatafactory_1']['connectionId']"
}
},
"method": "post",
"path": "/subscriptions/#{encodeURIComponent('<subscription id>')}/resourcegroups/#{encodeURIComponent('so1')}/providers/Microsoft.DataFactory/factories/#{encodeURIComponent('sodf1')}/pipelines/#{encodeURIComponent('sopipeline')}/CreateRun",
"queries": {
"x-ms-api-version": "2017-09-01-preview"
}
}
},
"Response": {
"runAfter": {
"Create_a_pipeline_run": [
"Succeeded"
]
},
"type": "Response",
"kind": "Http",
"inputs": {
"statusCode": 200
}
}
},
"outputs": {}
},
"parameters": {
"$connections": {
"value": {
"azuredatafactory_1": {
"connectionId": "[parameters('connections_azuredatafactory_1_externalid')]",
"connectionName": "azuredatafactory-1",
"connectionProperties": {
"authentication": {
"type": "ManagedServiceIdentity"
}
},
"id": "/subscriptions/<subscription-id>/<Subscriotion id>providers/Microsoft.Web/locations/centralus/managedApis/azuredatafactory"
}
}
}
}
}
}
],
"outputs": {}
}
Here is the reference image:
NOTE: I am using free subscription, so I don't have any restrictions but, in your case, maybe you have some restrictions that's why maybe your facing issue.
The second reasons may be your using system assigned access after creating logic app to give access to ADF & once check are you giving managed identity after creating ADF give access to logic app also. so maybe you are skipping one of managed identity that's why getting error in ARM template deployment. So, give access to both from ADF to logic app and logic app to ADF.
Here are some images for reference for logic app to ADF:
Go to "access control" of logic app.
Select owner as role.
Select managed identity as data factory.
Here are some images for reference for ADF to logic app:
Go to "access control" of data factory.
Select owner as role.
Select managed identity as logic app.
Did you try using "parameterValueType": "Alternative" instead of "parameterValueSet"?
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[parameters('connections_azuredatafactory_name')]",
"location": "francecentral",
"kind": "V1",
"properties": {
"displayName": "[parameters('connections_azuredatafactory_displayname')]",
"customParameterValues": {},
"parameterValueType": "Alternative"
"api": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/francecentral/managedApis/azuredatafactory')]"
}
}
}

Require Input.Toggle's to be Checked True Before Submitting?

I have the following adaptive card JSON code that has three Input.Toggle's. Is there a way to throw an error when the user clicks "Submit" and all three Input.Toggle's are not set to true? I saw in the Schema Explorer (Schema Explorer Input.Toggle) that they have Inherited properties called "fallback" and "requires", is that what I need? If so, how do I implement "fallback" and "requires" into this JSON code?
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.2",
"body": [
{
"placeholder": "1.1 Business Office Coordinator - RFQ Receipt",
"type": "Input.Text",
"id": "Title"
},
{
"text": "Quote ##{body('Get_response_details')?['b194cde8837234ccc80fu5017c1b0f869']} ",
"type": "TextBlock",
"id": "textBlock1"
},
{
"type": "Input.Toggle",
"title": "Customer Acknowledgement",
"valueOn": "custYes",
"valueOff": "custNo",
"id": "Customer"
},
{
"type": "Input.Toggle",
"title": "Create RFQ Log Number and Enter Information into RFQ Log",
"valueOn": "RFQYes",
"valueOff": "RFQNo",
"id": "RFQ"
},
{
"type": "Input.Toggle",
"title": "Populate Quote Folder with Customer Data",
"valueOn": "PopulateYes",
"valueOff": "PopulateNo",
"id": "Populate"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Submit",
"data": {
"id": "9876543210"
}
}
]
}
this is part of input validation which as of today is not available yet.
I'm afraid what you're asking for is not possible right now but will hopefully be soon.
You can follow the feature request here: https://portal.productboard.com/adaptivecards/1-adaptive-cards-features/c/21-input-validation-and-evolution , add your own vote to it aswell if you want to.
Depending on where you use the card however, you can get this working. In MS Teams you could verify the card submission in your own code and return an error. Its not client side but that way you can still do the check.

How to create new alerts in azure for all webapps at same time

I want to create new alerts(High CPU,RAM) for all AppServicePlans in a given subscription. I could not find Powershell commands to create new alerts. Is there a way we can create these alerts for all appserviceplans with a single script? May be using ARM template?
Sorry for pasting a direct answer, but I cannot yet comment. You get the error because in the documentation for Add-AzMetricAlertruleV2 it states: "$act is the output of New-AzActionGroup cmdlet". Meaning you need to use for example:
$act = New-AzActionGroup -ActionGroupId "testActionGroup"
After that you need to add it in the parameter -ActionGroup $act for it to work.
If you look at Resource Explorer and navigate to a manually created (near-realtime) alert, you should see the "critera" object defined like below. Here is a full example of a resource that seems to be working. Create some variables for each of your values:
{
"type": "Microsoft.Insights/metricAlerts",
"apiVersion": "2018-03-01",
"name": "[variables('alertName')]",
"location": "global",
"dependsOn": [],
"tags": {
"[concat('hidden-link:', variables('applicationInsightsResourceId'))]": "Resource",
"[concat('hidden-link:', variables('webtestResourceId'))]": "Resource"
},
"properties": {
"description": "[concat('Alert for ', parameters('availibilityTestName'))]",
"severity": 4,
"enabled": true,
"scopes": [
"[variables('webtestResourceId')]",
"[variables('applicationInsightsResourceId')]"
],
"evaluationFrequency": "PT5M",
"windowSize": "PT15M",
"criteria": {
"odata.type": "Microsoft.Azure.Monitor.WebtestLocationAvailabilityCriteria",
"webTestId": "[variables('webtestResourceId')]",
"componentId": "[variables('applicationInsightsResourceId')]",
"failedLocationCount": 3
},
"actions": [
{
"actionGroupId": "[resourceId('microsoft.insights/actiongroups', 'webhook')]",
"webHookProperties": {
// Some properties to send to webhook
}
}
]
}
}

Orion CB output regarding provisioned device

I have noticed that upon querying Orion CB, while it is working with provisioned devices and having IoT Agent receive HTTP and MQTT messages, it will always output all the values written in the quotation marks:
{
"id": "sensor_data",
"type": "Sensor",
"ActiveTime": {
"type": "Seconds",
"value": "17703",
"metadata": {
"TimeInstant": {
"type": "ISO8601",
"value": "2018-07-04T13:32:27.357Z"
}
}
},
"Distance": {
"type": "Number",
"value": "312",
"metadata": {
"TimeInstant": {
"type": "ISO8601",
"value": "2018-07-04T13:32:27.413Z"
}
}
}
}
However, if to work with only entities in Orion CB, it is possible to receive actual values (like in the example in the manual):
{
"id": "Room1",
"pressure": {
"metadata": {},
"type": "Integer",
"value": 720
},
"temperature": {
"metadata": {},
"type": "Float",
"value": 23
},
"type": "Room"
}
Sometimes, I need to receive the actual value from my sensor in order to format it and use in further applications, but they are in quotation marks, which makes it a little difficult.
Is it possible to somehow change?(maybe in device provisioning), or it really should be that way regarding devices?
Thanks in advance!
EDIT 1
This is the way I provisioned the device:
{
"devices": [
{
"device_id": "sensor_data",
"entity_name": "sensor_data",
"entity_type": "Sensor",
"transport": "MQTT",
"timezone": "Europe/Helsinki",
"attributes": [
{ "object_id": "act", "name": "ActiveTime", "type": "Seconds"},
{ "object_id": "dst", "name": "Distance", "type": "Number"}
]
}
]
}
And this is how the MQTT messages are sent from my sensor (I have set up the topics for IoT Agent to understand them)
/123456789/sensor_data/attrs/act 12
/123456789/sensor_data/attrs/dst 322
123456789 is the API Key I have set here.
This situation tipycally happens when IoT Agents uses NGSIv1 to push data to Context Broker, given that NGSIv1 always "string-fy" any attribute value. Recently, the ability to use NGSIv2 (which doesn't have this limitatino) was introduced in IoT Agents.
In order to solve your problem you have to:
Use a recent IOTA-UL version (the current one from master branch will work)
Enable NGSIv2 in configuration as explained in documentation. This is done in the config.js file:
config.iota = {
...
contextBroker: {
...
ngsiVersion: 'v2'
}
...
}
or using environament variable IOTA_CB_NGSI_VERSION=v2 for the IOTA-UL process.
Enable autocast as explained in documentation. This is done in config.js file:
config.iota = {
...
autocast: true,
...
}
or using environament variable IOTA_AUTOCAST=true for the IOTA-UL process.
Set the right type for each attribute at provision time. The documentation here) provides the right types:
Type "Number" for integer or float numbers
Type "Boolean" for boolean
Type "None" for null
Thus, in your case the provisioning for Distance is ok, but for ActiveTime you should use also Number as type.

ARM Error: The Template Resource is not found using resource(), copyIndex()

I'm trying to conditionally provide resource property values through translation of runtime resource properties within a copyIndex loop..
Upon deploying the following ARM template, I receive the error:
Unable to process template language expressions for resource '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Compute/virtualMachines/{vm-name}/extensions/Microsoft.EnterpriseCloud.Monitoring' at line '30' and column '10'. 'The template resource '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Compute/virtualMachines/{vm-name}' is not found.' (Code: InvalidTemplate)
"type": "[variables('extensionType')[reference(concat('Microsoft.Compute/virtualMachines/', parameters('virtualMachines')[copyIndex()].name)).storageProfile.osDisk.osType]]",
However, the VM exists with the ID it provides, so it doesn't make sense that the engine cannot find it. If I hard-code the Extension Type, there are no errors and the Extension is installed on the VM with the same ID.
Unfortunately, I don't know if this is a bug within ARM or if I'm just doing something wrong..
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspaceResourceId": { "type": "string" },
"virtualMachines": { "type": "array" }
},
"variables": {
"extensionType": {
"Windows": "MicrosoftMonitoringAgent",
"Linux": "OmsAgentForLinux"
}
},
"resources": [
{
"copy": {
"name": "VMMonitoringExtensionsCopy",
"count": "[length(parameters('virtualMachines'))]"
},
"type": "Microsoft.Compute/virtualMachines/extensions",
"apiVersion": "2015-05-01-preview",
"location": "[parameters('virtualMachines')[copyIndex()].location]",
"name": "[concat(parameters('virtualMachines')[copyIndex()].name, '/Microsoft.EnterpriseCloud.Monitoring')]",
"properties": {
"publisher": "Microsoft.EnterpriseCloud.Monitoring",
"type": "[variables('extensionType')[reference(concat('Microsoft.Compute/virtualMachines/', parameters('virtualMachines')[copyIndex()].name)).storageProfile.osDisk.osType]]",
"typeHandlerVersion": "1.0",
"autoUpgradeMinorVersion": true,
"settings": {
"workspaceId": "[reference(parameters('workspaceResourceId'), '2015-11-01-preview').customerId]"
},
"protectedSettings": {
"workspaceKey": "[listKeys(parameters('workspaceResourceId'), '2015-11-01-preview').primarySharedKey]"
}
}
}
]
}
The object array being passed in for virtualMachines looks like this:
[
{ "name": "vm-name", "location": "azure-region" }
]
A couple things you can try:
1) Assuming the VM is not defined in the same template try using the "full" resourceId in the reference function. See the last example in this doc:
https://azure.microsoft.com/en-us/documentation/articles/resource-group-template-functions/#reference - it seems like the error already knows the full resourceId, but it's worth trying
2) the other thought is that the reference function is evaluated at runtime and the resource provider doesn't like the expression but that's a swag.
I will do some more poking and see if we can't nail this down.