Search code examples
variablesterraformoutputazure-pipelines-yaml

Can't pass Terraform Output variables to another azure pipeline Job


I need to pass some terraform outputs to a task (that trigger an azurefunction) in another job:

  • TerraformTaskV3@3 is an agent pool task.
  • AzureFunction@1 is a server pool task.

So both are on separate jobs.

I based my pipeline on following resources:

https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#set-a-multi-job-output-variable

https://www.natmarchand.fr/using-terraform-output-values-in-azure-devops-pipeline/


stages:
  - stage: Deploy
    jobs:
    - deployment: Deploy
      displayName: Deploy
      environment: '$(devopsenvironment)'
      pool: 
        vmImage: $(vmImageName)
      strategy:
        runOnce:
          deploy:
            steps:      
            - download: $(pipeline)
            ....        
            - task: TerraformTaskV3@3
              name: terraformOutputTask
              displayName: 'Terraform : azurerm output'
              inputs:            
                command: output                
                environmentServiceNameAzureRM: $(serviceConnection)
                        - powershell: |
                $terraformOutput = Get-Content "$(terraformOutputTask.jsonOutputVariablesPath)" | ConvertFrom-Json
                $terraformOutput | Get-Member -MemberType NoteProperty | % { $o = $terraformOutput.($_.Name); Write-Host "##vso[task.setvariable variable=$($_.Name);isoutput=true;issecret=$($o.sensitive)]$($o.value)" }
              name: terraformOutput
              displayName: Read terraform outputs 
            - script: |             
                echo t:storage_primary_connection_string - $(terraformOutput.storage_primary_connection_string)
                echo t:maintenance_function_base_url - $(terraformOutput.maintenance_function_base_url)
                echo t:maintenance_function_key - $(terraformOutput.maintenance_function_key)
              condition: eq(${{ parameters.outputvariables }}, true) 
              displayName: Display terraform ouput
            .....
    - job: Post_Deploy
      displayName: Post deployment tasks
      dependsOn: Deploy
      variables: 
        maintenance_function_base_url: $[ dependencies.Deploy.outputs['terraformOutput.maintenance_function_base_url'] ]
        maintenance_function_key: $[ dependencies.Deploy.outputs['terraformOutput.maintenance_function_key'] ]
      pool: server                  
      steps:                 
        ...
        # Import localization
        - task: AzureFunction@1
          displayName: 'Execute Azure Import Localization Function'
          condition: not(eq('$(maintenance_function_key)', ''))
          retryCountOnTaskFailure: 1
          inputs:
            function: 'https://$(maintenance_function_base_url)/api/ImportLocalization'
            key: '$(maintenance_function_key)'
            method: 'POST'
            body: ''                       
            waitForCompletion: 'true'

  • Terraform task works as expected.
  • Script that set variables seems to work as the next task displays correct values.
  • AzureFunctionTask failed as $(maintenance_function_base_url) and $(maintenance_function_key) seem empty

Pipeline fails with:

URL https:///api/ImportLocalization?code=& for HttpRequest is not correct. Deploy • Post deployment tasks • Execute Azure Import Localization Function

enter image description here


Solution

  • Thanks to Ishuar direction I finaly pinpoint the source of the issue.

    The mistake is that my server task refer an output defined in a Deployment job (and not a regular job).

    So the dependency notation is slightly different than the one specified by microsoft documentation 'Set a multi-job output variable' https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#set-a-multi-job-output-variable

    For my case instead of using

    maintenance_function_base_url: $[ dependencies.Deploy.outputs['terraformOutput.maintenance_function_base_url'] ]
    

    I must use:

    maintenance_function_base_url: $[ dependencies.Deploy.outputs['Deploy.terraformOutput.maintenance_function_base_url'] 
    

    As stated in 'Deployment jobs - Support for output variables' https://learn.microsoft.com/en-us/azure/devops/pipelines/process/deployment-jobs?view=azure-devops#support-for-output-variables

    Note the notation is dependant of Deploy lifecycle (in my case runOnce) If you use another you must check the documention.