I have a solution consisting of different services I need to deploy in my Azure account:
global_params.json:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"globalParam1": {
"value": "v1"
},
"globalParam2": {
"value": "v2"
}
}
}
myservice_params.json:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"svcParam1": {
"value": "v1"
},
"svcParam2": {
"value": "v2"
},
"svcParam3": {
"value": "v3"
}
}
}
In my ARM template azuredeploy.json I need to get both groups of parameters:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"globalParam1": {...}
},
"globalParam2": {...}
},
"svcParam1": {...}
},
"svcParam2": {...}
},
"svcParam3": {...}
}
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2020-08-01",
"name": "[parameters('storageAccountName')]",
"location": "[parameters('globalParam1')]",
"sku": {
"name": "[parameters('svcParam1')]",
"tier": "[parameters('svcParam2')]"
},
"kind": "[parameters('svcParam3')]",
"properties": {
"accessTier": "[parameters('globalParam2')]"
}
}
]
}
How do I use the Azure CLI to make sure I pass parameters merged from both parameters file? I know one parameter file can be passed as follow (see doc):
az deployment group create ... --template-file ./azuredeploy.json --parameters #myservice_params.json
But how to specify two parameters files and get them merged?
The CLI (nor Azure itself) support this - you would have to do the merge yourself prior to calling into Azure.
You could use defaultValues on the parameters in the template to come close to replicating.
Although article is few months old, I tested it by adding second parameters file using #.
So command will be:
az deployment group create -g resourceGroup --template-file template.json --parameters #parameters1.json #parameters2.json
Related
I've set up the problem in the these two files. The template is simply POSTing the parameter with a fake url to check the value.
read_secret_params.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"ftpPrivateKey": {
"reference": {
"keyVault": {
"id": "/subscriptions/dummyid/resourceGroups/dummyrg/providers/Microsoft.KeyVault/vaults/myvault"
},
"secretName": "mysecret"
}
}
}
}
read_secret_template.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"ftpPrivateKey": {
"type": "securestring"
}
},
"resources": [
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2019-05-01",
"name": "read-secret",
"location": "East US",
"properties": {
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"contentVersion": "1.0.0.0",
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Week",
"interval": 1
},
"type": "Recurrence"
}
},
"actions": {
"HTTP": {
"inputs": {
"body": "[parameters('ftpPrivateKey')]",
"method": "POST",
"uri": "https://dummysite.com"
},
"runAfter": {},
"type": "Http"
}
},
"outputs": {}
},
"parameters": {}
}
}
]
}
The first issue is, when I try to deploy via the portal, no value comes thru for the parameter so it can't create it due to the validation error "Validation failed. Required information is missing or not valid.". Is this because it's not able to read the secret, permissions thing? NOTE: the key vault is also created by myself so I am the owner.
I can get around the validation error and successfully deploy by adding a default value as follows:-
"parameters": {
"ftpPrivateKey": {
"type": "securestring",
"defaultValue": "privateKeyDefault"
}
},
But when I run the logic app, it's using the default value in the POST command so it seems like it's not pulling the secret out of the key vault.
So in summary I have 2 questions:-
Has this test proved that the logic app is not reading the secret OR might it have successfully read the secret but is for some reason displaying the default value in the POST command?
If it is not reading the secret, can anyone suggest a cause + fix?
If I deploy using the Azure CLI then it works i.e. gets the secret from Azure Key Vault. If deployed in the portal then it always uses the default value.
I have managed to release secrets to my Azure key vault via CI/CD from DevOps using my arm templates. The initial release went fine and added my new non existing secrets to my key vault resource. Though men trying to update the value of the secret in my ARM template and then pushing it to my GIT-repo to in turn release it as to update my secret in azure it fails giving me:
At least one resource deployment operation failed. Please list deployment operations for
details. Please see https://aka.ms/DeployOperations for usage details.
Details:
BadRequest:
Check out the troubleshooting guide to see if your issue is addressed:
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-resource-group-deployment?view=azure-devops#troubleshooting
Task failed while creating or updating the template deployment.
My template looks like this:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"keyVault": {
"value": "test-kv-devopstest01-d"
},
"TestCedential_1": {
"value": "TestCedentialSecretValue1"
},
"TestCedentialName_1": {
"value": "TestCedentialSecretName1_SecondVersion"
}
}
}
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"keyVault": {
"type": "string"
},
"TestCedential_1": {
"type": "secureString"
},
"TestCedentialName_1": {
"type": "string"
}
},
"variables": {
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(parameters('keyVault'), '/', parameters('TestCedentialName_1'))]",
"apiVersion": "2015-06-01",
"properties": {
"contentType": "text/plain",
"value": "[parameters('TestCedential_1')]"
}
}
],
"outputs": {}
}
I've also tried granting permissions for the pipelines in access control in the key vault resource in azure.
Am i missing something maybe?
I tested the same code in my environment and it resulted in same error :
The issue is with the below :
"TestCedentialName_1": {
"value": "TestCedentialSecretName1_SecondVersion"
}
In Key vault secret '_' (underscore) is not allowed in name. The allowed values are alphanumeric characters and dashes.
Changing underscore to dash fixes the issue :
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"keyVault": {
"type": "string",
"defaultValue" :"test-kv-ansuman-d"
},
"TestCedential_1": {
"type": "secureString",
"defaultValue":"TestCedentialSecretValue1"
},
"TestCedentialName_1": {
"type": "string",
"defaultValue": "TestCedentialSecretName1-SecondVersion"
}
},
"variables": {
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(parameters('keyVault'), '/', parameters('TestCedentialName_1'))]",
"apiVersion": "2015-06-01",
"properties": {
"contentType": "text/plain",
"value": "[parameters('TestCedential_1')]"
}
}
],
"outputs": {}
}
Output:
I'm trying to make my parameter file a bit smarter but for the life of me can't figure out how to do so. I have a parameters.json file with 2 params: env & commonTags. env takes a string from my DevOps pipeline, and I need this parameter to fill a value in the commonTags-object parameter. See code snippet below:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"env": {
},
"location": {
"value": "westeurope"
},
"commonTags": {
"value": {
"contact":"dr#balloon.com",
"costcenter": "99999",
"env": "[parameters('env')]",
"criticality": "[parameters('env') == 'prd' ? 'high', 'low']"
}
}
}
}
The only other option I see is to set the env-specific parameters in the template file. Either by merging with the existing parameters or by setting the value of commonTags in the template file entirely. But I'd rather keep my template files free of parameter values and have these all located in a central parameter file.
Can anybody point me in the right direction? I can't seem to find anything online.
Many thanks!
You cannot nest parameters as you are trying to do here.
Instead, you can make use of conditional directly in your main arm template coupled with inline parameters. Let's take a simple Storage Account as an example.
azuredeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string"
},
"env": {
"type": "string"
},
"costcenter": {
"type": "string"
},
"contact": {
"type": "string"
},
"storageAccountType": {
"type": "string",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_ZRS",
"Premium_LRS"
],
"metadata": {
"description": "Storage Account type"
}
}
},
"variables": {
"storageAccountName": "[concat('store', uniquestring(resourceGroup().id))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"name": "[variables('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('storageAccountType')]"
},
"tags": {
"contact": "[parameters('contact')]",
"costcenter": "[parameters('costcenter')]",
"env": "[parameters('env')]",
"criticality": "[if(equals(parameters('env'),'prd'),'high','low')]"
},
"kind": "StorageV2"
}
]
}
azuredeploy.parameters.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountType": {
"value": "Standard_LRS"
},
"costcenter": {
"value": "99999"
},
"contact": {
"value": "dr#balloon.com"
},
"location": {
"value": "westeurope"
}
}
}
Note that the tag names remain static - there are ways to pass them inline instead/as well - see this answer.
From these, you can then use Az CLI or Powershell to deploy your template, the parameters kept in a single place and the dynamically provide the remaining one like env.
Example using Powershell :
New-AzResourceGroupDeployment -Name $deploymentName -ResourceGroupName $rgName -TemplateFile .\azuredeploy.json -TemplateParameterFile .\azuredeploy.parameters.json -env $env
I am trying to deploy Redis by the means of an ARM template and to keep the Redis hostname unique, I prepend the resource group name to it with:
"variables": {
"resourceName": "[concat(resourceGroup().id, '-', parameters('redisCacheName'))]"
},
However I suddenly get the following error, searching for which gives wildly different answers:
Deployment template validation failed: 'The template resource '/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX/resourceGroups/my-group-my-redis' for type 'Microsoft.WindowsAzure.ResourceStack.Frontdoor.Common.Entities.TemplateGenericProperty`1[System.String]' at line '1' and column '640' has incorrect segment lengths.
A nested resource type must have identical number of segments as its resource name. A root resource type must have segment length one greater than its resource name. Please see https://aka.ms/arm-template/#resources for usage details.'.
I do not understand why some "Frontdoor" is mentioned, when I am trying to deploy a Basic Redis instance and what is please the fix here?
Below is my ARM template:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"redisCacheName": {
"defaultValue": "my-redis",
"type": "String"
}
},
"variables": {
"resourceName": "[concat(resourceGroup().id, '-', parameters('redisCacheName'))]"
},
"outputs": {
"RedisCacheEndpoint": {
"type": "string",
"value": "[concat(reference(variables('resourceName')).hostName, ':', reference(variables('resourceName')).sslPort)]"
},
"RedisCachePassword": {
"type": "string",
"value": "[reference(variables('resourceName')).accessKeys.primaryKey]"
}
},
"resources": [
{
"type": "Microsoft.Cache/Redis",
"apiVersion": "2019-07-01",
"name": "[variables('resourceName')]",
"location": "[resourceGroup().location]",
"properties": {
"sku": {
"name": "Basic",
"family": "C",
"capacity": 1
},
"enableNonSslPort": false
}
}
]
}
And here is the parameters file:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"redisCacheName": {
"value": "my-redis"
}
}
}
I am trying to deploy the Redis instance into my RG called "my-group" and while deploying I use the parameter value "my-redis" -
while hoping to have a Redis endpoint with the unique name "my-group-my-redis.redis.cache.windows.net:6380" at the end.
you are using a wrong method, you should use this:
"[concat(resourceGroup().name, '-', parameters('redisCacheName'))]"
I am trying to deploy azure resources using Linked ARM template, for which i places the parameters file and template file on blob storage. Link for parameter file and blob storage i need to pass as parameter while executing the azure command from CLI. Below is my sample masterazuredeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {
"templateBaseUrl": "[parameters('templateBaseUrl')]",
"parameterBaseUrl": "[parameters('parameterBaseUrl')]",
"keyVaultDeployTemplateUrl": "[uri(variables('templateBaseUrl'), 'keyvaultdeploy.json')]"
},
"resources": [
{
"apiVersion": "[variables('apiVersionResourceDeployment')]",
"name": "keyVaultDeployment",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('keyVaultDeployTemplateUrl')]"
},
"parametersLink": {
"uri": "[variables('keyVaultparameterFileUrl')]"
}
}
}
]
}
To execute this i am giving following CLI command:
az group deployment create --resource-group abc-devops-test --template-file .\masterazuredeploy.json --parameters templateBaseUrl="https://test.blob.core
.windows.net/azurestackautomationtest/resourcetemplates/" parameterBaseUrl="https://test.blob.core.windows.net/azurestackautomationtest/parameters/dev/" --verbose
While executing i am getting following error:
unrecognized template parameter 'templateBaseUrl'. Allowed parameters:
command ran in 1.918 seconds.
I tried parameter values without inverted quotes, with single quotes. Still not working. Where exactly i am missing.
Also tried the another approach, placed both parameters in global.parameters.json as below,
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"templateBaseUrl": {
"value": "https://test.blob.core.windows.net/azurestackautomation/resourcetemplates/"
},
"parameterBaseUrl": {
"value": "https://test.blob.core.windows.net/azurestackautomation/parameters/dev/"
}
}
}
and uploaded this file to blob storage, and given path of blob storage as parameter
az group deployment create --resource-group abc-devops-test --template-file .\masterazuredeploy.json --parameters https://test.blob.core.windows.net/azur
estackautomationtest/parameters/dev/global.parameters.json --verbose
But getting below error:
400 Client Error: Bad Request for url: https://management.azure.com/subscriptions/XXXX-xx-x-x-x--x-x/resourcegroups/abc-devops-test/providers/Microsoft.Resources/deployments/masterazuredeploy?api-version=2018-05-01
command ran in 5.646 seconds.
As I see in your template, you miss setting the parameters, what you did is to input the parameter values to the parameters in the template, no matter the both CLI command you have provided. But you did not set parameters so that no parameters you can use. I suggest you change the template into below:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"templateBaseUrl": {
"type": "string"
},
"parameterBaseUrl": {
"type": "string"
}
},
"variables": {
"keyVaultDeployTemplateUrl": "[uri(parameters('templateBaseUrl'), 'keyvaultdeploy.json')]"
},
"resources": [
{
"apiVersion": "[variables('apiVersionResourceDeployment')]", #1
"name": "keyVaultDeployment",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('keyVaultDeployTemplateUrl')]"
},
"parametersLink": {
"uri": "[variables('keyVaultparameterFileUrl')]" #2
}
}
}
]
}
And you also miss setting the variables apiVersionResourceDeployment and keyVaultparameterFileUrl. You can use both parameter and variable as you like.