KungWaz
KungWaz

Reputation: 1956

How can I link a template in an Azure ARM template?

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: enter image description here

Copy templates to blob:

enter image description here

Deploy ARM template:

enter image description here

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

Answers (2)

json singh
json singh

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

4c74356b41
4c74356b41

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

Related Questions