<p>I tried combining things I have found on the syntax but this is as close as I can get. It creates multiple stages but says they have no steps.</p>
<p>I can get it to run a bunch of parallel steps on the same agent if I move the agent syntax down to where the &quot;test&quot; stage is defined but I want to spin up separate pods for each one so I can actually use the kubernetes cluster effectively and do my work parallel.</p>
<p>attached is an example Jenkinsfile for reference</p>
<pre><code>def parallelStagesMap

def generateStage(job) {
    return {
        stage (&quot;$job.key&quot;) {
            agent {
                kubernetes {
                    cloud 'kubernetes'
                    yaml &quot;&quot;&quot;
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: name
    image: image
    command:
    - sleep
    args:
    - infinity
&quot;&quot;&quot;
                }
            }
            steps {
                sh &quot;&quot;&quot;
                    do some important stuff
                &quot;&quot;&quot;
            }
        }
    }
}

pipeline {
    agent none
    stages {
        stage('Create List of Stages to run in Parallel') {
            steps {
                script {
                    def map = [
                        &quot;name&quot; : &quot;aparam&quot;,
                        &quot;name2&quot; : &quot;aparam2&quot;
                    ]
                    parallelStagesMap = map.collectEntries {
                        [&quot;${it.key}&quot; : generateStage(it)]
                    }
                }
            }
        }
        stage('Test') {
            steps {
                script {
                    parallel parallelStagesMap 
                }
            }
        }
        stage('Release') {
            agent etc
            steps {
                etc
            }
        }
    }
}

</code></pre>

<p>To run your dynamically created jobs in parallel you will have to use scripted pipeline syntax.<br />
The equivalent syntax for the declarative <code>kubernetes</code> agent in the scripted pipeline is <code>podTemplate</code> and <code>node</code> (see full <a href="https://plugins.jenkins.io/kubernetes/" rel="nofollow noreferrer">Doucumentation</a>):</p>
<pre class="lang-groovy prettyprint-override"><code>podTemplate(yaml: '''
    apiVersion: v1
    kind: Pod
    spec:
      containers:
      - name: maven
        image: maven:3.8.1-jdk-8
        command:
        - sleep
        args:
        - 99d
''') {
  node(POD_LABEL) {
     ...
    }
}
</code></pre>
<p>Notice that the <code>podTemplate</code> can receive the <code>cloud</code> parameter in addition to the yaml but it defaults to <code>kubernetes</code> so there is no need to pass it.</p>
<p>So in your case you can use this syntax to run the jobs in parallel on different agents:</p>
<pre class="lang-groovy prettyprint-override"><code>// Assuming yaml is same for all nodes - if not it can be passed as parameter
podYaml= &quot;&quot;&quot;
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: name
    image: image
    command:
    - sleep
    args:
    - infinity
&quot;&quot;&quot;

pipeline {
    agent none
    stages {
        stage('Create List of Stages to run in Parallel') {
            steps {
                script {
                    def map = [&quot;name&quot; : &quot;aparam&quot;,
                              &quot;name2&quot; : &quot;aparam2&quot;]
                    parallel map.collectEntries {
                        [&quot;${it.key}&quot; : generateStage(it)]
                    }
                }
            }
        }
    }
}

def generateStage(job) {
    return {
        stage(job.key) {
            podTemplate(yaml:podYaml)  {
                node(POD_LABEL) {
                    // Each execution runs on its own node (pod)
                    sh &quot;do some important stuff with ${job.value}&quot;
                }
            }
        }
    }
}
</code></pre>
