Reputation: 1956
I have multiple ARM templates that I want to link. But when I use "[uri(deployment().properties.templateLink.uri, 'transform.json')]"
I get an error telling me that deployment() gives an object that does not contain templateLink when running it locally or through the Azure DevOps pipeline.
So then I tried to send in the path to the artifact that I create when I build the project in Azure DevOps, "[concat(parameters('templateDirectory'), '/transform.json')]"
, and then provide it as a parameter when calling the template.
But then I get this error instead
At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-debug for usage details.
Details:
BadRequest: {
"error": {
"code": "InvalidContentLink",
"message": "The provided content link 'file:///D:/a/r1/a/_Infrastructure/ARM/shared/transform.json' is invalid or not supported. Content link must be an absolute URI not referencing local host or UNC path."
}
} undefined
Task failed while creating or updating the template deployment.
So my question is how should I handle the linking of templates when I deploy through the Azure DevOps pipeline?
Do I have to copy it to a storage in the build step so that I can access it with http or https in the deploy step, and if so, how is the best way to that? it seems a little complex.
Solution update
So the solution I went for was to upload all the template files to a temporary storage that I created and then added the path to that to the main template that refers to all the templates.
Task overview to get a better understanding of how it was done:
Copy templates to blob:
Deploy ARM template:
And here a snippet of how it was used in the main template referring other templates:
"resources": [
{
"apiVersion": "2015-01-01",
"name": "dashboard-24h",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat(parameters('templateBasePath'), '/dashboard/24h/azuredeploy-dashboard-deploy.json')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"templateBasePath": {
"value": "[parameters('templateBasePath')]"
},
"appName": {
"value": "[parameters('appName')]"
}
}
}
},
...
]
Upvotes: 2
Views: 7129
Reputation: 305
Expanding on the above if you are generating your ARM
Or
Using AzureResourceManagerTemplateDeployment@3
to deploy the generated templates you can override the variables like this
- task: AzureResourceManagerTemplateDeployment@3
inputs:
deploymentScope: 'Resource Group'
... other values
deploymentMode: 'Validation'
overrideParameters: '-LinkedTemplatesBaseUrl "$(BASE_URL)" -LinkedTemplatesUrlQueryString $(SAS_TOKEN)'
The LinkedTemplatesBaseUrl
and LinkedTemplatesUrlQueryString
must be defined in the *-parameters.json
file
Use LinkedTemplatesUrlQueryString
only when fetching from secured storage (which is a preferred way)
You can use AzureFileCopy@4
to copy your templates
steps:
- task: AzureFileCopy@4
name: AzureFileCopyTask
inputs:
SourcePath: '$(System.DefaultWorkingDirectory)/build_dir/*.json'
azureSubscription: $(AZURE_SUBSCRIPTION)
Destination: 'AzureBlob'
storage: $(STORAGE_ACCOUNT)
ContainerName: $(STORAGE_CONTAINER)
CleanTargetBeforeCopy: true
BlobPrefix: $(STORAGE_PREFIX)
And use the output variables like mentioned here
Upvotes: 1
Reputation: 72151
so, if you want to use the deployment().properties.templateLink.uri
your template has to be deployed from a url, not from a local disk.
nested templates ALWAYS have to be deployed from url. so, if you want to use the aforementioned method, everything has to be uploaded to someplace that is accessible publicly (or auth has to be done through URL, like SAS token).
What I usually do - run a simple powershell script before deployment that uploads all the templates to a common location, after that I just use deployment function.
Upvotes: 9