Can I define multiple agent labels in a declarative Jenkins Pipeline?

As described in Jenkins pipeline documentation and by Vadim Kotov one can use operators in label definition.

So in your case if you want to run your jobs on nodes with specific labels, the declarative way goes like this:

agent { label('small || medium') }

And here are some examples from Jenkins page using different operators

// with AND operator
agent { label('windows && jdk9 )')  }
 
// a more complex one
agent { label('postgres && !vm && (linux || freebsd)')  } 

Notes

When constructing those definitions one just needs to consider following rules/restrictions:

  • All operators are left-associative
  • Labels or agent names can be surrounded with quotation marks if they contain characters that would conflict with the operator syntax
  • Expressions can be written without whitespace
  • Jenkins will ignore whitespace when evaluating expressions
  • Matching labels or agent names with wildcards or regular expressions is not supported
  • An empty expression will always evaluate to true, matching all agents

You can see the 'Pipeline-syntax' help within your Jenkins installation and see the sample step "node" reference.

You can use exprA||exprB:

node('small||medium') {
    // some block
}

EDIT: I misunderstood the question. This answer is only if you know which specific agent you want to run for each stage.

If you need multiple agents you can declare agent none and then declare the agent at each stage.

https://jenkins.io/doc/book/pipeline/jenkinsfile/#using-multiple-agents

From the docs:

pipeline {
    agent none
    stages {
        stage('Build') {
            agent any
            steps {
                checkout scm
                sh 'make'
                stash includes: '**/target/*.jar', name: 'app' 
            }
        }
        stage('Test on Linux') {
            agent { 
                label 'linux'
            }
            steps {
                unstash 'app' 
                sh 'make check'
            }
            post {
                always {
                    junit '**/target/*.xml'
                }
            }
        }
        stage('Test on Windows') {
            agent {
                label 'windows'
            }
            steps {
                unstash 'app'
                bat 'make check' 
            }
            post {
                always {
                    junit '**/target/*.xml'
                }
            }
        }
    }
}

This syntax appears to work for me:

agent { label 'linux && java' }