Azure ARM template give scoping access to different subscription - azure

I have the following ARM template and I am trying to give scoping access to a subscription/resource group that is different from the subscription that I am currently deploying the ARM template. I read this documentation that talks about the scoping but I am not sure how to add the correct properties.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"publicIpName": {
"type": "string"
},
"publicIpSku": {
"type": "string",
"defaultValue": "Standard"
},
"publicIPPrefixResourceId": {
"type": "string",
"metadata": {
"description": "Resource Id of the PublicIpPrefix to create VM VIP"
}
}
},
"resources": [
{
"apiVersion": "2019-02-01",
"type": "Microsoft.Network/publicIPAddresses",
"name": "[parameters('publicIpName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('publicIpSku')]"
},
"properties": {
"publicIPAllocationMethod": "Static",
"publicIPPrefix": {
"Id": "[parameters('publicIPPrefixResourceId')]"
}
}
}
]
}

Below is the sample code where you can check properties related Arm Template here
ARM template
"parameters": {
"vnetAName": {
"type": "string",
"metadata": {
"description": "Name of the first VNET"
}
},
"vnetBName": {
"type": "string",
"metadata": {
"description": "Name of the Second VNET"
}
},
"vnetAPrefix": {
"type": "string",
"metadata": {
"description": "Prefix of the first VNET"
}
},
"vnetBPrefix": {
"type": "string",
"metadata": {
"description": "Prefix of the Second VNET"
}
},
"subscriptionAID": {
"type": "string",
"metadata": {
"description": "the Subscription ID for the first VNET"
}
},
"resourceGroupAName": {
"type": "string",
"metadata": {
"description": "the resource group name for the first VNET"
}
},
Go through this document for complete information.

Related

Trying to set up diagnostic settings for an API arm template

I am new to ARM templates and I have the following issue:
I have an ARM template which creates an API Management service and I want this API Management service to use Log Analytics workspace in order to store it's logs there.
I have already created a log analytics workspace resource.
So, according to Microsoft documentation: https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/resource-manager-diagnostic-settings
the only thing I need to do is to edit the API management ARM template and include a new resource:
"type": "Microsoft.Insights/diagnosticSettings"
but when I do that, I get the following error:
"Values must be one of the following values......" getting a long long list.
Am I doing something wrong here?
thank you for your time!
If we want to create a diagnostic setting for an Azure API Management resource, we can add a resource of type Microsoft.ApiManagement/service/providers/diagnosticSettings to the template.
For example
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"publisherEmail": {
"type": "string",
"minLength": 1,
"metadata": {
"description": "The email address of the owner of the service"
},
"defaultValue": "test#gmail.com"
},
"publisherName": {
"type": "string",
"minLength": 1,
"metadata": {
"description": "The name of the owner of the service"
},
"defaultValue": "test",
},
"sku": {
"type": "string",
"defaultValue": "Developer",
"allowedValues": [
"Developer",
"Standard",
"Premium"
],
"metadata": {
"description": "The pricing tier of this API Management service"
}
},
"skuCount": {
"type": "string",
"defaultValue": "1",
"allowedValues": [
"1",
"2"
],
"metadata": {
"description": "The instance size of this API Management service."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
}
},
"variables": {
"apiManagementServiceName": "[concat('myapiservice', uniqueString(resourceGroup().id))]"
},
"resources": [{
"type": "Microsoft.ApiManagement/service",
"apiVersion": "2019-12-01",
"name": "[variables('apiManagementServiceName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('sku')]",
"capacity": "[parameters('skuCount')]"
},
"properties": {
"publisherEmail": "[parameters('publisherEmail')]",
"publisherName": "[parameters('publisherName')]"
}
}, {
"type": "Microsoft.ApiManagement/service/providers/diagnosticSettings",
"apiVersion": "2017-05-01-preview",
"name": "[concat(variables('apiManagementServiceName'), '/Microsoft.Insights/', 'mytest')]",
"dependsOn": ["[resourceId('Microsoft.ApiManagement/service', variables('apiManagementServiceName'))]"],
"properties": {
"logs": [{
"category": "GatewayLogs",
"enabled": true,
}
],
"metrics": [{
"enabled": true,
"category": "AllMetrics"
}
],
"workspaceId": "<the resource id of workspace>",
}
}
]
}

Assign Roles via ARM Template to cosmos db

I'm trying to assign the role to 'Cosmos Db account' by using following template.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string",
"defaultValue": "gb9e32f1-678f-4552-ae0a-0000f765aaaa",
"metadata": {
"description": ""
}
},
"CosmosDbAccountName": {
"type": "string",
"defaultValue": "cosmosdbaccount",
"metadata": {
"description": "Cosmos Db Account name"
}
},
"RoleType": {
"defaultValue" : "Contributor",
"type": "string",
"metadata": {
"description": "Built-in role to assign"
},
"allowedValues" : [
"Contributor"
]
}
},
"variables": {
"Scope": "[concat(parameters('CosmosDbAccountName'),'/Microsoft.Authorization/',guid(subscription().subscriptionId))]"
},
"resources": [
{
"type": "Microsoft.DocumentDB/databaseAccounts/providers/roleAssignments",
"name": "[variables('Scope')]",
"apiVersion":"2020-04-01-preview",
"properties": {
"RoleDefinitionId":"/subscriptions/[subscription().subscriptionId]/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c",
"principalId": "[parameters('principalId')]"
}
}
]
}
I am currently getting error as
{"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.","details":[{"code":"BadRequest","message":"{\r\n "error": {\r\n "code": "RoleAssignmentUpdateNotPermitted",\r\n "message": "Tenant ID, application ID, principal ID, and scope are not allowed to be updated."\r\n }\r\n}"}]}
I think there is existing role assignment with the same name that you are trying to create through this template and it ends up giving the error for "RoleAssignmentUpdateNotPermitted".
Few changes to your template can solve your problem like generating a unique GUID and then concat it with cosmos DB account name, Please try the below updated template:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string",
"defaultValue": "gb9e32f1-678f-4552-ae0a-0000f765aaaa",
"metadata": {
"description": ""
}
},
"CosmosDbAccountName": {
"type": "string",
"defaultValue": "cosmosdbaccount",
"metadata": {
"description": "Cosmos Db Account name"
}
},
"RoleType": {
"defaultValue" : "Contributor",
"type": "string",
"metadata": {
"description": "Built-in role to assign"
},
"allowedValues" : [
"Contributor"
]
},
"guid": {
"defaultValue": "[newGuid()]",
"type": "String"
}
},
"variables": {
"Scope": "[concat(parameters('CosmosDbAccountName'),'/Microsoft.Authorization/', parameters('guid'))]"
},
"resources": [
{
"type": "Microsoft.DocumentDB/databaseAccounts/providers/roleAssignments",
"name": "[variables('Scope')]",
"apiVersion":"2020-04-01-preview",
"properties": {
"RoleDefinitionId":"/subscriptions/[subscription().subscriptionId]/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c",
"principalId": "[parameters('principalId')]"
}
}
]
}

Deployment template validation failed template parameters 'scriptUrldsc' in the parameters file are not valid they are not present in the original

I'm receiving the error mentioned on the subject, and I'm struggling to fix it.
I'm using an ARM template with several nested ARM templates, the deployment is being done using Azure DevOps.
Below the templates.
This first template is the one calling the nested ones:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"existingDataFactoryName": {
"type": "string",
"metadata": {
"description": "Existing Data Factory name"
}
},
"existingDataFactoryResourceGroup": {
"type": "string",
"metadata": {
"description": "Existing Data Factory resource group"
}
},
"existingDataFactoryVersion": {
"type": "string",
"metadata": {
"description": "Select the existing Data Factory version"
},
"allowedValues": [
"V1",
"V2"
]
},
"virtualMachineName": {
"type": "string",
"metadata": {
"description": "Virtual Machine Name where the runtime will run. Please don't provide the last numbers of the VM E.g: EUWE01PROJNIR "
}
},
"IntegrationRuntimeName": {
"type": "string",
"metadata": {
"description": "IR name must be unique in subscription"
}
},
"NodeCount": {
"type": "int",
"maxValue": 4,
"minValue": 1,
"metadata": {
"description": "the node count is between 1 and 4."
}
},
"vmSize": {
"type": "string",
"defaultValue": "Standard_A4_v2"
},
"adminUserName": {
"type": "string",
"metadata": {
"description": "User name for the virtual machine"
}
},
"adminPassword": {
"type": "securestring",
"metadata": {
"description": "Password for the virtual machine"
}
},
"existingVirtualNetworkName": {
"type": "string",
"metadata": {
"description": "Existing vnet name"
}
},
"existingVnetLocation": {
"type": "string",
"metadata": {
"description": "Virtual machine will be create in the same datacenter with VNET"
}
},
"existingVnetResourceGroupName": {
"type": "string",
"metadata": {
"description": "Name of the existing VNET resource group"
}
},
"existingSubnetInYourVnet": {
"type": "string",
"metadata": {
"description": "Name of the subnet in the virtual network you want to use"
}
},
"_artifactsLocation": {
"type": "string",
"metadata": {
"description": "The base URI where artifacts required by this template are located."
},
"defaultValue": "[deployment().properties.templateLink.uri]"
},
"_artifactsLocationSasToken": {
"type": "securestring",
"metadata": {
"description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated."
},
"defaultValue": ""
},
"diagnosticsStorageAccountName": {
"type": "string",
"metadata": {
"description": "Diagnostic storage account name"
},
"defaultValue": ""
},
"storageAccountNameRG": {
"type": "string",
"metadata": {
"description": "Diagnostic Resource Group of the Diagnostic storage account"
},
"defaultValue": ""
},
"availabilitySetName": {
"type": "string",
"metadata": {
"description": "Availability Set Name"
},
"defaultValue": ""
}
},
"variables": {
"delimiters": [
"-",
"_"
],
"prefix": "[split(parameters('IntegrationRuntimeName'), variables('delimiters'))[0]]",
"vmTemplateLink": "[uri(parameters('_artifactsLocation'), concat('nested/VMtemplate.json', parameters('_artifactsLocationSasToken')))]",
"irInstallTemplateLink": "[uri(parameters('_artifactsLocation'), concat('nested/IRInstall.json', parameters('_artifactsLocationSasToken')))]",
"IRtemplateLink": "[uri(parameters('_artifactsLocation'), concat('nested/IRtemplate.json', parameters('_artifactsLocationSasToken')))]",
"subnetId": "[resourceId(parameters('existingVnetResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', parameters('existingVirtualNetworkName'), parameters('existingSubnetInYourVnet'))]",
"scriptURL": "[uri(parameters('_artifactsLocation'), concat('gatewayInstall.ps1', parameters('_artifactsLocationSasToken')))]",
"scriptURLdsc": "[uri(parameters('_artifactsLocation'), concat('DscMetaConfigs.ps1', parameters('_artifactsLocationSasToken')))]"
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2019-09-01",
"name": "nestedTemplate",
"resourceGroup": "[parameters('existingDataFactoryResourceGroup')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('IRtemplateLink')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"existingDataFactoryName": {
"value": "[parameters('existingDataFactoryName')]"
},
"existingDataFactoryVersion": {
"value": "[parameters('existingDataFactoryVersion')]"
},
"IntegrationRuntimeName": {
"value": "[parameters('IntegrationRuntimeName')]"
}
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2019-09-01",
"name": "[concat('VMtemplate-', copyIndex())]",
"dependsOn": [
"[resourceId(parameters('existingDataFactoryResourceGroup'), 'Microsoft.Resources/deployments', 'nestedTemplate')]"
],
"copy": {
"name": "vmcopy",
"count": "[parameters('NodeCount')]"
},
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('vmTemplateLink')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"virtualMachineName": {
"value": "[take(concat(parameters('virtualMachineName'),'0',copyIndex(1)), 15)]"
},
"vmSize": {
"value": "[parameters('vmSize')]"
},
"adminUserName": {
"value": "[parameters('adminUserName')]"
},
"adminPassword": {
"value": "[parameters('adminPassword')]"
},
"existingVnetLocation": {
"value": "[parameters('existingVnetLocation')]"
},
"subnetId": {
"value": "[variables('subnetId')]"
},
"diagnosticsStorageAccountName": {
"value": "[parameters('diagnosticsStorageAccountName')]"
},
"availabilitySetName": {
"value": "[parameters('availabilitySetName')]"
},
"storageAccountNameRG": {
"value": "[parameters('storageAccountNameRG')]"
}
}
}
},
{
"apiVersion": "2019-09-01",
"type": "Microsoft.Resources/deployments",
"name": "[concat('IRInstalltemplate-', copyIndex())]",
"dependsOn": [
"vmcopy"
],
"copy": {
"name": "irinstallcopy",
"count": "[parameters('NodeCount')]",
"mode": "serial"
},
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('irInstallTemplateLink')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"existingDataFactoryVersion": {
"value": "[parameters('existingDataFactoryVersion')]"
},
"datafactoryId": {
"value": "[reference(resourceId(parameters('existingDataFactoryResourceGroup'), 'Microsoft.Resources/deployments', 'nestedTemplate')).outputs.irId.value]"
},
"virtualMachineName": {
"value": "[take(concat(parameters('virtualMachineName'),'0',copyIndex(1)), 15)]"
},
"existingVnetLocation": {
"value": "[parameters('existingVnetLocation')]"
},
"scriptUrl": {
"value": "[variables('scriptURL')]"
},
"scriptUrldsc": {
"value": "[variables('scriptURLdsc')]"
}
}
}
}
]
}
And this one is where "scriptUrldsc" parameter is being used inside of the nested template.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"existingDataFactoryVersion": {
"type": "string"
},
"datafactoryId": {
"type": "string"
},
"virtualMachineName": {
"type": "string"
},
"existingVnetLocation": {
"type": "string"
},
"scriptUrl": {
"type": "string"
},
"scriptUrldsc": {
"type": "string"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "[concat(parameters('virtualMachineName'), '/' ,parameters('virtualMachineName'), '-installGW')]",
"apiVersion": "2019-07-01",
"location": "[parameters('existingVnetLocation')]",
"tags": {
"virtualMachineName": "[parameters('virtualMachineName')]"
},
"properties": {
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.7",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": [
"[parameters('scriptURL')]",
"[parameters('scripturldsc')]"
]
},
"protectedSettings": {
"commandToExecute": "[concat('powershell.exe -ExecutionPolicy Unrestricted -File gatewayInstall.ps1', if(equals(parameters('existingDataFactoryVersion'), 'V2'), listAuthKeys(parameters('datafactoryId'), '2017-09-01-preview').authKey1, listAuthKeys(parameters('datafactoryId'), '2015-10-01').key1))]"
}
}
}
]
}
The error message says that the ARM template in the storage blob is missing the parameter scriptUrldsc. Assuming the parameter scriptUrldsc was added recently, perhaps the template has been updated locally to add the parameter but somehow the version in the storage blob did not get updated with the new parameter.
The error message says the ARM template from storage has the following parameters:
...
"parameters": {
"existingDataFactoryVersion": {
"type": "string"
},
"datafactoryId": {
"type": "string"
},
"virtualMachineName": {
"type": "string"
},
"existingVnetLocation": {
"type": "string"
},
"scriptUrl": {
"type": "string"
}
},
"variables": {},
...
It's difficult for me to debug and know for certain, but double check the ARM template file in the storage blob to ensure it has the additional parameter.

How to add AzureFunction as Event Subscription Endpoint in ARM Template?

I have written an ARM template to create an event subscription on an existing storage account, where I need to listen to a particular blob container's blob.created and blob.deleted events, and send them to an Azure eventgrid trigger function app.
The functionapp is already deployed in Azure https://myfunctionapp.azurewebsites.net, and I am having a hard time trying to create the event subscription through the ARM template. Please note that I have used API version 2020-01-01-preview in order to have AzureFunction as the endpoint. The template is as follows:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appName": {
"type": "string",
"metadata": {
"description": "Name of the function app"
}
},
"functionName": {
"type": "string",
"defaultValue": "MyFunction",
"metadata": {
"description": "Name of the function"
}
},
"eventSubName": {
"type": "string",
"defaultValue": "myfunctionappsub",
"metadata": {
"description": "The name of the event subscription to create."
}
},
"storageName": {
"type": "string",
"metadata": {
"description": "Storage account name"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Storage account location"
}
},
"containerNamefilter": {
"type": "string",
"defaultValue": "-inputblob",
"metadata": {
"description": "Container name filter"
}
}
},
"variables": {
"functionAppName": "[resourceId('Microsoft.Web/sites/functions/', parameters('appName'), parameters('functionName'))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts/providers/eventSubscriptions",
"name": "[concat(parameters('storageName'), '/Microsoft.EventGrid/', parameters('eventSubName'))]",
"apiVersion": "2020-01-01-preview",
"dependsOn": [
"[parameters('storageName')]"
],
"properties": {
"destination": {
"endpointType": "AzureFunction",
"properties": {
"resourceId": "[variables('functionAppName')]"
}
},
"filter": {
"subjectBeginsWith": "",
"subjectEndsWith": "",
"isSubjectCaseSensitive": false,
"includedEventTypes": [
"Microsoft.Storage.BlobCreated",
"Microsoft.Storage.BlobDeleted"
],
"advancedFilters": [
{
"key": "subject",
"operatorType": "StringContains",
"value": "[parameters('containerfilter')]"
}
]
}
}
}
]
}
This is the error I get when I try to run it on the pipeline:
2020-04-15T11:09:11.5347864Z Starting template validation.
2020-04-15T11:09:11.5368215Z Deployment name is azuredeploy-xxxxxxx-xxxxxx-xxxx
2020-04-15T11:09:13.1700166Z Template deployment validation was completed successfully.
2020-04-15T11:09:13.1700897Z Starting Deployment.
2020-04-15T11:09:13.1703528Z Deployment name is azuredeploy-xxxxxxx-xxxxxx-xxxx
2020-04-15T11:10:02.5842880Z There were errors in your deployment. Error code: DeploymentFailed.
2020-04-15T11:10:02.5893091Z ##[error]At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.
2020-04-15T11:10:02.5910677Z ##[error]Details:
2020-04-15T11:10:02.5915877Z ##[error]Conflict: {
"status": "Failed",
"error": {
"code": "ResourceDeploymentFailure",
"message": "The resource operation completed with terminal provisioning state 'Failed'.",
"details": [
{
"code": "Internal error",
"message": "The operation failed due to an internal server error. The initial state of the impacted resources (if any) are restored. Please try again in few minutes. If error still persists, report 72c636d4-6d09-4c50-8886-7153ddf2a4ee:4/15/2020 11:09:50 AM (UTC) to our forums for assistance or raise a support ticket ."
}
]
}
}
2020-04-15T11:10:02.5918976Z ##[error]Task failed while creating or updating the template deployment.
2020-04-15T11:10:02.5953000Z ##[section]Finishing: Create or update eventsubscription in RG
Am I doing anything wrong here? I'm very new to ARM templates.
If you want to create event grid subscription for the existing storage account, please refer to the following template
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"functionGroup": {
"type": "string",
"defaultValue" : "jimtest",
"metadata": {
"description": "he group name of function app"
}
},
"appName": {
"type": "string",
"defaultValue" : "testfunjs",
"metadata": {
"description": "Name of the function app"
}
},
"functionName": {
"type": "string",
"defaultValue": "EventGridTrigger1",
"metadata": {
"description": "Name of the function"
}
},
"eventSubName": {
"type": "string",
"defaultValue": "myfunctionappsub",
"metadata": {
"description": "The name of the event subscription to create."
}
},
"storageName": {
"type": "string",
"defaultValue" : "andyprivate",
"metadata": {
"description": "Storage account name"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Storage account location"
}
},
"containerNamefilter": {
"type": "string",
"defaultValue": "test",
"metadata": {
"description": "Container name filter"
}
}
},
"variables": {
"functionId" :"[resourceId(parameters('functionGroup'),'Microsoft.Web/sites/functions/', parameters('appName'), parameters('functionName'))]",
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts/providers/eventSubscriptions",
"name": "[concat(parameters('storageName'), '/Microsoft.EventGrid/', parameters('eventSubName'))]",
"apiVersion": "2020-01-01-preview",
"properties": {
"destination": {
"endpointType": "AzureFunction",
"properties": {
"resourceId": "[variables('functionId')]"
}
},
"filter": {
"subjectBeginsWith": "",
"subjectEndsWith": "",
"isSubjectCaseSensitive": false,
"includedEventTypes": [
"Microsoft.Storage.BlobCreated",
"Microsoft.Storage.BlobDeleted"
],
"advancedFilters": [
{
"key": "subject",
"operatorType": "StringContains",
"value": "[parameters('containerNamefilter')]"
}
]
}
}
}
]
}

Azure Kubernetes Service ARM template is not idempotent

I have created an ARM template to deploy an Azure Kubernetes Service instance, which I am trying to plug into a CI/CD pipeline in VSTS. On the first deployment, everything works as expected and the K8s cluster is created successfully. However, upon redeployment, the template fails the validation stage with the following error:
{
"message": "The template deployment 'Microsoft.Template' is not valid according to the validation procedure."
"details": [
{
"code":"PropertyChangeNotAllowed",
"message":"Provisioning of resource(s) for container service <cluster name> in resource group <resource group name> failed. Message:"
{
"code": "PropertyChangeNotAllowed",
"message": "Changing property 'linuxProfile.ssh.publicKeys.keyData' is not allowed.",
"target": "linuxProfile.ssh.publicKeys.keyData"
}
}
]
}
The template is therefore clearly not idempotent which completely dishonours the intended nature of ARM template deployments.
Has anyone managed to find a workaround for this?
The solution to this is to specify the SSH RSA Public Key as a template parameter and use it when configuring the Linux profile. I have posted my ARM template below:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"clusterName": {
"type": "string",
"metadata": {
"description": "The name of the Kubernetes cluster."
}
},
"location": {
"type": "string",
"metadata": {
"description": "The data center in which to deploy the Kubernetes cluster."
}
},
"dnsPrefix": {
"type": "string",
"metadata": {
"description": "DNS prefix to use with hosted Kubernetes API server FQDN."
}
},
"osDiskSizeGB": {
"defaultValue": 32,
"minValue": 0,
"maxValue": 1023,
"type": "int",
"metadata": {
"description": "Disk size (in GB) to provision for each of the agent pool nodes. This value ranges from 0 to 1023. Specifying 0 will apply the default disk size for that agentVMSize."
}
},
"agentCount": {
"defaultValue": 1,
"minValue": 1,
"maxValue": 50,
"type": "int",
"metadata": {
"description": "The number of agent nodes for the cluster."
}
},
"agentVMSize": {
"defaultValue": "Standard_D1_v2",
"type": "string",
"metadata": {
"description": "The size of the Virtual Machine."
}
},
"servicePrincipalClientId": {
"type": "securestring",
"metadata": {
"description": "The Service Principal Client ID."
}
},
"servicePrincipalClientSecret": {
"type": "securestring",
"metadata": {
"description": "The Service Principal Client Secret."
}
},
"osType": {
"defaultValue": "Linux",
"allowedValues": [
"Linux"
],
"type": "string",
"metadata": {
"description": "The type of operating system."
}
},
"kubernetesVersion": {
"defaultValue": "1.10.6",
"type": "string",
"metadata": {
"description": "The version of Kubernetes."
}
},
"enableOmsAgent": {
"defaultValue": true,
"type": "bool",
"metadata": {
"description": "boolean flag to turn on and off of omsagent addon"
}
},
"enableHttpApplicationRouting": {
"defaultValue": true,
"type": "bool",
"metadata": {
"description": "boolean flag to turn on and off of http application routing"
}
},
"networkPlugin": {
"defaultValue": "kubenet",
"allowedValues": [
"azure",
"kubenet"
],
"type": "string",
"metadata": {
"description": "Network plugin used for building Kubernetes network."
}
},
"enableRBAC": {
"defaultValue": true,
"type": "bool",
"metadata": {
"description": "Flag to turn on/off RBAC"
}
},
"logAnalyticsWorkspaceName": {
"type": "string",
"metadata": {
"description": "Name of the log analytics workspace which will be used for container analytics"
}
},
"logAnalyticsWorkspaceLocation": {
"type": "string",
"metadata": {
"description": "The data center in which the log analytics workspace is deployed"
}
},
"logAnalyticsResourceGroup": {
"type": "string",
"metadata": {
"description": "The resource group in which the log analytics workspace is deployed"
}
},
"vmAdminUsername": {
"type": "string",
"metadata": {
"description": "User name for the Linux Virtual Machines."
}
},
"sshRsaPublicKey": {
"type": "securestring",
"metadata": {
"description": "Configure all linux machines with the SSH RSA public key string. Your key should include three parts, for example: 'ssh-rsa AAAAB...snip...UcyupgH azureuser#linuxvm'"
}
}
},
"variables": {
"logAnalyticsWorkspaceId": "[resourceId(parameters('logAnalyticsResourceGroup'), 'Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsWorkspaceName'))]",
"containerInsightsName": "[concat(parameters('clusterName'),'-containerinsights')]"
},
"resources": [
{
"type": "Microsoft.ContainerService/managedClusters",
"name": "[parameters('clusterName')]",
"apiVersion": "2018-03-31",
"location": "[parameters('location')]",
"properties": {
"kubernetesVersion": "[parameters('kubernetesVersion')]",
"enableRBAC": "[parameters('enableRBAC')]",
"dnsPrefix": "[parameters('dnsPrefix')]",
"addonProfiles": {
"httpApplicationRouting": {
"enabled": "[parameters('enableHttpApplicationRouting')]"
},
"omsagent": {
"enabled": "[parameters('enableOmsAgent')]",
"config": {
"logAnalyticsWorkspaceResourceID": "[variables('logAnalyticsWorkspaceId')]"
}
}
},
"agentPoolProfiles": [
{
"name": "agentpool",
"osDiskSizeGB": "[parameters('osDiskSizeGB')]",
"count": "[parameters('agentCount')]",
"vmSize": "[parameters('agentVMSize')]",
"osType": "[parameters('osType')]",
"storageProfile": "ManagedDisks"
}
],
"linuxProfile": {
"adminUsername": "[parameters('vmAdminUsername')]",
"ssh": {
"publicKeys": [
{
"keyData": "[parameters('sshRsaPublicKey')]"
}
]
}
},
"servicePrincipalProfile": {
"clientId": "[parameters('servicePrincipalClientId')]",
"secret": "[parameters('servicePrincipalClientSecret')]"
},
"networkProfile": {
"networkPlugin": "[parameters('networkPlugin')]"
}
},
"dependsOn": [
"[concat('Microsoft.Resources/deployments/', 'SolutionDeployment')]"
]
},
{
"type": "Microsoft.Resources/deployments",
"name": "SolutionDeployment",
"apiVersion": "2017-05-10",
"resourceGroup": "[parameters('logAnalyticsResourceGroup')]",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"apiVersion": "2015-11-01-preview",
"type": "Microsoft.OperationsManagement/solutions",
"location": "[parameters('logAnalyticsWorkspaceLocation')]",
"name": "[variables('containerInsightsName')]",
"properties": {
"workspaceResourceId": "[variables('logAnalyticsWorkspaceId')]"
},
"plan": {
"name": "[variables('containerInsightsName')]",
"product": "OMSGallery/ContainerInsights",
"promotionCode": "",
"publisher": "Microsoft"
}
}
]
}
}
}
],
"outputs": {
"controlPlaneFQDN": {
"type": "string",
"value": "[reference(concat('Microsoft.ContainerService/managedClusters/', parameters('clusterName'))).fqdn]"
},
"sshMaster0": {
"type": "string",
"value": "[concat('ssh ', parameters('vmAdminUsername'), '#', reference(concat('Microsoft.ContainerService/managedClusters/', parameters('clusterName'))).fqdn, ' -A -p 22')]"
}
}
}

Resources