Search code examples
jenkinsjenkins-pipeline

How can I set environmnet variables for different values of a matrix axis in a declarative Jenkinsfile


I want to deploy a build to a increasing number of destination. My idea is to use matrix to define that destinations. But I can't find a way to set some variables depending on the axis value.

pipeline {
    agent any
    stages {
        stage('Source') {
            steps {
                git  url: 'git@bitbucket.org:XXXX/YYYYY.git'
            }
        }
        stage ( 'build docker'){
            steps {
                sh 'docker build -t aaaaaaa/bbbbbbb .'
                sh 'docker push aaaaaaa/bbbbbbb'
            }
        }
        stage('matrix') {
            matrix {
              axes {
                axis {
                    name 'DEPLOY_TO'
                    values 'host1', 'host2'
                }
              }
               
             environment {
               when { environment  name: DEPLOY_TO, value: 'host1' }
                REMOTE_HOST = '10.0.0.1'
                REMOTE_USER= 'user1'
              }
              environment {
                  when { environment  name: DEPLOY_TO, value: 'host2'}
                 REMOTE_HOST = '10.0.0.2'
                 REMOTE_USER= 'user2'
              }
              stages {
                stage('deploy ') {
                  steps {
                     sh "scp prod/${DEPLOY_TO}/docker-compose.yml ${REMOTE_USER}@$REMOTE_HOST:"
                  }
                }

                stage('start') {
                  steps {
                      sh 'ssh ${REMOTE_USER}@$REMOTE_HOST "docker-compose pull; docker-compose down; docker compose up -d"'
                  }
                }
              }
            }
        }
    }
}

I have tried to use different environment blocks with included when statements. But this is not allowed. So I search for another idea for that.


Solution

  • One way to achieve what you want is to predefine the environment variables in a dictionary, with keys matching you axes values, then use it to set you environment parameters.
    For example;

    
    // Global maps that contain values per axis value 
    HOSTS = ['host1': '10.0.0.1', 'host2': '10.0.0.2']
    USERS = ['host1': 'user1', 'host2': 'user2']
    
    pipeline {
        agent any
        stages {
            stage('Source') {
                steps {
                    git url: 'git@bitbucket.org:XXXX/YYYYY.git'
                }
            }
            stage ( 'build docker'){
                steps {
                    sh 'docker build -t aaaaaaa/bbbbbbb .'
                    sh 'docker push aaaaaaa/bbbbbbb'
                }
            }
            stage('matrix') {
                matrix {
                   axes {
                      axis {
                         name 'DEPLOY_TO'
                         values 'host1', 'host2'
                      }
                   }          
                   environment {
                       REMOTE_HOST = "${HOSTS[env.DEPLOY_TO]}" // use value from map according to runtime axis value
                       REMOTE_USER = "${USERS[env.DEPLOY_TO]}" // use value from map according to runtime axis value
                   }
                   stages {
                      stage('deploy') {
                         steps {
                            sh "scp prod/${DEPLOY_TO}/docker-compose.yml $REMOTE_USER@$REMOTE_HOST:"
                         }
                      }
                      stage('start') {
                         steps {
                            sh 'ssh $REMOTE_USER@$REMOTE_HOST "docker-compose pull; docker-compose down; docker compose up -d"'
                         }
                      }
                   }
                }
            }
        }
    }
    ``