Unable to pass secure values between linked ARM templates - azure

I am trying to output a secret created in one linked template and reference this as a parameter in another.
Test scenario:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"templateBaseUrl": {
"type": "string"
}
},
"variables": {
"deployment1url": "[concat(parameters('templateBaseUrl'), '/deployment1.json')]",
"deployment2url": "[concat(parameters('templateBaseUrl'), '/deployment2.json')]"
},
"resources": [
{
"apiVersion": "2017-08-01",
"name": "deployment1",
"dependsOn": [],
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('deployment1url')]",
"contentVersion": "1.0.0.0"
},
"parameters": {}
}
},
{
"apiVersion": "2017-08-01",
"name": "deployment2",
"dependsOn": [],
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('deployment2url')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"testInput2": {
"value": "[reference('deployment1').outputs.testOutput1.value]"
}
}
}
}
],
"outputs": {}
}
Deployment1:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
},
"resources": [],
"outputs": {
"testOutput1": {
"type": "securestring",
"value": "thisisapassword"
}
}
}
Deployment2:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"testInput2": {
"type": "securestring"
}
},
"resources": [],
"outputs": {}
}
Running this scenario throws the error
"Unable to process template language expressions for resource
'/subscriptions//resourceGroups/testrg1/providers/Microsoft.Resources/deployments/deployment2' at line '34' and column '9'.
'The language expression property 'value' doesn't exist, available properties are 'type'.'"
So '.value' on the securestring output doesn't work, if I change the reference parameter to
"testInput2": {
"value": "[reference('deployment1').outputs.testOutput1]"
}
the errors changes to 'Deployment template validation failed: 'The provided value for the template parameter 'testInput2' at line '5' and column '23' is not valid.'.'
Is it possible to achieve what I am doing?
Thanks in advance

I think the only way to pass secureStrings across deployments is using a KeyVault reference. The secureString output isn't very useful in that securestrings are masked by ARM at the deployment level.
That help?

Related

Can output of an ARM template be used in another template as a reference which is not called as nested?

I'm trying to use different templates for creating a NSG and then for a spoke. I don't want to use nested template, instead I want the out of NSG template as resource ID and give reference to spoke template as a parameter. Can this be achieved or is it just the case for nested template also the parameters in the spoke template where NSG resource ID is needed is in a array as I have used copy function.
"outputs": {"resourceID": {
"type": "string",
"value": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]"}}
This output is to be used here
"subnetsConfiguration": {
"value": [
{
"name": "app-subnet",
"addressPrefix": "10.112.0.0/20",
"networkSecurityGroupName": "set the resource ID as a reference here",
To get an output value from a linked template, retrieve the property value with syntax like: [reference('deploymentName').outputs.propertyName.value]
First, the linked template- helloworld.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [],
"outputs": {
"greetingMessage": {
"value": "Hello World",
"type" : "string"
}
}
}
The main template deploys the linked template and gets the returned value -
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-06-01",
"name": "linkedTemplate",
"properties": {
"mode": "incremental",
"templateLink": {
"uri": "[uri(deployment().properties.templateLink.uri, 'helloworld.json')]",
"contentVersion": "1.0.0.0"
}
}
}
],
"outputs": {
"messageFromLinkedTemplate": {
"type": "string",
"value": "[reference('linkedTemplate').outputs.greetingMessage.value]"
}
}
}
Please refer this documentation for more details.

location property is not allowed for a deployment at resource group scope

I created linked ARM template and trying to deploy but I am getting below error.
I am deploying Sql Server and Server Database using linked templates. Individual ARM (Sql Server and sql database is working fine).
Error: InvalidDeployment;
Message=The 'location' property is not allowed for a deployment at resource
group scope. Please see https://aka.ms/deploy-to-subscription for usage
details.
If I remove location and trying to deploy I am getting below error.
The location property is required for this definition
Is my mistake is in Schema version or api version or something?
New-AzResourceGroupDeployment -Name "ARMLinkedDeployment" -ResourceGroupName "Test-POC-RG" -TemplateFile ".......\MainTemplates\SqlApp\azuredeploy.json" -TemplateParameterFile ".....\MainTemplates\SqlApp\parameters.json"
parameters.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"sqlserver_linkedTemplatepath": {
"value": "https://stvirtuosotest.blob.core.windows.net/armlinkedtemplates/azuredeploysql.json"
},
"sqldb_linkedTemplatepath": {
"value": "https://stvirtuosotest.blob.core.windows.net/armlinkedtemplates/azuredeploysqldb.json"
},
"sqlserver_parameters_linkedTemplatepath": {
"value": "https://stvirtuosotest.blob.core.windows.net/armlinkedtemplates/azuredeploy.sqlparameters.json"
},
"sqldb_parameters_linkedTemplatepath": {
"value": "https://stvirtuosotest.blob.core.windows.net/armlinkedtemplates/azuredeploy.sqldbparameters.json"
}
}
}
azuredeploy.json file
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"sqlserver_linkedTemplatepath": {
"type": "string",
"metadata": {
"description": "The sql server arm template json file path from storage account.."
}
},
"sqldb_linkedTemplatepath": {
"type": "string",
"metadata": {
"description": "The sql database deploy arm template json file path from storage account."
}
},
"sqldb_parameters_linkedTemplatepath": {
"type": "string",
"metadata": {
"description": "The sql database arm parameters file json file path from storage account."
}
},
"sqlserver_parameters_linkedTemplatepath": {
"type": "string",
"metadata": {
"description": "The sql server arm parameters json file path from storage account."
}
}
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-06-01",
"name": "sqlDbDeployment",
"resourceGroup": "[resourceGroup().name]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[parameters('sqldb_linkedTemplatepath')]",
"contentVersion": "1.0.0.0"
},
"parametersLink": {
"contentVersion": "1.0.0.0",
"uri": "[parameters('sqldb_parameters_linkedTemplatepath')]"
}
},
"dependsOn": [
"sqlServerDeployment"
]
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-06-01",
"name": "sqlServerDeployment",
"resourceGroup": "[resourceGroup().name]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[parameters('sqlserver_linkedTemplatepath')]",
"contentVersion": "1.0.0.0"
},
"parametersLink": {
"contentVersion": "1.0.0.0",
"uri": "[parameters('sqlserver_parameters_linkedTemplatepath')]"
}
}
}
],
"outputs": {
"sqldbresourceid": {
"type": "object",
"value": "[reference('sqlDbDeployment').outputs.resourceGroup.resourceId]"
},
"sqlserverresourceid": {
"type": "object",
"value": "[reference('sqlServerDeployment').outputs.resourceGroup.resourceId]"
}
}
}
Here is how I fixed the same issue.
parameters.json file
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"value": "eastus2"
}
}
}
azuredeploy.json file
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2021-04-01",
"name": "deployment1",
"resourceGroup": "[resourceGroup().name]",
"properties": {
"mode": "Incremental",
"templateLink": {
"relativePath": "templates/template.json"
},
"parameters": {
"location": {
"value" : "[parameters('location')]"
}
}
}
}
]
}
So the location can be used from the template.json as required.
Reference: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-test-cases#location-uses-parameter

ARM Templates: get parameters from different file

I am using Azure CLI (Linux host) to deploy Infra as code, I am having different deployment files and parameter files,
My goal is to avoid duplicate input parameters,
main_parameters.json:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"artifactLocation": {
"value": "xxxx_xxxx_path"
}
}
}
main.deploy:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"artifactLocation": {
"type": "string",
"metadata": {
"description": "artifactLocation path"
}
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2019-10-01",
"name": "linkedTemplate",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri":"[parameters('artifactLocation')]",
"contentVersion":"1.0.0.0"
}
}
}
],
"outputs": {
}
}
sub_parameters.json:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"artifactLocation": {
"value": "xxxx_xxxx_path"
},
"customName": {
"value": "Name"
}
}
}
sub_deploy.json:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"artifactLocation": {
"type": "string",
"metadata": {
"description": "artifactLocation path"
}
},
"customName": {
"type": "string",
"metadata": {
"description": "some name"
}
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2019-10-01",
"name": "[parameters('customName')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri":"[parameters('artifactLocation')]",
"contentVersion":"1.0.0.0"
}
}
}
],
"outputs": {
}
}
Both main.parameters and sub.parameters has input parameter "artifactLocation", Is there a way i Can import parameters from main_parameters to sub_deploy.json. so that I will avoid adding same parameters in multiple parameter files.
I am fine to create resources main_deploy and sub_deploy together, but I want to keep main_deploy and sub_deploy files separately for easy readability

parametersLink option not passing parameters to templateLink

I am receiving an error:
"The value of deployment parameter 'appServiceName' is null."
Even though it is defined in the file obtained via parametersLink. I am never prompted so null is expected, but why am I never prompted? How do I properly pass parameters from a parametersLink file to a templateLink?
Master Template:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"rgName": {
"type": "string",
"metadata": {
"description": "Resource Group required in which to create App Service"
}
}
},
"variables": {},
"resources": [
{
"name": "LinkedAppServiceTemplate",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"resourceGroup": "[parameters('rgName')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "uri_to_template_file",
"contentVersion": "1.0.0.0"
},
"parametersLink": {
"uri": "uri_to_params_file",
"contentVersion": "1.0.0.0"
}
}
}
]
}
Linked Template:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"name": "[parameters('appServiceName')]",
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2015-05-01",
"location": "[parameters('rgLocation')]"
}
]
}
Linked Params:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appServiceName": {
"metadata": {
"description": "Name of the App Service to be created"
}
},
"rgLocation": {
"defaultValue": "eastus",
"metadata": {
"description": "Location of the resource group to be created"
}
}
}
}
You need to define the parameters in the file you've referred to as Linked Template:
Follow the tutorial on how to create linked templates as it will also show you how to pass the parameter from the main template to the linked template.
In this case, your Linked Template requires a parameter declaration in the parameters object.
"parameters": {
"appServiceName" : {
"type": "string",
"metadata" : {
"description": "This parameter needs to exist to pass from the link file"
}
}
}

Azure notification hub installantion

Fast question. How create installation using templates? Can you give an example? How construct 'InstallationTemplate' object.
When you want to create an ARM template based on the json schema of Microsoft.NotificationHubs:
Create a new project in Visual Studio 2015.
Choose for a Cloud project
Choose for Azure Resource Group
Choose Blank Template
Open azuredeploy.json
You will see this:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
},
"variables": {
},
"resources": [
],
"outputs": {
}
}
Then begin with the resources part by typing apiVersion (note that you get intellisense already):
"resources": [
{
"apiVersion": ""
}
],
After this add the type: Just select the correct value.
After the type is set. You will get intellisense on the allowed properties.
There are more parameters available. But when using the main properties and
create parameters of the hardcoded values and at the end you will get a template like:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"namespaceLocation": {
"type": "string"
},
"namespaceName": {
"type": "string"
},
"notificationHubName": {
"type": "string"
}
},
"variables": {
},
"resources": [
{
"apiVersion": "2014-09-01",
"name": "[parameters('namespaceName')]",
"type": "Microsoft.NotificationHubs/namespaces",
"location": "[parameters('namespaceLocation')]",
"properties": {
"name": "[parameters('namespaceName')]",
"namespaceType": "NotificationHub"
},
"resources": [
{
"apiVersion": "2014-09-01",
"name": "[parameters('notificationHubName')]",
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs",
"location": "[parameters('namespaceLocation')]",
"dependsOn": [
"[concat('Microsoft.NotificationHubs/namespaces/', parameters('namespaceName'))]"
],
"properties": {
"name": "[parameters('notificationHubName')]"
}
}
]
}
],
"outputs": {
}
}

Resources