Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-43911

Environment variables can't be used in agent configuration

    Details

    • Similar Issues:
    • Epic Link:

      Description

      If you try something like

      agent {
        label "${SOME_ENV_VAR}"
      }
      environment {
        SOME_ENV_VAR = "some-label"
      }
      

      You'll get an error due to SOME_ENV_VAR not existing in the binding. Not ideal, obviously, but I'm not sure if we can actually solve this without significant rewrites.

        Attachments

          Issue Links

            Activity

            Hide
            allanlewis_youview Allan Lewis added a comment -

            I finally found a workaround for this:

            registry = 'my-registry'
            imageRepo = 'my-repo-name'
            
            def getImageName(def doCheckout = false) {
              def treeHash = node {
                if (doCheckout) checkout scm
                sh(script: 'git rev-parse HEAD:', returnStdout: true).trim()
              }
              "$registry/$imageRepo:$treeHash"
            }
            
            pipeline {
              agent {
                label 'docker-builder'
              }
            
              stages {
                stage('Build & Push Docker Image') {
                  steps {
                    script {
                      docker.build(getImageName()).push()
                    }
                  }
                }
                stage('Do Stuff') {
                  agent {
                    docker {
                      image getImageName(true)
                    }
                  }
                  steps {
                    sh 'echo hello'
                  }
                }
              }
            }
            
            Show
            allanlewis_youview Allan Lewis added a comment - I finally found a workaround for this: registry = 'my-registry' imageRepo = 'my-repo-name' def getImageName( def doCheckout = false ) { def treeHash = node { if (doCheckout) checkout scm sh(script: 'git rev-parse HEAD:' , returnStdout: true ).trim() } "$registry/$imageRepo:$treeHash" } pipeline { agent { label 'docker-builder' } stages { stage( 'Build & Push Docker Image' ) { steps { script { docker.build(getImageName()).push() } } } stage( 'Do Stuff' ) { agent { docker { image getImageName( true ) } } steps { sh 'echo hello' } } } }
            Hide
            eplodn1 efo plo added a comment -

            Would also like to have this implemented.

             

            We need to dynamically assign a label based on branch, so that branches of Team A run on the resources of that team, etc. We contact Consul for the mapping of branch to label. Currently this is not possible as the label expression is evaluated before the pipeline is run, not at the beginning of the relevant step, so any changes to variables or environment do not affect the node where the step is run.

            Show
            eplodn1 efo plo added a comment - Would also like to have this implemented.   We need to dynamically assign a label based on branch, so that branches of Team A run on the resources of that team, etc. We contact Consul for the mapping of branch to label. Currently this is not possible as the label expression is evaluated before the pipeline is run, not at the beginning of the relevant step, so any changes to variables or environment do not affect the node where the step is run.
            Hide
            datajack Jack P added a comment -

             I would like to bump interest in this as well recently got diverted here from posting a [similar question on stack overflow|https://stackoverflow.com/questions/55267427/how-can-i-use-different-private-docker-agents-based-on-parameter-in-jenkins-decl.]

             

            The solution seems to mean restarting the same environment between stages which feels a bit off and results in me having to merge stages that would be nice to keep separate.

            Show
            datajack Jack P added a comment -  I would like to bump interest in this as well recently got diverted here from posting a [similar question on stack overflow| https://stackoverflow.com/questions/55267427/how-can-i-use-different-private-docker-agents-based-on-parameter-in-jenkins-decl .]   The solution seems to mean restarting the same environment between stages which feels a bit off and results in me having to merge stages that would be nice to keep separate.
            Hide
            eplodn1 efo plo added a comment -

            Jack P We worked around this limitation by implementing a scripted pipeline before declarative:

            node('master') {
                stage('Choose Label') {
                    LABEL = 'my_desired_label' // script it anyway you want
                }
            }
            
            
            pipeline {
                agent {
                    node {
                        label "${LABEL}"
                    }
                }
            // etc.
            }
            
            Show
            eplodn1 efo plo added a comment - Jack P We worked around this limitation by implementing a scripted pipeline before declarative: node( 'master' ) { stage( 'Choose Label' ) { LABEL = 'my_desired_label' // script it anyway you want } } pipeline { agent { node { label "${LABEL}" } } // etc. }
            Hide
            datajack Jack P added a comment - - edited

            efo plo Thank you! I am eternally greatful. Totally works with docker and azure storage plugin, here's my stackoverflow example fixed as per yours.

             
             

            node('master') { 
             stage('Choose Label') { 
              URL_VAR = "${env.registrySelection == "PROD" ? "urlProd.azure.io" : "urlTest.azure.io"}" 
              CREDS_VAR = "${env.registrySelection == "PROD" ? "credsProd" : "credsTest"}" 
             } 
            } 
            pipeline { 
              parameters { 
                choice( 
                name: 'registrySelection', 
                choices: ['TEST', 'PROD'], 
                description: 'Is this a deployment to STAGING or PRODUCTION environment?' ) 
              } 
              agent { 
                docker { 
                  image "${URL_VAR}/image:tag" 
                  registryUrl "https://${URL_VAR}" registryCredentialsId "${CREDS_VAR}" 
                } 
              } 
              stages{ 
                stage('test'){ 
                  steps{ 
                    echo "${URL_VAR}" 
                    echo "${CREDS_VAR}" 
                  } 
                } 
              } 
            }

             

            Show
            datajack Jack P added a comment - - edited efo plo Thank you! I am eternally greatful. Totally works with docker and azure storage plugin, here's my stackoverflow example fixed as per yours.     node( 'master' ) { stage( 'Choose Label' ) { URL_VAR = "${env.registrySelection == " PROD " ? " urlProd.azure.io " : " urlTest.azure.io "}" CREDS_VAR = "${env.registrySelection == " PROD " ? " credsProd " : " credsTest "}" } } pipeline { parameters { choice( name: 'registrySelection' , choices: [ 'TEST' , 'PROD' ], description: 'Is this a deployment to STAGING or PRODUCTION environment?' ) } agent { docker { image "${URL_VAR}/image:tag" registryUrl "https: //${URL_VAR}" registryCredentialsId "${CREDS_VAR}" } } stages{ stage( 'test' ){ steps{ echo "${URL_VAR}" echo "${CREDS_VAR}" } } } }  

              People

              • Assignee:
                abayer Andrew Bayer
                Reporter:
                abayer Andrew Bayer
              • Votes:
                20 Vote for this issue
                Watchers:
                32 Start watching this issue

                Dates

                • Created:
                  Updated: