{"id":487,"date":"2026-10-14T18:01:23","date_gmt":"2026-10-14T18:01:23","guid":{"rendered":"http:\/\/www.scmgalaxy.com\/tutorials\/2016\/08\/17\/generate-jenkins-job-configuration-automatically\/"},"modified":"2026-10-14T18:01:23","modified_gmt":"2026-10-14T18:01:23","slug":"generate-jenkins-job-configuration-automatically","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/generate-jenkins-job-configuration-automatically\/","title":{"rendered":"Automating Jenkins Job Configuration: Job DSL, Multibranch, Job Generator, and JJB"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Generating Jenkins jobs automatically helps teams avoid repetitive UI work, reduce configuration drift, and review CI changes in version control. This guide is for DevOps engineers who manage many similar jobs and need a practical map of the available approaches.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Originally published on 2016-08-17; fully revised and updated.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img decoding=\"async\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2016\/08\/generate-jenkins-job-config.png\" alt=\"Generate Jenkins job configuration automatically\" \/><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Main options for automatic Jenkins job generation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The original post listed several ways to automate Jenkins configuration. The table below summarizes what each option is meant to do and where to read more.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Option<\/th><th>What it automates<\/th><th>Best fit<\/th><th>References<\/th><\/tr><\/thead><tbody><tr><td>Job DSL Plugin<\/td><td>Programmatic creation of Jenkins projects using a DSL script.<\/td><td>Teams that want Jenkins job definitions in code, generated by a seed job.<\/td><td><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Job+DSL+Plugin\">Plugin page<\/a><br><a href=\"https:\/\/github.com\/jenkinsci\/job-dsl-plugin\/wiki\/Tutorial---Using-the-Jenkins-Job-DSL\">Tutorial<\/a><\/td><\/tr><tr><td>Multi-Branch Project Plugin<\/td><td>Creates sub-projects for each branch from shared configuration.<\/td><td>Repositories where branch-based job creation is required.<\/td><td><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Multi-Branch+Project+Plugin\">Plugin page<\/a><\/td><\/tr><tr><td>Job Generator Plugin<\/td><td>Adds a \u201cJob Generator\u201d job type that creates projects when executed.<\/td><td>Use cases that need runtime generation of jobs from a generator job.<\/td><td><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Job+Generator+Plugin\">Plugin page<\/a><\/td><\/tr><tr><td>Jenkins Job Builder (JJB)<\/td><td>Defines Jenkins jobs in YAML or JSON and applies them via CLI.<\/td><td>Teams preferring YAML-based job definitions outside Jenkins.<\/td><td><a href=\"http:\/\/docs.openstack.org\/infra\/jenkins-job-builder\/\">JJB docs<\/a><br><a href=\"https:\/\/www.slalom.com\/thinking\/automatically-generating-jenkins-jobs\">Example write-up<\/a><\/td><\/tr><tr><td>Templates + parameterized builds<\/td><td>Uses reusable templates and parameters to reduce manual duplication.<\/td><td>Organizations creating many similar jobs frequently.<\/td><td><a href=\"http:\/\/www.blackpepper.co.uk\/generating-new-jenkins-jobs-from-templates-and-parameterised-builds\/\">Case study<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Typical workflow for jobs-as-code in Jenkins<\/h2>\n\n\n\n<pre class=\"mermaid\">\nflowchart TD\n    A[Store job definitions in Git] --> B[Seed job or jenkins-jobs CLI runs]\n    B --> C[Generate or update Jenkins jobs]\n    C --> D[Optional branch-based job creation]\n    D --> E[Builds run with shared standards]\n    E --> F[Changes reviewed and audited in Git]\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Example: generate jobs with Job DSL<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A common pattern is to keep DSL scripts in Git and execute them from a seed job. The snippet below shows a simple generated freestyle job.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript language-groovy\">folder(<span class=\"hljs-string\">'services'<\/span>)\n\njob(<span class=\"hljs-string\">'services\/sample-java-build'<\/span>) {\n  description(<span class=\"hljs-string\">'Generated by Job DSL'<\/span>)\n  scm {\n    git(<span class=\"hljs-string\">'https:\/\/git.example.com\/team\/sample-java.git'<\/span>, <span class=\"hljs-string\">'main'<\/span>)\n  }\n  triggers {\n    scm(<span class=\"hljs-string\">'H\/5 * * * *'<\/span>)\n  }\n  steps {\n    shell(<span class=\"hljs-string\">'.\/gradlew test'<\/span>)\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">A seed pipeline can then apply all DSL files in a repository path.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript language-groovy\">pipeline {\n  agent any\n  stages {\n    stage(<span class=\"hljs-string\">'Generate jobs'<\/span>) {\n      steps {\n        jobDsl targets: <span class=\"hljs-string\">'jobs\/**\/*.groovy'<\/span>, <span class=\"hljs-attr\">removedJobAction<\/span>: <span class=\"hljs-string\">'DISABLE'<\/span>\n      }\n    }\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Example: manage jobs with Jenkins Job Builder (YAML)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Jenkins Job Builder lets you store human-readable YAML and push it to Jenkins from the command line.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript language-yaml\">- job:\n    name: sample-java-build\n    project-type: freestyle\n    <span class=\"hljs-attr\">scm<\/span>:\n      - git:\n          url: https:<span class=\"hljs-comment\">\/\/git.example.com\/team\/sample-java.git<\/span>\n          branches:\n            - main\n    <span class=\"hljs-attr\">builders<\/span>:\n      - shell: |\n          .\/gradlew test<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-bash\">jenkins-jobs --conf jenkins_jobs.ini test jobs\/\njenkins-jobs --conf jenkins_jobs.ini update jobs\/<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Quick decision guide<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Use <strong>Job DSL<\/strong> when Jenkins-native job generation from Groovy scripts is your preferred model.<\/li><li>Use <strong>Jenkins Job Builder<\/strong> when you want YAML\/JSON definitions and CLI-driven updates.<\/li><li>Use <strong>Multibranch<\/strong> when branch discovery and shared per-branch configuration are central requirements.<\/li><li>Use <strong>template + parameterized patterns<\/strong> when reducing repetitive job cloning is the primary goal.<\/li><li>Consider <strong>Job Generator Plugin<\/strong> only after confirming it matches your current Jenkins\/plugin ecosystem.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Further reading from the original post<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The original article was a curated link list. Those references are preserved below.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Job+DSL+Plugin\">https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Job+DSL+Plugin<\/a><\/li><li><a href=\"https:\/\/github.com\/jenkinsci\/job-dsl-plugin\/wiki\/Tutorial---Using-the-Jenkins-Job-DSL\">https:\/\/github.com\/jenkinsci\/job-dsl-plugin\/wiki\/Tutorial&#8212;Using-the-Jenkins-Job-DSL<\/a><\/li><li><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Multi-Branch+Project+Plugin\">https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Multi-Branch+Project+Plugin<\/a><\/li><li><a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Job+Generator+Plugin\">https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Job+Generator+Plugin<\/a><\/li><li><a href=\"http:\/\/docs.openstack.org\/infra\/jenkins-job-builder\/\">http:\/\/docs.openstack.org\/infra\/jenkins-job-builder\/<\/a><\/li><li><a href=\"https:\/\/www.slalom.com\/thinking\/automatically-generating-jenkins-jobs\">https:\/\/www.slalom.com\/thinking\/automatically-generating-jenkins-jobs<\/a><\/li><li><a href=\"http:\/\/www.blackpepper.co.uk\/generating-new-jenkins-jobs-from-templates-and-parameterised-builds\/\">http:\/\/www.blackpepper.co.uk\/generating-new-jenkins-jobs-from-templates-and-parameterised-builds\/<\/a><\/li><li><a href=\"https:\/\/www.youtube.com\/watch?v=ZCfrNvu6nMc\">https:\/\/www.youtube.com\/watch?v=ZCfrNvu6nMc<\/a> (linked in the original page\u2019s broken YouTube gallery error message)<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Best practices<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Keep all job definitions in version control and require pull-request review for changes.<\/li><li>Use one seed\/generator path per team or domain to keep ownership clear.<\/li><li>Start with naming conventions and folder standards before scaling job generation.<\/li><li>Test generated configs in a non-production Jenkins first, then promote.<\/li><li>Document rollback steps when generated jobs are changed or removed.<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Manually creating many Jenkins jobs is slow and error-prone. This guide compares the main automation options and shows practical jobs-as-code examples for repeatable setup.<\/p>\n","protected":false},"author":1,"featured_media":2944,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[42],"tags":[795,282,793,145,797,794,798,796],"class_list":["post-487","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-jenkins","tag-automatically","tag-configuration","tag-generate","tag-jenkins","tag-jenkins-job-builder","tag-jenkins-job-configuration","tag-jenkins-tutorials","tag-job-generator"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/487","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=487"}],"version-history":[{"count":3,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/487\/revisions"}],"predecessor-version":[{"id":79369,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/487\/revisions\/79369"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media\/2944"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=487"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=487"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=487"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}