Craig
Craig

Reputation: 21

Jenkins: For each loop issue

I am using Jenkins to trigger an Ansible playbook. I would like to pass in an array of computer names in order for the Ansible playbook to trigger the playbook and image the machines one by one.

In order to do this I believe I need a foreach loop.

I have little skill in groovy/Jenkins and have ran into an issue.

error = "Expected a symbol @ line..." The line that this is referring to is HOSTS.each {item ->

Can someone please assist me? My script is below (I have edited out some private data)

pipeline {
    agent any
    // every day
    triggers {
        cron('H 7 * * *')
    }

    environment {
          HOSTS = ['node1','node2']
    }

stages {

    stage('MachineDB Scheduler') {
            steps {
                HOSTS.each { item -> // review
                    HOSTNAME = ${item} // review
                    ansibuildPlaybookperf(
                        sshUser: env.USER,
                        vaultUser: env.USER,
                        server: "$SERVER",
                        dir: "$HOMEDIR/$BUILD_TAG",
                        playbook: "$PLAYBOOK",
                        extras: "--vault-password-file passmgr.sh",
                        extraVars: "$VARS_JENKINS"
                    )
                }
            }
        }
    }
}

Upvotes: 2

Views: 10462

Answers (1)

lvthillo
lvthillo

Reputation: 30723

I don't really know a lot about ansible but maybe this helps. This pipeline shows a list of PC's. In the declarative pipeline I call a groovy function which is defined after the pipeline. In this function I go through the list and past every PC-name.

def list = [
        'PCNAME1',
        'PCNAME2',
        'PCNAME3'
]

pipeline {
    agent any

    stages {
        stage('Loop through PCs') {
            steps {
                loopPC(list)
            }
        }
    }
}

def loopPC(list){
    list.each {
        println "Computer ${it}"
    }
}

OUTPUT:

[Pipeline] {
[Pipeline] stage
[Pipeline] { (Loop through PCs)
[Pipeline] echo
Computer PCNAME1
[Pipeline] echo
Computer PCNAME2
[Pipeline] echo
Computer PCNAME3
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

You can also use a script block in your declarative pipeline to execute the script immediately. It's less clean but maybe easier in the beginning and to make it work (and closer to your attempt):

def list = [
        'PCNAME1',
        'PCNAME2',
        'PCNAME3'
]

pipeline {
    agent any

    stages {
        stage('Loop through PCs') {
            steps {
                script {
                    list.each {
                    println "Computer ${it}"
                    }
                }
            }
        }
    }
}

Upvotes: 1

Related Questions