João Amaro
João Amaro

Reputation: 496

How to fetch variables from yaml and map them in jenkinsfile?

I have a jenkinsfile with a declarative pipeline. I'm trying to retrieve ECR image names from a config.yml, put them in a map and print them with a loop in Jenkins. Here's what I did so far:

config.yml:

images:
  - "123.dkr.ecr.eu-west-1.amazonaws.com/image-1:latest"
  - "123.dkr.ecr.eu-west-1.amazonaws.com/image-2:latest"
  - "456.dkr.ecr.eu-west-1.amazonaws.com/image-9:latest"

jenkinsfile:

def account_info = readYaml file: "config.yml"
def image_info = "${account_info.images}"

def map = [
        ("image") : "${image_info}"
]

pipeline {  
  stages {
    stage('tests') {     
      steps {
        loopImages(map)
      }     
    }
  }
}

def loopImages(map){
  map.each { entry ->
    stage('test-' + entry.key) {
      catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
        script {
          sh """
          echo "${image_info}"
        """
        }
      }
    }
  }
}

Wanted to know if you recommend I do this in a different way? I'm new to Jenkins and don't really know how to fetch the variables from yaml and put them in a map.

Having it this way is giving me the following error:

Required context class hudson.FilePath is missing

My objective is to have a map like this:

def map = [
    ("image") : "123.dkr.ecr.eu-west-1.amazonaws.com/image-1:latest"
    ("image") : "123.dkr.ecr.eu-west-1.amazonaws.com/image-2:latest"
    ("image") : "456.dkr.ecr.eu-west-1.amazonaws.com/image-9:latest"    
]

Upvotes: 0

Views: 3001

Answers (1)

zett42
zett42

Reputation: 27756

The mistake here is that you are trying to use a step (readYaml) outside of the pipeline block. This doesn't work because steps require context from the pipeline, such as the current node.

Really you should see pipeline as your main function and don't do much outside of it except simple variable initialization.

For things I have to initialize via steps, I usually create an "Initialize" stage. This keeps things separated and follows single-level of abstraction principle.

def account_info = null
def image_info = null
def map = null

pipeline {  
  stages {
    stage('initialize') {
      steps {
        initialize()
      }
    }
    stage('tests') {     
      steps {
        loopImages(map)
      }     
    }
  }
}

void initialize() {
  account_info = readYaml file: "config.yml"
  //... and so on
}

Upvotes: 2

Related Questions