azureazure-devopsazure-pipelines-yamlazure-pipelines-tasks

AzureResourceManagerTemplateDeployment fails to find template using pattern when executed in Deployment Job


I have been experimenting with Azure Logic Apps and wanted to figure out a way to codify the deployment process so that I could setup a CI/CD pipeline with secrets and all the good stuff.

So I set out with a yml file with multiple ways to deploy the same Logic App.

  1. Hardcoding the values of the input params to the task like Connected Service, Subscription, Resource Group etc. in a step inside a regular job.
  2. Doing the same thing but inside a Deployment job.
  3. Use Pipeline variables to extract these values and repeat as 1 and 2.
  4. 1 and 2 again but this time using Pipeline Variables that are marked as Secrets so on and so forth.

However, everytime I run the AzureResourceManagerTemplateDeployment@3 inside a deployment job, it fails to find the ARM template file.

Everytime I search for the AzureResourceManagerTemplateDeployment task docs, I get the docs page of AzureResourceGroupDeployment task which is very similar but not the same https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-resource-group-deployment?view=azure-devops#troubleshooting

As I was about to post this question, I did more searching online and came across the original docs of the AzureResourceManagerTemplateDeployment which states that if the file is part of a repository then one must specify the path to the ARM template using the help of system variables.

csmFile: "$(Build.Repository.LocalPath)/**/LogicApp.json"
csmParametersFile: "$(Build.Repository.LocalPath)/**/LogicApp.parameters.json"

I can confirm that this did not work either.

What could I be missing?

stages:
- stage: 'HardcodedJobStage'
  displayName: 'HardcodedJobStage'
  jobs:
  - job: 'HardcodedJob'
    displayName: HardcodedJob
    pool:
      vmImage: ubuntu-latest
      workspace:
        clean: all
    steps:
    - task: AzureResourceManagerTemplateDeployment@3
      inputs:
          deploymentScope: 'Resource Group'
          ConnectedServiceName: 'Subscription (e6d1dg8c-bcd6-4713-b2f1-c9a0375d687d)'
          subscriptionName: 'e6d1dg8c-bcd6-4713-b2f1-c9a0375d687d'
          action: 'Create Or Update Resource Group'
          resourceGroupName: 'AzureLogicApp'
          location: 'UK South'
          templateLocation: 'Linked artifact'
          csmFile: '**/LogicApp.json'
          csmParametersFile: '**/LogicApp.parameters.json'
          deploymentMode: 'Incremental'

- stage: 'HardCodedDeployJobStage'
  displayName: 'HardCodedDeployJobStage'
  jobs:
  - deployment: 'HardCodedDeployJob'
    displayName: HardCodedDeployJob
    pool:
      vmImage: ubuntu-latest
      workspace:
        clean: all
    environment: development
    strategy:
     runOnce:
       deploy:
         steps:
         - task: AzureResourceManagerTemplateDeployment@3
           inputs:
              deploymentScope: 'Resource Group'
              ConnectedServiceName: 'Subscription (e6d1dg8c-bcd6-4713-b2f1-c9a0375d687d)'
              subscriptionName: 'e6d1dg8c-bcd6-4713-b2f1-c9a0375d687d'
              action: 'Create Or Update Resource Group'
              resourceGroupName: 'AzureLogicApp'
              location: 'UK South'
              templateLocation: 'Linked artifact'
              csmFile: '**/LogicApp.json'
              csmParametersFile: '**/LogicApp.parameters.json'
              deploymentMode: 'Incremental'

Solution

  • The problem here was that I had to publish the templates as artifacts and share it between the stages.

    So I copied the ARM template json files to a folder using CopyFiles task and then used the PublishPipelineArtifact task to publish the contents as a pipeline artifact. This can then be referenced later by the following stage by using the DownloadPipelineArtifact task.

    Now my YAML looks something like:

    stages:
    - stage: 'HardcodedJobStage'
      displayName: 'HardcodedJobStage'
      jobs:
      - job: 'HardcodedJob'
        displayName: HardcodedJob
        pool:
          vmImage: ubuntu-latest
          workspace:
            clean: all
        steps:
        - task: AzureResourceManagerTemplateDeployment@3
          inputs:
              deploymentScope: 'Resource Group'
              ConnectedServiceName: 'Subscription (e6d1dg8c-bcd6-4713-b2f1-c9a0375d687d)'
              subscriptionName: 'e6d1dg8c-bcd6-4713-b2f1-c9a0375d687d'
              action: 'Create Or Update Resource Group'
              resourceGroupName: 'AzureLogicApp'
              location: 'UK South'
              templateLocation: 'Linked artifact'
              csmFile: '**/LogicApp.json'
              csmParametersFile: '**/LogicApp.parameters.json'
              deploymentMode: 'Incremental'
        
        - task: CopyFiles@2
          inputs:
            Contents: $(Build.SourcesDirectory)/AzureLogicApp/**/*.json
            targetFolder: $(Build.ArtifactStagingDirectory)
        
        - task: PublishPipelineArtifact@1
          inputs:
            targetPath: $(Build.ArtifactStagingDirectory)
            artifactName: armtemplate
            
    - stage: 'HardCodedDeployJobStage'
      displayName: 'HardCodedDeployJobStage'
      jobs:
      - deployment: 'HardCodedDeployJob'
        displayName: HardCodedDeployJob
        pool:
          vmImage: ubuntu-latest
          workspace:
            clean: all
        environment: development
        strategy:
         runOnce:
           deploy:
             steps:
             - task: DownloadPipelineArtifact@2
               inputs:
                 artifact: armtemplate
    
             - task: AzureResourceManagerTemplateDeployment@3
               inputs:
                  deploymentScope: 'Resource Group'
                  ConnectedServiceName: 'Subscription (e6d1dg8c-bcd6-4713-b2f1-c9a0375d687d)'
                  subscriptionName: 'e6d1dg8c-bcd6-4713-b2f1-c9a0375d687d'
                  action: 'Create Or Update Resource Group'
                  resourceGroupName: 'AzureLogicApp'
                  location: 'UK South'
                  templateLocation: 'Linked artifact'
                 csmFile: $(Pipeline.Workspace)/armtemplate/**/LogicApp.json
                 csmParametersFile: $(Pipeline.Workspace)/armtemplate/**/LogicApp.parameters.json
                  deploymentMode: 'Incremental'