Jenkins pipeline with for loop

Hi guys,

I want to run for loop as part of my pipeline and then to apply terraform init and apply. I have some errors in the *.tf code for testing purpose but when I build the job the job is successful even if there are errors. What I’m doing wrong and how to tell Jenkins to stop the build on failure?

pipeline {
    agent any

    stages {
        stage('Checkout') {
            steps {
               checkout scmGit(branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: 'xxx-xxxx', url: 'https://github.com/xxxxxx/xxx-xxxx-xxxxx-xxxxxx']])
            }
        }
	stage("Terraform deploy"){
	steps { 
	    script {
	        sh '''#!/bin/bash
	        for d in $(find . -mindepth 2 -maxdepth 3  -not -path "*/.*" -type f -name "*.tf" | awk -F / ' { print $2 } ')
	   do 
	        cd ${d}
	        echo $(terraform init && terraform apply --auto-approve) 
	        cd - 
     done
            '''
    }
  }
}
    	stage("List directory"){
    	steps {
    	sh "pwd"
          }
        }
  }
}

My Jenkins version is 2.395

Regards,
Ivo

you added a shebang (the !/bin/bash) in your sh step. This disables the automatic failure of the shell script and the result of the sh step is that of the last command cd -, which obviously is not failing.
So either

  • remove that line
  • explicitly add set -x to your script
  • execute the 2 terraform commands separately ( why did you wrap that in an echo?) and read the result from $? so you can do other things after the command failed and exit the script at the end when something failed.

Hi Markus,

Thank you very much for your response!

I’ve added the sheband to the script because Jenkins is installed on docker container and from my previous experience I remember that I had to include sh ‘bash command’ to the step, otherwise the step failed due to the different interpreter type.

For testing purpose I’ve added set -xe and this is included to the script, to see in which folders the loop is searching for the files.

Commands are together in one echo because I want to run the second command right after the first command.

Regarding your last advice to use echo $? to take the status code of the previous command I guess you mean to add it to if else statement, right? Because I did this earlier today and the result was the same. Always the status is SUCCESS even if there are errors in my lambda module block and each lambda throwing an error.

Regards,
Ivo

There should be no need to wrap the 2 commands in an echo

do something like

error=0
for d in ... 
do
  cd $d
  terraform init
    if [ $? != 0 ]; then
     error=1
  else
    terraform apply --auto-approve
    if [ $? != 0 ]; then
     error=1
    fi
  fi
  cd -
done 

exit $error

Thank you, Markus.

Your block seems to work fine and now I’m getting the correct stratus code in Jenkins. Let me fix several other issues and I will write back here with the status.

Again, I appreciate very much your help!

Regards,
Ivo